Three Production Failures in AI-Generated MQL Code That the Strategy Tester Never Catches
I review AI-generated MQL code regularly in rescue projects. Since 2024, the same three failure patterns appear in the majority of AI-generated EAs. The code compiles clean and backtests well. It fails in production because it misses the conditions that only exist when real money is on the line.
No State Persistence After Terminal Restart
AI-generated EAs store trade state in RAM — static variables, global scope counters. When the terminal restarts, everything resets. The EA forgets its open positions and opens duplicates.
A common AI pattern:
In the Strategy Tester, this works perfectly — the tester never restarts mid-run. In live trading, after a VPS reboot, openTradeCount resets to 0. The EA opens a new position while the previous one is still running.
I see this in roughly 40% of AI-generated EA rescue projects. The fix requires scanning the order pool on every init:
The counter is never the source of truth. The broker's order pool is.
Missing Order Context Validation
AI treats the order pool as a static list. It selects an order by position index, reads its properties, runs trailing logic, then calls OrderModify() — assuming the pool stayed frozen between operations.
Two things break this assumption in live trading. First, the order can close between OrderSelect() and OrderModify() . Second, if the trailing logic contains any intervening OrderSelect() call — checking a hedge position, scanning for a related order — the internal selection shifts. The subsequent OrderOpenPrice() and OrderTakeProfit() calls return values from whatever order was last selected, not the intended target.
The production-ready pattern re-selects by ticket before every modification:
Three extra lines. One concept: the order pool is live, and any operation that changes it invalidates previous selections.
Broker Constraint Blindness
AI generates order operations that ignore runtime constraints enforced by the broker's trade server.
Stop level violation. Every broker defines MODE_STOPLEVEL — the minimum distance between price and any stop loss or take profit. AI generates OrderModify() without checking this. The broker either rejects with error 130 or silently adjusts.
Lot step mismatch. AI sends raw calculated lot sizes to OrderSend() . The broker rounds to the nearest MODE_LOTSTEP . The actual risk differs from the intended risk, and the EA never knows.
Trade context busy. In MT4, one trade operation at a time per terminal. AI never checks IsTradeAllowed() . The EA gets error 146 and proceeds as if the order was never attempted.
A composite production-ready pattern:
Why the Strategy Tester Misses All of This
The tester never restarts mid-run. Orders do not close between operations within the same tick. Broker constraints are often not enforced or set to zero. Trade context is always available. AI learns from code that works in this controlled environment because production failures are posted as forum complaints — not as code samples.
The code is not broken. It is incomplete. It handles the strategy logic and nothing else.
Quick Diagnostic Checklist
Before running any AI-generated EA live, search the source for:
- GlobalVariableSet or FileWrite in OnInit() — state persistence
- OrdersTotal() or PositionsTotal() in OnInit() — position reconciliation
- OrderSelect(ticket, SELECT_BY_TICKET) before every OrderModify() — re-selection
- MODE_STOPLEVEL or SYMBOL_TRADE_STOPS_LEVEL — stop level validation
- MODE_LOTSTEP or SYMBOL_VOLUME_STEP — lot normalization
- IsTradeAllowed() before OrderSend() — trade context guard
If any of these is missing, the code is not production-ready.


