There's a moment in every MT4-to-MT5 move where the terminal reports "0 errors" and it feels like the job is done. It isn't. A clean compile only tells you the syntax converted. It says nothing about whether your Expert Advisor still manages positions the way it did on MT4 — and that is precisely where a recompile quietly breaks.
The assumption that doesn't survive the move
Most MT4 EAs are written around one silent assumption: one position per symbol. On MT4 that's effectively true, so a lot of order-management code was built on it — check if a trade exists, if not open one, if so manage the single one you have.
MT5 doesn't guarantee that. Depending on the account's margin mode, MT5 uses either netting (one aggregated position per symbol) or hedging (multiple independent positions per symbol). The naive one-liner everyone reaches for after a recompile hides the problem:
On a hedging account, PositionSelect(_Symbol) selects a single position and silently ignores the rest. On a netting account, several discrete "trades" your EA thinks it opened have been aggregated into one position with an averaged price — so logic that expected to close trade #2 independently no longer maps to reality.
Counting positions the way MT5 actually stores them
The portable pattern is to stop assuming and iterate, matching by symbol and magic number:
Even this is only half the story. Before your open/close logic can be correct, the EA has to know which model it's running under:
A hedging account needs per-position tracking and close-by-ticket. A netting account needs you to reason about a single aggregated position and a net volume that can flip sign. A recompile asks none of these questions — it just carries the MT4 assumption forward and compiles it cleanly.
Why it passes the backtest and fails live
This is the uncomfortable part: the Strategy Tester often won't catch it. On a symbol and period where positions rarely overlap, the broken assumption never gets exercised, and the equity curve looks fine. It's live trading — overlapping entries, partial fills, a second signal before the first closed — that finally hits the code path where "one position per symbol" was never true. By then it's doubling up, orphaning a ticket, or closing the wrong one.
The practical takeaway
Treat MT4-to-MT5 as re-implementation of the trade-management layer, not a translation of it. Before you trust a migrated EA:
- Confirm ACCOUNT_MARGIN_MODE and handle both netting and hedging explicitly.
- Replace every "one position per symbol" assumption with an explicit position enumeration by symbol and magic.
- Run the MT4 original and the MT5 rebuild in parallel on the same feed and compare trade-by-trade before you cut over — the divergences you're looking for show up in the comparison, not in a solo backtest.
If your EA "already compiles on MT5," that's the signal to open the order-management code and read it against MT5's model — not to ship it.


