TradingView Repainting: Why Your Backtest Fails Live

Huzefa Kudrati 8 min read

Repainting is when a TradingView script shows past signals that it wouldn't actually have given you in real time. On a finished chart, every signal sits neatly at the right bar. Live, a signal can appear mid-bar and vanish before the close, or be drawn on a bar after the fact. Backtests run on finished bars, and alerts fire on bars that are still forming. So a repainting script can look excellent in the Strategy Tester and behave very differently once it's automated.

The four common causes of repainting

Cause What happens Typical symptom
Signals on the unclosed bar The condition is true mid-bar, the alert fires, then the bar closes and the condition is false Alerts that don't match any arrow on the finished chart
Higher-timeframe data (request.security) On history, the script sees the higher-timeframe bar's final value. Live, that bar is still forming, or lookahead leaks future data into history A backtest that's too good to be true on a multi-timeframe strategy
Late-confirming indicators Pivots and zigzags only know a high was a high some bars later, but draw it on the original bar Perfect tops and bottoms on the chart that couldn't be traded
Backtest fill assumptions Orders fill at prices the live market wouldn't give, such as on Heikin Ashi or Renko charts or with optimistic settings Live fills consistently worse than the Strategy Tester's

The first two cause most of the trouble in automated strategies. The third mostly misleads people visually. The fourth isn't repainting in the strict sense, but it produces the same gap between backtest and live.

Fix 1: only act on confirmed bars

On historical bars, your script runs once per bar, on the closed values. On the live bar, it can run on every price update, depending on the alert and strategy settings. A crossover can be true at 10:17 and false by the 10:20 close.

The simplest fix is to require the bar to be confirmed:

//@version=5
strategy("EMA cross, confirmed", overlay=true)
fast = ta.ema(close, 9)
slow = ta.ema(close, 21)
longSignal  = ta.crossover(fast, slow)  and barstate.isconfirmed
shortSignal = ta.crossunder(fast, slow) and barstate.isconfirmed
if longSignal
    strategy.entry("Long", strategy.long)
if shortSignal
    strategy.entry("Short", strategy.short)

Then, when you create the alert in TradingView, choose Once Per Bar Close where the alert dialog offers a frequency. The alert can then only fire on a signal that will still be on the chart tomorrow.

The trade-off is speed. You act at the close of the signal bar, not the moment the line crosses. For most strategies on 5-minute or longer charts, that's the right trade-off. A strategy that genuinely needs intrabar entries has to be tested on live prices, because history can't show you what happened inside each bar.

Fix 2: fetch higher-timeframe data without peeking

Multi-timeframe scripts are the classic source of backtests that are too good. Ask for the hourly close on a 5-minute chart the wrong way, and on historical bars the script can see the hourly bar's final close at 09:20, long before that close existed.

The non-repainting pattern takes the previous completed higher-timeframe value:

htfClose = request.security(syminfo.tickerid, "60", close[1], lookahead = barmerge.lookahead_on)

The [1] means you always use the last finished hourly bar. With lookahead on, history and live then line up. It's slightly slower to react, and it's honest.

Fix 3: be careful with pivots and zigzags

A swing high is only known to be a swing high after a few lower bars follow it. Functions like ta.pivothigh(high, 5, 5) return the pivot 5 bars later, and many scripts then draw it back on the original bar. That's fine for analysis. But a strategy that "buys at the swing low" is often buying at a price it could only identify later. If your strategy uses pivots, enter on the bar where the pivot is confirmed, not where it's drawn.

Fix 4: make the backtest's fills realistic

  • Use standard candles for the backtest. Heikin Ashi, Renko and similar charts compute prices that never traded, and TradingView warns that strategy results on them can be unrealistic.
  • Set commission and slippage in the strategy's properties. Both default to zero.
  • Check where orders fill: next bar's open, or this bar's close (process_orders_on_close). Match it to how your alerts will trigger.

For the whole list of reasons a backtest and live trading drift apart, read nine reasons your backtest doesn't match live trading.

How to check a script for repainting

  1. Use Bar Replay. Replay a past session bar by bar, and note where signals appear and disappear compared with the finished chart.
  2. Compare the alert log with the chart. After a live session, line up each alert's timestamp against the chart's signals. Alerts with no matching arrow are repainting.
  3. Mark confirmed bars. Temporarily plot a marker on barstate.isconfirmed signals only, and see whether the signal markers move.
  4. Search the code for request.security calls without [1] on the series, for lookahead_on on current values, and for pivot functions.

The Indian execution gap, on top of repainting

Even a perfectly non-repainting script can see live results drift from the Strategy Tester when it trades in India:

  • Index signal, option trade. A strategy backtested on the NIFTY chart, but traded through an ATM option, earns the option's move, not the index's. Delta, spread and time decay all differ from what the backtest saw.
  • Opening gaps. A signal on the first candle at 09:15 can meet a very different option price from the previous close the backtest assumed.
  • Algo orders aren't plain market orders. Under SEBI's retail algo framework, algo orders go out as limit or price-protected orders, so a fast candle can mean a partial fill or a worse price. The details are in is TradingView auto trading legal in India?
  • Expiry days. Weekly expiry options move fast in the afternoon. A strategy tested on futures behaves very differently on expiring options.

Run it forward before you trust it

TradingView's Strategy Tester tells you how a script did on history. It can't tell you how the alerts behave live. That's where the gap shows up, so run the automated version forward first.

On Tradetron, paste the script into Create โ†’ Pine Script Strategy (PineBridge), choose what each signal trades, and deploy it Live Offline. It runs on live prices and records every signal and trade, but Tradetron places no order. Compare the recorded signals with the finished chart for a week or two. If they match, the script isn't repainting in practice. The setup is in automate a TradingView Pine Script on Indian brokers. If you're unsure which kind of script you have, read Pine Script indicator vs strategy.

Past performance, including a backtest, does not indicate future results. This guide is for education and isn't investment advice.

Frequently asked questions

What is repainting in TradingView?

Repainting is when a script's past signals differ from what it would have shown in real time. Usually a signal appears on a bar that's still forming and then disappears, or a signal is drawn on a bar after the fact. The finished chart then looks better than any live trader could have done.

Why does my TradingView strategy work in backtest but not live?

The most common reasons are signals that fire before the bar closes, higher-timeframe data fetched with lookahead, and unrealistic fills (no commission or slippage, or a non-standard chart type). In India, trading an option on an index-chart signal adds another gap.

How do I stop a Pine Script from repainting?

Require barstate.isconfirmed on your signal conditions, set alerts to fire once per bar close, fetch higher-timeframe data as request.security(..., close[1], lookahead = barmerge.lookahead_on), and enter pivot-based trades only once the pivot is confirmed.

Are non-repainting indicators better?

They're more honest, not necessarily more profitable. A non-repainting version reacts a little later, because it waits for confirmation. But what you see in the backtest is what you could have traded.

Does Heikin Ashi repaint?

Heikin Ashi candles don't redraw the past, but strategy backtests on Heikin Ashi charts fill at prices that never traded. Run backtests on standard candles, even if you use Heikin Ashi for reading the chart.

How can I check my strategy's live behaviour without risking money?

Run it forward on live prices. On Tradetron, deploy the automated strategy Live Offline: it records every signal and trade, but no order is placed. Then compare the recorded signals with the finished chart.

Want to join Tradetron?

Thousands of traders have moved to algo trading. Leave your number and our team will help you get started.