Home/Blog/Development
Development2024-11-089 min read

MQL4 vs MQL5: Key Differences Every EA Developer Should Know

Language Overview

MQL4 and MQL5 look similar but have fundamental differences that affect how you write EAs. Understanding these differences is crucial for writing efficient, bug-free code.

MQL4 Characteristics

  • Procedural programming focus
  • Direct indicator value access
  • Simple order model (OrderSend/OrderModify)
  • Single-threaded execution
  • Backwards compatible with legacy code
  • MQL5 Characteristics

  • Full object-oriented programming (OOP)
  • Handle-based indicator system
  • Position/Order/Deal separation
  • Multi-threaded backtesting
  • More powerful but steeper learning curve
  • Key insight: MQL5 isn't just "MQL4 with more features." It's a fundamentally different approach to trading system development.

    Order System Differences

    This is where MQL4 and MQL5 differ most dramatically.

    MQL4: Order-Centric Model

    ``mql4 // Open a trade int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Ask - 50*Point, Ask + 100*Point);

    // Modify stop loss if(OrderSelect(ticket, SELECT_BY_TICKET)) { OrderModify(ticket, OrderOpenPrice(), newSL, OrderTakeProfit(), 0); }

    // Close trade if(OrderSelect(ticket, SELECT_BY_TICKET)) { OrderClose(ticket, OrderLots(), Bid, 3); } `

    Simple concepts:

  • Each trade has one ticket number
  • OrderSend opens, OrderClose closes
  • Everything is straightforward
  • MQL5: Position/Order/Deal Model

    `mql5 // Open a trade MqlTradeRequest request = {}; MqlTradeResult result = {};

    request.action = TRADE_ACTION_DEAL; request.symbol = Symbol(); request.volume = 0.1; request.type = ORDER_TYPE_BUY; request.price = SymbolInfoDouble(Symbol(), SYMBOL_ASK); request.sl = request.price - 50 * Point(); request.tp = request.price + 100 * Point(); request.deviation = 3;

    OrderSend(request, result);

    // Modify position request.action = TRADE_ACTION_SLTP; request.position = result.deal; // Position ticket request.sl = newSL; OrderSend(request, result);

    // Close position request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_SELL; request.position = positionTicket; OrderSend(request, result); ``

    Complex concepts:

  • Order: A request to trade (pending or executed)
  • Deal: A single transaction (fill)
  • Position: Aggregate of all deals on a symbol (netting) or individual trades (hedging)
  • Why the complexity? MQL5 supports real exchange trading where one order can result in multiple partial fills (deals).

    Indicator Access

    MQL4: Direct Access

    ``mql4 // Get RSI value - one line! double rsi = iRSI(Symbol(), Period(), 14, PRICE_CLOSE, 0);

    // Get moving average double ma = iMA(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE, 0);

    // Access custom indicator double custom = iCustom(Symbol(), Period(), "MyIndicator", param1, param2, 0, 0); `

    Simple and direct. Each call returns the value immediately.

    MQL5: Handle-Based Access

    `mql5 // Create indicator handles (in OnInit) int rsiHandle = iRSI(Symbol(), Period(), 14, PRICE_CLOSE); int maHandle = iMA(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE);

    // Prepare buffers double rsiBuffer[]; double maBuffer[]; ArraySetAsSeries(rsiBuffer, true); ArraySetAsSeries(maBuffer, true);

    // Copy values (in OnTick) CopyBuffer(rsiHandle, 0, 0, 1, rsiBuffer); CopyBuffer(maHandle, 0, 0, 1, maBuffer);

    double rsi = rsiBuffer[0]; double ma = maBuffer[0]; ``

    Why handles?

  • Performance: Indicator calculated once, reused
  • Efficiency: Multiple values copied at once
  • Multi-threading: Safe for parallel execution
  • Pro tip: Create handles in OnInit, copy buffers in OnTick. Don't create handles repeatedly.

    Event Handling

    MQL4 Events

    ``mql4 int OnInit() { // Called once when EA starts return INIT_SUCCEEDED; }

    void OnDeinit(const int reason) { // Called when EA stops }

    void OnTick() { // Called on every tick (main logic here) }

    void OnTimer() { // Called on timer events }

    void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { // Chart interaction events } `

    MQL5 Events (Additional)

    `mql5 // All MQL4 events plus:

    void OnTrade() { // Called when trade events occur (order placed, modified, closed) }

    void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { // Detailed trade transaction info }

    void OnBookEvent(const string& symbol) { // Market depth changes }

    double OnTester() { // Custom optimization criterion return customScore; }

    void OnTesterInit() { // Before optimization starts }

    void OnTesterPass() { // After each optimization pass }

    void OnTesterDeinit() { // After optimization ends } ``

    Key addition: OnTrade and OnTradeTransaction give you precise control over trade event handling without polling in OnTick.

    Code Migration Tips

    Converting MQL4 to MQL5

    Order functions: `` MQL4 OrderSend() → MQL5 OrderSend() with MqlTradeRequest MQL4 OrderModify() → MQL5 OrderSend() with TRADE_ACTION_SLTP MQL4 OrderClose() → MQL5 OrderSend() with opposite direction MQL4 OrderSelect() → MQL5 PositionSelect() or OrderSelect() MQL4 OrdersTotal() → MQL5 PositionsTotal() or OrdersTotal() `

    Indicator functions: ` MQL4 iRSI(Symbol(), Period(), 14, PRICE_CLOSE, 0) ↓ MQL5 int handle = iRSI(Symbol(), Period(), 14, PRICE_CLOSE); double buffer[]; CopyBuffer(handle, 0, 0, 1, buffer); double value = buffer[0]; `

    Price data: ` MQL4 Close[0] → MQL5 iClose(Symbol(), Period(), 0) MQL4 Open[0] → MQL5 iOpen(Symbol(), Period(), 0) MQL4 High[0] → MQL5 iHigh(Symbol(), Period(), 0) MQL4 Bid → MQL5 SymbolInfoDouble(Symbol(), SYMBOL_BID) MQL4 Ask → MQL5 SymbolInfoDouble(Symbol(), SYMBOL_ASK) `

    Using the Standard Library

    MQL5's Standard Library simplifies trading:

    `mql5 #include #include

    CTrade trade; CPositionInfo position;

    // Open trade (much simpler!) trade.Buy(0.1, Symbol(), 0, sl, tp);

    // Close position trade.PositionClose(Symbol());

    // Modify SL/TP trade.PositionModify(Symbol(), newSL, newTP); ``

    Which to Choose

    Choose MQL4 When:

  • Your broker only supports MT4
  • You're maintaining existing MT4 EAs
  • Target audience primarily uses MT4
  • Simple strategy, quick development needed
  • Working with legacy indicators
  • Choose MQL5 When:

  • Building new projects (future-proof)
  • Need multi-currency backtesting
  • Trading stocks/futures (not just forex)
  • Building complex, scalable systems
  • Want better optimization tools
  • Need accurate tick-by-tick backtesting
  • Migration Decision Matrix

    | Factor | Stay MT4 | Move to MT5 | |--------|----------|-------------| | Broker support | MT4 only | MT5 available | | Strategy complexity | Simple | Complex/Multi-asset | | Backtest needs | Basic | Advanced/Multi-currency | | Development time | Limited | Flexible | | Future plans | Maintenance | New development |

    Our recommendation: For any new project starting in 2024 or later, choose MQL5. The learning curve pays off quickly.

    Need help migrating your EA from MT4 to MT5? Contact us for professional conversion services.

    🧑‍💻

    TradeMetrics Pro Team

    Expert EA developers with 10+ years of experience in automated trading systems.

    Need Help With Your EA Project?

    Get expert assistance with strategy conversion, EA development, or optimization.