Instructions/probuilder · probacktest · proorder · proscreener

BarIndex

BarIndex returns the zero-based position of the current bar within the loaded chart data. Reference it in ProBuilder to locate bars in the price history.

Syntax

probuilder
BarIndex

How it works

BarIndex is a read-only value maintained by the platform. On the first bar of the loaded history it equals 0, on the second bar 1, and so on. Each script evaluation sees the index of the bar currently being processed, so during a full recalculation BarIndex sweeps from 0 up to the index of the most recent bar.

The value says nothing about time or price. It carries no open, high, low, close, or timestamp information, only the ordinal position of the bar inside the data set. For clock-based logic, the date and time constants are the right tools; BarIndex is for counting and positioning.

Two usage patterns dominate. The first is warm-up protection: indicators and strategies with long lookbacks produce unreliable values until enough bars exist, and a condition such as IF BarIndex > 200 THEN suppresses signals until the history is deep enough. The second is coordinate anchoring: the drawing instructions take a bar position as their x-coordinate, and expressions like barindex - 10 address a point ten bars back from the current bar.

Because counting starts at the first loaded bar, the same bar can have a different BarIndex when the amount of loaded history changes. Logic should therefore use BarIndex for relative measurements, not as a stable identifier for a specific calendar bar.

Examples

Example 1, Displaying the current bar position (Indicator)

probuilder
// Read the position of the bar being processed
currentBarIndex = BarIndex
RETURN currentBarIndex AS "Current bar index"

The indicator plots a straight ramp that increases by 1 per bar, making the zero-based counting directly visible on the chart.

Example 2, Warm-up guard for a long lookback (ProOrder)

probuilder
DEFPARAM CumulateOrders = false

slowMA = Average[200](close)
fastMA = Average[20](close)

// Block entries until 200 bars exist, so the slow average is fully formed
IF BarIndex > 200 THEN
  IF fastMA CROSSES OVER slowMA THEN
    BUY 1 CONTRACT AT MARKET
  ENDIF
ENDIF

SET STOP %LOSS 2

Without the BarIndex guard, the 200-period average would be computed from fewer bars than intended at the start of the history, producing distorted early signals.

Example 3, Requiring sufficient history (ProScreener)

probuilder
// Ignore instruments with fewer than 100 loaded bars
enoughData = BarIndex >= 100
momentum = ROC[90](close)

SCREENER[enoughData AND momentum > 10] (momentum AS "ROC 90")

The screener uses BarIndex to filter out instruments whose loaded history is too short for the 90-bar rate of change to be meaningful.

Common errors and gotchas

  • Zero-based counting. The first bar has index 0, so a chart of n bars ends at index n minus 1. Off-by-one mistakes are common when converting between bar counts and indices.
  • Not stable across data loads. BarIndex counts from the first loaded bar. Loading more or fewer bars, or letting old bars roll off, shifts the index of every bar. Avoid persisting a BarIndex value as a permanent reference to a calendar date.
  • No bar content. BarIndex carries position only. Reading price or time requires the usual constants such as close or the date and time keywords.
  • Session counting confusion. BarIndex never resets during the day. For a counter that restarts at each session open, use IntradayBarIndex instead.
  • IntradayBarIndex, bar counter that resets at the start of each trading day.
  • BarsSince, number of bars since a condition was last true.
  • HighestBars, offset in bars of the highest value over a period.
  • LowestBars, offset in bars of the lowest value over a period.
  • ONCE, initializes a variable on the first bar only.
  • TRADEINDEX, bar index at which a position was opened in a strategy.
  • DRAWTEXT, drawing instruction that takes a bar position as x-coordinate.
  • Highest, highest value of a series over a fixed number of bars.