Why live results differ from your backtest
The usual reasons a strategy earns less live than in its backtest: costs, slippage, data, time zones, overfitting and outages, and how to measure the gap.
A backtest replays past prices through your trading rules and reports what would have happened. Then the strategy goes live and the numbers come out lower. Almost everyone who automates a strategy sees this, and it is usually not bad luck.
A backtest is a model of trading, and every model leaves things out. The gap between the model and the live account comes from a short list of causes. Some of them you can fix, some you can only measure, and a few mean the strategy never had an edge at all.
This post goes through that list, shows how to measure each cause on your own account, and ends with a checklist. It applies to MT4 and MT5, and to MQL programs as much as to Python.
Costs and fills the backtest gets wrong
Costs
Trading costs are the most common cause, and the easiest to check.
- Spread. The spread is the gap between the bid and the ask. Many backtests use a fixed spread, or the spread stored with each candle. Real spreads change: they widen around news, at the daily rollover and when markets are thin. A strategy that trades often, or trades at those moments, feels this most.
- Commission. Some account types charge a commission per lot on top of the spread. Make sure the backtest charges the same.
- Swap. Holding a position overnight earns or costs a swap (a financing charge). Strategies that hold for days can see swaps add up to more than the spread.
The fix is simple: use your own account’s real costs in the test, and add a margin for bad days.
Fills
A backtest usually assumes your order fills at the price on the chart, at once, in full. Live orders do not always.
- Slippage. The price moves between your decision and the fill. Slippage is the difference between the price you expected and the price you got. It is often small, and sometimes large during fast markets.
- Latency. Your program reads a price, decides, and sends an order. Each step takes time. A rule that depends on reacting within a fraction of a second is the most fragile.
- Rejections and requotes. The broker can refuse an order (not enough margin, market closed, price changed) or offer a new price. A backtest rarely models either.
- Stops and limits. A stop loss in a backtest often fills exactly at its level. Live, a gap over the weekend or a news spike can fill it well beyond. Brokers also set a minimum distance for stops from the current price, which the backtest may ignore.
The data was not the market
The backtest can only be as good as the prices you fed it.
- Candles hide the path. A 1-hour candle has an open, high, low and close, but not the order in which they happened. If a candle touched both your stop and your target, the test has to guess which came first. MT5’s Strategy Tester offers several modelling modes, from open prices only to every tick based on real ticks, and the choice changes the result.
- Different brokers, different prices. Each broker has its own price feed. History downloaded from one place may not match what your broker quoted.
- Gaps and errors in the history. Missing candles or bad ticks can create trades that could never have happened.
Time zones shift the candles
Broker server time is often not UTC. A broker on a UTC+2 or UTC+3 clock draws its daily candle from its own midnight, not from yours. If your historical data used one clock and your live broker uses another, the daily and 4-hour candles are cut at different moments, so indicators built on them give different values and different signals.
The same applies to rules such as “do not trade on Friday after 20:00” or “reset the daily loss at midnight”. Decide which clock each rule means, and check it against the broker’s real time. See broker server time is not UTC for how to measure the offset.
The strategy was fitted to the past
This is the cause that costs the most, because no amount of better data fixes it.
- Overfitting. If you tried hundreds of parameter combinations and kept the best one, part of its performance is luck on that particular stretch of history. The more you tune, the more the backtest describes the past instead of the strategy.
- Look-ahead bias. The code uses information it could not have had at the time, such as the close of the current candle before it has closed, or a daily high before the day ended.
- Regime change. Markets change. A strategy that did well in a calm, trending year may not do well in a choppy one.
Some defences:
- Keep a slice of history out of all tuning, and test on it once at the end.
- Prefer rules with few parameters, and check that nearby parameter values give similar results.
- Forward test on live prices without real money for weeks. Practise on a demo account before you risk money.
Things a backtest never sees
Some live problems have nothing to do with the market.
- The terminal was open but not connected to the broker, so signals were missed.
- A timeout made the program retry, and the first order had already been filled, so it opened two.
- The program restarted and lost track of which positions were its own.
- The machine slept, updated or ran out of memory.
These show up as missed trades or doubled trades, and they can turn a good month into a bad one. They need engineering, not a better strategy: check health before acting, give every order a unique key so a retry cannot open a second position, and reconcile positions after a restart. See a retry should never place a second trade.
How to measure the gap
Treat the difference between backtest and live results as something to measure, not something to hope away. If you know that live fills cost, say, an extra half a pip per trade on average, you can put that into the next backtest and ask whether the strategy still makes sense. A pip is a small, standard price step, 0.0001 on most currency pairs.
What matters is whether the gap is explained. A small gap you understand is fine. A large gap you cannot explain means the backtest is not telling you anything useful yet.
You cannot fix what you do not record. For every live trade, log:
| Field | Why |
|---|---|
| Signal time and the price the signal used | What the backtest would have assumed |
| Order send time and fill time | Latency |
| Requested price and fill price | Slippage |
| Spread at the moment of the signal | Real cost |
| Commission and swap | Real cost |
| Result code from the broker | Rejections and requotes |
After a few weeks, rerun the backtest over exactly the live period and compare trade by trade. Each difference falls into one of the causes above. Missing trades usually point to connectivity or timing; worse prices to costs and slippage; different trades to data or time zones.
Checklist
- Real spread, commission and swap from your own account in the backtest.
- A modelling mode, or tick data, fine enough for your stops and targets.
- Historical data from the same broker, on the same server clock.
- A held-out period that was never used for tuning.
- No look-ahead: decisions only on closed candles.
- A forward test on live prices before any real money.
- A trade log with signal price, fill price, latency and costs.
- Health checks, unique order keys and reconciliation after restarts.
Doing this with Tickwire
Tickwire keeps a real MT4 or MT5 terminal connected for each account, and gives your code what it
needs to measure the gap. Every order answer carries the broker’s own result code and an outcome
(applied, rejected or unknown), and every change is in an audit log with who made it and why.
Health says whether the terminal is really connected, with evidence, and broker time is labelled as
broker time with its offset, never assumed to be UTC.
See idempotency and trade outcomes, health and time zones in the docs. Tickwire gives no investment advice and does not judge whether a strategy is good.
Trading carries risk, and you can lose money. This post explains software and how it behaves; it is not investment advice.