Pine v6: var vs varip vs const — State Management and Real‑Time Semantics
The most common Pine confusion is persistent state. This guide demystifies var
, varip
, and const
, the bar update model, and safe patterns for robust indicators and strategies.
The Pine bar update model in 60 seconds
- Every historical bar executes once. The current (real-time) bar can execute multiple times as price updates.
barstate.isrealtime
is true during live updates;barstate.isconfirmed
is true only after the bar closes.timeframe.change()
andta.change(time(tf))
help detect new bars/sessions and HTF boundaries.
What <code>var</code> does
var
initializes once on the first script execution, then persists across all future bars. Use it for long‑lived state like arrays, tables, labels, rolling stats, and previous values you must remember across bars.
//@version=6 indicator("Session High/Low", overlay=true) sess = input.session("0930-1600", "Session") inSess = time(timeframe.period, sess) var float sessHigh = na var float sessLow = na newSess = ta.change(inSess) if newSess sessHigh := high sessLow := low else sessHigh := math.max(sessHigh, high) sessLow := math.min(sessLow, low) plot(sessHigh, color=color.new(color.orange, 0)) plot(sessLow, color=color.new(color.orange, 0))
What <code>varip</code> does
varip
persists only within the current real‑time bar. It resets at the next bar open. Use for intrabar accumulation like micro‑high/low, tick counters, or per‑bar running stats. It won’t pollute state across bars.
//@version=6 indicator("Intrabar Extremes (varip)", overlay=false) varip float hi = na varip float lo = na hi := na(hi) ? high : math.max(hi, high) lo := na(lo) ? low : math.min(lo, low) plot(hi, color=color.new(color.lime, 0)) plot(lo, color=color.new(color.red, 0))
What <code>const</code> does
const
creates compile‑time constants. Use it for values that never change (e.g., immutable color palettes, fixed ratios) to improve clarity and allow potential compile‑time optimizations.
//@version=6 indicator("Using const", overlay=false) const float GOLDEN = 1.618 plot(close / ta.ema(close, 55) * GOLDEN)
Choosing between var and varip
- Need state across bars? Use var.
- Need state only within the current live bar? Use varip.
- Need a constant at compile time? Use const.
Patterns: labels and arrays safely
//@version=6 indicator("Label Reuse", overlay=true) var label lab = na if barstate.islast if na(lab) lab := label.new(bar_index, close, text="Hi", style=label.style_label_down) else label.set_x(lab, bar_index) label.set_y(lab, close)
Reusing a single label
via var
prevents memory growth. For arrays, initialize once with var
and update in place.
Edge cases and gotchas in v6
- Booleans are never
na
in v6. Use guards around series that can bena
. - Reset
var
state on boundaries explicitly (session change, symbol change) if required. - Mixing
var
andvarip
? Document the intent—intrabar vs interbar—so future edits don’t regress behavior.
For repaint‑safe patterns and HTF confirmation, see our guides onrepaint pitfalls andMTF design.
FAQ
varip
persist across symbols or reloads?No. varip
lives only within the current bar’s intrabar updates. It resets on the very next bar.
var
scalars?Use arrays for collections (watchlists, rolling windows); use var
scalars for single persistent values.