Migrating from MT4 to MT5 requires reworking order management, history access, and event structure. Two critical areas often break: position vs order separation, and historical data retrieval with time filters.
1. Order Pool: No Global Selection
MQL4 uses a single pool with
OrderSelect(). MQL5 separates positions, pending orders, and history:``
cpp
// MQL4 style (deprecated in MQL5)
for(int i=0; i
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
double op = OrderOpenPrice();
}
}
// MQL5 correct: iterate positions
for(int i= PositionsTotal()-1; i>=0; i--) {
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket)) {
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double profit = PositionGetDouble(POSITION_PROFIT);
}
}
`
2. HistorySelect: Time Range Mandatory
MQL4's OrderSelect() works without time filters. MQL5 requires HistorySelect() before accessing historical orders:
`cpp
// MQL5: select last 30 days of history
datetime from = TimeCurrent() - 30243600;
datetime to = TimeCurrent();
if(HistorySelect(from, to)) {
int total = HistoryDealsTotal(); // not OrdersTotal()
for(int i=0; i
ulong ticket = HistoryDealGetTicket(i);
double price = HistoryDealGetDouble(ticket, DEAL_PRICE);
}
}
`
Without HistorySelect(), HistoryDealsTotal() returns 0.
3. Event Handler Differences
MQL4's init() and deinit() become OnInit() and OnDeinit(). MQL5 adds OnTimer() and OnTrade():
`cpp
// MQL5 event handlers
int OnInit() {
EventSetTimer(60); // 60-second timer
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
EventKillTimer();
}
void OnTimer() {
// periodic logic, e.g., trailing stop
}
void OnTrade() {
// triggered on any trade event (fill, modification)
}
`
4. Complete Migration Utility Function
Get total net profit across closed and open positions:
`cpp
double GetTotalNetProfit() {
double profit = 0;
// closed profit from history
datetime from = 0;
datetime to = TimeCurrent();
HistorySelect(from, to);
for(int i=0; i
ulong ticket = HistoryDealGetTicket(i);
if(HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_SELL ||
HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_BUY) {
profit += HistoryDealGetDouble(ticket, DEAL_PROFIT);
}
}
// open positions profit
for(int i=0; i
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
profit += PositionGetDouble(POSITION_PROFIT);
}
return profit;
}
``Reference: MQL5 Documentation, "History and Orders in MQL5" (mql5.com/en/docs/trading/history), 2025.