Data Sources
Subscribe to market series, read typed accessors, and use higher timeframes safely.
Use subscribe(...) at top level to attach market data to your script.
Subscribe
subscribe(source)
subscribe(source, { exchange?: string, symbol?: string, timeframe?: number | string, bucket?: number })
subscribe(source, exchange, symbol)Use the options-object form whenever you need a custom timeframe, when you want to override exchange and symbol in the same call, or when you want to select a VD/CVD bucket.
Pass one of the data.* constants as the source:
| Constant | Description | Page |
|---|---|---|
data.OHLCV | Candle data with volumes | OHLCV |
data.OI | Open interest candles | OI |
data.VD | Volume delta candles | VD |
data.CVD | Cumulative volume delta candles | CVD |
data.STAT | Funding, liquidations, mark price | STAT |
data.BOOK | Order book snapshots and native depth helpers | BOOK |
data.VOLUME | Volume profile snapshots and native profile helpers | VOLUME |
Common Rules
subscribe()is top-level only.- Duplicate subscriptions are reused.
- Aggregated exchange keys like
"binance:bybit"are normalized for keying. - Scalar reads that are out of range return
NaN. - BOOK and VOLUME native helpers may return
null; guard them before reading properties.
Data Retention
Retention is tracked per subscription.
- Free plan:
10,000retained bars fordata.OHLCV,data.OI,data.VD,data.CVD,data.STAT, anddata.VOLUME - Free plan:
5,000retained bars fordata.BOOK - Pro:
20,000retained bars for non-BOOKsources - Pro:
10,000retained bars fordata.BOOK - If a TA period exceeds retained history, the runtime warns and uses the available window.
Exchange Aggregation
All scripting data sources except data.OHLCV support aggregated exchange strings.
data.OHLCV: single exchange onlydata.OI,data.VD,data.CVD,data.STAT,data.BOOK,data.VOLUME: aggregated exchanges supported
Use a colon-separated exchange string such as "binancef:bybitf", or build one with agg(...):
const ex = agg("bybitf", "binancef")
const oi = subscribe(data.OI, { exchange: ex })agg(...) sorts and deduplicates exchange ids for you, so agg("bybitf", "binancef", "bybitf") returns "binancef:bybitf".
Guard Helper Results
Helpers such as book.depth(), book.imbalance(), volume.summary(), volume.poc(), and volume.valueArea() can return null when the slot is missing or the selected range has no levels. Always check the return value before reading fields like .price or .lowPrice.
Offsets
Most accessors accept offset?:
0(default) = current bar1= previous bar2= two bars ago
Offsets are always evaluated on that subscription's own clock:
htf.close(1)means the previous higher-timeframe barhtf.unix(1)means the previous higher-timeframe bar timestamp
Higher Timeframes
//@version=2
indicator("Higher Timeframe Subscription", false)
const htf = subscribe(data.OHLCV, { timeframe: "1h" })
function onBar(index) {
plot("HTF Close", htf.close(), { color: color.blue })
}options.timeframe accepts either:
- a positive integer number of seconds, such as
3600 - a timeframe string such as
5m,1h,4h,1D,1W,3M, or1Y
Rules and behavior:
- Requested timeframes must be greater than or equal to the script/chart timeframe.
- Lower-timeframe requests return inert accessors and emit a warning.
- Calendar-based timeframes (
W,M,Y) align to UTC calendar boundaries. - While a higher-timeframe bar is still active, accessors such as
htf.close()keep returning that current higher-timeframe value on each lower-timeframe script bar.
Derived Series with calc
subscription.calc(fn) -> numericSeries | objectSnapshotSeriescalc(fn) is top-level only. The callback receives the same accessor type as the parent subscription and runs on the subscription's own clock. Return either a number or a flat object of numbers; use NaN for missing numeric values.
//@version=2
indicator("HTF EMA", false)
const htf = subscribe(data.OHLCV, { timeframe: "1h" })
const htfEma = htf.calc(src => ta.ema(src.close(), 20))
function onBar(index) {
plot("HTF Close", htf.close(), { color: color.blue })
plot("HTF EMA", htfEma(), { color: color.orange })
}Inside calc(fn):
- plotting is not allowed
- entities are not allowed
log()is not allowedindicator(),subscribe(), andinput.*()are not allowed- chart-bar helpers such as
unix(),barIndex(), andbarCount()are not allowed