Guide · Testing and backtesting

How to tell if an indicator repaints, and how to fix it

A repainting indicator changes its past signals, so it looks far better on history than it ever was live. By the end you will know how to test any indicator for it, which ones usually do it, and how to fix it in Pine Script and MQL.

Based on our team’s research and live testing since 2018.

A repainting indicator changes values on bars that have already closed. On a historical chart it shows the perfect arrows, at the perfect turns. Live, the arrows appear late, move, or vanish. Any backtest or EA built on it is testing signals that could not have existed at the time. It is one of the first things we check when an EA works in the backtest but not live, and when a client asks us to rebuild an indicator as one of our custom MT4 and MT5 indicators.

What does repainting actually mean?

Two things are often confused:

  • Normal forming-bar updates. While a bar is open, its close keeps changing, so almost every indicator’s current value moves. Once the bar closes, the value stays. This is not repainting.
  • Repainting. A value or signal on a closed bar changes later, or a signal is drawn back on an earlier bar than the one where it became known. Some people call the second case backpainting.

TradingView’s Pine documentation defines repainting broadly, as script behaviour that makes historical and realtime calculations or plots differ. That is a useful test in itself: does the indicator look the same on history as it did when those bars were live?

Which indicators usually repaint?

TypeWhy it repaints
ZigZagThe last leg moves, or is replaced, as new highs and lows arrive
Fractals and pivotsConfirmed only after later bars close, but drawn on the earlier bar
Higher-timeframe valuesReading the current, unfinished higher-timeframe bar, or looking ahead on history
Centred averages and bandsUse bars on both sides of each point, so recent values change as new bars arrive
Heikin-Ashi strategiesClosed candles are stable, but their prices are averages, not prices you could trade at
Intrabar logicSignals computed on every tick appear and disappear inside the bar

How do you check for repainting in the MT4 or MT5 Strategy Tester?

Both MetaTrader testers can run an indicator on its own in visual mode. In the Strategy Tester of either platform, choose to test an indicator instead of an Expert Advisor, then pick it from the list. Visual mode switches on automatically. The tester then draws the indicator bar by bar, as if the history were live.

  1. Run it at a slow speed over a period with clear swings.
  2. Note where each signal appears, and on which bar it is drawn.
  3. When the run ends, compare the final chart with what you saw during the run.

Arrows that moved, disappeared or were drawn several bars back are repainting. The MT4 tester builds its ticks from bar data, so treat it as a visual check, not a precise one.

How do you prove it? Record the values, then recompute with more data

A precise test compares what the indicator said when each bar closed with what it says about the same bars later, after more data has arrived. This small MQL5 EA does it. It writes the closed-bar value once per bar, then writes the same bars again when the run ends:

RepaintLogger.mq544 lines
1// RepaintLogger.mq5: attach in the visual Strategy Tester or on a demo chart.2// Writes the indicator's value for each bar the moment it closes (at_close.csv),3// then the values for the same bars when the run ends (at_end.csv). Compare the two.4input string InpIndicator = "MyIndicator";  // file name in MQL5\Indicators5input int    InpBuffer    = 0;              // buffer index to check6input int    InpBarsAtEnd = 500;            // bars to write when the run ends7 8int      handle  = INVALID_HANDLE;9datetime lastBar = 0;10 11int OnInit()12{13   handle = iCustom(_Symbol, _Period, InpIndicator);14   return(handle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED);15}16 17void Append(string file, datetime t, double v)18{19   int f = FileOpen(file, FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI, ',');20   if(f == INVALID_HANDLE) return;21   FileSeek(f, 0, SEEK_END);22   FileWrite(f, TimeToString(t), DoubleToString(v, _Digits));23   FileClose(f);24}25 26void OnTick()27{28   datetime t0 = iTime(_Symbol, _Period, 0);29   if(t0 == lastBar) return;                        // once per new bar30   lastBar = t0;31   double v[1];32   if(CopyBuffer(handle, InpBuffer, 1, 1, v) == 1)   // bar 1 = the bar that just closed33      Append("at_close.csv", iTime(_Symbol, _Period, 1), v[0]);34}35 36void OnDeinit(const int reason)37{38   double   v[];39   datetime t[];40   int n = CopyBuffer(handle, InpBuffer, 1, InpBarsAtEnd, v);41   if(n <= 0 || CopyTime(_Symbol, _Period, 1, n, t) != n) return;42   for(int i = 0; i < n; i++)43      Append("at_end.csv", t[i], v[i]);44}

Run it in the visual tester or on a demo chart, then line the two files up by time. Any closed bar with two different values is repainting. In the tester, the files are written to the testing agent’s own MQL5\Files folder, not the terminal’s. The same idea works in MT4 with iCustom() and shift 1.

How do you check if a TradingView indicator repaints?

TradingView’s Bar Replay plays history back one bar at a time. Add the indicator, start the replay some way back, and step forward. Note each signal as it appears. Then stop the replay and compare with the normal chart. Signals that appear in one view and not the other, or sit on different bars, point to repainting.

A second check is a plain alert: create one on the script with no webhook attached, let it run, and compare the times in the alert log with the signals on the chart. TradingView’s help centre warns that alerts on scripts prone to repainting may behave differently from the chart, and recommends not setting alerts on such scripts. If you automate TradingView alerts on MT5, this check is essential.

How do you fix repainting in Pine Script?

Three rules cover most cases:

  • Higher timeframes: request the previous, confirmed value with close[1] and lookahead = barmerge.lookahead_on. TradingView’s documentation notes the two only work together.
  • Signals: add barstate.isconfirmed so a signal only fires once the chart bar has closed.
  • Pivots: ta.pivothigh(5, 5) is only known five bars after the pivot. Plot the signal on the bar where it was confirmed, or make the offset optional and clearly labelled.
htf_filter.pine16 lines
1//@version=62indicator("Non-repainting HTF filter", overlay = true)3tf = input.timeframe("240", "Higher timeframe")4 5// Repaints on live bars: the current HTF close keeps changing until that HTF bar closes6// htfClose = request.security(syminfo.tickerid, tf, close)7 8// Does not repaint: the last CONFIRMED higher-timeframe close9htfClose = request.security(syminfo.tickerid, tf, close[1], lookahead = barmerge.lookahead_on)10 11ma = ta.sma(close, 20)12// barstate.isconfirmed: only signal once the chart bar has closed13longSignal = ta.crossover(close, ma) and close > htfClose and barstate.isconfirmed14 15plot(htfClose, "HTF close")16plotshape(longSignal, "Long", shape.triangleup, location.belowbar)

On Heikin-Ashi charts, compute signals from Heikin-Ashi values if you want them, but fill strategy orders at real prices. TradingView added a “Fill orders using standard OHLC” strategy property for this (fill_orders_on_standard_ohlc in strategy()), which only applies to Heikin-Ashi charts.

How do you fix repainting in MQL4 and MQL5?

  • Read closed bars. Take signals from shift 1 (CopyBuffer(handle, buffer, 1, ...) in MQL5) and act once per new bar.
  • Fractals and pivots: only use a point after the bars that confirm it have closed, and treat the signal time as the confirmation bar, not the pivot bar.
  • Higher timeframes: read shift 1 on the higher timeframe, the last bar that has fully closed, never shift 0.
  • ZigZag: treat the last leg as provisional. Only swing points before it are final.

The trade-off is always the same: a non-repainting signal is later than the repainting one looked on history. That lateness is the real performance of the idea, and it is what a backtest should measure. Our custom MT4 and MT5 indicator and Pine Script builds are non-repainting by default for this reason.

Checklist

  • Indicator run in visual mode or bar replay, and compared with the finished chart
  • Closed-bar values logged and compared after more data arrived
  • Higher-timeframe values read from the last closed bar
  • Signals confirmed on bar close; pivot signals dated at confirmation
  • Strategy orders filled at real prices, not synthetic chart prices
  • EA trades checked one by one against values that existed at the time
These tests show whether signals change after the fact. A non-repainting indicator is testable, not necessarily profitable. Not financial advice.

Quick answers

Do all indicators change on the current bar?

Yes, most do while the bar is forming, because the close keeps moving. That is normal. Repainting means values on bars that have already closed change later.

Is a lagging indicator better than a repainting one?

For automated trading, yes. A signal that arrives one bar late but never changes can be tested honestly. A signal that moves after the fact cannot.

Can an EA use a repainting indicator safely?

Sometimes, if it only reads values that are already final, such as a ZigZag point that is no longer the last one. The backtest must be checked trade by trade to confirm the EA never used a value that later changed.

Does TradingView mark scripts that repaint?

Do not rely on it. TradingView’s help centre warns that alerts on scripts prone to repainting can behave differently from the chart and advises against setting alerts on them. Test the script yourself.

Why do my arrows appear several bars late?

The indicator is probably honest. Pivot and fractal signals can only be confirmed after a set number of later bars. Drawing them back on the original bar is what makes some indicators look early.

Written by
Rohit B., Vertex Algorithms

Co-founder and lead developer. Building MT4/MT5 Expert Advisors, Python trading bots and Pine Script since 2018, with trading analysis by co-founders Harshal K. and Bilal M. About the founders →

Need a non-repainting version of your indicator?

I rebuild indicators in MQL4, MQL5 or Pine Script so signals are fixed once the bar closes, and I show you where any delay comes from.

WhatsApp