Market LabDocs
Scripting V2 - PythonPlain Python Files

Sources

Declare Python V2 market-data selectors and access them at runtime.

In Python V2, history.source(...) both declares a source and reads its history. There is no separate --source, TOML [sources], or script.sources declaration.

Selectors

<symbol>@<source>@<exchange>
<symbol>@<source>@<exchange>@<provider>

Add source options after the final segment:

candles = history.source("btc@candles@binancef:timeframe=60")
book = history.source("btc@orderbook@bulkf:depth=20", 0)
oi = history.source("btc@oi@hyperliquidf@mmt:timeframe=30")

Core futures use the base asset, such as btc. Hyperliquid HIP-3 uses {dex}:{coin}, such as xyz:tsla. Spot uses the exact pair, such as hype/usdc. Outcome symbols keep their side, such as 1009:0.

xyz_direct = history.source("xyz:tsla@candles@hyperliquidf:timeframe=60")
xyz_mmt = history.source("xyz:tsla@candles@hyperliquidf@mmt:timeframe=60")

Selector lookup is ASCII case-insensitive, so XYZ:TSLA and xyz:tsla resolve to the same declared feed. Market Lab keeps hyperliquidf as the canonical exchange and handles the provider-specific DEX route internally.

MMT selectors include both the indexed exchange and mmt:

candles = history.source("btc@candles@binancef@mmt:timeframe=60")
trades = history.source("btc@trades@binancef@mmt")

Declare selectors with literal strings or module-level string constants. Market Lab inspects them before the job starts so every subscription is deterministic. F-strings and other dynamic lookups may read only feeds declared elsewhere in the script.

Runtime access

With no index, history.source returns the retained list. Index 0 returns the newest record:

CANDLES = "btc@candles@binancef:timeframe=60"


def on_data(ctx, history):
    records = history.source(CANDLES)
    latest = history.source(CANDLES, 0)

Source options are part of the declaration, but Market Lab exposes a normalized identity on ctx:

ctx.source          # btc@candles@binancef
ctx.source_type     # candles
ctx.provider
ctx.exchange
ctx.symbol
ctx.source_configs

The market record remains in history; it is not copied onto ctx.

Availability

SourceStandalone BinanceMMTBULKHyperliquid
candlesBacktestLive and backtestLive and backtestLive and backtest
orderbookNoLive and backtestLiveLive
tradesNoLiveLiveLive
vdNoLive and backtestLiveLive
oiNoLive and backtestLiveLive
volumesBacktestLive and backtestLive and backtestLive and backtest

Provider and market type determine whether a source is valid. Spot and outcome markets do not provide perpetual-only OI.

Multiple sources

Declare each feed where it is read:

def on_data(ctx, history):
    btc = history.source("btc@candles@binancef:timeframe=900", 0)
    zec = history.source("zec@candles@binancef:timeframe=900", 0)
    if btc is None or zec is None:
        return

Then backtest without repeating the selectors:

mlab script backtest pairs.py \
  --from 2026-07-15 \
  --to 2026-07-16

Each selector gets an independent history buffer. See History.

Source references:

On this page