Back to Blog

MT5 Expert Advisor Development: Complete Developer's Guide

Everything about MT5 Expert Advisor development in 2026 — MQL5 architecture, event handlers, order management, risk controls, backtesting, and deployment.

Viprasol Tech Team
March 30, 2026
13 min read

MT5 Expert Advisor Development: Complete Developer's Guide | Viprasol Tech

MT5 Expert Advisor Development: Complete Developer's Guide

MetaTrader 5 Expert Advisors are automated trading programs that run inside the MT5 terminal. They handle market analysis, signal generation, order placement, and position management without manual intervention. This guide covers the full development lifecycle — from architecture to deployment.

EA Structure and Event Handlers

An MT5 EA is an MQL5 program with specific event handlers that the terminal calls at defined times:

// Complete MT5 EA structure
#property copyright "Viprasol Tech"
#property version   "2.00"
#property strict

#include <Trade/Trade.mqh>
#include <Trade/PositionInfo.mqh>

// Input parameters
input group "=== Strategy ==="
input int      InpFastMA    = 10;          // Fast MA Period
input int      InpSlowMA    = 50;          // Slow MA Period
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_H1;

input group "=== Risk Management ==="
input double   InpRiskPct   = 1.0;        // Risk per trade (% of balance)
input double   InpStopLoss  = 50;         // Stop loss (pips)
input double   InpTakeProfit = 100;       // Take profit (pips)
input int      InpMaxTrades  = 3;         // Max simultaneous positions

input group "=== Prop Firm Compliance ==="
input double   InpMaxDailyLoss  = 5.0;   // Max daily loss %
input double   InpMaxDrawdown   = 10.0;  // Max total drawdown %
input bool     InpPropMode      = false;  // Enable prop firm rules

// Global objects
CTrade     trade;
CPositionInfo posInfo;

// Global state
double g_AccountHighWater = 0;
double g_DayStartBalance  = 0;
datetime g_LastDay        = 0;

//+------------------------------------------------------------------+
int OnInit() {
    // Validate inputs
    if (InpFastMA >= InpSlowMA) {
        Print("ERROR: Fast MA must be less than Slow MA");
        return INIT_PARAMETERS_INCORRECT;
    }

    // Configure trade object
    trade.SetExpertMagicNumber(123456);  // Unique identifier for this EA's trades
    trade.SetSlippage(30);              // 3 pips slippage tolerance
    trade.SetTypeFilling(ORDER_FILLING_IOC);

    // Initialise state
    g_AccountHighWater = AccountInfoDouble(ACCOUNT_BALANCE);
    g_DayStartBalance  = AccountInfoDouble(ACCOUNT_BALANCE);
    g_LastDay          = TimeCurrent();

    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
void OnTick() {
    // 1. Check risk limits first — always
    if (!RiskChecksPass()) return;

    // 2. Only process on new bar (avoid multiple signals per bar)
    static datetime lastBar = 0;
    datetime currentBar = iTime(_Symbol, InpTimeframe, 0);
    if (currentBar == lastBar) return;
    lastBar = currentBar;

    // 3. Get signal
    int signal = GetSignal();
    if (signal == 0) return;

    // 4. Check if we can open new position
    int openPositions = CountMyPositions();
    if (openPositions >= InpMaxTrades) return;

    // 5. Check we don't already have a position in this direction
    if (HasPositionInDirection(signal)) return;

    // 6. Calculate lot size based on risk
    double lots = CalculateLotSize(InpStopLoss, InpRiskPct);
    if (lots <= 0) return;

    // 7. Open trade
    if (signal > 0) OpenBuy(lots);
    if (signal < 0) OpenSell(lots);
}

//+------------------------------------------------------------------+
int GetSignal() {
    double fastMA_0 = iMA(_Symbol, InpTimeframe, InpFastMA, 0, MODE_EMA, PRICE_CLOSE, 0);
    double fastMA_1 = iMA(_Symbol, InpTimeframe, InpFastMA, 0, MODE_EMA, PRICE_CLOSE, 1);
    double slowMA_0 = iMA(_Symbol, InpTimeframe, InpSlowMA, 0, MODE_EMA, PRICE_CLOSE, 0);
    double slowMA_1 = iMA(_Symbol, InpTimeframe, InpSlowMA, 0, MODE_EMA, PRICE_CLOSE, 1);

    // Bullish crossover
    if (fastMA_1 <= slowMA_1 && fastMA_0 > slowMA_0) return 1;
    // Bearish crossover
    if (fastMA_1 >= slowMA_1 && fastMA_0 < slowMA_0) return -1;

    return 0;
}

//+------------------------------------------------------------------+
bool RiskChecksPass() {
    double balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double equity  = AccountInfoDouble(ACCOUNT_EQUITY);

    // Update daily state
    MqlDateTime today;
    TimeToStruct(TimeCurrent(), today);
    MqlDateTime lastDayStruct;
    TimeToStruct(g_LastDay, lastDayStruct);
    if (today.day != lastDayStruct.day) {
        g_DayStartBalance = balance;
        g_LastDay = TimeCurrent();
    }

    // Update high water mark
    if (balance > g_AccountHighWater) g_AccountHighWater = balance;

    // Check daily loss limit (prop firm critical)
    if (InpPropMode) {
        double dailyLoss = (g_DayStartBalance - equity) / g_DayStartBalance * 100;
        if (dailyLoss >= InpMaxDailyLoss) {
            Print("Daily loss limit reached: ", dailyLoss, "%");
            CloseAllPositions();
            return false;
        }

        // Check total drawdown
        double totalDrawdown = (g_AccountHighWater - equity) / g_AccountHighWater * 100;
        if (totalDrawdown >= InpMaxDrawdown) {
            Print("Max drawdown reached: ", totalDrawdown, "%");
            CloseAllPositions();
            return false;
        }
    }

    return true;
}

//+------------------------------------------------------------------+
double CalculateLotSize(double stopLossPips, double riskPct) {
    double balance   = AccountInfoDouble(ACCOUNT_BALANCE);
    double riskAmount = balance * riskPct / 100.0;
    double pipValue  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double tickSize  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
    double pipValueNorm = pipValue / tickSize * _Point;

    double lots = riskAmount / (stopLossPips * pipValueNorm * 10);
    double minLot  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double maxLot  = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);

    lots = MathFloor(lots / lotStep) * lotStep;
    return MathMax(minLot, MathMin(maxLot, lots));
}

Backtesting Best Practices

Run backtests in MT5 Strategy Tester with:

  • Every tick based on real ticks — most accurate
  • At least 5 years of history
  • Multiple currency pairs — strategy should work across pairs, not just EURUSD
  • Walk-forward optimisation — optimise on 70% of data, test on remaining 30%
  • Monte Carlo simulation — randomise trade order to test equity curve robustness

Watch for: results that are suspiciously good (>80% win rate, unrealistic Sharpe ratio), strategies that only work on one pair, and forward-test results that diverge heavily from backtest.

🤖 Can This Strategy Be Automated?

In 2026, top traders run custom EAs — not manual charts. We build MT4/MT5 Expert Advisors that execute your exact strategy 24/7, pass prop firm challenges, and eliminate emotional decisions.

  • Runs 24/7 — no screen time, no missed entries
  • Prop-firm compliant (FTMO, MFF, TFT drawdown rules)
  • MyFXBook-verified backtest results included
  • From strategy brief to live EA in 2–4 weeks

Deployment Checklist

Before going live:

  • Forward test on demo account for minimum 30 trades
  • Verify lot size calculation across different account currencies
  • Test with news filter during high-impact events
  • Verify prop firm compliance layer if applicable
  • Set up MyFXBook verification
  • VPS with < 20ms latency to broker

Need a professional MT5 EA built to your strategy? Viprasol builds MQL5 Expert Advisors with MyFXBook-verified results. Contact us.

See also: AI Forex Trading Bot Guide · Algorithmic Trading Trends 2026

Share this article:

About the Author

V

Viprasol Tech Team

Custom Software Development Specialists

The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.

MT4/MT5 EA DevelopmentAI Agent SystemsSaaS DevelopmentAlgorithmic Trading

Ready to Automate Your Trading?

Get a custom Expert Advisor built by professionals with verified MyFXBook results.

Free consultation • No commitment • Response within 24 hours

Viprasol · Trading Software

Need a custom EA or trading bot built?

We specialise in MT4/MT5 Expert Advisor development — prop-firm compliant, forward-tested before live, MyFXBook verifiable. 5.0★ Upwork, 100% Job Success, 100+ projects shipped.