Sources
Market data sources and exact runtime selectors for Market Lab scripts.
The manifest declares base source kinds. Runtime flags bind those kinds to a symbol, provider, and exchange.
<symbol>@<source>@<provider>
<symbol>@<source>@<exchange>@<provider>Selectors
The symbol is always first. Futures use the base asset, so btc means BTC and zec means ZEC. Spot keeps the real pair, such as hype/usdc for HYPE/USDC.
MMT is a multi-exchange provider, so its selector includes the symbol, source, exchange, and provider:
--source btc@candles@binancef@mmt:timeframe=60
--source btc@candles@hyperliquidf@mmt:timeframe=30
--source btc@oi@binancef@mmt:timeframe=60
--source btc@trades@binancef@mmtStandalone exchanges remain their own selector even when combined with MMT data:
--source btc@candles@binance:timeframe=60
--source btc@candles@binancef:timeframe=60
--source btc@volumes@binance:timeframe=60
--source btc@volumes@binancef:timeframe=60
--source btc@orderbook@bulkf:depth=20
--source btc@candles@bulkf:timeframe=5
--source btc@trades@bulkf
--source btc@orderbook@hyperliquidf:depth=20
--source btc@candles@hyperliquidf:timeframe=5
--source btc@trades@hyperliquidf
--source tsla@candles@hyperliquidf-xyz:timeframe=60
--source tsla@orderbook@hyperliquidf-xyz:depth=20
--source tsla@trades@hyperliquidf-xyz
--source tsla@oi@hyperliquidf-xyz
--source sndk@candles@hyperliquidf-io:timeframe=60
--source sndk@orderbook@hyperliquidf-io:depth=20
--source sndk@trades@hyperliquidf-io
--source sndk@oi@hyperliquidf-io
--source hype/usdc@orderbook@hyperliquid:depth=20
--source hype/usdc@candles@hyperliquid:timeframe=5
--source hype/usdc@trades@hyperliquid
--source '1009:0@orderbook@hyperliquid:depth=20'
--source '1009:0@candles@hyperliquid:timeframe=60'
--source '1009:0@trades@hyperliquid'There are no script-level --symbol, --provider, or --exchange flags. The source selector contains that information. This lets one script consume several symbols from standalone Binance, MMT, BULK, Hyperliquid, HIP-3 DEXs, and outcome markets at the same time.
For outcomes, 1009:0 is the complete market symbol. The colon inside the symbol is not a source-option separator. Options are parsed only after the final exchange or provider segment.
Standalone Binance selectors are historical-only. They work with script backtest, not live script run streams.
mlab script backtest ./scripts/ema-cross.js \
--from <UTC_DATETIME> \
--to <UTC_DATETIME> \
--source btc@candles@binancef:timeframe=60 \
--param fast=20 \
--param slow=50Example:
mlab script run ./scripts/cross-market.js \
--source btc@candles@binancef@mmt:timeframe=5 \
--source btc@candles@hyperliquidf@mmt:timeframe=5 \
--source btc@orderbook@bulkf:depth=20 \
--source btc@orderbook@hyperliquidf:depth=20The symbols do not need to match:
mlab script backtest ./scripts/pairs.js \
--from 2024-01-01 \
--to 2024-01-02 \
--source btc@candles@binancef:timeframe=900 \
--source zec@candles@binancef:timeframe=900The manifest still lists each required base kind once:
export const script = {
name: 'cross-market',
version: '1',
sources: ['candles', 'orderbook'],
params: {},
}Market Lab validates that every configured kind appears in script.sources and that every manifest kind has at least one concrete selector.
Runtime Access
Use the same exact selector with history.source:
const binanceDirect = history.source('btc@candles@binancef')
const binance = history.source('btc@candles@binancef@mmt')
const hyperliquid = history.source('btc@candles@hyperliquidf@mmt')
const bulkBook = history.source('btc@orderbook@bulkf', 0)
const hyperliquidBook = history.source('btc@orderbook@hyperliquidf', 0)
const xyzBook = history.source('tsla@orderbook@hyperliquidf-xyz', 0)
const entropyBook = history.source('sndk@orderbook@hyperliquidf-io', 0)
const bulkTrades = history.source('btc@trades@bulkf')
const latestBulkTrade = history.source('btc@trades@bulkf', 0)
const hypeSpotBook = history.source('hype/usdc@orderbook@hyperliquid', 0)
const outcomeBook = history.source('1009:0@orderbook@hyperliquid', 0)Use the complete selector. history.source('candles') and history.source('btc@candles') do not identify a concrete configured source.
Market records are not duplicated under input.candles, input.sources, or input.data. input carries metadata:
input.source // exact selector that triggered this hook
input.source_type // base source kind
input.symbol // normalized source symbol
input.source_configs['btc@candles@binancef@mmt'].timeframe_secAvailable sources:
| Source | Binance backtest | Binance live | MMT backtest | MMT live | BULK backtest | BULK live | Hyperliquid backtest | Hyperliquid live |
|---|---|---|---|---|---|---|---|---|
candles | Yes | No | Yes | Yes | Yes | Yes | Yes | Yes |
orderbook | No | No | Yes | Yes | No | Yes | No | Yes, depth 1-20 |
vd | No | No | Yes | Yes | No | Yes, trade-derived | No | Yes, trade-derived |
oi | No | No | Yes | Yes | No | Yes, snapshots | No | Yes, snapshots |
volumes | Yes, candle-derived | No | Yes | Yes | Yes | Yes | Yes | Yes |
trades | No | No | No | Yes | No | Yes | No | Yes |
Config keys:
| Source | Config |
|---|---|
candles | timeframe |
orderbook | backtest: timeframe, optional depth; live: optional depth |
vd | MMT: timeframe, bucket; standalone live: neither |
oi | MMT: timeframe; standalone live: no timeframe |
volumes | timeframe |
trades | none |
The timeframe value is always an integer number of seconds. Support for arbitrary intervals is specific to live candles; other time-series sources and historical data retain provider-supported intervals.
trades is live-only. It delivers raw WebSocket trades to scripts and cannot be used in a backtest. See Trades Source for its record shape and runtime behavior.
Hyperliquid outcomes support orderbook, trades, and candles. They do not support perpetual-only oi or funding data. Add --testnet to script run when both the outcome sources and execution should use testnet. Outcome metadata is discovered live rather than loaded from a static market snapshot.
See Source History for list/index semantics and Candles Source for live aggregation details.