One of the most-shared TradingView patterns: enter on a fast/slow EMA crossover, but only in the direction of a higher-timeframe trend pulled in with request.security(). It backtests beautifully — and that is exactly the problem.
//@version=6
strategy("EMA cross + HTF filter", overlay = true)
fast = ta.ema(close, 12)
slow = ta.ema(close, 26)
// Higher-timeframe trend — the way it's usually written
htfTrend = request.security(syminfo.tickerid, "240", close, lookahead = barmerge.lookahead_on)
if ta.crossover(fast, slow) and close > htfTrend
strategy.entry("Long", strategy.long)Look-ahead bias: request.security() uses barmerge.lookahead_on without a [1] offset — on historical bars it returns the higher-timeframe value before it exists. The backtest looks great; live will not match.
Our engine flags a critical look-ahead bias. barmerge.lookahead_on with no [1] offset means that on historical bars the 4-hour value is stamped onto every lower-timeframe bar inside that 4-hour candle — including bars that occurred before the 4-hour candle had closed. The backtest is effectively trading on information from the future, which is why the equity curve looks unusually smooth. Live, that value simply is not available, so the strategy behaves nothing like the tester. The fix is to offset the requested series by [1] and use barmerge.lookahead_off.
Code-correctness analysis only — not financial advice, and not a measure of profitability. The code shown is a representative community pattern, not any specific author's script. Trading involves substantial risk of loss.