MMTMMT Docs

Scripting v3

Build fast, typed indicators with MMT's purpose-built market scripting language.

Scripting v3 is MMT's purpose-built language for indicators and market analysis. Scripts declare their data, inputs, and visual outputs up front, then react to typed market-data events.

A first script

script "Momentum"

data chart = subscribe(data.ohlcv)

input (
  len = input.int(10, title: "Momentum Length", min: 1, max: 200)
)

pane momentumPane = pane(title: "Momentum", height: 0.3)

plot (
  momentumPlot = plot.line(title: "Momentum", color: color.blue, width: 2, on: momentumPane)
)

on chart.update {
  let past = chart.close[len]
  let momentum: float? = past == null ? null : (chart.close ?? 0.0) - past
  momentumPlot.plot(momentum)
}

The declarations name the data, settings, and plots. The update handler calculates momentum as the data changes. Missing history is represented by null.

Momentum is a price difference, so this line uses its own pane with on: momentumPane. Without that argument, the line would share the chart's price scale.

Chart context

context.exchange, context.symbol, context.base, context.quote (strings), context.timeframe (timeframe), context.tickSize and context.stepSize (floats) describe the chart the script is attached to. They are readable in any position, and remain fixed for each run. Changing the chart or configuration restarts the script with the updated values.

There is no timeframe * int. To subscribe to a multiple of the chart timeframe, go through seconds:

script "Higher timeframe"

input mult = input.int(4, title: "Timeframe multiple", min: 1, max: 60)

setup higherTf = time.tfFromSeconds(time.tfSeconds(context.timeframe) * mult)

data (
  chart = subscribe(data.ohlcv)
  higher = subscribe(data.ohlcv, timeframe: higherTf)
)

pane ticksPane = pane(title: "Ticks from higher-TF close", height: 0.3)

plot ticksAway = plot.line(title: "Ticks from higher-TF close", on: ticksPane)

on chart.update {
  let c = chart.close
  let h = higher.close
  if c != null && h != null {
    ticksAway.plot((c - h) / context.tickSize)
  }
}

time.tfFromSeconds normalizes like tf("Ns") (900 is 15m, 86400 is 1D) and always yields a fixed s/m/h/D timeframe. W, M, and Y charts report nominal 7/30/365-day spans; check time.isCalendar(context.timeframe) first when that matters.

Start building

On this page