MQL4 to MQL5 Syntax Reference
Look up how a function, event handler, or predefined variable in MQL4 maps to its MQL5 equivalent.
| MQL4 | MQL5 | Notes |
|---|---|---|
| init() | OnInit() | MQL5 requires the OnInit/OnDeinit/OnTick naming; MQL4 (build 600+) also accepts these names. |
| deinit() | OnDeinit(const int reason) | MQL5 passes a deinitialization reason code. |
| start() | OnTick() | Runs on every new tick for the chart symbol. |
| OrderSend(symbol, cmd, volume, price, slippage, sl, tp, ...) | OrderSend(MqlTradeRequest &request, MqlTradeResult &result) or CTrade::PositionOpen() | MQL5 uses a request/result struct pair, or the CTrade class from Trade.mqh for simpler calls. |
| OrderClose(ticket, lots, price, slippage) | CTrade::PositionClose(ticket) or OrderSend() with ORDER_TYPE_CLOSE_BY | MQL5 closes positions (netting) or specific deals (hedging), not raw order tickets. |
| OrderModify(ticket, price, sl, tp, expiration) | CTrade::PositionModify(ticket, sl, tp) | Pending order modification uses OrderModify() with a request struct in MQL5 too. |
| OrdersTotal() | PositionsTotal() or OrdersTotal() | MQL5 separates open positions (PositionsTotal) from pending orders (OrdersTotal). |
| OrderSelect(index, SELECT_BY_POS) | PositionGetTicket(index) then PositionSelectByTicket(ticket) | MQL5 has no order pool selection model; positions and history deals are queried separately. |
| OrderTicket() | PositionGetInteger(POSITION_TICKET) | For historical orders/deals use HistoryOrderGetInteger / HistoryDealGetInteger. |
| Bid / Ask | SymbolInfoDouble(_Symbol, SYMBOL_BID) / SYMBOL_ASK | MQL5 has no global Bid/Ask predefined variables for arbitrary symbols. |
| Digits | (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS) | _Digits also works for the current chart symbol. |
| Point | SymbolInfoDouble(_Symbol, SYMBOL_POINT) | _Point also works for the current chart symbol. |
| MarketInfo(symbol, MODE_SPREAD) | SymbolInfoInteger(symbol, SYMBOL_SPREAD) | MarketInfo() is removed in MQL5; each MODE_* maps to a SymbolInfoDouble/Integer call. |
| iHigh(symbol, tf, shift) | CopyHigh(symbol, tf, shift, count, array) | MQL5 price/time/volume series are read into arrays via Copy* functions, not single-value calls. |
| iClose(symbol, tf, shift) | CopyClose(symbol, tf, shift, count, array) | Same pattern applies to iOpen/iLow/iTime/iVolume -> CopyOpen/CopyLow/CopyTime/CopyTickVolume. |
| iMA(symbol, tf, period, shift, method, price, shift) | handle = iMA(...); CopyBuffer(handle, 0, shift, count, array) | MQL5 indicator calls return a handle once; values are pulled with CopyBuffer, not per-call. |
| AccountBalance() | AccountInfoDouble(ACCOUNT_BALANCE) | Same pattern for AccountEquity, AccountMargin, AccountFreeMargin. |
| AccountCurrency() | AccountInfoString(ACCOUNT_CURRENCY) | |
| extern int Period = 14; | input int Period = 14; | MQL4 (build 600+) supports input too; extern still compiles but input is preferred. |
| ArrayResize + implicit series behavior | ArraySetAsSeries(array, true) required explicitly | MQL5 arrays are not series-ordered by default; you must opt in per array. |
| Procedural only (pre build 600) | Full OOP: classes, inheritance, CTrade/CPositionInfo/CSymbolInfo standard library | MQL5's Trade.mqh, PositionInfo.mqh, etc. remove most of the boilerplate above. |
| No OnTrade / OnTimer distinction in early builds | OnTrade(), OnTimer(), OnTradeTransaction(), OnBookEvent() | MQL5 exposes finer-grained event handlers with no MQL4 equivalent. |
MQL4 and MQL5 share the same C-like syntax, but MetaQuotes changed how trading, price series, and indicator data are accessed between the two languages. There is no fully automatic converter that produces correct MQL5 for every MQL4 Expert Advisor or indicator — order handling, array series behavior, and indicator buffers all changed enough that a straight find-and-replace breaks on anything beyond trivial scripts.
Why porting MQL4 to MQL5 is not a simple find-and-replace
The biggest source of bugs when porting is the trading model. MQL4's order-ticket system (OrderSend, OrderSelect, OrderModify) assumes every trade is an independently addressable ticket. MQL5's default netting accounts work with aggregated positions instead, so code that loops over open orders by ticket needs to be rewritten around PositionGetTicket and the CTrade class. Price and indicator access changed too: MQL4's single-value calls like iClose() and iMA() become buffer copies (CopyClose, CopyBuffer) in MQL5, which return arrays instead of one number at a time.
The table above covers the mappings that come up most often when converting an EA or custom indicator: event handlers, order/position management, market and price-series access, account info, and input declarations. Search by function name or filter by category to find the MQL5 equivalent for a specific line of MQL4 code.
If you're porting a full Expert Advisor and want it done correctly — tested against live and historical data, not just syntax-swapped — that's exactly the kind of work I take on through the Fiverr gig linked below.