Skip to content
ChartTailor
WorkServicesPricingField NotesAbout Start a build
← Pine Discoveries

varip escapes realtime rollback, but it does not make history remember the ticks

Pine realtime rollback, drawing objects, and `varip` can produce behaviour that is useful live and impossible to reproduce after reload.

Drawings make realtime Pine behaviour visible. A line extends, a label moves, a box grows, and it feels like the script is storing the path of the live bar. Sometimes it is. Sometimes it is only storing the current committed state. The difference becomes obvious when the chart reloads and the live behaviour no longer matches what was seen during the session.

It keeps coming up because varip is powerful enough to be useful and dangerous enough to deserve a warning label. It can preserve values across realtime updates inside the same bar, escaping the normal rollback that Pine applies while a bar is forming. That does not mean the historical chart can reconstruct those updates later.

Why this catches people

The quick-but-wrong version is to treat varip as a general anti-repaint tool. It is not. It is a realtime persistence tool. On a live bar, Pine may recalculate as new updates arrive and roll variables back to their last committed state between executions. varip lets a variable keep its intrabar value through those updates. That can be exactly what you need for tick counters, intrabar flags, and temporary drawing state.

But once the realtime bar becomes historical and the script reloads, the original sequence of updates is gone. The chart can only rebuild from historical bars. Any behaviour that depended on those intrabar updates may repaint in the plain sense that the reloaded history cannot show what the live chart showed.

The Pine bit

The detail I write down is that varip changes realtime persistence, not historical knowledge. It also does not remove the need to reset state. Because a varip variable can survive intrabar executions, it is easy to accidentally carry a flag too far unless the script resets it at the start of each new realtime bar.

Drawing object IDs add another layer. A var array of lines, labels, or boxes may still be affected by rollback unless the state that manages those drawings is designed for realtime. The code has to distinguish between committed drawings and intrabar drawings that are only meaningful while the bar is alive.

//@version=6
indicator("varip reset pattern", overlay = true)

varip bool touchedDuringBar = false

if barstate.isnew
    touchedDuringBar := false

touchedDuringBar := touchedDuringBar or high > ta.highest(high[1], 20)
plotshape(touchedDuringBar, style = shape.circle)

Why it can survive a quick review

This can slip through review because the live chart can look perfect. The script catches the intrabar event, the drawing appears, and the user sees proof. The reload test is what reveals the contract. If the event was never visible from the final OHLC values, or if the exact sequence mattered, the historical chart cannot be expected to reproduce it.

That is not automatically a reason to avoid varip. Some tools are intentionally live-only. A live warning can still be valuable even if it does not become a permanent historical marker. The problem is when the script presents a live-only event as if it were a durable historical signal.

How I handle it in builds

In custom indicators, I try to label live-only behaviour in the design. Confirmed drawings and realtime drawings should not be visually identical. If a line only exists because the current bar touched a level, I want the user to know whether that touch is confirmed, provisional, or just a live trace.

I keep the reset logic close to the varip variable. When the reset is far away, future edits can accidentally change the variable’s lifetime. That is the kind of bug that only appears while the market is moving.

Where this shows up

A good live test is to put a temporary counter next to the drawing. Count how many realtime updates created or moved the object, then reload the chart. If the counter or drawing disappears, that confirms the behaviour was live-only. That is not a failure by itself. It is information the design needs to carry.

I am also careful with alerts attached to varip state. A live-only flag can fire an alert that will never be visible on the reloaded chart. That may be acceptable for a warning tool, but it is a poor fit for a signal archive or a strategy claim. The alert payload should include a state like live_touch rather than pretending the event is a confirmed historical signal.

The more object-heavy the script becomes, the more important this distinction is. Boxes and labels can make provisional information look permanent.

The implementation detail that saves the most trouble is separating “candidate object” from “confirmed object.” A candidate line can move during the live bar. A confirmed line should be created or frozen only when the confirmation condition is true. If the same line ID changes roles, the code becomes harder to audit because a reload may rebuild only the confirmed part while the live session showed both.

I avoid using varip as a shortcut for poor state design. If the script can work with normal confirmed state, that is usually better. varip earns its place when the live path itself is valuable.

How I test it

I test realtime behaviour with a reload test. Watch the script during a live bar, then refresh or reload the chart and compare what survives. The difference tells me which parts were confirmed history and which parts were live-only behaviour.

When realtime behavior is central, I test three states: live before close, immediately after close, and after reload. Those are the moments where rollback, commit, and historical reconstruction separate. A script that explains all three is much easier to trust.

Checks before I trust it

  • Use varip for realtime persistence, not as a promise of historical reproducibility.
  • Reset varip state deliberately with barstate.isnew when the value is bar-scoped.
  • Distinguish live-only drawings from confirmed drawings.
  • Reload the chart after observing live behaviour and compare what survives.
  • Explain live-only behaviour in the script notes if users will rely on it.

What matters here is that varip is not a memory of history. It is memory during realtime execution. Used with that limitation in mind, it is useful. Used casually, it can make a chart look more certain than it really is.