Skip to content

Non-Repaint Compliance

Critical patterns for reliable, non-repainting indicators.

What is Repainting?

Repainting = Historical signals change after they're drawn.

This makes backtests unreliable because you see signals that didn't exist in real-time.

Critical Rules

Rule 1: Signal on Confirmed Bars Only

// WRONG - repaints!
if myCondition
    label.new(bar_index, high, "Signal")

// CORRECT
if myCondition and barstate.isconfirmed
    label.new(bar_index, high, "Signal")

Rule 2: No Lookahead in request.security

// WRONG - uses future data!
htf = request.security(sym, tf, close, lookahead=barmerge.lookahead_on)

// CORRECT
htf = request.security(sym, tf, close, lookahead=barmerge.lookahead_off)

Rule 3: No barstate.isrealtime for Signals

// WRONG - won't exist in backtest!
if barstate.isrealtime and condition
    // Signal...

// CORRECT - works in both live and backtest
if barstate.isconfirmed and condition
    // Signal...

Rule 4: No Backdating Drawings

// WRONG - changes history!
if condition
    label.new(bar_index[5], high[5], "Signal")

// CORRECT - draw at current bar
if condition
    label.new(bar_index, high, "Signal")

Testing for Repaint

  1. Bar Replay: Enable bar replay, step through. Do signals change?
  2. Reload Chart: Save signals, reload. Same signals?
  3. Compare Live vs History: Does behavior differ?

Compliance Checklist

  • All signals use barstate.isconfirmed
  • No request.security with lookahead_on
  • No barstate.isrealtime for signals
  • No backdated drawings
  • State changes only on confirmed bars