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 insideonBar())- 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:
| Option | Type | Description |
|---|---|---|
key | string | Stable input key (recommended for overrides and onlyIf) |
description | string | UI description text |
sameLine | bool | Render inline with previous input |
required | bool | Mark value as required |
onlyIf | object | Conditional 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 equalityinput.when(key, [values])for membershipinput.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?) -> stringvalue 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?) -> numbervalue 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?) -> stringCreates 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?) -> stringCreates 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?) -> stringSingle 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) {}