MT5 Lab

How to Forward-Test an MT5 EA on a Demo Account

A reproducible checklist for forward-testing an MT5 Expert Advisor on demo: uptime, duplicate orders, protective stops, execution drift, and stop criteria.

한국어 원문 읽기

Key takeaways

A demo forward test is primarily an operational falsification test, not a short-term profit contest.

Reconcile every signal through request, server response, order, deal, position, and protective-stop state.

Freeze the EA and inputs, preserve evidence, and stop escalation while any duplicate, missing protection, or recovery defect remains unexplained.

Forward-test an MT5 EA to find operational failures

Key takeaways

  • The first objective on demo is not profit. It is proving that the EA stayed active, sent each intended request once, and attached the required protection to the resulting position.
  • Reconcile signal → request → retcode → order → deal → position → Stop Loss/Take Profit; a chart icon or one visible position is not enough evidence.
  • Any code or input change starts a new observation. Unexplained duplicate orders, missing stops, or restart failures block further escalation.

How to Read an MT5 Strategy Tester Report ends at a deliberately narrow conclusion: a valid historical result can justify another experiment, but not a move directly to live capital.

The next experiment is forward observation on a demo account. Here, forward test means attaching a frozen EA and input set to current quotes from a demo trade server instead of replaying a selected historical interval.

This exposes conditions that a historical tester cannot fully reproduce: changing spread, session state, request rejection, partial execution, network loss, terminal restart, and two copies of an EA acting on the same account. Demo execution still does not reproduce every live liquidity, queue, latency, or slippage condition. Treat it as an operational lab, not a live-performance proxy.

Freeze the observation baseline

An observation is only comparable while its inputs and environment remain known. Create an observation ID and capture the baseline before enabling the EA.

Evidence fieldRecord
Observation IDFor example, FWD-20260714-01
Source and executableEA file, source version, release, commit or hash when available
RuntimeOperating system and MT5 terminal build from Help → About
Account contextBroker/server, demo status, netting or hedging, currency, leverage
Chart contextExact symbol, timeframe, and server timezone
InputsSaved .set file, volume rule, SL/TP, Magic Number
Symbol specificationDigits, point/tick size, volume limits, and trading sessions
Observation scopeStart and end rules, sessions and recovery events to cover

Do not store a complete account number, password, API key, or identity document in the evidence bundle. A symbol name alone is insufficient: two servers can expose similar names with different contract sizes, sessions, stops levels, and execution rules.

Changing the code, inputs, account, symbol, or timeframe closes the current observation. Open a new ID. Adjusting volume or stop distance after an uncomfortable loss is a parameter change, not a continuation of the same test.

Define coverage by events, not calendar days

Five or ten elapsed days do not create evidence by themselves. Ten quiet days with no signal exercise less of the system than three days containing intended sessions, trade requests, a reconnection, and end-of-day handling.

StagePurposeExample completion evidence
InitializationConfirm load, permissions, and account contextEA initializes on the intended account, chart, and inputs without error
First sessionAudit the entire order path under supervisionFirst signal is reconciled through position and protection
Continuous observationCover session transitions and normal connectivityIntended active hours and daily rollover behaviour are observed
Controlled recoveryTest restart/reconnect state restorationExisting account state is recognized without a duplicate entry
Closeout reviewClassify every discrepancyEach difference has a cause, severity, and next reproducible test

Begin restart testing while the demo account has no exposure. Turning off a terminal while a position is open can disable EA-managed exits or synthetic stops. A position-held recovery drill belongs in a separate controlled experiment after the code's intended behaviour is documented.

A low-frequency EA may produce no trades for several days. Record order path not yet observed, not “passed.” Do not loosen the signal rule merely to generate activity.

Monitor four operational surfaces

1. Uptime, connection, and permissions

A locally hosted EA needs the MT5 process, power, operating system, network, and broker-server connection to remain available. Toolbox → Journal records platform and network events; Experts contains EA initialization and messages emitted by the program.

At each review, ask:

  • Is there an unexplained gap between log timestamps?
  • Did sleep, an update, a reboot, or a crash stop the terminal?
  • Is the EA still attached to the intended symbol and timeframe?
  • Are global Algo Trading and the EA-level permission in the intended state?
  • After reconnection, is there evidence that quotes and account state were re-read?

If continuous observation is required, a VPS can remove some local power and connectivity dependencies. The official MetaTrader virtual-hosting guide opens in a new tab explains why an EA requires uninterrupted terminal-to-server connectivity. A VPS migration changes the runtime environment, so open a new observation ID. Do not knowingly run the same EA on the same account from both local and hosted terminals; two active instances can process one signal twice.

2. One intended action, one reconciled trade idea

One position row does not prove that only one request was sent. MT5 distinguishes an order, a deal, and a position, and one order can generate multiple deals.

Position accounting also changes what the operator sees:

Account modeTwo same-direction executions on one symbol can appear as
NettingIncreased volume in one aggregate position
HedgingTwo separate positions

Inspect account History as well as the current Trade tab. The official order, deal, and position reference opens in a new tab describes their identifiers and relationships.

For every intended trade idea, retain this chain:

signal timestamp / source bar
EA version / chart / Magic Number
request timestamp / requested volume
server retcode / order ticket / deal ticket
position identifier / resulting volume

Common duplicate paths include:

  • the EA is attached to two charts or launched from two terminals;
  • local MT5 and a VPS instance both act on the same account;
  • an OnTick rule processes one bar repeatedly without an idempotent new-bar gate;
  • a timeout triggers immediate resend before account state is reconciled;
  • restart logic forgets existing positions or pending orders; or
  • the EA does not scope state by Magic Number, symbol, and position side.

A true return from MQL5 OrderSend() does not establish completed execution. The official OrderSend reference opens in a new tab requires inspection of MqlTradeResult.retcode, available order/deal fields, subsequent trade events, and final account state. Treating an ambiguous response as a definite failure and resending immediately can create the duplicate being investigated.

3. Protective stops on the resulting position

An EA log line that says “SL set” is not the same evidence as a non-zero Stop Loss on the resulting position. If the strategy design requires protection, inspect every new position.

CheckQuestion
PresenceIs the SL/TP price non-zero on the actual position?
SideIs a long SL below the relevant market price and a short SL above it?
Price normalizationDoes the level respect tick size, digits, and the server's stops rules?
Modification resultIf protection was added after entry, did that second request succeed?
Recovery behaviourAfter reconnect, was existing protection preserved rather than removed or overwritten?

Server-held Stop Loss and Take Profit levels are associated with a position and can operate without the client terminal. By contrast, a synthetic or “virtual” stop calculated only inside the EA cannot act while that runtime is unavailable. Keep those two mechanisms distinct in the record. The official position-protection documentation opens in a new tab explains the server-held behaviour and its account-mode caveats.

Record the count and affected tickets for responses such as invalid stops, trade disabled, price changed, timeout, no connection, or too many requests. Classify them with the MQL5 trade-server return-code table opens in a new tab. A position missing required protection is not a successful observation merely because entry completed. For stop-distance diagnosis, use How to Fix “Invalid Stops” in MT5.

4. Explain the backtest-to-demo gap

Do not try to force daily demo P/L to match a historical report. Start at the event level: did the same rule see a signal, send the same type of request, and reach a comparable account state?

DimensionStrategy TesterDemo forward observation
Price inputStored historical ticks/bars under a modelling choiceCurrent quotes delivered by the selected server
SpreadHistorical or tester assumptionCurrent spread that can change through the session
ExecutionSelected delay and tester modelNetwork path, server response, and current price state
Trading hoursHistorical symbol/session dataCurrent server sessions and closures
RuntimeControlled tester processSleep, disconnect, restart, and multiple-instance risk
Account rulesConfigured test accountDemo server's netting/hedging and symbol restrictions

After the forward interval ends, rerunning the same dates in Strategy Tester with the frozen EA and inputs can help diagnose differences. That interval is now observed data, so the comparison is a post-hoc diagnostic—not new out-of-sample evidence.

Align server timezones first, then reconcile:

  1. source bar and prices used by the signal;
  2. request timestamp, side, volume, and requested price;
  3. contemporaneous Bid, Ask, and spread;
  4. retcode and executed deal price;
  5. resulting SL/TP and modification history; and
  6. exit cause, commission, swap, and other reported costs.

A different deal price is not automatically an EA defect. It is also not enough to write “slippage” and move on. Determine whether the difference changes the rule, clusters in a session or spread regime, or is amplified by retry logic.

Use a three-point daily routine

Review pointVerifyPreserve
Before the sessionAccount/server, symbol, timeframe, EA version, inputs, permissions, unexpected exposureBaseline entry or settings capture
After each trade eventSignal, retcode, order/deal, volume, position, SL/TPExperts/Journal lines and History tickets
End of dayConnection gaps, errors, unexpected requests, manual intervention, environment changesLog files, account history, discrepancy list

Fill these lines before looking at daily profit or loss:

Was the EA available for its full intended window?
Signals observed / requests sent / reconciled trade ideas:
Any duplicate, skipped, rejected, or partial execution?
Did every position have its required protection?
Unexplained differences and next reproduction attempt:

Preserve logs daily. MetaTrader maintains separate Experts and platform journals, and older entries may need to be opened from log files; see the official Platform Logs guide opens in a new tab. A screenshot alone usually omits the preceding event, exact return code, and later state transition.

Predefine stop and hold criteria

A forward test is a cheap place to discover the next failure, not a certification ceremony. Three statuses keep short-term P/L from weakening the evidence threshold.

StatusExamplesResponse
StopWrong symbol/side/volume, duplicate entry, required SL missing, failed state recoveryBlock new entries according to the documented kill procedure; preserve logs and tickets
HoldRepeated timeout, timezone mismatch, unexplained fill drift, spread sensitivityMake no escalation decision; design a frozen reproduction
Observation completePredefined events covered and no unexplained discrepancy remainsRecord only “no operational defect observed under this scope”

Keep live-capital consideration blocked while any of these is true:

  • requests, deals, or position changes do not match the written rule;
  • required protection is absent or attached at an incorrect level;
  • reconnect or restart repeats an already-processed signal;
  • a profitable outcome is being used to waive an unresolved error;
  • code or inputs changed but results are still pooled as one run;
  • account mode, symbol specification, or server differences remain unknown; or
  • no one can explain how open positions are handled after the kill switch is used.

Detaching an EA immediately is not a complete incident procedure. Server-held SL/TP may remain, while EA-only exits and trailing logic stop. Document the sequence for blocking new entries, managing existing demo exposure, and preserving evidence before an incident occurs.

Copyable forward-test record

Observation ID:
Start / end timestamp and timezone:
OS / MT5 build / broker server:
Demo account mode / currency / leverage:
EA file / version / commit or hash:
Symbol / timeframe / contract notes:
Inputs file / Magic Number:
Expected sessions and signal rule:

Uptime or connection gaps:
Signals observed:
Requests sent:
Server retcodes:
Orders / deals / positions reconciled:
Missing or changed SL/TP:
Duplicate or skipped entries:
Spread / requested price / deal price differences:
Manual intervention or environment changes:

Unexplained discrepancies:
Stop / hold / observation-complete decision:
Next reproducible test:
Evidence paths:

Record manual intervention rather than editing it out of the story. If a position was manually closed or a stop moved, subsequent P/L is not the EA-only path. Keep failed observations; they become comparison evidence when the same defect returns.

Frequently asked questions

How many days should an MT5 demo forward test run?

There is no universal day count. The first few days can expose basic uptime and request-path defects, but the observation is incomplete until its defined sessions, real signals, protective-order path, and recovery events have been exercised. A low-frequency strategy may require a much longer calendar window.

Does the EA keep running when the PC is off?

Not when the EA runs only in that local terminal. Existing server-held SL/TP may still operate, but EA-managed entries, exits, synthetic stops, and trailing logic do not execute. Treat VPS hosting as a separate environment and validate it separately.

Does demo profit confirm the backtest?

No. A short demo interval has limited observations, and demo execution can differ from live execution. The useful conclusion is whether the frozen rule and operational path behaved as documented under the observed conditions.

Does one visible position rule out duplicate orders?

No. A netting account can aggregate multiple deals into one position. Reconcile History, order and deal tickets, resulting volume, Magic Number, and the EA's intended trade idea.

What if no trade occurs for several days?

Separate “no valid signal” from a silent data, permission, session, or initialization failure. Without heartbeat or signal-evaluation evidence, label the order path unobserved rather than stable.

Risk note

A demo account provides a no-real-funds environment for learning platform behaviour and testing a strategy, but it cannot reproduce every aspect of live liquidity, execution priority, latency, slippage, or spread expansion. Historical and demo results do not establish future performance. Leveraged products can produce rapid and substantial losses.

This article is educational and broker-neutral. It does not recommend an EA, broker, symbol, parameter set, or trade. Confirm current platform behaviour with the official MetaTrader 5 getting-started documentation opens in a new tab, your terminal build, and the selected server's current contract specifications.

Up next

Continue with How to Recover MT5 EA State After Restart or Reconnect for Magic Number scoping, open-position and pending-order reconciliation, idempotent new-bar entry, OnTradeTransaction evidence, and the single-active-runtime rule for local terminals and VPS hosting.