6fe1a3e0f0
DOCUMENTATION.md: Two-section guide covering the full project — plain-English trader guide (indicators, scoring, trade setups) and developer reference (architecture, data flow, every threshold/weight). mt5.md: Architecture plan for automated order execution via MT5 bridge (REST API on Windows, async client on Linux, risk-based lot sizing). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
186 lines
7.5 KiB
Markdown
186 lines
7.5 KiB
Markdown
# MT5 Auto-Execution Integration Plan
|
|
|
|
## Context
|
|
ForexBot2 generates trade signals with full setups (entry, SL, TP) but currently only displays them in Telegram. The user wants fully automatic order execution via MetaTrader 5.
|
|
|
|
**Constraint:** MT5 runs on a separate Windows machine. The Python `MetaTrader5` package requires Windows (COM interface). The bot runs on Linux. A network bridge is needed.
|
|
|
|
**Broker:** TIO Markets (demo first, live later via config change).
|
|
**Execution mode:** Fully automatic for actionable signals (A+/A/B grades).
|
|
|
|
## Architecture: REST API Bridge
|
|
|
|
```
|
|
Linux (telegram_bot.py) Windows (mt5_bridge.py)
|
|
======================== ========================
|
|
Signal fires with TradeSetup FastAPI server running
|
|
-> mt5_client.execute_trade() -> Wraps MetaTrader5 package
|
|
POST /api/order ─────── HTTP ───────> -> mt5.order_send()
|
|
<- {ticket: 12345} <──── HTTP ────── <- Returns ticket or error
|
|
-> Telegram: "ORDER PLACED" -> Idempotency via order_id
|
|
```
|
|
|
|
**Why REST over WebSocket/file-sync:** Stateless, debuggable, retry-safe. For a bot placing 1-5 trades/day, HTTP latency (5-50ms LAN) is negligible.
|
|
|
|
## Files to Create/Modify
|
|
|
|
### New Files
|
|
|
|
**1. `mt5_bridge/mt5_bridge.py`** — Windows-side FastAPI server (~200 lines)
|
|
- Wraps `MetaTrader5` Python package
|
|
- Endpoints: `/api/health`, `/api/account`, `/api/positions`, `/api/order` (POST), `/api/order/close` (POST)
|
|
- Lot size calculation on bridge side (has access to `mt5.symbol_info()` for tick value, contract size, volume step)
|
|
- Idempotency: stores `{order_id: ticket}` to prevent duplicate orders on retry
|
|
- API key auth via `X-API-Key` header
|
|
- MT5 credentials from env vars: `MT5_LOGIN`, `MT5_PASSWORD`, `MT5_SERVER`, `MT5_PATH`
|
|
|
|
**2. `mt5_bridge/requirements.txt`** — Windows dependencies
|
|
- `fastapi`, `uvicorn`, `MetaTrader5`, `pydantic`
|
|
|
|
**3. `mt5_client.py`** — Linux-side async HTTP client (~150 lines)
|
|
- `MT5ExecutionClient` class with `aiohttp`
|
|
- `execute_trade(setup: TradeSetup, quality: str)` — sends order to bridge
|
|
- Symbol mapping: `EURUSD=X` -> `EURUSD` (TIO Markets format, configurable)
|
|
- Duplicate prevention: tracks open positions per symbol
|
|
- Retry: 3 attempts, exponential backoff, same `order_id` for idempotency
|
|
- Position sync: periodically calls `/api/positions` to stay in sync with MT5
|
|
- Graceful degradation: if bridge offline, logs warning, bot continues signal-only
|
|
|
|
### Modified Files
|
|
|
|
**4. `config.py`** — Add `MT5Config` dataclass
|
|
```python
|
|
@dataclass
|
|
class MT5Config:
|
|
enabled: bool = False
|
|
bridge_url: str = "http://192.168.1.100:8080"
|
|
bridge_api_key: str = ""
|
|
risk_pct: float = 1.0 # % of balance risked per trade
|
|
max_open_positions: int = 3
|
|
max_daily_trades: int = 10 # Circuit breaker
|
|
magic_number: int = 234000 # Identifies ForexBot2 orders
|
|
slippage_points: int = 20 # 2 pips for 5-digit brokers
|
|
auto_execute_grades: List[str] # ["A+", "A", "B"]
|
|
symbol_map: Dict[str, str] # Internal -> broker symbol
|
|
```
|
|
All overridable via env vars (`MT5_BRIDGE_URL`, `MT5_RISK_PCT`, etc.)
|
|
|
|
**5. `telegram_bot.py`** — Wire execution into signal flow
|
|
- In `_scan_timeframe()`: after sending Telegram messages, call `mt5_client.execute_trade()` for actionable signals
|
|
- In `_handle_breach()`: same pattern after breach scan produces actionable signal
|
|
- Add background task `_mt5_position_sync_loop()` for periodic position sync
|
|
- Add Telegram commands: `/mt5status` (bridge health + account info), `/positions` (open trades)
|
|
- Register new commands in `set_my_commands()`
|
|
- Execution result messages sent to Telegram (ticket # on success, error on failure)
|
|
|
|
**6. `requirements.txt`** — Add `aiohttp>=3.9` (async HTTP for Linux-side client)
|
|
|
|
## Safety Layers
|
|
|
|
1. **Demo account first** — `MT5_SERVER=TIOMarkets-Demo`
|
|
2. **`enabled: False` default** — must explicitly opt-in via `MT5_ENABLED=true`
|
|
3. **Duplicate prevention** — 3 layers: client-side tracking, bridge-side position check, idempotent `order_id`
|
|
4. **Circuit breaker** — `max_daily_trades` stops execution if too many orders fire
|
|
5. **Position limit** — `max_open_positions` caps concurrent exposure
|
|
6. **Risk-based sizing** — lot size from `risk_pct` of account balance, calculated on bridge with live tick values
|
|
7. **Graceful degradation** — bridge offline = signal-only mode, no crash
|
|
|
|
## Position Sizing (calculated on Windows bridge)
|
|
|
|
```
|
|
risk_amount = balance * (risk_pct / 100)
|
|
tick_value = mt5.symbol_info(symbol).trade_tick_value
|
|
tick_size = mt5.symbol_info(symbol).trade_tick_size
|
|
sl_ticks = abs(entry - stop_loss) / tick_size
|
|
lot_size = risk_amount / (sl_ticks * tick_value)
|
|
lot_size = round_down(lot_size, volume_step)
|
|
lot_size = clamp(lot_size, volume_min, volume_max)
|
|
```
|
|
|
|
Bridge side is best because it has real-time `tick_value` (varies with exchange rates for cross pairs).
|
|
|
|
## Symbol Mapping (TIO Markets)
|
|
|
|
| Internal | MT5 Symbol |
|
|
|----------|-----------|
|
|
| `EURUSD=X` | `EURUSD` |
|
|
| `USDJPY=X` | `USDJPY` |
|
|
| `GBPUSD=X` | `GBPUSD` |
|
|
| `XAU/USD` | `XAUUSD` |
|
|
|
|
Configurable via `MT5_SYMBOL_MAP` env var (JSON) for broker variations.
|
|
|
|
## Integration Points
|
|
|
|
### In `_scan_timeframe()` (after line ~406):
|
|
```python
|
|
mt5 = _get_mt5_client()
|
|
if mt5:
|
|
for report in actionable:
|
|
if report.trade_setup and report.signal_quality in mt5.config.auto_execute_grades:
|
|
result = await mt5.execute_trade(report.trade_setup, report.signal_quality)
|
|
# Send execution confirmation/error to Telegram
|
|
```
|
|
|
|
### In `_handle_breach()` (after line ~477):
|
|
```python
|
|
if report.trade_setup and report.signal_quality in mt5.config.auto_execute_grades:
|
|
mt5 = _get_mt5_client()
|
|
if mt5:
|
|
result = await mt5.execute_trade(report.trade_setup, report.signal_quality)
|
|
# Send execution confirmation/error to Telegram
|
|
```
|
|
|
|
## New Telegram Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `/mt5status` | Bridge health, account balance/equity, open positions count |
|
|
| `/positions` | List all open MT5 positions with P/L |
|
|
|
|
## Implementation Order
|
|
|
|
1. `config.py` — Add `MT5Config`
|
|
2. `mt5_bridge/mt5_bridge.py` + `requirements.txt` — Windows bridge server
|
|
3. `mt5_client.py` — Linux HTTP client
|
|
4. `telegram_bot.py` — Wire execution + new commands
|
|
5. `requirements.txt` — Add `aiohttp`
|
|
|
|
## Verification
|
|
|
|
1. Start bridge on Windows: `python mt5_bridge.py` -> verify `curl /api/health` returns MT5 connected
|
|
2. Test order via curl: `POST /api/order` with demo credentials -> verify order appears in MT5
|
|
3. Start bot on Linux with `MT5_ENABLED=true` -> verify `/mt5status` command works
|
|
4. Wait for actionable signal (or manually trigger scan) -> verify order placed + Telegram confirmation
|
|
5. Verify duplicate prevention: same signal shouldn't place second order
|
|
6. Kill bridge -> verify bot continues in signal-only mode without crashing
|
|
|
|
## Windows Bridge Setup (one-time)
|
|
|
|
```bash
|
|
# On Windows machine:
|
|
pip install fastapi uvicorn MetaTrader5 pydantic
|
|
|
|
# Set environment variables:
|
|
set MT5_LOGIN=12345678
|
|
set MT5_PASSWORD=your-password
|
|
set MT5_SERVER=TIOMarkets-Demo
|
|
set MT5_PATH=C:\Program Files\MetaTrader 5\terminal64.exe
|
|
set BRIDGE_API_KEY=your-random-32-char-key
|
|
set BRIDGE_PORT=8080
|
|
|
|
# Run:
|
|
python mt5_bridge.py
|
|
```
|
|
|
|
## Linux Bot Config (env vars)
|
|
|
|
```bash
|
|
MT5_ENABLED=true
|
|
MT5_BRIDGE_URL=http://<windows-ip>:8080
|
|
MT5_BRIDGE_API_KEY=your-random-32-char-key
|
|
MT5_RISK_PCT=1.0
|
|
MT5_MAX_OPEN_POSITIONS=3
|
|
MT5_AUTO_EXECUTE_GRADES=A+,A,B
|
|
```
|