Settings inputs and dialog
Settings a trader can change without editing code, such as a length, a colour or a higher timeframe, are declared at the top of the script with input.*, arranged with dialog and layout, and read in onBar as ctx.params.<id>. Indicators and definitions share the whole surface.
The surface
API | Purpose |
|---|---|
| The settings window: title, description, size, reset-to-defaults, enabled checkbox |
| Single fields |
| Richer fields |
| Where each field sits in the dialog |
| Show a field, tab, section or group only when a condition holds |
pane(...) is not a setting. It routes outputs into a subpane: see Panes & scales.
Inputs become ctx.params
Every input needs an id and a label. In onBar, read ctx.params.<id>. The handle input.* returns is for wiring only (layout, when, colorFrom, timeframe(handle), warmup), never for reading the value.
dialog({ title: "EMA" });
const length = input.number({ id: "length", label: "Length", default: 20, min: 1 });
const color = input.color({ id: "color", label: "Color", default: "#2196f3" });
const htf = input.timeframe({ id: "htf", label: "Higher timeframe", default: "1h" });
layout(
tab({ id: "main", title: "Main" },
section({ id: "params", title: "Parameters" }, length, color, htf))
);
function onBar(ctx) {
const len = ctx.params.length;
const tf = ctx.params.htf; // "1h"
}Field kinds
Kind |
| Notable options |
|---|---|---|
| number |
|
| boolean |
|
| string |
|
| the chosen |
|
| array of values |
|
| hex or rgba string |
|
|
| |
| number |
|
|
|
|
| timeframe string |
|
| array of row objects |
|
Every kind also takes description, tooltip, visibleWhen, disabled and required. Colour, line style and line width inputs are cosmetic by default (isCosmetic): changing them restyles the output without counting as a different setting.
dialog({ title: "Zones", description: "Configure zone filters" });
const modes = input.multiSelect({
id: "modes",
label: "Modes",
default: ["fast"],
options: [
{ value: "fast", label: "Fast" },
{ value: "slow", label: "Slow" },
],
});
const band = input.range({ id: "band", label: "Band", default: [20, 80], min: 0, max: 100 });
const rows = input.array({
id: "rows",
label: "Rows",
defaultItems: [{ enabled: true, n: 1 }],
itemTemplate: (input) => {
input.boolean({ id: "enabled", label: "On", default: true, isEnableField: true });
input.number({ id: "n", label: "N", default: 1, min: 1 });
},
});
layout(
tab({ id: "main", title: "Main" },
section({ id: "p", title: "Params" }, modes, band, rows))
);Inside itemTemplate, ids only need to be unique within the row. Arrays cannot nest. isEnableField: true marks a row's on/off switch.
On both indicators and definitions, input.array gives you a list of rows in ctx.params.<id>. Expanding the rows into chart series with output.bandTemplate is indicator-only: see Series types.
Layout
layout(...) takes tab(...) nodes in dialog order. A tab holds section(...) nodes. A section holds input handles and group(...) nodes, and groups can nest. Tabs and sections take a title; a group takes a label. Sections accept columns, collapsible and defaultCollapsed; groups accept border.
when: conditional visibility
when(handle) starts a condition. Chain equals, notEquals, gt, lt, includes or notIncludes, and combine with and / or. Pass it as visibleWhen on an input, tab, section or group.
const mode = input.select({
id: "mode",
label: "Mode",
default: "simple",
options: [
{ value: "simple", label: "Simple" },
{ value: "advanced", label: "Advanced" },
],
});
const depth = input.number({
id: "depth",
label: "Depth",
default: 3,
visibleWhen: when(mode).equals("advanced"),
});Inside itemTemplate, refer to a sibling field by id: when("enabled").equals(true).
Timeframe inputs
input.timeframe values come from the palette 1m, 5m, 15m, 30m, 1h, 2h, 4h, 1d, 1w. default must be one of them, and options, when given, must include the default. Case does not matter.
To read the chosen timeframe, pass the handle itself to timeframe(htf) at module scope. There is no ctx.params at module scope, and a timeframe string built by concatenation is rejected. An input.select whose options all look like timeframes gets the warning tf/use-input-timeframe, and timeframe(selectHandle) does not build. See Timeframe handles and runOn.
Definitions and meta.params
Definitions also accept the older meta({ params: { id: { type, def, … } } }) form, with types number, string, boolean, color, timeframe, multiSelect, range and array. The two forms merge. Write new scripts with input.*: it gives layout and every field kind above.
