Problem
MetaTrader 5’s Python API is request/response based. For Socketrade, I wanted the terminal to push ticks, closed bars and trade transactions to Python strategies, with commands travelling back for order execution.
The runtime also needed to manage concurrent setups—each a strategy, symbol or pair, timeframe and risk configuration. Changing a setup should not require restarting the bot, and disabling new entries should not abandon positions already open.
Architecture
An MQL5 Expert Advisor and Python asyncio hub form a newline-delimited JSON socket bridge. The hub feeds terminal events into a strategy runtime whose setups are defined by YAML configuration and model files. A backtester feeds historical bars through the same strategy runtime, with a small web UI generating forms from the configuration schema and charting results.
What I built
- Built both sides of the bridge, including subscriptions to ticks, symbol/timeframe bars and trade transactions, and commands for account information, historical rates, positions and order execution.
- Built the event runtime, hot-reloadable setup lifecycle and persistent position state.
- Implemented rule-based and PyTorch strategies, streaming feature windows, position sizing and trading controls.
- Built historical replay and its configuration-driven web interface.
The related statistical-arbitrage project covers the pair research and earlier execution engines.
Engineering decisions
- Closed bars are emitted when the next bar opens, ensuring strategies receive completed data while accepting that notification depends on the next bar.
- Request IDs match replies to waiting callers. Requests have timeouts, shared subscriptions are reference-counted and strategy failures are isolated from other setups.
- Both sides queue outbound messages. The EA recovers partial writes and reconnects automatically; the hub restores active subscriptions after reconnection and handles socket backpressure.
- Setup schemas are derived from strategy dataclasses. Disabling a setup blocks new entries but keeps management of its existing positions active.
- Streaming feature windows avoid rebuilding full history for each event, and historical replay shares live strategy logic while acknowledging it cannot reproduce every fill, spread, delay or connection failure.
Technologies
Python 3.12 (uv, asyncio), MQL5, MetaTrader 5, PyTorch, scikit-learn, statsmodels, pandas, boto3.
Results
Socketrade supported live rule-based and ML trading setups within one event-driven runtime. It connects terminal events, configurable strategy lifecycles and historical replay: setups can be changed while the bot runs, with disabled setups continuing to manage open positions rather than abandoning them.