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
MQL5 Characteristics
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:
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:
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?
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
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:
Choose MQL5 When:
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.