The order pool split
In MT4, `OrdersTotal()` counted open positions and pending orders in one pool, and you walked it with `OrderSelect()`. In MT5 that pool is split: positions live in `PositionsTotal()`, pending orders in `OrdersTotal()` (now pending-only), and closed deals in history. The function name survives the recompile, so a management loop ported verbatim looks correct and quietly manages nothing.
// MT4 habit — in MT5 this iterates pending orders only: for(int i = OrdersTotal() - 1; i >= 0; i--) { /* trail stops... */ } // MT5 — open trades live here: for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); // trail / break-even on the actual position }
Array series direction
MT4 price arrays were series-indexed by default: index 0 was the current bar. In MT5 you copy into your own array with `CopyRates()`, `CopyClose()`, or `CopyBuffer()`, and those arrays are **not** series by default — index 0 is the oldest copied bar unless you say otherwise.
double buf[]; CopyBuffer(maHandle, 0, 0, 3, buf); ArraySetAsSeries(buf, true); // without this, buf[1] is NOT the previous bar
Lot-size precision
Money-based sizing reads the balance and the broker's volume constraints. MT4 used `AccountBalance()` and `MarketInfo(Symbol(), MODE_LOTSTEP)`; MT5 deprecates both in favor of `AccountInfoDouble()` and `SymbolInfoDouble()`. The compatibility wrappers still compile, which is exactly why the drift slips through.
double rawLots = 0.13; // risk-based size from your sizing logic, before broker rounding double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); double lots = MathFloor(rawLots / step) * step; lots = MathMax(lots, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)); lots = MathMin(lots, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX));
State rebuild after a restart
A restart — a VPS reboot, a terminal update, a relaunch — runs `OnDeinit()` then `OnInit()` and wipes `static` and global in-memory state. That is true in both platforms, so robust EAs rebuild state in `OnInit()`. The migration-specific trap is *how* the rebuild reads the account: an MT4 reconstruction that scans `OrdersTotal()` finds the open positions; ported to MT5, it scans the pending-only pool, sees nothing, and concludes the account is flat.
int OnInit() { for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); // re-attach magic number, volume, grid level... } return INIT_SUCCEEDED; }


