Add project documentation and MT5 integration plan
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).
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user