Built-In Functions
Market Lab helper functions exposed to JavaScript scripts.
Built-In Functions
Scripts can call helper functions through ctx.study inside onData(ctx, input, history).
These helpers execute the same Rust functions used by Market Lab's built-in study commands. JavaScript only passes inputs and receives the serialized result; it does not maintain a separate calculation implementation.
Candle Functions
Candle helpers use a retained candle list from history.source(selector).
Available helpers:
ctx.study.sma(candles, { field, window })ctx.study.ema(candles, { field, window })
Example:
export function onData(ctx, input, history) {
const candles = history.source('candles@binancef@mmt')
const sma20 = ctx.study.sma(candles, { field: 'c', window: 20 })
return {
metrics: {
sma20: sma20.latest,
},
}
}ctx.study.sma
Calculates a simple moving average.
const result = ctx.study.sma(candles, {
field: 'c',
window: 20,
})Returns:
{
latest: number | null
previous: number | null
points: Array<number | null>
}ctx.study.ema
Calculates an exponential moving average.
const result = ctx.study.ema(candles, {
field: 'c',
window: 20,
})EMA is seeded with the SMA of the first full window.
ctx.study.cvd
Calculates cumulative volume delta from MMT VD candles only.
Do not pass normal OHLCVT candles into this helper. CVD in Market Lab is tied to the vd source because MMT already buckets the underlying trades by notional size.
const vd = history.source('vd@hyperliquid@mmt')
const result = ctx.study.cvd(vd, {
bucket: input.source_configs['vd@hyperliquid@mmt'].bucket,
})You can also pass a single live record:
const current = history.source('vd@hyperliquid@mmt', 0)
const result = ctx.study.cvd(current, {
bucket: input.source_configs['vd@hyperliquid@mmt'].bucket,
})Returns:
{
latest: number | null
previous: number | null
delta: number
bucket: number
points: Array<{
t: number | null
delta: number
cumulative: number
}>
}Window VD example:
export function onData(ctx, input, history) {
const selector = 'vd@hyperliquid@mmt'
const cvd = ctx.study.cvd(history.source(selector), {
bucket: input.source_configs[selector].bucket,
})
return {
metrics: {
cvd_delta: cvd.delta,
latest_cvd: cvd.latest,
points: cvd.points.length,
},
}
}Live VD example:
export function onData(ctx, input, history) {
const selector = 'vd@hyperliquid@mmt'
if (input.source !== selector) return
const current = history.source(selector, 0)
if (!current) return
const cvd = ctx.study.cvd(current, {
bucket: input.source_configs[selector].bucket,
})
return {
metrics: {
vd_delta: cvd.delta,
latest_cvd: cvd.latest,
},
}
}Orderbook Functions
Orderbook helpers use a snapshot from history.source(selector, 0).
Available helpers:
ctx.study.spread(book)ctx.study.depth(book, { levels })ctx.study.imbalance(book, { depth })ctx.study.slippage(book, { side, notional })ctx.study.vamp(book, { dollar_depth })
Example:
export function onData(ctx, input, history) {
const book = history.source('orderbook@bulk', 0)
if (!book) return
const spread = ctx.study.spread(book)
const slippage = ctx.study.slippage(book, {
side: 'buy',
notional: 100000,
})
return {
metrics: {
spread_bps: spread.spread_bps,
slippage_bps: slippage.slippage_bps,
},
}
}ctx.study.spread
Calculates best bid, best ask, absolute spread, spread in basis points, and mid price.
const result = ctx.study.spread(book)Returns:
{
best_bid: number
best_ask: number
spread_abs: number
spread_bps: number
mid: number
}ctx.study.depth
Sums base and quote depth across a fixed number of levels.
const result = ctx.study.depth(book, {
levels: 20,
})Returns:
{
bid_base: number
ask_base: number
bid_quote: number
ask_quote: number
total_quote: number
}ctx.study.imbalance
Calculates book imbalance across a fixed depth.
const result = ctx.study.imbalance(book, {
depth: 20,
})Returns:
{
bid_volume: number
ask_volume: number
imbalance: number
}ctx.study.slippage
Estimates market-order slippage against available book levels.
const result = ctx.study.slippage(book, {
side: 'buy',
notional: 100000,
})Returns:
{
avg_fill_price: number
best_price: number
slippage_abs: number
slippage_bps: number
levels_consumed: number
}ctx.study.vamp
Calculates VAMP from bid and ask VWAP at a target quote depth.
const result = ctx.study.vamp(book, {
dollar_depth: 250000,
})Returns:
{
ask_vwap: number
bid_vwap: number
vamp: number
ask_levels_consumed: number
bid_levels_consumed: number
max_reachable_quote_ask: number
max_reachable_quote_bid: number
complete: boolean
}