MarketLab Docs
Scripting

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).

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 an array from input.candles.candles.

Available helpers:

  • ctx.study.sma(candles, { field, window })
  • ctx.study.ema(candles, { field, window })

Example:

export function onData(ctx, input) {
  const candles = input.candles.candles
  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 result = ctx.study.cvd(input.vd.candles, {
  bucket: input.vd.bucket
})

You can also pass a single live record:

const result = ctx.study.cvd(input.vd.candle, {
  bucket: input.vd.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) {
  const cvd = ctx.study.cvd(input.vd.candles, {
    bucket: input.vd.bucket
  })

  return {
    metrics: {
      cvd_delta: cvd.delta,
      latest_cvd: cvd.latest,
      points: cvd.points.length
    }
  }
}

Live VD example:

export function onData(ctx, input) {
  if (input.source !== "vd") return { metrics: { skipped: true } }

  const cvd = ctx.study.cvd(input.vd.candle, {
    bucket: input.vd.bucket
  })

  return {
    metrics: {
      vd_delta: cvd.delta,
      latest_cvd: cvd.latest
    }
  }
}

Orderbook Functions

Orderbook helpers use a book from input.orderbook.books.

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) {
  const book = input.orderbook.books.at(-1)
  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;
}

On this page