Expert Advisor AI for MT5 Deriv — MQL5 Tutorial
Expert Advisors (EAs) are automated trading programs that run inside MetaTrader 5. Unlike Deriv Bot Builder (drag-drop) or Python (external), EAs run natively in MT5 — they see every tick, execute instantly, and don’t need an external connection. This tutorial builds a complete RSI EA in MQL5 from scratch.
🎯 What You’ll Build
A working .mq5 file that: (1) calculates RSI in real-time, (2) places BUY/SELL orders when RSI crosses thresholds, (3) uses 2% risk per trade, (4) closes positions at SL/TP, (5) logs to MT5 Experts journal. All native MT5 code — no external dependencies.
EA vs Deriv Bot vs Python
- Deriv Bot: drag-drop, no code, perfect for beginners. Limited to Deriv’s UI.
- Python + Deriv API: full control, external script, requires Python knowledge.
- MT5 EA: native MT5, runs alongside manual trading, fastest execution, MQL5 language.
Choose EA if you: (1) already use MT5 for manual trading, (2) want fastest execution, (3) prefer .mq5 ecosystem with thousands of free EAs available.
Prerequisites
- Deriv account (demo or live) — open here
- Deriv MT5 installed — see install guide
- Basic understanding of trading (RSI, stop-loss, take-profit)
- Some programming familiarity (helpful but not required — MQL5 is C-like)
Step 1: Open MetaEditor
- Launch Deriv MT5
- Click “Tools” → “MetaQuotes Language Editor” (or press F4)
- MetaEditor opens in new window
- Click “New” → “Expert Advisor (template)” → Next
- Name:
RSI_EA_IATraderPro→ Next → Finish - Template .mq5 file opens — we’ll replace its contents
Step 2: Complete EA Code
Paste this into MetaEditor (replace template content):
//+------------------------------------------------------------------+
//| RSI_EA_IATraderPro.mq5 |
//| IA Trader Pro - Educational use only |
//+------------------------------------------------------------------+
#property copyright "IA Trader Pro 2026"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
CTrade trade;
// === INPUTS ===
input int RSI_Period = 14;
input double RSI_Oversold = 30.0;
input double RSI_Overbought = 70.0;
input double Risk_Percent = 2.0; // 2% per trade
input double SL_Points = 500; // Stop-loss in points
input double TP_Points = 1000; // Take-profit in points
input int Magic_Number = 20260514;
input int Max_Trades = 1; // Concurrent positions
// === GLOBAL ===
int rsi_handle;
double rsi_buffer[];
//+------------------------------------------------------------------+
int OnInit() {
rsi_handle = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE);
if(rsi_handle == INVALID_HANDLE) {
Print("ERROR: Failed to create RSI indicator");
return(INIT_FAILED);
}
ArraySetAsSeries(rsi_buffer, true);
trade.SetExpertMagicNumber(Magic_Number);
trade.SetDeviationInPoints(10);
trade.SetTypeFilling(ORDER_FILLING_FOK);
Print("RSI EA initialised. Symbol=", _Symbol,
" Period=", _Period);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {
IndicatorRelease(rsi_handle);
Print("RSI EA stopped. Reason=", reason);
}
//+------------------------------------------------------------------+
void OnTick() {
if(!IsNewBar()) return;
if(CopyBuffer(rsi_handle, 0, 0, 3, rsi_buffer) < 3) return;
double rsi_now = rsi_buffer[0];
double rsi_prev = rsi_buffer[1];
if(CountOpenPositions() >= Max_Trades) return;
// BUY signal: RSI crosses ABOVE oversold from below
if(rsi_prev < RSI_Oversold && rsi_now >= RSI_Oversold) {
OpenBuy();
}
// SELL signal: RSI crosses BELOW overbought from above
else if(rsi_prev > RSI_Overbought && rsi_now <= RSI_Overbought) {
OpenSell();
}
}
void OpenBuy() {
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double sl = ask - SL_Points * point;
double tp = ask + TP_Points * point;
double volume = CalcLotSize(SL_Points);
if(trade.Buy(volume, _Symbol, ask, sl, tp,
"IATraderPro RSI BUY")) {
Print("BUY opened: vol=", volume, " SL=", sl, " TP=", tp);
} else {
Print("BUY failed: ", trade.ResultRetcodeDescription());
}
}
void OpenSell() {
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double sl = bid + SL_Points * point;
double tp = bid - TP_Points * point;
double volume = CalcLotSize(SL_Points);
if(trade.Sell(volume, _Symbol, bid, sl, tp,
"IATraderPro RSI SELL")) {
Print("SELL opened: vol=", volume, " SL=", sl, " TP=", tp);
} else {
Print("SELL failed: ", trade.ResultRetcodeDescription());
}
}
//+------------------------------------------------------------------+
double CalcLotSize(double sl_points) {
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double risk_amount = balance * Risk_Percent / 100.0;
double tick_value = SymbolInfoDouble(_Symbol,
SYMBOL_TRADE_TICK_VALUE);
double tick_size = SymbolInfoDouble(_Symbol,
SYMBOL_TRADE_TICK_SIZE);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double pip_value = (tick_value / tick_size) * point;
double lot_size = risk_amount / (sl_points * pip_value);
// Normalize to broker minimum/maximum
double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double max_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lot_size = MathFloor(lot_size / step) * step;
lot_size = MathMax(min_lot, MathMin(max_lot, lot_size));
return(NormalizeDouble(lot_size, 2));
}
int CountOpenPositions() {
int count = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--) {
if(PositionGetTicket(i) > 0 &&
PositionGetInteger(POSITION_MAGIC) == Magic_Number) {
count++;
}
}
return(count);
}
bool IsNewBar() {
static datetime last_bar = 0;
datetime current = iTime(_Symbol, _Period, 0);
if(current != last_bar) {
last_bar = current;
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
Step 3: Compile
- In MetaEditor, press F7 (or Compile button)
- Bottom panel “Errors” tab — should show
0 error(s), 0 warning(s) - If errors: paste error message back to Claude/ChatGPT for fix
- Compiled .ex5 file appears next to .mq5
Step 4: Attach to Chart
- Return to MT5 (not MetaEditor)
- Open chart (e.g. EUR/USD H1, or Volatility 75 Index if available)
- Navigator (left panel) → Expert Advisors → find your EA
- Drag onto chart
- Dialog opens: Common tab → check “Allow Algo Trading”
- Inputs tab → adjust parameters if needed
- OK → EA active (smiling face top-right means running)
- Top toolbar → click “Algo Trading” button to enable globally
Step 5: Backtest
- MT5 → View → Strategy Tester (Ctrl+R)
- Expert: your EA
- Symbol: V75 or EUR/USD
- Period: H1 (1-hour timeframe)
- Date range: last 6 months
- Model: “Every tick based on real ticks” (most accurate)
- Click Start
- Results tab shows: profit factor, max drawdown, win rate
⚠️ Backtest Realism
MT5 backtest is more realistic than TradingView because it processes every tick. But still demo-test for 30+ days before live deployment. Live execution always differs slightly from backtest due to spread, slippage, and broker fill quality.
Common Issues
🔧 Troubleshooting
“Trade context busy”: close other EAs first
“Not enough money”: Risk_Percent too high or account too small
EA running but no trades: RSI hasn’t crossed thresholds — check Experts journal
“Algo Trading disabled”: top toolbar button + Common tab checkbox
Smiley face is sad: EA has error — check Experts log
Compile errors: paste error to AI, get fix in seconds
Going Live
- Test 30 days on Demo with this EA
- Track every trade in spreadsheet
- If profitable + drawdown under 15%, consider live
- Switch MT5 account to Real (top right)
- Re-attach EA
- Start with Risk_Percent=1.0 (half of demo) for first week
- If live performance matches demo at 70-85%, ramp to 2%
VPS for 24/7 Operation
For SA traders running EAs:
- Vultr JHB: $5/mo (~R92), best latency to Deriv from SA
- DigitalOcean Frankfurt: $6/mo (~R110)
- Install Windows VPS, RDP from your PC, run MT5 24/7
- Avoids load shedding issues affecting bot uptime
🚀 Test this EA on Deriv MT5 demo (FSCA-licensed, $10,000 virtual):
Open Free Demo Account