pine scriptrepaintingtradingviewbugs

Pine Script Repainting: What It Is and How to Avoid It

Repainting is one of the most common and costly bugs in TradingView indicators. Learn what causes it, how to spot it, and how professional Pine Script developers prevent it.

·4 min read

What Is Repainting?

Repainting is when a TradingView indicator shows a signal on historical bars that would not have been visible in real time when that bar was forming.

In plain terms: the indicator looks perfect on backtests but fails in live trading.

This is one of the most dangerous bugs in custom indicators — and one of the most common. Many traders have lost money trading signals that were generated by repainting indicators without knowing it.


Why Does Repainting Happen?

There are two main causes:

1. Using security() with lookahead

The request.security() function fetches data from higher timeframes. If you use it incorrectly, it can "look into the future" — using a higher timeframe bar's closing value before that bar has actually closed.

// ❌ This repaints — uses future bar data
htf_close = request.security(syminfo.tickerid, "D", close, lookahead=barmerge.lookahead_on)

// ✅ This does not repaint — uses confirmed bar data
htf_close = request.security(syminfo.tickerid, "D", close[1], lookahead=barmerge.lookahead_off)

2. Using close Instead of a Confirmed Value

When a bar is still forming, close is the current price — not the final close. Any signal calculated using close on the current bar can change before the bar closes.

// ❌ Signal changes as price moves on the current bar
signal = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))

// ✅ Only fires on confirmed closes
signal = ta.crossover(ta.ema(close[1], 9), ta.ema(close[1], 21))

How to Spot a Repainting Indicator

The Replay Test

Use TradingView's Bar Replay feature. Go back in time and play the chart forward bar by bar. If signals appear or disappear as you advance, the indicator repaints.

The Live Watch Test

Add the indicator to a live chart and watch it for several bars as they close. If a signal that appeared during a bar disappears after the bar closes — it repaints.

Code Review

Look for:

  • lookahead=barmerge.lookahead_on in request.security() calls
  • Signals calculated on close (current bar) without [1] offset
  • Use of var variables that get recalculated on historical bars

Common Repainting Patterns to Watch For

PatternIssueFix
request.security(..., close)Uses unconfirmed HTF closeUse close[1] or lookahead_off
Signal on close (no offset)Changes while bar is openAdd [1] offset or use barstate.isconfirmed
Dynamic support/resistanceRecalculates on historyUse var and only update on confirmed bars
highest(high, n)Includes current barOffset by [1] for historical accuracy

How to Write Non-Repainting Indicators

Use barstate.isconfirmed

Only trigger signals when a bar has fully closed:

if barstate.isconfirmed
    // safe to act on close here
    signal := ta.crossover(fast, slow)

Use [1] Offsets Correctly

Reference the previous bar's confirmed value instead of the current forming bar:

confirmed_rsi = ta.rsi(close, 14)[1]

Test on Both Historical and Live Data

A non-repainting indicator should produce the same signal at the same bar whether you're viewing it historically or watching it in real time.


Why This Matters for Custom Indicators

If you're commissioning a custom Pine Script indicator, always ask:

  • "Is this indicator non-repainting?"
  • "How did you test for repainting?"
  • "Does it use lookahead_on anywhere?"

At TraderOSHQ, every indicator we deliver is explicitly tested for repainting using Bar Replay and live testing before delivery. Non-repainting code is a baseline requirement, not an optional feature.


Summary

Repainting happens when an indicator uses future data — either through incorrect security() calls or signals calculated on unconfirmed bars. It makes backtests look great while failing in live trading.

The fix is: use confirmed bar values, avoid lookahead_on, and always test with Bar Replay.

Need a reliable, non-repainting custom indicator? Get a quote from TraderOSHQ — repainting-free code is guaranteed.

TraderOSHQ

Need a custom Pine Script indicator?

Professional Pine Script v6 development with 3–5 day delivery and lifetime support. Starting from $49.

Get a Quote