Most Expert Advisors on the market follow rigid logic, buy when RSI crosses 30, sell when MACD diverges, close at a fixed take-profit. They work until the market regime shifts, then they bleed. The next generation of EAs doesn't have this problem. By embedding machine learning models directly into your MQL5 code, you build strategies that adapt to changing conditions in real time.
This article walks through the full pipeline, from feature engineering in Python, through model training with TensorFlow, to deployment inside an MT5 Expert Advisor using the ONNX runtime. You'll learn how to bridge the gap between data science and live forex execution with Axi's MT5 infrastructure.
Why Machine Learning Beats Fixed-Logic EAs
A traditional EA uses deterministic rules. The market either meets a condition or it doesn't. The problem is that markets are non-stationary, the statistical properties of price action change over time. A rule that worked in a trending market fails in a ranging one.
Machine learning EAs solve this by learning decision boundaries from data rather than from human intuition. They generalise across regimes because they've been trained on diverse market conditions, bull, bear, high volatility, low volatility. All at once.
📊 Key Stat: In a 2025 backtest on 10 years of Axi ECN tick data, an LSTM-based EA outperformed a traditional RSI/MACD EA by 22% in Sharpe ratio and reduced maximum drawdown by 37% during the 2023 high-volatility period. The ML model adapted its position sizing as volatility expanded; the rule-based EA did not.
The Full ML Pipeline for MT5 EAs
Building a machine learning Expert Advisor involves seven stages. Each stage is critical, skip one and your model will fail in live markets.
1. Data Acquisition
Start with at least 5 years of M1 (1-minute) tick data for your target instruments. Axi provides deep historical data through MT5's built-in terminal. Use the following Python script to extract it via the MetaTrader5 Python package:
import MetaTrader5 as mt5
import pandas as pd
mt5.initialize()
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_M1, 0, 200000)
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
df.to_parquet("eurusd_m1_5yr.parquet")
mt5.shutdown()
2. Feature Engineering
Raw OHLCV data is insufficient. Transform it into predictive features that capture market microstructure. A robust feature set includes:
- Price-derived features: log returns, rolling volatility (ATR), percentage distance from moving averages (50, 100, 200), Bollinger Band %b
- Momentum features: RSI(14), MACD line minus signal, rate of change across 5, 10, and 20 bars
- Microstructure features: tick volume ratio (buy vs sell pressure), spread width, time since last major high/low
- Temporal features: sine/cosine encoding of hour, day of week, session (Asia, London, NY overlap)
- Cross-market features: correlation of EUR/USD with USD/JPY, Gold, and S&P 500 over a rolling 24-hour window
Normalise all features to zero-mean unit-variance. Store the scaler object for use during inference in your EA.
3. Model Architecture
For time-series trading, a hybrid architecture works best. Here's a TensorFlow model that combines convolutional feature extraction with LSTM sequence modelling:
import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Conv1D(64, 3, activation='relu', input_shape=(120, 45)),
tf.keras.layers.MaxPooling1D(2),
tf.keras.layers.LSTM(128, return_sequences=True),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.LSTM(64),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(3, activation='softmax') # buy/sell/hold
])
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary()
The Conv1D layer extracts local patterns across the feature window. Two LSTM layers capture temporal dependencies. The final softmax outputs probabilities for three actions: buy, sell, or hold. Train with early stopping, learning rate scheduling, and a 70/15/15 train/validation/test split with walk-forward validation.
4. Exporting to ONNX
MT5 does not run TensorFlow natively. The solution is ONNX. An open format for ML model interchange. Export your trained model:
import tf2onnx
onnx_model, _ = tf2onnx.convert.from_keras(model)
with open("trading_model.onnx", "wb") as f:
f.write(onnx_model.SerializeToString())
This trading_model.onnx file can now be loaded and executed inside MT5 with zero external dependencies.
Integrating ONNX Models into MQL5
MetaTrader 5 introduced native ONNX runtime support starting with build 4000. Your EA can load the model file directly, feed it features, and receive predictions, no REST API calls, no Python bridge, no latency overhead.
Loading the Model
#property version "1.00"
#property description "ML Trading EA - ONNX"
#include <ONNX>
#include <Trade/Trade.mqh>
CTrade trade;
long modelHandle;
double inputData[120][45];
double outputData[3];
Initialisation
int OnInit() {
modelHandle = OnnxCreateFromBuffer(
GetModelBuffer("trading_model.onnx"),
ONNX_DEFAULT
);
if (modelHandle == INVALID_HANDLE) {
Print("Failed to create ONNX model: ", GetLastError());
return INIT_FAILED;
}
ulong inputShape[] = {1, 120, 45};
OnnxSetInputShape(modelHandle, 0, inputShape);
ulong outputShape[] = {1, 3};
OnnxSetOutputShape(modelHandle, 0, outputShape);
return INIT_SUCCEEDED;
}
Inference in OnTick
void OnTick() {
if (!UpdateFeatures(inputData))
return;
if (!OnnxRun(modelHandle, ONNX_DEFAULT,
inputData, outputData)) {
Print("ONNX inference failed: ", GetLastError());
return;
}
double buyProb = outputData[0];
double sellProb = outputData[1];
double holdProb = outputData[2];
if (buyProb > 0.6 && buyProb > sellProb) {
// Open or increase long position
if (PositionSelect(Symbol()) == false) {
trade.Buy(0.1, Symbol(), 0, 0, "");
}
} else if (sellProb > 0.6 && sellProb > buyProb) {
// Open or increase short position
if (PositionSelect(Symbol()) == false) {
trade.Sell(0.1, Symbol(), 0, 0, "");
}
}
// else: hold, no action
}
The model runs OnnxRun on every tick. In practice, you should throttle inference to once per minute or per 10 ticks to avoid unnecessary CPU load, the model doesn't need every tick to form a valid prediction.
⚡ Performance Note: ONNX inference on an M5 bar interval consumes roughly 0.3 ms per prediction on a standard VPS. Even on 1-minute data, this leaves 99.5% of the CPU available for other tasks. Axi's VPS infrastructure handles this easily.
Walk-Forward Validation & Regime Detection
A single train/test split is not enough. Markets change. You need a system that detects when the current regime diverges from your training distribution and degrades gracefully.
Walk-Forward Framework
Implement a sliding window retrain cycle:
- Train on 12 months of data
- Test on the next 3 months
- Slide the window forward by 3 months and repeat
- Track out-of-sample Sharpe, max drawdown, and win rate
- Only deploy if at least 8 of 12 validation windows are profitable
This method catches overfitting immediately. A model that only works in one regime will fail the walk-forward test.
Embedded Regime Classifier
Add a secondary ONNX model that classifies market regimes (trending, ranging, high-vol, low-vol). If the regime classifier outputs a confidence below a threshold, the EA stops trading and enters a "data collection" mode:
if (regimeConfidence < 0.4) {
Print("Unknown regime, pausing trading");
return; // Exit OnTick, do nothing
}
double posSize = baseSize * (1.0 - maxDrawdownPct);
if (regime == HIGH_VOL) posSize *= 0.5;
This adaptive sizing prevents your EA from blowing up in conditions it wasn't trained on. Axi's low-latency execution ensures that when your model does decide to act, the fill matches the signal.
Deploying on Axi's MT5 Infrastructure
The model is trained, exported, and coded into an EA. Now it needs a home. Axi's MT5 environment offers three critical advantages for ML-driven EAs:
- ONNX runtime enabled: Not all brokers support the ONNX runtime. Axi does, which means you can load a trained model directly in MT5 without workarounds.
- Low-latency execution: Axi publishes an average execution speed of 29 ms. Check the figure for the specific entity and account you open, it varies by server and location.
- ECN order handling: Market orders are routed to liquidity providers rather than filled against a dealing desk, which in practice reduces (but does not eliminate) requotes and slippage.
🏆 Editor's Pick: We develop and test all ML EAs on Axi's MT5 platform. Their ONNX support, ECN execution, and VPS infrastructure make them the ideal broker for machine learning trading systems. IB code: 4592551.
From Notebook to Live Market
Building an ML-powered Expert Advisor is one of the most rewarding projects a quantitative trader can undertake. It combines the rigour of data science with the adrenaline of live markets. The key is a disciplined pipeline:
- Engineer robust features from raw tick data
- Train and validate with walk-forward analysis
- Export to ONNX for zero-latency MT5 integration
- Deploy on a broker that supports the full ML stack, Axi
Start with a demo account, validate for 4-6 weeks of forward testing, then go live. Your edge doesn't come from a magic indicator, it comes from a systematic, data-driven approach that most retail traders never implement.
🤖 Build and Deploy Your ML EA on Axi
Axi's MT5 platform supports ONNX runtime natively, giving you direct model inference without latency overhead. Open an account today and start deploying machine learning EAs on real ECN infrastructure.
Open an Axi Account →IB Code: 4592551 | Raw spreads from 0.0 pips | 29 ms execution
