Pine Script v6 collections

Pine Script arrays: storage, indexing and safe updates

Pine Script arrays store an ordered collection of elements of one type. Create an array with array.new<float>(0), append with array.push(), read with array.get(), and replace an existing element with array.set(). For forward indexing, require 0 <= index < array.size(). Use var to retain the same array across bars and explicitly remove old elements to bound its size. Array positions describe your collection; they do not automatically mean bars ago.

Review array logic with AI

Create, append, read and replace

This complete indicator uses fixed numbers so the output is easy to inspect. On each execution it creates an empty float array, appends 10 and 20, then replaces the first element with 15. The resulting collection is [15, 20], its size is 2, and its average is 17.5. Runtime assertions describe the expected result; run the script on a chart to execute them.

OperationEffectRequired condition
array.new<float>(0)Creates an empty float arrayNo readable element yet
array.new<float>(3, 0.0)Creates three zero-valued elementsSize is 3, not reserved capacity
array.from(10.0, 20.0)Creates two elements from valuesElements have a compatible common type
array.push(a, value)Adds a new last elementKeep growth within your chosen limit
array.get(a, i)Reads an existing elementIndex must address an element
array.set(a, i, value)Replaces an existing elementDoes not create a missing position
Complete Pine v6 example: expected average 17.5pinescript
//@version=6
indicator("Array operations and checks")

array<float> values = array.new<float>(0)
array.push(values, 10.0)
array.push(values, 20.0)
array.set(values, 0, 15.0)

float first = array.get(values, 0)
float last = array.get(values, array.size(values) - 1)
float mean = array.avg(values)

if array.size(values) != 2 or first != 15.0 or last != 20.0 or mean != 17.5
    runtime.error("Expected [15, 20] with average 17.5")

plot(mean, "Expected 17.5")

Empty arrays, missing IDs and valid indices

For an array of size 3, forward indices are 0, 1 and 2. Pine v6 also allows -1, -2 and -3 in get and set, counting from the end. An empty array has neither a valid forward index nor a valid negative index. The examples here use forward indexing for guards so a search failure cannot accidentally select the last element. A float array created with a positive size but no initial value contains na elements; it is not empty.

  • Check size > 0 before reading the first or last element, or removing with pop or shift.
  • If an array variable may hold na, check its ID before calling size or another array operation.
  • Use na(element) to test missing numeric data. A missing element and a missing array ID are separate states.
  • An array can contain at most 100,000 elements. A smaller application limit avoids keeping an entire chart history unnecessarily.

Keep the last N confirmed closes with var

The buffer below starts empty and stores one close per confirmed bar. var preserves the array between bars. Each insertion is followed by a size check; shift removes the oldest value when the buffer exceeds N. With N = 3 and successive closes 100, 102, 101 and 105, the fourth update leaves [102, 101, 105], whose average is 102.6667. This arithmetic example is illustrative, not market data.

  • The mean remains na until N samples exist. It then holds the previous confirmed result during an open bar.
  • Removing var would recreate the array on every execution, so it could not accumulate N samples when N > 1.
  • var persists across bars but does not bypass realtime rollback. varip changes intrabar persistence; substituting it can change the sampling behavior.
  • If you push only on selected events, the array holds the last N events, which may span more than N bars.
Complete Pine v6 rolling buffer: confirmed bars onlypinescript
//@version=6
indicator("Last N confirmed closes", overlay=true)

int length = input.int(3, "Samples", minval=1, maxval=500)
var array<float> samples = array.new<float>(0)

if barstate.isconfirmed
    array.push(samples, close)
    if array.size(samples) > length
        array.shift(samples)

int count = array.size(samples)
float oldest = count > 0 ? array.get(samples, 0) : na
float newest = count > 0 ? array.get(samples, count - 1) : na
float mean = count == length ? array.avg(samples) : na

plot(mean, "Confirmed sample mean", color=color.blue, linewidth=2)
plot(oldest, "Oldest stored close", display=display.data_window)
plot(newest, "Newest stored close", display=display.data_window)
plot(count, "Stored count", display=display.data_window)

Array object history is different from element history

array.get(a, 1) reads position 1 in the current array. a[1] retrieves the array instance assigned to variable a on the previous bar. If a is a persistent var array, do not treat a[1] as a detached copy of its old contents. By contrast, first[1] retrieves the previous bar value of a scalar series named first. The script below deliberately creates a fresh single-element array on every bar, making the previous instance distinct from the current one.

ExpressionWhat it selectsIn this example
array.get(a, 0)Element 0 of the current arrayCurrent close
a[1]Previous array instance assigned to aPrevious bar's one-element array
first[1]Previous value of the scalar series firstPrevious close
array.get(a, 1)Element 1 of the current arrayInvalid: this array has only one element
Complete Pine v6 comparison: three plots should overlappinescript
//@version=6
indicator("Array instance history and scalar history", overlay=true)

array<float> a = array.from(close)
array<float> previous = a[1]
float first = array.get(a, 0)
float fromObject = na(previous) ? na : array.get(previous, 0)
float fromSeries = first[1]

plot(fromObject, "Previous array element", color=color.blue, linewidth=4)
plot(fromSeries, "Previous scalar result", color=color.orange, linewidth=2)
plot(close[1], "Previous close", color=color.white)

Handle indexof returning -1 and locate na explicitly

array.indexof returns the first matching index or -1 when a value is absent. Searching [10, na, 30] for 99 therefore returns -1, not na. Never pass that result straight into get: v6 would read the last element, 30. For a missing-value search, scan with na(value) instead of treating an equality lookup as a missing-data test. This script locates the missing element at index 1, replaces it with 20, and leaves the unsuccessful lookup as na.

Complete Pine v6 repair: guard search results and scan missing valuespinescript
//@version=6
indicator("Array search guards")

array<float> values = array.from(10.0, float(na), 30.0)
int found = array.indexof(values, 99.0)
float selected = found >= 0 ? array.get(values, found) : na

int missingIndex = -1
for [i, value] in values
    if na(value)
        missingIndex := i
        break

if missingIndex >= 0
    array.set(values, missingIndex, 20.0)

array<float> empty = array.new<float>(0)
float emptyFirst = array.size(empty) > 0 ? array.get(empty, 0) : na
if found != -1 or not na(selected) or missingIndex != 1 or not na(emptyFirst)
    runtime.error("Search or empty-array guard failed")
if array.get(values, 1) != 20.0
    runtime.error("Expected repaired middle element 20")

plot(array.avg(values), "Repaired average: 20")
plot(selected, "Absent value: na", display=display.data_window)

Recognize errors that compilation alone cannot find

The fragments in the first column are intentionally incorrect diagnostic examples, not runnable scripts. The conditions make each failure reproducible. Use the complete corrected scripts above. A successful syntax check does not execute array accesses across chart bars or prove that the sampling policy matches your intended calculation.

Incorrect fragment (do not run)Failure conditionCorrection
array.set(a, 0, close)a was created empty: position 0 does not existAppend with push first; the operations script does this
array.get(a, array.size(a))Index equals the size, so it is beyond the last elementCheck size > 0, then read size - 1 as in the rolling buffer
array.get(a, array.indexof(a, 99.0))99 is absent: -1 reads the last element in v6 when a is nonemptyRequire found >= 0; otherwise return na
array.pop(a)a has no elementsCheck size > 0 before removing; otherwise do nothing
array.size(a)a holds an na array ID rather than an array objectInitialize a with array.new<float>(0) before array operations
array.get(a, 0) == naEquality is not a valid missing-value testUse na(value), as in the missing-element scan
Where Pineify fits

Pine Script AI Coding Agent

Give the agent your complete script, element type, maximum buffer length, update timing and expected output. Ask it to refactor the array logic and run a syntax check. Then inspect empty, first-bar, full-buffer and missing-value cases in TradingView; compilation alone cannot verify those results.

Review array logic with AI

Frequently asked questions

Educational programming examples, not investment advice or a trading strategy. Syntax validation does not prove runtime behavior, profitability or correct results on every data feed. Run the examples and inspect their outputs before adapting them.

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.