How to Fix Repainting in Pine Script: A Developer’s Guide

Fix Pine Script Repainting Issue: A Developer’s Guide to Reliable Code

You’ve built the perfect strategy. The backtest shows a 95% win rate. The equity curve is a straight line up. You are ready to mortgage the house and go all-in.

Then, you turn it on live… and lose money.

You watch closely: a “Buy” arrow appears on the chart. You enter the trade. Five minutes later, the candle closes, the price drops, and the “Buy” arrow vanishes into thin air.

This is Repainting. It is the “Silent Killer” of algorithmic trading.

As a Pine Script Expert Freelancer, fixing repainting is the #1 service I provide in my Pine Script Debugging Service. In this guide, I will explain why this happens, how to spot it, and exactly how to fix Pine Script repainting issues so your backtests match reality.

What is Repainting?

In simple terms, repainting occurs when a script changes its past values based on future data.1

Imagine betting on a football game. Repainting is like the script waiting until the game ends, seeing who won, and then placing a bet on the winner at the odds from the start of the game. Of course, you’d win every time.

In TradingView, this usually happens because the script is accidentally “peeking” at future data that wouldn’t have been available at the moment the trade was supposedly taken.2

The 3 Most Common Causes of Repainting

If you are looking for a TradingView Strategy Developer to audit your code, these are the first three things we look for.

1. The request.security Trap (The #1 Culprit)

This function allows you to pull data from other timeframes (e.g., seeing a Daily Moving Average on a 15-minute chart). This is the core of any Multi-Timeframe Indicator Pine Script.

However, if you don’t handle the “lookahead” parameter correctly, the script reads the closing price of the Daily candle before the day has actually finished.

❌ The Bad Code (Repaints):
// V5 Example
dailyClose = request.security(syminfo.tickerid, "D", close)

// This reads the FINAL close of the day at 00:01 AM.
// On history, it cheats. Real-time, it waits.
✅ The Fixed Code (Does Not Repaint):

To fix this, we must ensure the script only looks at the previous bar’s data or disables lookahead.

// Option A: Use barmerge.lookahead_off (Safest)
dailyClose = request.security(syminfo.tickerid, "D", close, lookahead = barmerge.lookahead_off)

// Option B: Reference the PREVIOUS bar explicitly [1]
dailyClosePrevious = request.security(syminfo.tickerid, "D", close[1], lookahead = barmerge.lookahead_on)

2. calc_on_every_tick=true in Strategies

When building an Automated Trading Strategy Pine Script, you might enable calc_on_every_tick=true to get faster signals.

The problem? In backtesting, TradingView strategies generally only calculate on the Close of the bar.3 In real-time, this setting calculates on every price tick.

  • Result: A signal might flash “True” mid-candle, trigger an alert, and then turn “False” when the candle closes.
  • The Fix: Unless you are an advanced coder using “Intrabar Inspection,” always treat strategy signals as confirmed only on Bar Close.

3. Negative Offsets (offset=-1)

Sometimes a developer wants to shift a Moving Average to the left to “center” it.

Code: plot(sma, offset=-5)

Issue: This literally draws the line in the past. You cannot trade a signal 5 bars ago. It looks great visually, but it is impossible to trade.

How to Test Your Script for Repainting

Before you Hire a Pine Script Coder or risk real money, perform these two simple tests.

The “Bar Replay” Test

  1. TradingView’s “Bar Replay” feature is the quickest way to catch repainting.
  2. Load your indicator.
  3. Click the “Replay” button on the top toolbar.
  4. Cut off the last month of data.
  5. Play the chart forward.
  6. Watch closely: Do signals appear and stay? Or do they flicker and disappear as new bars form?

The “On-Chart” Debugging Test

If you are coding it yourself, use plotchar to debug the exact moment a condition triggers.

// Debugging Code
// Plot a small "X" every time your condition is true
plotchar(buyCondition, "Buy Debug", "X", location.top, size = size.tiny)

If the “X” moves or disappears after a refresh, you have a repainting bug.

Why “Non-Repainting” Indicators Lag

A common complaint I get: “I want a non-repainting indicator that gives signals at the very top and bottom.”

Here is the hard truth of Algo Trading: There is always a trade-off between Lag and Reliability.

  • Repainting Scripts: Zero lag, but fake signals.
  • Non-Repainting Scripts: Slight lag (confirmation), but real signals.

To build a reliable Custom TradingView Indicator, we wait for the candle to close to confirm the signal. This means you might enter the trade 1 candle “late,” but you will never enter a trade that disappears.

Fixing “Strategy Not Firing Alerts”

A side effect of repainting is broken automation. You might set up a TradingView Alert Webhook Setup to send signals to 3Commas or Binance.

Scenario: Your repainting script fires a “Buy” alert mid-candle.
The Bot: Executes the Buy instantly.
The Market: The candle reverses and closes Red. The signal disappears from the chart.
Outcome: You are stuck in a trade that your strategy says “never happened.”

The Solution:

Always automate based on “Once Per Bar Close.” When I Automate TradingView Signals for clients, I force the alert condition to check barstate.isconfirmed.

// Only trigger alert if the bar has officially closed
isConfirmed = barstate.isconfirmed
alertcondition(buySignal and isConfirmed, title="Confirmed Buy", message="Buy Now")

Conclusion: Clean Code = Real Profits

Repainting isn’t always malicious; often, it’s just an honest mistake in understanding how TradingView handles data arrays. But in the world of live trading, an honest mistake drains your wallet just as fast as a scam.

If your strategy looks “too good to be true” (e.g., >90% Win Rate, Profit Factor > 5), it is almost certainly repainting.

Don’t trade on hope. Trade on confirmed data.

Is your script acting weird?

I can audit your code, identify the “future leak,” and rewrite it to be 100% reliable for live trading. Whether you need to Fix Pine Script Repainting Issues or build a robust Automated Trading Strategy, I am here to help.

👉 Audit My Pine Script Code

Stop the repainting. Start the earning.

Frequently Asked Questions (FAQ)

Q: Can a repainting indicator ever be useful?

Yes, for visual analysis. For example, “ZigZag” indicators repaint by design to show market structure highs and lows. They are great for manual analysis but terrible for automated trading entries.

Q: Why does my script work in Replay mode but not Live?

Replay mode isn’t perfect. It simulates historical bars closing. If your script relies on real-time tick data volume or “intra-bar” price movement, Replay mode cannot simulate that data perfectly.

Q: Does request.security_lower_tf cause repainting?

It is very prone to it. Requesting lower timeframe data (like 1-minute data on a 1-hour chart) requires complex handling of arrays. If you just grab the last element of the array without proper indexing, it will repaint.