🐍 Practical Tutorial

How to Export Python (PyTorch + Sklearn) to ONNX and Use in MT5

By Dan Machado · 11 min read

Step-by-step tutorial, no fluff: you finish with two working ONNX models (one Sklearn Random Forest, one PyTorch LSTM), ready to be consumed in MT5 Expert Advisors. Prerequisite: Python 3.10+ and MT5 installed.

Python environment setup

# Essential libraries
pip install MetaTrader5 numpy pandas scikit-learn

# ONNX exporters
pip install onnx onnxruntime onnxmltools skl2onnx

# For PyTorch (CPU)
pip install torch torchvision

Part 1 — Random Forest (Sklearn) → ONNX

Use case: classify next candle direction (up/down) based on lagged returns. Random Forest is lightweight, trains fast, works well as baseline.

Step 1: Collect MT5 data

import MetaTrader5 as mt5
import pandas as pd

mt5.initialize()
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_H1, 0, 20000)
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
df.to_csv("eurusd_h1.csv", index=False)
mt5.shutdown()

Step 2: Train and export Random Forest

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType

X = np.load("X.npy")  # shape (N, 10) - 10 lagged returns
y = np.load("y.npy")  # 1 if next candle up, 0 otherwise

split = int(len(X) * 0.8)
model = RandomForestClassifier(n_estimators=200, max_depth=8, random_state=42)
model.fit(X[:split], y[:split])
print(f"Accuracy: {model.score(X[split:], y[split:]):.3f}")

# Export to ONNX
initial_type = [('input', FloatTensorType([None, 10]))]
onnx_model = convert_sklearn(model, initial_types=initial_type, target_opset=15)
with open("rf.onnx", "wb") as f:
    f.write(onnx_model.SerializeToString())

Part 2 — LSTM (PyTorch) → ONNX

import torch
import torch.nn as nn

class LSTMTrader(nn.Module):
    def __init__(self):
        super().__init__()
        self.lstm = nn.LSTM(1, 32, 2, batch_first=True, dropout=0.2)
        self.fc = nn.Linear(32, 2)
    
    def forward(self, x):
        out, _ = self.lstm(x)
        return self.fc(out[:, -1, :])

model = LSTMTrader()
# ... training loop ...

model.eval()
dummy_input = torch.randn(1, 10, 1)
torch.onnx.export(
    model, dummy_input, "lstm.onnx",
    input_names=['input'], output_names=['output'],
    dynamic_axes={'input': {0: 'batch'}, 'output': {0: 'batch'}},
    opset_version=15
)

Part 3 — Use in MT5 Expert Advisor

The .onnx files go to the MQL5\Files folder of your MT5 installation. In the EA, load via OnnxCreate:

long handle = OnnxCreate("rf.onnx", ONNX_DEFAULT);

const long input_shape[]  = {1, 10};
const long output_shape[] = {1};
OnnxSetInputShape(handle, 0, input_shape);
OnnxSetOutputShape(handle, 0, output_shape);

matrix input(1, 10);
for(int i = 0; i < 10; i++) {
    double c0 = iClose(_Symbol, PERIOD_CURRENT, i + 1);
    double c1 = iClose(_Symbol, PERIOD_CURRENT, i + 2);
    input[0][i] = (float)((c0 - c1) / c1);
}

vector output(1);
OnnxRun(handle, ONNX_DEFAULT, input, output);
int direction = (int)output[0];
Print("Prediction: ", direction == 1 ? "BUY" : "SELL");

Validation in Strategy Tester

Before going live, always backtest in MT5 Strategy Tester. Checklist: Profit factor > 1.5, max drawdown < 20%, 200+ trades on the sample, 30 days demo trading minimum, risk per trade ≤ 2%, stop loss always set.

Common troubleshooting

  • 'Operator not supported' on export: adjust opset_version (try 13, 14, 15, 17)
  • OnnxRun returns false: check shapes — MQL5 input must exactly match what was declared on export
  • NaN or constant predictions: feature scaling. Normalise features in Python and replicate in MQL5
  • Huge model: simplify. LSTM with hidden 32 is enough baseline

🚀 To test ONNX EAs, free Deriv MT5 demo ($10,000 virtual):

Open Deriv MT5 Demo →

DM

Dan Machado

Founder IA Trader Pro · AI applied to trading expert

⚠️ Disclaimer: Educational content, not investment advice. Trading involves substantial risk. AI models don't guarantee profit. Always test in demo before going live. Article contains Deriv affiliate link.