A trader showed us an EA that automatically reduced position size 15 minutes before NFP. Not a hard-coded time filter. The EA "decided" on its own, based on a machine learning model running directly inside MT5.
No API calls. No internet dependency. No latency. The model runs as a local .onnx file inside the EA, producing predictions in microseconds.
MT5 has natively supported ONNX Runtime since Build 3600. This means you can train a model in Python using any framework — TensorFlow, PyTorch, Scikit-learn — export it to the universal .onnx format, and run it inside your EA with three MQL5 function calls.
The workflow: four steps
-
Train your model in Python. Standard ML pipeline: prepare features, train classifier or regressor, evaluate.
-
Export to
.onnx. One line of code:skl2onnxfor Scikit-learn,tf2onnxfor TensorFlow,torch.onnx.export()for PyTorch. -
Place the
.onnxfile inMQL5/Files/or compile it as a resource into the EA. -
In MQL5:
OnnxCreate()to load,OnnxRun()to infer,OnnxRelease()to clean up. Three functions, done.
From training to deployment in an afternoon. Training a model that actually improves your EA is a different story.
What types of models work
Classification: input technical indicator values, output buy/sell/hold. Random forest, XGBoost, simple neural networks. This is where most people should start. Simple logic, easy to debug, clear output.
Regression: predict specific values like next-candle closing price or 4-hour volatility range. Linear regression, LSTM, Transformer architectures.
Anomaly detection: train the model on "normal" market behavior, flag when conditions deviate. Useful for detecting liquidity anomalies or sudden regime changes. Isolation Forest and Autoencoders are common choices.
Start with classification. Add complexity only after you've proven the concept works.
Example: Random Forest signal filter
Python training:
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
# Features: RSI(14), price deviation from MA20 (%), normalized ATR(14)
# Labels: 1 = price up over next 5 candles, 0 = down
X_train = np.array(features_train, dtype=np.float32)
y_train = np.array(labels_train)
model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
model.fit(X_train, y_train)
# Export to ONNX
initial_type = [('input', FloatTensorType([None, 3]))]
onnx_model = convert_sklearn(model, initial_types=initial_type)
with open("rf_signal.onnx", "wb") as f:
f.write(onnx_model.SerializeToString())
MQL5 loading and inference:
#resource "\\Files\\rf_signal.onnx" as uchar OnnxModel[]
long onnxHandle = INVALID_HANDLE;
int OnInit()
{
onnxHandle = OnnxCreate(OnnxModel, ONNX_DEFAULT);
if(onnxHandle == INVALID_HANDLE)
{
Print("Failed to load ONNX model");
return INIT_FAILED;
}
ulong inputShape[] = {1, 3};
ulong outputShape[] = {1};
OnnxSetInputShape(onnxHandle, 0, inputShape);
OnnxSetOutputShape(onnxHandle, 0, outputShape);
return INIT_SUCCEEDED;
}
void OnTick()
{
// Calculate features (simplified)
double rsiVal[], maVal[], atrVal[];
// ... copy indicator buffers ...
float inputData[3];
inputData[0] = (float)rsiVal[0];
inputData[1] = (float)((close - maVal[0]) / maVal[0] * 100);
inputData[2] = (float)(atrVal[0] / close * 100);
long prediction[1];
if(OnnxRun(onnxHandle, ONNX_NO_CONVERSION, inputData, prediction))
{
if(prediction[0] == 1)
Print("Model prediction: bullish");
else
Print("Model prediction: bearish");
}
}
void OnDeinit(const int reason)
{
if(onnxHandle != INVALID_HANDLE)
OnnxRelease(onnxHandle);
}
Why local ONNX beats API calls
| Local ONNX | External API | |
|---|---|---|
| Latency | 50–500 microseconds | 200–500 milliseconds |
| Internet dependency | None | Required |
| Cost per inference | Zero | Per-call billing |
| Data security | All local | Sent to third-party server |
| Offline capability | Full | None |
For trading where execution speed and reliability matter, local inference wins on every dimension. The only advantage of APIs is access to larger, continuously updated models. For quantitative trading that requires deterministic, low-latency execution, local ONNX is the right choice.
The pitfalls
Models go stale. Financial markets are non-stationary. A model trained on 2024 data may degrade by 2026, or even within weeks. Plan to retrain monthly with fresh data and monitor prediction accuracy in live trading. Two consecutive weeks of accuracy decline = time to retrain.
Garbage in, garbage out. ONNX is a deployment tool. It won't fix bad features, dirty data, or poorly defined labels. Feature engineering matters 10x more than model selection. Spending time on what inputs to feed the model is far more valuable than debating random forest vs neural network.
Overfitting is the primary risk. 99% accuracy on historical data? Almost certainly memorizing noise. Ensure your training and backtest data don't overlap. Use walk-forward validation. If the model doesn't generalize to unseen data, it's worthless.
Set realistic expectations. ML in trading isn't about "predicting the future." It's about improving signal quality. If your EA's win rate goes from 48% to 53% thanks to ONNX filtering, that's a meaningful edge over hundreds of trades. Don't expect 90% accuracy or guaranteed profits.
Start simple. A well-tuned random forest often performs as well as deep learning for trading applications, trains in seconds, resists overfitting better, and infers faster. Get the basic pipeline working before attempting LSTM or Transformer architectures.
FAQ
Do I need to know Python?
Yes, for training and exporting the model. The MQL5 side is straightforward (three functions). Python ML basics take 1–2 weeks to learn with Scikit-learn's documentation. You don't need to be an ML expert. Being able to train a random forest classifier is enough to start.
Can ONNX models be backtested in MT5?
Yes. The strategy tester fully supports ONNX inference. But watch for data leakage: if you train on 2020–2025 data and backtest on the same range, results will be misleadingly good. Always ensure training and test data don't overlap.
Can I run multiple models in one EA?
Yes. Each OnnxCreate() returns an independent handle. One model for trend direction, another for volatility assessment, a third for signal filtering. Multi-model setups often outperform single models but are more complex to manage. Get one working first.
How often should I retrain?
Monthly is a conservative default. Monitor live prediction accuracy weekly. If accuracy drops significantly for two consecutive weeks, retrain immediately. Some teams automate this with Python scripts that periodically fetch new data, train, export, and notify.
Every EA in the FXTool marketplace uses traditional technical indicators rather than ML models, but the infrastructure we've built supports ONNX deployment for traders who want to experiment with hybrid approaches. Read our AI-assisted EA coding guide for the broader picture of using AI in EA development.
About the author: The FXTool team builds and tests MetaTrader trading tools daily. We run every EA we sell on live accounts and publish the results. This guide reflects what we've learned from building 50+ EAs and working with thousands of retail traders.
Forex trading involves significant risk and may result in total loss of capital. This article is for educational purposes only and is not investment advice. Understand the risks and consider your financial situation before trading.