MMTMMT Docs

Inputs

Define script settings with typed inputs, grouping, and conditional visibility.

Inputs are declared at top level and rendered in the script settings UI.

Rules

  • input.* calls are top-level only (not allowed inside onBar())
  • Maximum inputs per script: 256
  • The 257th+ input is ignored with a warning
  • Every input has a key; duplicate keys throw an error

Top-Level Only

Call input.* before onBar(). Calling input APIs inside onBar() throws an error.

Keys and Shared Options

For APIs that accept an options object, you can set:

OptionTypeDescription
keystringStable input key (recommended for overrides and onlyIf)
descriptionstringUI description text
sameLineboolRender inline with previous input
requiredboolMark value as required
onlyIfobjectConditional visibility

If key is omitted, the engine derives one from label text (lowercase with separators).

Conditional Visibility

Inputs are visible by default. Use onlyIf when an input should appear only for a specific mode or toggle state.

Most scripts should build conditions with the input.when* helpers:

  • input.when(key, value) for equality
  • input.when(key, [values]) for membership
  • input.whenEq(key, value)
  • input.whenNeq(key, value)
  • input.whenIn(key, values)
  • input.whenTrue(key)
  • input.whenFalse(key)
onlyIf: {
  key: "mode",
  op: "eq" | "neq" | "in",
  value: string | number | bool,    // for eq/neq
  values: [string | number | bool]  // for in
}
//@version=2
indicator("Conditional Inputs", false)
const mode = input.select("Mode", 0, {
  key: "mode",
  selectables: ["Fixed", "ATR", "Disabled"]
})

const fixed = input.float("Fixed Value", 10, {
  key: "fixed_value",
  onlyIf: input.when("mode", "Fixed")
})

const atrLen = input.int("ATR Length", 14, {
  key: "atr_length",
  onlyIf: input.when("mode", "ATR")
})

function onBar(index) {}

Input APIs

input.int

input.int(name, value, options?) -> number
//@version=2
indicator("Integer Input Example", false)
const len = input.int("Length", 20, {
  key: "length",
  min: 1,
  max: 500,
  description: "SMA period"
})

function onBar(index) {}

Options: min, max, plus shared options.

input.float

input.float(name, value, options?) -> number
//@version=2
indicator("Float Input Example", false)
const mult = input.float("Multiplier", 2.0, { min: 0.1, max: 10 })

function onBar(index) {}

Options: min, max, plus shared options.

input.color

input.color(name, value, options?) -> string

value may be ABGR number or hex color (#RRGGBB / #RRGGBBAA). Return value is normalized hex (#RRGGBBAA).

//@version=2
indicator("Color Input Example", false)
const upColor = input.color("Up Color", color.green)
const downColor = input.color("Down Color", "#ff4d4d")

function onBar(index) {}

Options: shared options.

input.bool

input.bool(name, value, options?) -> boolean
//@version=2
indicator("Boolean Input Example", false)
const showSignals = input.bool("Show Signals", true)

function onBar(index) {}

Options: shared options.

input.timeframe

input.timeframe(name, value, options?) -> number

value may be a positive integer number of seconds or a timeframe string such as 5m, 1h, 4h, 1D, 1W, 3M, or 1Y.

The return value is always a number of seconds, which makes it suitable for subscribe(..., { timeframe }).

In the client UI, the picker is populated from:

  • the built-in chart timeframe list
  • the user's custom extra timeframes

The selected value is still passed to the script as seconds.

//@version=2
indicator("Timeframe Input Example", false)
const htf = input.timeframe("Higher Timeframe", "4h", { key: "htf" })
const htfCandles = subscribe(data.OHLCV, { timeframe: htf })

function onBar(index) {
  plot("HTF Close", htfCandles.close(), { color: color.blue })
}

Options: shared options.

input.select

input.select(name, defaultIndex, options) -> string | undefined
//@version=2
indicator("Select Input Example", false)
const mode = input.select("Mode", 0, {
  key: "mode",
  selectables: ["SMA", "EMA", "RMA"]
})

function onBar(index) {}

Required option: selectables: string[]. Also supports shared options.

input.section

input.section(name, options?) -> string
//@version=2
indicator("Section Input Example", false)
input.section("Appearance")

function onBar(index) {}

Supports shared options.

input.tab

input.tab(name, options?) -> string

Creates a tab container. Supports key in options.

//@version=2
indicator("Tab Input Example", false)
input.tab("General", { key: "tab_general" })

function onBar(index) {}

input.group

input.group(name, options?) -> string

Creates a group (inside active tab when present).

//@version=2
indicator("Group Input Example", false)
input.group("Signals", {
  key: "grp_signals",
  collapsible: true,
  collapsed: false
})

function onBar(index) {}

Options: key, collapsible, collapsed.

input.exchange

input.exchange(name, defaultExchange, options?) -> string

Single exchange selector.

//@version=2
indicator("Exchange Input Example", false)
const ex = input.exchange("Exchange", "binancef", {
  key: "exchange",
  required: true,
  filter: ["futures", "inverse"]
})

function onBar(index) {}

Options: key, required, filter: string[], onlyIf.

filter accepts exchange-type categories, not exchange IDs. Accepted values are:

  • "futures" for linear futures/perpetual exchanges
  • "inverse" for inverse-settled futures/perpetual exchanges
  • "spot" for spot exchanges

input.exchanges

input.exchanges(name, defaultExchanges, options?) -> string[]

Multi-exchange selector.

//@version=2
indicator("Exchanges Input Example", false)
const exchanges = input.exchanges("Exchanges", ["binancef"], {
  key: "exchanges",
  required: true,
  minSelected: 1,
  maxSelected: 3,
  filter: ["futures"]
})

function onBar(index) {}

Options: key, required, minSelected, maxSelected, filter: string[], onlyIf.

filter accepts exchange-type categories, not exchange IDs. Accepted values are:

  • "futures" for linear futures/perpetual exchanges
  • "inverse" for inverse-settled futures/perpetual exchanges
  • "spot" for spot exchanges

Tabs, Groups, and Conditional Inputs

//@version=2
indicator("Tabbed Input Layout", false)

input.tab("General", { key: "general" })

input.group("Display", {
  key: "display",
  collapsible: true
})

const mode = input.select("Calculation Mode", 0, {
  key: "mode",
  selectables: ["Fixed", "ATR", "Disabled"]
})

const showLabels = input.bool("Show Labels", true, {
  key: "show_labels"
})

const fixed = input.float("Fixed Value", 10, {
  key: "fixed_value",
  min: 0.1,
  max: 100,
  onlyIf: input.when("mode", "Fixed")
})

const atrLen = input.int("ATR Length", 14, {
  key: "atr_length",
  min: 1,
  max: 100,
  onlyIf: input.when("mode", "ATR")
})

input.tab("Advanced", { key: "advanced" })

input.group("Signals", {
  key: "signals",
  collapsible: true,
  collapsed: false
})

const enableSignals = input.bool("Enable Signals", false, {
  key: "enable_signals"
})

const signalThreshold = input.float("Signal Threshold", 1.5, {
  key: "signal_threshold",
  min: 0.1,
  max: 10,
  onlyIf: input.whenTrue("enable_signals")
})

const signalStyle = input.select("Signal Style", 0, {
  key: "signal_style",
  selectables: ["Trend", "Reversal", "Breakout"],
  onlyIf: input.whenTrue("enable_signals")
})

function onBar(index) {}

On this page