Pine Script Historical Lookback

Pine Script Event History: Tracking Signals with barssince and valuewhen

In Pine Script, event history is tracked primarily through ta.barssince() and ta.valuewhen(). ta.barssince(condition) counts the number of bars elapsed since a specific boolean condition was true, returning na if the event has never occurred. ta.valuewhen(condition, source, occurrence) retrieves the historical value of a source expression at the moment the condition was met, allowing traders to reference past signal prices and pivot levels.

Build Event Logic with AI

Comparing ta.barssince and ta.valuewhen in Pine Script v6

Tracking past market conditions without manual loop indexing is vital for time-based exits, pullback validation, and multi-stage trade confirmation.

FunctionArgumentsReturned valueTypical trading use case
ta.barssince(condition)condition (series bool)Integer bar count or naEnforcing a 5-bar cooldown between consecutive trade signals
ta.valuewhen(condition, source, 0)condition, source, occurrenceSource value at most recent eventAnchoring stop loss to the breakout candle low
ta.valuewhen(condition, source, 1)condition, source, occurrenceSource value at 2nd most recent eventComparing current swing high against the previous swing high
ta.highestbars(source, length)source, lengthNegative offset to highest barLocating exact candlestick of highest peak within 20 bars

Complete Pine Script v6 script: Signal tracking and price anchoring

The following Pine Script v6 indicator measures bars since an RSI oversold crossover, plots the candle close of that signal as a support level, and highlights fresh signals that occur after a required cooldown window.

Pine Script v6: Event lookback with barssince and valuewhenpinescript
//@version=6
indicator("Event Lookback & Anchor Tracker [v6]", overlay = true)

// Input settings
int rsiLength = input.int(14, "RSI Length", minval = 1)
float rsiOversold = input.float(30.0, "Oversold Level")
int minCooldownBars = input.int(5, "Minimum Cooldown Bars", minval = 1)

// Calculations
float rsiVal = ta.rsi(close, rsiLength)
bool rawSignal = ta.crossover(rsiVal, rsiOversold)

// Bars since previous signal
int barsSincePrior = ta.barssince(rawSignal[1])
bool isReady = na(barsSincePrior) or (barsSincePrior >= minCooldownBars)
bool confirmedSignal = rawSignal and isReady

// Store price of the latest confirmed signal
float anchorPrice = ta.valuewhen(confirmedSignal, close, 0)
int barsSinceSignal = ta.barssince(confirmedSignal)

// Plotting
plot(anchorPrice, "Anchor Support Price", color = color.blue, linewidth = 2, style = plot.style_linebr)
plotshape(confirmedSignal, "Confirmed Entry", shape.triangleup, location.belowbar, color.green, size = size.small)

// Visual label displaying bars elapsed on the last bar
if barstate.islast and not na(barsSinceSignal)
    label.new(bar_index, high, "Bars since signal: " + str.tostring(barsSinceSignal), 
              color = color.purple, textcolor = color.white, style = label.style_label_down)

Common pitfalls when working with barssince and valuewhen

Understanding how historical series buffers behave prevents confusing calculation errors:

  • Evaluating current bar triggers: Writing ta.barssince(myCond) on a bar where myCond is true returns 0. To check bars since the previous occurrence, evaluate ta.barssince(myCond[1]) + 1.
  • Initial na state: If a signal has not yet fired on the chart, both functions return na. Always test with na(val) before performing mathematical comparisons.
  • Occurrence index ordering: In ta.valuewhen(), occurrence 0 is the latest event, occurrence 1 is the one before it, and so forth. Supplying negative values causes compiler errors.
  • Repainting risk with intrabar conditions: Ensure the condition passed to valuewhen is based on confirmed bars to prevent the recorded historical value from shifting during live candle ticks.

When to choose var variables over valuewhen

While ta.valuewhen() is concise for one-off lookbacks, declaring a var variable is often preferred when building complex state machines:

  • Performance optimization: Storing values in var variables executes slightly faster than querying deep occurrence lookbacks across long chart histories.
  • Multi-stage resets: A var variable can be reset to na when a trade completes, preventing accidental lookbacks to events from weeks earlier.
  • State persistence: A var variable can be updated across multiple conditions without duplicating nested valuewhen calls.
Where Pineify fits

Pine Script AI Coding Agent

Generate event-tracking indicators, barssince cooldown rules, and anchored multi-condition strategies in Pine Script v6 using Pineify AI.

Also useful: Visual Pine Editor. Build signal conditions, price alerts, and indicator workflows visually without coding.

Build Event Logic with AI

Frequently asked questions

Historical event tracking and price lookups reflect mathematical bar sequences on chart data. Verify execution behavior and slippage allowances when trading live markets.

Sources and verification