# MT4 to MT5 EA Migration: A Practical Guide
Why Migration Isn't Just Recompilation
Moving Expert Advisors from MT4 (MQL4) to MT5 (MQL5) is often mistaken for a simple recompilation. This is fundamentally wrong. MT5 uses a completely different trading architecture: multi-currency backtesting, built-in hedging option, and most importantly, a separation between orders (pending) and positions (market trades).
In MQL4, a market trade is an "order" from open to close. In MQL5, pending orders and market positions are distinct objects, each managed with its own set of functions.
Core Difference: Order Management Model
| Aspect | MQL4 | MQL5 |
|:---|:---|:---|
| Open market trade | `OrderSend()` | `PositionOpen()` |
| Close market trade | `OrderClose()` | `PositionClose()` |
| Modify SL/TP | `OrderModify()` | `PositionModify()` |
| Place pending order | `OrderSend()` | `OrderSend()` (different params) |
| Open price retrieval | `OrderOpenPrice()` | `PositionGetDouble(POSITION_PRICE_OPEN)` |
1. OrderSend to Position/Order Replacement
In MQL4 – Opening a Buy Order:
```cpp
int ticket = OrderSend(
Symbol(), // symbol
OP_BUY, // operation
lotSize, // volume
Ask, // price
3, // slippage
stopLoss, // stoploss
takeProfit, // takeprofit
"EA Trade", // comment
magicNumber, // magic
0, // expiration
clrGreen // arrow color
);
```
In MQL5 – Opening a Buy Position:
MQL5 replaces `OrderSend()` with specialized functions. Opening a market trade requires creating a trade request structure and checking the result.
```cpp
#include
CTrade trade;
// Configure trade
trade.SetExpertMagicNumber(magicNumber);
trade.SetDeviation(3); // slippage
// Build request
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = stopLoss;
double tp = takeProfit;
// Send order
bool success = trade.PositionOpen(
_Symbol, // symbol
ORDER_TYPE_BUY, // trade direction
lotSize, // volume
price, // open price
sl, // stop loss
tp, // take profit
"EA Trade" // comment
);
if(success)
{
ulong ticket = trade.ResultOrder(); // Get order ticket
Print("Position opened. Ticket: ", ticket);
}
else
{
Print("PositionOpen failed. Error: ", trade.ResultRetcode());
}
```
2. MarketInfo Replacement: SymbolInfo
`MarketInfo()` is gone in MQL5. Use `SymbolInfoDouble()`, `SymbolInfoInteger()`, and `SymbolInfoDouble()`.
| MQL4 | MQL5 Equivalent |
|:---|:---|
| `MarketInfo(Symbol(), MODE_BID)` | `SymbolInfoDouble(_Symbol, SYMBOL_BID)` |
| `MarketInfo(Symbol(), MODE_ASK)` | `SymbolInfoDouble(_Symbol, SYMBOL_ASK)` |
| `MarketInfo(Symbol(), MODE_POINT)` | `SymbolInfoDouble(_Symbol, SYMBOL_POINT)` |
| `MarketInfo(Symbol(), MODE_DIGITS)` | `(int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS)` |
| `MarketInfo(Symbol(), MODE_STOPLEVEL)` | `(int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL)` |
| `MarketInfo(Symbol(), MODE_SPREAD)` | `(int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)` |
| `MarketInfo(Symbol(), MODE_MINLOT)` | `SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)` |
| `MarketInfo(Symbol(), MODE_MAXLOT)` | `SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX)` |
Example – Getting Ask price with validation:
```cpp
// MQL5 version
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
if(ask == 0)
{
Print("Failed to get ASK price. Error: ", GetLastError());
return;
}
```
3. Time Function Migration
MQL5 introduces a critical distinction between trade server time and local computer time.
| MQL4 | MQL5 | Note |
|:---|:---|:---|
| `TimeCurrent()` | `TimeTradeServer()` or `TimeCurrent()` | MQL5 still supports `TimeCurrent()` |
| `Time[0]` (array) | `iTime(_Symbol, PERIOD_CURRENT, 0)` | For series access |
| `CopyTime()` for history | `CopyTime()` (similar but more features) | Both support `CopyTime()` |
| N/A | `TimeLocal()` | Computer time (not recommended for logic) |
Best practice – Use trade server time:
```cpp
// MQL5 – Recommended for EA logic
datetime currentTime = TimeTradeServer();
```
4. Position and Order Selection
In MQL4, you loop through `OrdersTotal()` for everything. In MQL5, separate loops exist:
| Purpose | MQL5 Function |
|:---|:---|
| Loop through open positions | `PositionsTotal()` + `PositionSelect()` / `PositionGetTicket()` |
| Loop through pending orders | `OrdersTotal()` + `OrderSelect()` |
| Loop through closed history | `HistorySelect()` + `HistoryDealsTotal()` |
MQL5 – Getting current open positions:
```cpp
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
{
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentSL = PositionGetDouble(POSITION_SL);
double currentTP = PositionGetDouble(POSITION_TP);
long magic = PositionGetInteger(POSITION_MAGIC);
if(magic == magicNumber)
{
// Process this position
}
}
}
```
5. Complete Migration Checklist
Before recompiling, verify these items have been addressed:
Common Pitfalls
Pitfall 1: ECN Brokers and Stop Loss Attachment
Some brokers reject stop loss in the initial request. The workaround is to open the trade with 0 SL/TP, then modify immediately after confirmation .
Pitfall 2: Point vs SymbolInfoDouble
`Point` still exists in MQL5, but `SymbolInfoDouble(_Symbol, SYMBOL_POINT)` is more reliable, especially for symbols with unusual point values.
Pitfall 3: Lot Step Validation
Always check `SYMBOL_VOLUME_STEP` and round lot sizes accordingly:
```cpp
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
double roundedLot = MathRound(lotSize / lotStep) * lotStep;
```
Summary
| Component | MQL4 Approach | MQL5 Approach |
|:---|:---|:---|
| Market trade | `OrderSend()` | `CTrade.PositionOpen()` |
| SL/TP modification | `OrderModify()` | `CTrade.PositionModify()` |
| Quotes | `Bid`, `Ask` | `SymbolInfoDouble()` |
| Time | `TimeCurrent()` | `TimeTradeServer()` |
| Symbol info | `MarketInfo()` | `SymbolInfoDouble/Integer()` |
Migration requires rewriting core trade management logic. The CTrade class provides a cleaner abstraction, but the learning curve is steep for developers accustomed to MQL4's simpler model. Always test migrated EAs in demo mode before live deployment.
References:
1. MQL5 Documentation – Migration from MQL4 (docs.mql5.com)
2. MQL5 Community Forum – OrderSend error 130 ECN workaround (2025)
3. MQL5 Book – Trading Operations Programming
4. MetaQuotes – MQL4 vs MQL5 Feature Comparison (2026)