Multi-Timeframe Analysis: The Backtest Leak Nobody Checks

9 min readQuantParadox research

Filter the entries with a higher timeframe and results improve almost every time. Some of that improvement is real. A surprising amount of it is the higher timeframe quietly telling the lower one how the next few hours went.

The short answer

Multi-timeframe analysis leaks future information whenever a higher-timeframe value is read before that bar has closed, because the four-hour candle a trader references at 10:15 will not finish forming until 12:00 and its final values are not yet knowable.

How does the leak happen?

It happens whenever a higher-timeframe bar's values are used at a moment before that bar has closed, because those values are not final until it does — and most naive implementations use the completed bar by default.

Picture a strategy trading M15 with an H4 trend filter. At 10:15 the current H4 candle opened at 08:00 and closes at 12:00. Its high, low and close are not yet known. A backtest that resamples the data to H4 and joins it onto the M15 series will typically attach that candle's FINAL values to every M15 bar inside it, including the ones at 08:15.

The strategy is then filtering its 08:15 entries using information about what happened by 12:00. It is not subtle once seen, and it is the default behaviour of a straightforward pandas resample-and-merge.

The result is a filter that looks remarkably effective, because it partly knows the answer.

How do you close it?

Use only the LAST COMPLETED higher-timeframe bar at every moment, which means shifting the higher-timeframe series forward by one full bar before joining it.

In practice: at any M15 timestamp, the H4 values available are those of the H4 candle that closed most recently — the 04:00–08:00 candle for every M15 bar between 08:00 and 12:00. The current, forming candle contributes nothing until 12:00 has passed.

The cost is real and worth stating: your filter is now up to four hours stale. A trend that turned at 08:30 will not be visible to the filter until noon. That staleness is not a flaw in the method; it is the actual information a trader had at the time, and any result that avoids it is describing a trader who did not exist.

The correctness check is straightforward. Run the strategy with the shift and without it. If the results are dramatically better without, the filter was leaking, and the size of the gap tells you how much of the original result was the leak.

What about indicators computed on the higher timeframe?

An indicator inherits the leak of the series it is computed on, and some indicators extend it — a moving average across N higher-timeframe bars leaks whenever the most recent of those bars is still forming.

The same rule applies: compute the indicator on completed higher-timeframe bars only, then carry the value forward across the lower-timeframe bars until the next higher-timeframe bar closes. The resulting series is a step function, which is exactly what a trader watching two charts actually sees.

Watch for indicators with long warm-ups. A 200-period H4 moving average needs 200 completed H4 bars, which is more than a month of history before the strategy can trade at all — and a backtest that starts trading at bar one is using a partially warmed indicator whose early values are not what the same code would produce live.

The habit worth building is to treat every cross-timeframe value as a timestamped fact: what was knowable, at what moment, and by whom.

Does multi-timeframe filtering help once the leak is closed?

Often yes, and by considerably less than the leaky version suggested — which is the whole reason the check matters before adopting the approach.

The mechanism is plausible. A higher timeframe summarises a longer stretch of price action and is less affected by noise, so using it to select direction and a lower one to time entry is a reasonable division of labour rather than superstition.

But it is a filter, and every filter costs sample size. Requiring H4 agreement can remove half the trades, which makes the remaining result noisier and improves it by chance roughly half the time. The comparison has to hold the setup constant and measure the filtered subset against the unfiltered one, rather than adding the filter and checking whether the total went up.

Then count the variants. Which higher timeframe, which indicator, which threshold for agreement — that is easily twenty combinations, and the best of twenty needs a higher bar than the first one tested.

Questions people actually ask

Which timeframe combination works best?

There is no universally best pair, and combinations are usually chosen by a rule of thumb such as a four-to-six times ratio between them. Because each candidate combination is a trial, testing eight of them and reporting the best is a search — the defensible approach is to fix the combination on one part of the history and grade it once on another.

Does this leak affect TradingView strategies too?

Pine Script's higher-timeframe requests have specific settings governing whether the current forming bar is included, and the lookahead setting is the one that matters. Enabling lookahead produces exactly the leak described here, and it is a documented option rather than a bug — which means the responsibility for using it correctly sits with the script author.

How do I tell if my multi-timeframe backtest is leaking?

Run it twice: once using the current higher-timeframe bar and once using only the last completed one. A large gap between them is the leak, measured. If the strategy's advantage disappears when the shift is applied, the higher timeframe was contributing information from the future rather than context from the past.

The only backtest that settles it is yours.

Build a strategy from a sentence, paste your own Python, or import your live trade history and have it graded. Five full backtests free, no card, and we'll tell you plainly when the result is indistinguishable from luck.

We publish research and tooling, not trading advice, and we make no claim about future returns. Everything above describes how to test an idea — not a reason to trade one.