Appearance
Time Series
Kind: module
Namespace: ts
Provides functions for creating and manipulating time series.
Overview
Time series are the core data structure for calculations. A series stores historical values with efficient lookback access, enabling stateful calculations across bars.
Series are continuous: every bar must have a value. If not explicitly set, it defaults to NaN. Internally, series use a ring buffer with constant memory usage regardless of how many bars are processed.
Index 0 is the current (most recent) value, 1 is the previous value, and so on:
Index: [0] [1] [2] [3] [4]
↓ ↓ ↓ ↓ ↓
Value: 100 99 101 98 97
↑
currentThe ts() function creates a series once on the first tick, then reuses the same instance on subsequent ticks. Each tick either shifts the series forward (new bar) or overwrites [0] (bar update):
Bar 0: [10] ← created
Bar 1: [20, 10] ← shifted, 10 is now [1]
Bar 1*: [25, 10] ← update, [0] changed from 20 to 25
Bar 2: [30, 25, 10] ← shiftedA series without an index is automatically converted to its current value in a numeric context (+, -, >, <, ==, !=, etc.). However, === and !== never trigger this conversion. Also, == and != between two series compare references, not values. See details below.
Built-in Series
Price and volume data are available as pre-defined read-only series:
| Series | Description |
|---|---|
time | Candle timestamp in millisecond |
open | Opening price |
high | Highest price |
low | Lowest price |
close | Closing price |
volume | Total volume |
bidVolume | Bid volume |
askVolume | Ask volume |
count | Number of trades |
vwap | Volume-weighted average price |
impVolatility | Implied volatility |
openInterest | Open interest |
hl2 | (high + low) / 2 |
hlc3 | (high + low + close) / 3 |
ohlc4 | (open + high + low + close) / 4 |
ts()
Kind: func
Creates a new time series for storing calculated values.
Syntax
ts() → series
ts(value) → seriesArguments
| Name | Type | Default | Description |
|---|---|---|---|
| value? | double | NaN | Value for the current bar. Defaults to NaN if not provided |
Returns
A mutable series object.
Caveats
- Must be called inside
onTick, not in theinitsection - Must be at the top level of
onTick, not inside conditionals or loops. This ensures the call count and order remain constant across ticks
Pitfall
javascript
const y = ts(); // ❌ in init section
function onTick() {
if (close > open) {
const x = ts(close); // ❌ inside conditional
}
}Example
javascript
function onTick() {
// Create series at top level
const diff = ts(close - open);
const range = ts(high - low);
const trend = ts();
// Access history using [index]
const prevDiff = diff[1];
const avgRange = (range + range[1] + range[2]) / 3;
// Update inside conditionals using .set()
if (close > close[1]) {
trend.set(1); // method syntax
} else if (close < close[1]) {
trend[0] = -1; // array syntax (equivalent)
} else {
trend.set(trend[1]);
}
spline(diff, {title: "diff"});
spline(trend, {title: "trend"});
}Series Object
The series object stores values and provides history access.
series[index]
Kind: operator
Reads historical values of a series.
Syntax
series[lookback] → double
series → doubleArguments
| Name | Type | Description |
|---|---|---|
| lookback | int | Offset from current bar. 0 = current, 1 = previous |
Returns
The value at the specified offset, or NaN if the index exceeds available history.
Notes
serieswithout index is equivalent toseries[0]- Index
0is the current bar,1is previous, etc.
Example
javascript
function onTick() {
// Explicit index access
const current = close[0];
const prev = close[1];
const old = close[10];
// Implicit current value (numeric context)
const sum = close + open; // same as close[0] + open[0]
const change = close - close[1];
// Comparisons (numeric context)
const isUp = close > close[1];
// ⚠️ Strict equality — use explicit [0]
const equal = close[0] === high[0]; // ✅
const noEqual = close[0] !== high[0]; // ✅
}Equality operators with series
=== and !== never convert a series to its value, bevause they compare object references:
javascript
// ❌ always true — two different objects
if (high !== low) { ...
}
// ❌ always false — object vs number
if (close === 5) { ...
}== and != convert a series to a number when compared with a primitive, but not when comparing two series:
javascript
// ✅ works — series is converted to number
if (close != 0) { ...
}
// ❌ compares references, not values
if (high != low) { ...
}Use explicit [0] to avoid ambiguity:
javascript
// ✅ always correct
if (high[0] !== low[0]) { ...
}
if (close[0] === 5) { ...
}series.set()
Kind: method
Sets the value for the current bar.
Syntax
javascript
series.set(value)
series[0] = valueArguments
| Name | Type | Description |
|---|---|---|
| value | double | Value to set |
Returns
void
Notes
- Only index
0(current bar) can be written - Calling multiple times overwrites the same bar
- Can be used inside conditionals (unlike
ts())
Example
javascript
function onTick() {
const signal = ts();
if (close > close[1]) {
signal.set(1); // method syntax
} else {
signal[0] = -1; // array syntax (equivalent)
}
spline(signal, {title: "signal"});
}