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.