Page 1 of 1

The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 09, 2026 3:44 pm
by FTtrader
Hey everyone,

We’ve all been there. You code or find a new scalping strategy on TradingView. The backtest looks like the Holy Grail—a smooth 45-degree equity curve, 85% win rate, and massive profit factors. You load it onto a live chart, fund the account, and... it immediately starts hemorrhaging money.

Welcome to the Repainting Trap.

In 99% of these cases, your strategy isn’t actually a stroke of genius; it’s just illegally looking into the future. In Pine Script, this is known as leaking future data. Here is exactly how it happens, why the Pine engine gets confused, and how to fix the two most common traps.

1. The Higher Timeframe (HTF) Trap

This is the most common way coders accidentally leak future data. It happens when you use request.security() to pull data from a higher timeframe down to your scalping timeframe (e.g., pulling 1-hour data onto a 5-minute chart).

The Problem:

Historically, if you ask Pine Script for the 1-hour close while you are on the 10:05 AM 5-minute candle, Pine engine already knows how that 1-hour candle ended. It will feed the final 11:00 AM closing price to your 10:05 AM candle. Your strategy executes a perfect trade at 10:05 based on information it couldn't possibly have known yet! But in live trading, the 1-hour close doesn't exist yet, so the indicator behaves completely differently.

❌ The Bad Code (Leaks Data):

Code: Select all

// This looks at the 1-hour close on historical bars before the hour is actually over!
htf_close = request.security(syminfo.tickerid, "60", close)
✅ The Fix:

You must tell Pine Script to only pull the data from the previous, fully closed higher timeframe candle.

Code: Select all

// This forces the script to use the last completed 1-hour candle, preventing leaks.
htf_close_safe = request.security(syminfo.tickerid, "60", close[1], lookahead = barmerge.lookahead_on)
(Note: Using close[1] with lookahead_on is the standard Pine v5 trick to fetch the previous HTF close exactly when it completes, without shifting it forward unnecessarily).

Re: The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 09, 2026 3:45 pm
by FTtrader
2. The Intra-Bar "Phantom Signal" Trap

Scalpers love fast signals, but reacting to prices before a candle closes causes massive repainting.

The Problem:
During a live, unclosed candle, the close variable constantly updates with every new tick. Your indicator might flash a valid "Buy" signal because the RSI crossed 70 mid-candle. You take the trade. But two minutes later, the price drops, the candle closes, and the RSI finishes at 65.

When you refresh the chart, that Buy signal completely disappears. The chart looks pristine, but your trading account took a loss that the backtester now pretends never happened.

❌ The Bad Code (Phantom Signals):

Code: Select all

// Triggers mid-candle live, but only shows on closed candles historically.
buy_signal = ta.rsi(close, 14) > 70
✅ The Fix:

Lock your signals to confirmed candle closes. It adds slight lag, but it makes your backtests 100% honest.

Code: Select all

// The 'barstate.isconfirmed' variable ensures the signal only fires when the candle permanently closes.
buy_signal_safe = ta.rsi(close, 14) > 70 and barstate.isconfirmed

Re: The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 09, 2026 3:47 pm
by FTtrader
🛠️ The Ultimate Sanity Check: The Replay Test

Never trust a chart that just loaded historically. Before you trade any script live:

1.) Open the Bar Replay tool in TradingView.

2.) Cut the chart back a few days.

3.) Hit "Play" at 1x or 3x speed.

If the indicator draws a signal, and then miraculously moves it, erases it, or shifts it a few bars later as new price data comes in—it repaints. Dump it, or fix the code.

Protect your capital and stop trusting unverified backtests. Has anyone else gotten burned by a repainting script recently? Drop your stories below. 👇

Re: The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 09, 2026 3:48 pm
by FTtrader
To understand barmerge.lookahead_on, you have to look at how Pine Script's engine merges data from a higher timeframe (HTF) down to a lower timeframe (LTF) chart.

The lookahead argument controls time travel: it dictates whether your script is allowed to look ahead and grab the final closing value of a higher timeframe candle before that candle has actually closed in real-time.

Here is the exact breakdown of how it behaves across the three possible configurations.

1. The Default: lookahead_off (Safe, but Laggy)

If you don't specify the lookahead argument, Pine Script defaults to barmerge.lookahead_off.

To prevent repainting, Pine Script waits until the HTF candle is completely closed before making its data available to your LTF chart.

The Setup: You are on a 5-minute chart, pulling data from a 1-hour chart.

The Action: The 10:00 AM 1-hour candle opens.

The Result: From 10:00 to 10:55, your script cannot see the 10:00 AM HTF candle because it hasn't closed yet. It is forced to look at the 09:00 AM HTF candle. The data for the 10:00 AM HTF close will not become available until your 11:00 AM 5-minute candle opens.

Code: request.security(syminfo.tickerid, "60", close)
Verdict: 100% safe from repainting, but introduces a frustrating 1-bar delay.

Re: The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 09, 2026 3:49 pm
by FTtrader
2. The Trap: lookahead_on (The Future Leak)

If you turn lookahead_on but ask for the current candle's close, you break the spacetime continuum. You are telling Pine Script: "Fetch the data for this HTF candle, and merge it onto the LTF bars right now, even if the HTF candle hasn't finished yet."

The Setup: 5-minute chart, pulling 1-hour data.

The Action: The 10:00 AM 1-hour candle opens.

The Result: On the 10:05 AM 5-minute candle, Pine Script jumps forward in time, grabs the final 11:00 AM closing price, and feeds it to your 10:05 AM candle.

In a historical backtest, your script behaves as if it knows exactly where the price will be 55 minutes in the future. In live trading, this is impossible, resulting in massive repainting and destroyed trading accounts.

Code:

Code: Select all

request.security(syminfo.tickerid, "60", close, lookahead = barmerge.lookahead_on)
Verdict: Repaints historically. Never use this for backtesting executable signals.

Re: The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 09, 2026 3:50 pm
by FTtrader
3. The Professional Fix: lookahead_on + [1] (Perfect Alignment)

To get historical data without the artificial delay of lookahead_off and without the repainting of lookahead_on, professional Pine coders combine lookahead_on with the historical reference [1].

You tell the engine: "Merge the HTF data instantly without delay (lookahead_on), but specifically give me the close of the PREVIOUS HTF candle (close[1])."

The Setup: 5-minute chart, pulling 1-hour data.

The Action: The 10:00 AM 1-hour candle opens.

The Result: At exactly 10:00 AM, the script instantly fetches the close of the 09:00 AM HTF candle. There is no artificial delay waiting for 11:00 AM, and there is no time-traveling into the future. It grabs the most recent, fully-closed HTF data exactly when it becomes mathematically true.

Code:

Code: Select all

request.security(syminfo.tickerid, "60", close[1], lookahead = barmerge.lookahead_on)
Verdict: 100% safe. Zero lag, zero repainting. This is the industry standard for pulling HTF data in Pine v5.

Re: The "Repainting" Trap: How Pine Script Leaks Future Data (And Ruins Your Backtests)

Posted: Wed Sep 23, 2026 8:41 pm
by LondonScalper
FTtrader wrote:To understand barmerge.lookahead_on , you have to look at how Pine Script's engine merges data from a higher timeframe (HTF) down to a lower timeframe (LTF) chart.
Lookahead on HTF merges is one of those silent backtest lies. The script looks prophetic on the chart and average live.

My rule for any HTF filter in Pine: confirm it does not peek, then re-check on replay with realistic assumptions. If performance collapses when lookahead is off, the edge was the leak.

I would rather a slightly lagging honest signal than a beautiful curve I cannot trade in London hours.

What is your standard checklist before you trust an HTF condition in a public script?

I keep a short note in the script header: lookahead status, HTF pair, and last review date. If that note is missing I treat the script as unsafe for size.