Pine Script v6 indexing

Pine Script bar_index: Coordinates, History and Offsets

Pine Script bar_index is the current bar number in the loaded dataset, starting at zero. The number inside a history reference such as close[3] means three bars ago. To read a saved bar index, subtract it from the current bar_index first. At bar 100, index 97 is three bars ago, so close[3] selects it; close[97] selects bar 3.

Review indexing with AI

Translate an index into bars ago

Use barsAgo = currentIndex - targetIndex. A target must have occurred, and the resulting nonnegative offset must fit the relevant history buffer. Do not treat a series as an array whose positions stay fixed. The following values assume the script is executing at bar_index 100.

ExpressionMeaningResult at index 100
bar_indexCurrent dataset coordinate100
bar_index - 3Coordinate three bars earlier97
bar_index[3]Value of bar_index three bars earlier97, when that history exists
close[3]Close three bars earlierClose from index 97
close[97]Close 97 bars earlierClose from index 3
close[0]Current close series valueCurrent price until this bar closes

A minimal wrong lookup and its correction

This example creates synthetic values equal to 1000 plus each bar index. It deliberately compares the wrong lookup with the corrected lookup only at index 100. The target is index 97: the wrong result is 1003, while the corrected result is 1097. At least 101 loaded bars are needed to reach the comparison. These are arithmetic test values, not prices or measured market results.

  • Inspect the two points at index 100. The assertion checks the intended arithmetic when TradingView executes that bar.
  • The branch also prevents a negative history offset before targetIndex is reached. In a general script, guard the computed offset before reading it.
  • For an event whose age can grow without a fixed bound, store its price and time when the event occurs instead of retrieving it with an ever-growing history offset.
Complete v6 reproduction: both lines compile, but only one selects index 97pinescript
//@version=6
indicator("Index versus history offset", max_bars_back = 101)

float sample = 1000.0 + bar_index
int targetIndex = 97
int barsAgo = bar_index - targetIndex
float wrong = na
float corrected = na

if bar_index == 100
    wrong := sample[targetIndex] // Wrong: interprets 97 as bars ago.
    corrected := sample[barsAgo] // Correct: 100 - 97 = 3 bars ago.
    if wrong != 1003.0 or corrected != 1097.0
        runtime.error("Expected wrong = 1003 and corrected = 1097")

plot(wrong, "Wrong lookup: 1003", color = color.red, style = plot.style_circles, linewidth = 4)
plot(corrected, "Correct lookup: 1097", color = color.teal, style = plot.style_circles, linewidth = 4)

Find the first bar and the current last bar

barstate.isfirst identifies index 0. barstate.islast identifies the rightmost bar in the dataset, including an open realtime bar; it does not mean that bar has closed. last_bar_index supplies the last dataset coordinate. With 101 bars, the first index is 0 and the last is 100. The rightmost visible candle after panning the chart is a different concept.

  • On the first bar, Previous index is na because no preceding bar exists.
  • An indicator updates on realtime ticks, but the index stays the same throughout that bar. A new bar advances it by one.
  • Use barstate.isconfirmed when a condition must wait for the closing update. A strategy normally executes at bar close unless its calculation settings change.
  • When the market is open, barstate.islastconfirmedhistory marks the bar preceding the realtime bar. When closed, it marks the final historical bar.
Complete v6 diagnostics: inspect indices in the Data Windowpinescript
//@version=6
indicator("First and last dataset indices", overlay = true)

plot(bar_index, "Current index", display = display.data_window)
plot(last_bar_index, "Last dataset index", display = display.data_window)
plot(bar_index[1], "Previous index", display = display.data_window)

if barstate.isfirst
    label.new(bar_index, high, "First: 0", style = label.style_label_down)

var label lastLabel = label.new(na, na, "")
if barstate.islast
    label.set_xy(lastLabel, bar_index, high)
    label.set_text(lastLabel, "Last: " + str.tostring(bar_index))

Why a saved bar number changes after loading history

Indices are assigned from the dataset start. If a reload includes 200 additional earlier bars, a candle previously numbered 97 would be numbered 297, assuming those are the only dataset changes. This is why an index copied from one run is a poor permanent identifier. More history, a different symbol or timeframe, and data-feed revisions can change the dataset and recalculated results.

  • Use time when an anchor must describe a particular bar opening time. For a durable reference, also retain the symbol and timeframe.
  • Panning within the same loaded dataset does not itself turn the leftmost visible candle into index 0. Loading additional history can cause recalculation.
  • A timestamp anchor still needs a matching bar in the selected dataset. A date can fall inside a session gap or outside the loaded history.
  • Do not use the final dataset position as evidence that was available to a historical trading signal. A last-N-bars display filter can change when new bars arrive.

Drawing coordinates, plot offsets and history limits

With xloc.bar_index, a drawing interprets its x value as an absolute index. With xloc.bar_time, it interprets x as a UNIX timestamp in milliseconds. A plot offset instead moves the displayed output relative to its calculation bar. Positive offsets move it right and negative offsets move it left; the source value is still calculated on the original bar.

  • The coordinate limits above follow the current TradingView documentation verified on October 17, 2026. Older references may show a different backward bound.
  • Being allowed to place a drawing 10000 bars back does not guarantee that an arbitrary calculated series can retrieve its value from that bar.
  • A future drawing coordinate or positive plot offset does not provide future OHLC data. A past plot offset can also make a signal appear earlier than it was calculated.
OperationBoundary or failureCorrection
Drawing at current index + 500The documented forward limit for xloc.bar_indexCap a configurable forward distance at 500; +501 is beyond it
Drawing at current index - 10000The documented backward coordinate limitUse xloc.bar_time and a valid stored timestamp for older anchors
Timestamp supplied with xloc.bar_indexA millisecond timestamp is interpreted as a huge bar numberSet xloc.bar_time explicitly
A large history offset inside []Most series have a maximum 5000-bar buffer; some built-ins, including close and time, support 10000Bound the lookup and size the buffer where appropriate; max_bars_back does not remove the ceiling
History requested before the first barA valid in-buffer lookup can return na because that bar does not existCheck history availability rather than replacing missing prices with zero

Give a coding agent a reproducible indexing task

Provide the smallest complete script, the target bar or event, and the expected output. For this reproduction, require index 100 to read index 97 as 1097 from the synthetic series. Ask the agent to preserve the guard and explain the history buffer. Request a syntax check, then compare the first bar, the target bar, realtime updates and a history reload in TradingView.

Where Pineify fits

Pine Script AI Coding Agent

Use Pineify to generate or revise a Pine script from your reproduction and expected values. Ask for a syntax check, then verify the selected bars and drawing positions in TradingView. Compilation cannot detect every index-versus-offset mistake.

Review indexing with AI

Frequently asked questions

Educational programming examples, not trading recommendations. Syntax checks do not verify chart behavior or strategy results. Run the examples in TradingView before adapting their indexing logic.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.