ChartnautDocs

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

dialog({ title, … })

The settings window: title, description, size, reset-to-defaults, enabled checkbox

input.number / boolean / text / select / color / timeframe

Single fields

input.multiSelect / lineStyle / lineWidth / range / array

Richer fields

layout(tab(section(group(…))))

Where each field sits in the dialog

when(handle)

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

ctx.params value

Notable options

number

number

min, max, step, precision, unit, slider

boolean

boolean

variant: "checkbox" / "switch" / "toggle"

text

string

placeholder, maxLength, multiline, rows

select

the chosen value

options: [{ value, label, description? }], layout: "select" or "radio", searchable

multiSelect

array of values

minSelections, maxSelections

color

hex or rgba string

allowAlpha, presetColors

lineStyle

LineStyle.*

lineWidth

number

min, max, step

range

[min, max] tuple

min, max, step, marks

timeframe

timeframe string

options, searchable

array

array of row objects

itemTemplate, defaultItems, minItems, maxItems

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.