# DRL‑MT5‑Lab

Deep Reinforcement Learning (SB3) + MetaTrader 5 (MT5) for **backtesting** and **live trading**.

This repo keeps research and production concerns separate:
- **Notebooks** for data/feature engineering, training, optimization, backtesting and reports.
- **CLI** for **live inference only** (stable, safe, log‑rich).


---

## Highlights

- **Stable‑Baselines3** agents: PPO, A2C, DQN.
- Clean **live trading CLI** (`live_bot.py`) with multi-algorithm support:
  - **DRY‑RUN** by default (no orders until `--live`).
  - **Market guard**: weekend + stale tick check (configurable).
  - FinRL‑style **verbose logs** + rotating file logs.
  - Feature snapshot (e.g., `close`, `ma_fast`, `ma_slow`, `rsi`).
- Backtest notebook with equity curve; optional QuantStats HTML report.
- Config via `.env` + CLI flags.

---

## Repo layout (typical)

```
.
├─ notebooks/
│  ├─ 1_Data.ipynb
│  ├─ 2_Train.ipynb
│  ├─ 3_Backtest.ipynb
│  └─ 4_Live_Demo.ipynb
│  └─ models/
│    ├─ selected_features.json   # list of columns used by the model
│    └─ ppo_{SYMBOL}_{TF}.zip    # exported Stable‑Baselines3 model
├─ adapters/
│  └─ broker.py                  # MT5 wrapper used by the CLI
│  └─ mt5.py                     # MT5 API functions
├─ features.py                   # add_indicators(...) etc.
├─ live_bot.py                   # ASCII logs + market‑hours guard  ← recommended
├─ utils.py                     
├─ requirements.txt
├─ .env.example
└─ README.md
```

---

## Quickstart

### 1) Environment
```bash
# create and activate your venv/conda, then:
pip install -r requirements.txt
# TA‑Lib on Windows: you may prefer a prebuilt 'ta-lib' wheel or conda-forge.
```

### 2) Create `.env`
Copy `.env.example` → `.env` and fill your MT5 credentials and defaults.

### 3) Train / export a model
Use the notebooks (recommended) to train and save:
- `models/ppo_{SYMBOL}_{TF}.zip`
- `models/selected_features.json` (list of feature column names)

> Alternatively point `--model`/`--features` at your own paths.

### 4) Run the live CLI (default DRY‑RUN)
```bash
# Windows PowerShell
python live_bot.py --symbol EURUSD --timeframe M15

# Place real orders (be careful)
python live_bot.py --symbol EURUSD --timeframe M15 --live
```

The bot will:
1) Pull latest bars via `adapters/broker.fetch_last_n(...)`
2) Build features with `features.add_indicators(...)`
3) Predict action with SB3
4) Close opposite‑side positions if any
5) Place a market order (unless DRY‑RUN)
6) Sleep to the next bar boundary

Logs are streamed to console and to `logs/live_bot.log` (rotating).

---

## CLI options

```bash
python live_bot.py --help
```

Important flags:

- `--symbol EURUSD`           Trading symbol
- `--timeframe M15`           M1/M5/M15/M30/H1/H4/D1 etc.
- `--model PATH`              Model zip (default: models/ppo_{SYMBOL}_{TF}.zip; also checks notebooks/models/)
- `--features PATH`           JSON list of feature columns (default: models/selected_features.json)
- `--volume 0.01`             Lot size
- `--live`                    Actually place orders (otherwise DRY‑RUN)
- `--dry-run`                 Force dry‑run even if `--live` was set
- `--order-comment DRL-Live`  MT5 order comment (shows up in the terminal)
- `--log-file logs/live_bot.log`
- `--skip-market-check`       Bypass weekend/stale‑tick guard
- env: `WEEKEND_TRADING=true` Allow weekend trading (e.g., crypto)

> **Action mapping:** This CLI maps **`0=BUY, 1=HOLD, 2=SELL`** by default (legacy-friendly).  
> If your model uses **`0=BUY, 1=HOLD, 2=SELL`** (common in your legacy notebook), edit `action_to_signals(...)` in the file accordingly.

---

## .env example

See **.env.example** in this repo. Key fields:

```ini
# MT5 connection
MT5_LOGIN=12345678
MT5_PASSWORD=your_password
MT5_SERVER=YourBroker-Server


# Defaults (used if CLI flags are not provided)
TRAINING_SYMBOL=EURUSD
TIMEFRAME=M15
VOLUME=0.01
ORDER_COMMENT=DRL-Live

# Optional Telegram (enable in code where noted)
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=

# Live behavior
WEEKEND_TRADING=false
ALGO=auto
MAGIC=234002
USE_SLTP=false
SL_ATR=2.0
TP_ATR=3.0
```

---

## Backtesting

- Use `notebooks/3_Backtest.ipynb` for a full workflow:
  - Load test split
  - Roll the policy
  - Plot equity curve
  - Compute rough Sharpe (rescaled by bar frequency)
  - (Optional) `QuantStats` report

Minimal snippet you can adapt inside the notebook:
```python
from stable_baselines3 import PPO
import pandas as pd, numpy as np, matplotlib.pyplot as plt

model = PPO.load("models/ppo_EURUSD_M15.zip")

# df_test & feature_cols prepared earlier…
obs, _ = env.reset()
equity = [1.0]
while True:
    action, _ = model.predict(obs, deterministic=True)
    obs, reward, terminated, truncated, info = env.step(int(action))
    equity.append(equity[-1] * (1.0 + reward))
    if terminated or truncated: break

equity = pd.Series(equity, index=df_test.index[:len(equity)])
equity.plot(title="Equity Curve")
plt.show()
```


---

## Broker adapter

All live operations go through `adapters/broker.py`. It should implement:

- `open_session(login, password, server, path) -> bool`
- `close_session() -> None`
- `fetch_last_n(symbol, timeframe, n) -> pd.DataFrame[open,high,low,close,tick_volume,…]`
- `current_positions(symbol) -> pd.DataFrame[ticket,type,volume,profit,magic?,…]`
- `place_market_order(symbol, side, volume, comment, sl=None, tp=None, **kwargs) -> dict`
- (optional) `last_tick(symbol) -> dict` with `bid/ask/time`

> If you want **magic‑number scoping** and **ATR‑based SL/TP**, expose `magic` in positions and accept `sl/tp/deviation` in the order call, then wire the CLI through (tiny patch).

---

## Logging & Windows notes

- Console + rotating file logs (`logs/live_bot.log`).
- On legacy Windows consoles you can also enable UTF‑8:
  - PowerShell: `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8`
  - CMD: `chcp 65001`

---

## Safety checklist

- Start in **DRY‑RUN**. Inspect logs for a few bars.
- Confirm **action mapping** matches your trained model.
- Verify **volume**, **symbol**, **timeframe**, **order comment**.
- Test with a **demo** account first.
- Use **market guard** unless you’re sure about weekend/overnight behavior.

---

## FAQ

**Q: The bot says “market closed” on Saturday**  
A: Expected for most FX pairs. Either wait for Monday or set `WEEKEND_TRADING=true` and `--skip-market-check` (only if your instrument trades on weekends).

**Q: No trades are placed in DRY‑RUN**  
A: That’s by design. Add `--live` to actually send orders.

**Q: My BUY/SELL seem inverted**  
A: Update `action_to_signals(...)` to match your model’s action semantics (see note above).

---

## Backtesting Report

The `3_Backtest.ipynb` notebook evaluates all trained models and generates a comparison of their equity curves, along with detailed individual performance reports.

### Equity Curve Comparison

| Metric       | Value       |
|--------------|-------------|
| Model        | PPO         |
| File         | ppo_EURUSD_M15.zip |
| Bars         | 9956.0      |
| Sharpe       | 0.896809    |
| Sortino      | 1.245242    |
| CAGR         | 0.065507    |
| Calmar       | 1.755408    |
| MaxDD        | -0.037317   |
| WinRate      | 0.476195    |
| ProfitFactor | 1.018795    |
| Exposure     | 0.995078    |
| Trades       | 238.0       |
| AvgHoldBars  | 847.694255  |
![Equity Curve Comparison](notebooks/reports/ppo_EURUSD.png)
![Equity Curve Comparison](notebooks/reports/newplot.png)


📊 Individual model reports (PPO, A2C, DQN) are available in `notebooks/reports/`.  
To view them, download the HTML files locally for full interactivity.

📊 [View PPO quantstats  Report (Rendered)](https://htmlpreview.github.io/?https://github.com/maghdam/Deep-Reinforcement-Learning-MT5-Bot/blob/master/notebooks/reports/qs_ppo_EURUSD_M15.html)

📊 [View PPO Plotly Report (Rendered)](https://raw.githack.com/maghdam/Deep-Reinforcement-Learning-MT5-Bot/master/notebooks/reports/plotly/plotly_ppo_EURUSD_M15.html)



> Note: You may need to download the HTML files to view the interactive charts. GitHub provides a static preview.

---

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

---

## Disclaimer

This repository is for educational and research purposes only.
Nothing herein constitutes financial, investment, or trading advice.
Trading involves substantial risk. You are solely responsible for any
use of the code and any resulting outcomes.

