MMTMMT Docs
Data Sources

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:

ConstantDescriptionPage
data.OHLCVCandle data with volumesOHLCV
data.OIOpen interest candlesOI
data.VDVolume delta candlesVD
data.CVDCumulative volume delta candlesCVD
data.STATFunding, liquidations, mark priceSTAT
data.BOOKOrder book snapshots and native depth helpersBOOK
data.VOLUMEVolume profile snapshots and native profile helpersVOLUME

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,000 retained bars for data.OHLCV, data.OI, data.VD, data.CVD, data.STAT, and data.VOLUME
  • Free plan: 5,000 retained bars for data.BOOK
  • Pro: 20,000 retained bars for non-BOOK sources
  • Pro: 10,000 retained bars for data.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 only
  • data.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 bar
  • 1 = previous bar
  • 2 = two bars ago

Offsets are always evaluated on that subscription's own clock:

  • htf.close(1) means the previous higher-timeframe bar
  • htf.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, or 1Y

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 | objectSnapshotSeries

calc(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 allowed
  • indicator(), subscribe(), and input.*() are not allowed
  • chart-bar helpers such as unix(), barIndex(), and barCount() are not allowed

Source Pages

On this page