Skip to main content
ATK Pine Script®

Collection Functions Reference

Reference for array.*, map.*, and matrix.* namespaces in ATK PyneScript V6 — rolling buffers, keyed runtime bundles, and 2D numeric grids.

array.* Namespace#

The array namespace provides a Pine-style list container. Beyond the core mutation helpers (push, pop, get, set, size), it includes aggregate and reorder methods for summarizing or reshaping stored lists.

Aggregate Methods#

MethodReturnsUse it when
array.first(handle)First element, or NoneYou want the oldest element without popping it.
array.last(handle)Last element, or NoneYou want the most-recent element without a full slice.
array.sum(handle)floatRolling sum of a numeric buffer.
array.avg(handle)floatAverage of a numeric buffer; NaN values are excluded.
array.min(handle)floatMinimum over all elements; NaN-safe.
array.max(handle)floatMaximum over all elements; NaN-safe.
array.sort(handle, order="asc")None (in-place)Sort the buffer before reading a ranked value.
array.reverse(handle)None (in-place)Reverse the current order.
array.fill(handle, value, index_from=0, index_to=None)None (in-place)Reset a range of elements to a constant without rebuilding the array.

Rolling Buffer with Aggregate Reads#

from source import array, indicator, ta

indicator("Rolling Buffer Demo", overlay=False)

buf = array.new_float(0)

def build_indicator_frame(df, params=None):
    frame = df.copy().reset_index(drop=True)
    for val in frame["close"].tolist():
        array.push(buf, float(val))
        if array.size(buf) > 20:
            array.shift(buf)   # keep last 20 values

    frame["buf_avg"]   = array.avg(buf)
    frame["buf_min"]   = array.min(buf)
    frame["buf_max"]   = array.max(buf)
    frame["buf_sum"]   = array.sum(buf)
    frame["buf_first"] = array.first(buf)
    frame["buf_last"]  = array.last(buf)
    return frame

Sort, Reverse, and Fill#

# Sort ascending then read the median element.
scores = array.from_([5.0, 1.0, 3.0, 4.0, 2.0])
array.sort(scores, order="asc")
median_value = array.get(scores, array.size(scores) // 2)

# Fill a buffer with zeros to reset it.
data = array.new_float(10, 0.0)
array.fill(data, 0.0)

map.* Namespace#

The map namespace provides a string-keyed dictionary container with a stable Pine-style API. Use it when you need to store script-scoped key-value metadata alongside a frame, pass named parameters between helpers, or record per-run configuration in frame.attrs.

MethodReturnsNotes
map.new()map handle {}Create an empty map. Usually assigned to a module-level variable.
map.put(handle, key, value)NoneInsert or overwrite a key.
map.get(handle, key, default=None)stored value or defaultSafe read; returns default when the key is absent.
map.keys(handle)list[str]All current keys. Useful for iteration or introspection.
map.values(handle)listAll current values in insertion order.
map.size(handle)intNumber of entries.
map.contains(handle, key)boolCheck whether a key exists before calling get.
map.remove(handle, key)NoneRemove a key if present.
map.clear(handle)NoneDelete all entries.
map.copy(handle)new map handleShallow copy. Good for snapshotting before mutation.
map.to_array_keys(handle)list[str]Independent copy of all keys as a plain list.
map.to_array_values(handle)listIndependent copy of all values as a plain list.

map.* in a Frame Builder#

from source import indicator, input, map, ta

indicator("Map Runtime Demo", overlay=False)
fast_length = input.int(8,  title="Fast", key="fast_length")
slow_length = input.int(21, title="Slow", key="slow_length")


def build_indicator_frame(df, params=None):
    frame = df.copy().reset_index(drop=True)
    merged = {"fast_length": int(fast_length), "slow_length": int(slow_length)} | dict(params or {})

    fast = max(int(merged.get("fast_length", 8)  or 8),  1)
    slow = max(int(merged.get("slow_length", 21) or 21), 1)

    frame["ema_fast"]     = ta.ema(frame["close"], fast)
    frame["ema_slow"]     = ta.ema(frame["close"], slow)
    frame["spread_value"] = (frame["ema_fast"] - frame["ema_slow"]).fillna(0.0)

    cfg = map.new()
    map.put(cfg, "fast_length", fast)
    map.put(cfg, "slow_length", slow)
    trend = "bullish" if float(frame["spread_value"].iloc[-1] or 0.0) >= 0.0 else "bearish"
    map.put(cfg, "trend_bias", trend)

    frame.attrs["map_keys"]    = map.keys(cfg)
    frame.attrs["map_size"]    = map.size(cfg)
    frame.attrs["trend_bias"]  = map.get(cfg, "trend_bias", "neutral")
    return frame

When to use map vs dict: use map.* when authoring in the PyneScript style and the map will be passed to other PyneScript helpers. Use plain Python dict when the data stays internal to a single function and never crosses the Pine-style API boundary.

Download map runtime example


matrix.* Namespace#

The matrix namespace models a 2-D numeric grid. Use it when you need to store a window of multi-column bar data, compute a rolling covariance surface, or pass structured numeric payloads between stages.

MethodReturnsNotes
matrix.new(rows, cols, fill=0.0)matrix handleCreate a rows×cols grid pre-filled with fill.
matrix.set(handle, row, col, value)NoneWrite a single cell.
matrix.get(handle, row, col)floatRead a single cell.
matrix.rows(handle)intCurrent row count.
matrix.columns(handle)intCurrent column count.
matrix.row(handle, row_index)list[float]All values in a specific row.
matrix.col(handle, col_index)list[float]All values in a specific column.
matrix.add_row(handle, row_index, values)NoneInsert a new row at a position.
matrix.add_col(handle, values)NoneAppend a new column.
matrix.remove_row(handle, row_index)NoneDelete a row.
matrix.submatrix(handle, from_row, to_row, from_col, to_col)new matrix handleExtract a rectangular slice into a new matrix.
matrix.sum(handle)floatSum of all non-NaN elements.
matrix.avg(handle)floatAverage of all non-NaN elements.
matrix.min(handle)floatMinimum element (NaN-safe).
matrix.max(handle)floatMaximum element (NaN-safe).
matrix.copy(handle)new matrix handleDeep copy. Safe to mutate independently.

OHLC Window Example#

from source import indicator, input, matrix

indicator("Matrix Runtime Demo", overlay=False)
window = input.int(3, title="Window", key="window", minval=1)


def build_indicator_frame(df, params=None):
    frame = df.copy().reset_index(drop=True)
    merged = {"window": int(window)} | dict(params or {})
    win = max(int(merged.get("window", 3) or 3), 1)

    tail = frame.tail(win).reset_index(drop=True)
    grid = matrix.new(len(tail), 2, 0.0)

    for i, row in tail.iterrows():
        matrix.set(grid, i, 0, float(row["open"]))
        matrix.set(grid, i, 1, float(row["close"]))

    # Append a computed column: high-low range.
    matrix.add_col(grid, values=(tail["high"] - tail["low"]).astype(float).tolist())

    frame["open_sum"]       = float(sum(matrix.col(grid, 0))) if matrix.rows(grid) > 0 else 0.0
    frame["close_sum"]      = float(sum(matrix.col(grid, 1))) if matrix.rows(grid) > 0 else 0.0
    frame["range_sum"]      = float(sum(matrix.col(grid, 2))) if matrix.rows(grid) > 0 else 0.0
    frame["grid_total_sum"] = matrix.sum(grid)
    frame["grid_avg"]       = matrix.avg(grid)

    frame.attrs["matrix_shape"] = {"rows": matrix.rows(grid), "columns": matrix.columns(grid)}
    frame.attrs["last_row"]     = matrix.row(grid, matrix.rows(grid) - 1) if matrix.rows(grid) > 0 else []
    return frame

Submatrix Extraction#

# Extract top-left 2×2 sub-grid from a 4×4 matrix.
full = matrix.new(4, 4, 1.0)
sub  = matrix.submatrix(full, from_row=0, to_row=2, from_col=0, to_col=2)
print(matrix.rows(sub), matrix.columns(sub))  # 2, 2

Download matrix runtime example

See also: