# Options (/vela/user/options)



The second argument to `new Vela(container, options, deps?)` configures market data, display, and behavior. Everything here is optional — `new Vela('#chart', { data: myBars })` is enough to render candles.

This vocabulary is shared with the [workspace](/vela/user/workspace), which accepts every
option below except `height` (plus its shell options) — there, each one is the DEFAULT
of every cell, overridable per cell through `cells`.

Per-indicator options (the third argument to `addIndicator`) are covered at the end.

## Market options [#market-options]

How the chart obtains its candles.

| Option         | Type                              | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                             |
| -------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `symbol`       | string                            | Symbol to load — the string is the WHOLE market identity. A **bare** ticker (`'BTCUSDT'`) resolves against the registered providers in **declaration order** (first one whose index lists it); an `EXCHANGE:` prefix (`'coinbase:BTC-USD'`, case-insensitive) **pins** the venue — a registered provider name, or a [listing prefix](/vela/user/data-providers#listing-prefixes-nasdaqaapl) a provider's index declares (`'NASDAQ:AAPL'`, strict: a wrong venue resolves to nothing). |                                                                                                                                                                                                                                             |
| `timeframe`    | string                            | Bar interval, e.g. `'1h'`.                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                                                                                                                                                             |
| `session`      | `'regular' \| 'extended'`         | Trading session to show, on markets that have one (`regular` = RTH, the default; `extended` = pre/post-market included). The flag rides every data request — providers without a session concept ignore it. Switch at runtime with `chart.setMarket({ session })` or the bottombar's RTH/ETH toggle.                                                                                                                                                                                  |                                                                                                                                                                                                                                             |
| `bars`         | number                            | How many bars of history to load. Depths beyond one \~10k-bar chunk paint the recent window first, then backfill older bars in the background — watch `history:progress` / await `chart.historyComplete()` for the full depth.                                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                             |
| `visibleRange` | `VisibleRangePreset \| {from,to}` | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | The window to frame on the **first paint** (`'1D'`, `'YTD'`, an explicit range…). The chart then loads its depth in one pass and paints that window straight away, instead of flashing a recent-bars preview and re-framing a moment later. |
| `data`         | `OHLCV[]`                         | **Offline bars.** When set, no network fetch happens.                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                                                                             |

> **`data` and provider fetch are mutually exclusive.** Supply `data` to run fully offline (recommended for first runs and tests), or set `symbol`/`timeframe`/`bars` to fetch.
>
> **The fetch path needs a registered provider.** No provider is bundled — register one with [`chart.data.registerProvider(...)`](/vela/user/data-providers); registering it fires the chart's parked initial load. Each bar is `{ time, open, high, low, close, volume? }` with `time` in epoch milliseconds.
>
> With offline `data`, `timeframe` is still honored — it sets bar spacing and axis labels — while `symbol` and `bars` are ignored.

A fetching chart pairs these market options with a registered provider — the display flags ride along in the same object, and registering the provider fires the parked initial load.

```js
import { Vela } from '@luxalgo/vela';
import { BinanceProvider } from '@luxalgo/vela/providers/binance';

const chart = new Vela('#chart', {
  symbol: 'BTCUSDT',        // bare = first registered provider that lists it; 'binance:BTCUSDT' pins
  timeframe: '1h',
  bars: 500,                // how many bars of history to load
  live: true,               // history + a forming candle on each tick
  theme: 'dark',
  logScale: true,           // logarithmic price scale
  currentPriceLine: true,   // dashed line + axis label at the last price
  upColor: '#26a69a',       // recolor the default cyan/white candles
  downColor: '#ef5350',
});

// registering the provider resolves the symbol and fires the fetch
chart.data.registerProvider('binance', new BinanceProvider());
```

## Display & behavior options [#display--behavior-options]

| Option             | Type                                                                | Default                   | Notes                                                                                                                                                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `live`             | boolean                                                             | `false`                   | `true` adds a forming candle + live ticks on top of history.                                                                                                                                                                                                              |
| `theme`            | `'dark' \| 'light'` or a theme object                               | `dark`                    | Pass an object to fully customize colors/fonts.                                                                                                                                                                                                                           |
| `renderer`         | renderer **class**                                                  | native                    | A renderer class to instantiate; omit for the built-in native renderer (default). The multi-renderer port (`IChartRenderer`) stays open — pass any class implementing it.                                                                                                 |
| `defaultLanguage`  | string                                                              | first registered engine\* | Scripting language used when `addIndicator` doesn't name one. Falls back to the first engine registered at construction, then to `'pine'`.                                                                                                                                |
| `currentPriceLine` | boolean                                                             | `true`                    | Dashed line + axis label at the latest price.                                                                                                                                                                                                                             |
| `logScale`         | boolean                                                             | `false`                   | Logarithmic price scale.                                                                                                                                                                                                                                                  |
| `nativeBackend`    | `'auto' \| 'canvas2d' \| 'webgl2'`                                  | `auto`                    | Native geometry backend. `auto` = WebGL2 if available, else canvas2d. Only applies to the native renderer.                                                                                                                                                                |
| `animations`       | boolean or `{ zoom?, pan?, scroll?, autoscale?, liveBar?, intro? }` | **on**                    | `true`/`false` toggles every motion; an object configures each on its own (see [The `animations` option](#the-animations-option) below). Defaults: eased zoom on, pan momentum on (short snappy glide), autoscale glide on, first-load reveal on, live-bar glide **off**. |
| `glow`             | number                                                              | `0`                       | Neon glow/bloom for line series (\~0.6 = strong). **WebGL2 only** — ignored on canvas2d.                                                                                                                                                                                  |
| `upColor`          | string                                                              | `#089981` (green)         | Bullish candle color (native renderer).                                                                                                                                                                                                                                   |
| `downColor`        | string                                                              | `#f23645` (red)           | Bearish candle color (native renderer).                                                                                                                                                                                                                                   |
| `priceStyle`       | `'candles' \| 'bars' \| 'line' \| 'area' \| 'baseline'`             | `'candles'`               | How the base price series is drawn (native renderer).                                                                                                                                                                                                                     |
| `drawings`         | `boolean \| { toolbar?, tools?, groups? }`                          | **toolbar shown**         | Interactive [drawing tools](/vela/user/drawing-tools). `true`/omitted ⇒ toolbar visible; `false` ⇒ toolbar hidden (the `chart.drawings` API still works headlessly); object customizes it (see below). Capability-gated (native renderer only).                           |
| `settings`         | `{ hidden?: string[] }`                                             | **all visible**           | Chart-settings dialog visibility policy: setting ids to hide — a whole tab, a group, or a single row (see below).                                                                                                                                                         |
| `priceAxis`        | `{ ticks?: (ctx) => PriceAxisTick[] \| null }`                      | built-in ticks            | Your own price-axis ladder (native renderer): `ticks` returns each pane's ticks, and the axis labels and horizontal gridlines both follow them (see below).                                                                                                               |

\* `defaultLanguage` falls back to the first injected engine's language if you don't set it.

Leave `renderer` off for the built-in native backend; a custom renderer class (implementing `IChartRenderer`) can be passed to swap the whole rendering backend.

### The `drawings` option [#the-drawings-option]

By default the drawing toolbar is **shown** (on a renderer that supports it). Pass `false` to hide
the bar while still driving drawings from code, or an object to customize which tools appear:

| Field     | Type                     | Effect                                                                    |
| --------- | ------------------------ | ------------------------------------------------------------------------- |
| `toolbar` | boolean                  | Show/hide the bar (default `true`).                                       |
| `tools`   | `DrawingTypeKey[]`       | Allow-list of tools; each is bucketed into its own group.                 |
| `groups`  | `{ id, label, tools }[]` | Explicit, custom-labelled groups (unregistered/empty groups are dropped). |

```js
// hide the bar but keep the programmatic API:
new Vela('#chart', { data: bars, drawings: false });

// only a few tools:
new Vela('#chart', { data: bars, drawings: { tools: ['trendline', 'hline', 'box'] } });
```

See [Drawing tools](/vela/user/drawing-tools) for the full catalogue and the `chart.drawings` API.

### The `animations` option [#the-animations-option]

Every eased motion of the native renderer is configured on its own. Each field takes
`true` (the built-in feel), `false` (instant — the motion is off), or a **duration in
milliseconds**: the ease time-constant, after which the motion has covered about 63% of
the remaining distance; it looks settled after roughly three of them. Durations are
capped at 1000 ms.

| Field       | Default                     | What it eases                                                                                                                                                                                                                                            |
| ----------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `zoom`      | `true` (70 ms)              | The wheel zoom: bar spacing glides toward each notch's target instead of jumping. Off, the keyboard zoom keys of the widget jump too.                                                                                                                    |
| `pan`       | `true` (110 ms)             | Pan momentum on touch: the velocity a finger flick releases with decays over this time. `false` = the chart stops dead on release. A mouse release always stops dead.                                                                                    |
| `scroll`    | follows `pan` (130 ms)      | The programmatic scroll glide — the scroll-to-latest button, `chart.panBy`, the keyboard pan keys — easing the view to its target at constant zoom. Left unset it is on whenever `pan` is on, so `{ pan: false }` still means an instant pan everywhere. |
| `autoscale` | `true` (80 ms)              | The price scale's glide toward its new range while a zoom or fling is in flight (off = it snaps every frame).                                                                                                                                            |
| `liveBar`   | `false`                     | The forming candle (and the current-price line and label) slide toward each live tick instead of snapping: `true` = a 90 ms ease. A new bar always snaps; the crosshair, legend and data window always show the real values.                             |
| `intro`     | `true` (`'settle'`, 650 ms) | The first-load reveal: candles draw themselves in left to right. `'settle'` overshoots and eases back, `'grow'` eases out; `false` skips it; `{ style?, duration? }` sets the style and/or the sweep duration in ms (capped at 5000).                    |

```js
new Vela('#chart', {
  animations: {
    zoom: 150,          // a slower, softer zoom glide
    pan: false,         // …but a drag release stops dead (and panBy is instant)
    liveBar: true,      // the forming candle glides to each tick
    intro: { style: 'grow', duration: 400 },
  },
});
```

Each motion is also a live renderer feature — `animZoom`, `animPan`, `animScroll`,
`animAutoscale`, `animLiveBar`, `intro` — so `chart.renderer.set('animZoom', 0)` switches
it off at runtime (see [Renderer features](/vela/user/renderer-features#interaction)). The
settings dialog's *Symbol → Animation* group carries on/off switches for zoom, pan
momentum (inertia and scroll glide together), the price scale, price changes (the live
bar) and the reveal; switching one back on restores the duration configured here. In the
rich config they are `animations.{zoom, pan, autoscale, intro}` plus
`priceScale.animateLastPrice`.

### The `settings` option — hiding settings-dialog entries [#the-settings-option--hiding-settings-dialog-entries]

By default the chart-settings dialog shows everything. `settings.hidden` lists setting
**ids** to hide; an id hides its whole subtree, and a tab with nothing left disappears
from the rail:

```js
new VelaWorkspace('#chart', {
  layout: false,
  bars: 1000,                                  // force the fetch depth…
  settings: { hidden: ['advanced'] },          // …and remove the tab that would change it
});

// or a finer cut: one group, one row
new Vela('#chart', { data: bars, settings: { hidden: ['canvas.grid', 'scales.price-scale.countdown'] } });
```

Hiding is **display-only**: hidden values keep being stored, delivered, and applied —
which is exactly what makes "force an option, hide its control" work. The policy is
instance state, not chart config: it never rides `getConfig()`/`applyConfig()` into
exported templates. It can also be set at runtime with
`chart.renderer.setSettingsVisibility({ hidden: [...] })`.

Ids are dot-separated paths: `<tab>`, `<tab>.<group>`, `<tab>.<group>.<row>`. Enumerate
every addressable id of a live chart with `chart.renderer.listSettingsIds()` (plugin
chart types and host-app sections included).

The complete catalog — every id, at every depth. Any subset works; a parent id makes
its children redundant:

```js
new VelaWorkspace('#chart', {
  settings: {
    hidden: [
      // ══ Symbol tab ════════════════════════════════════════════════
      'symbol',                              // the whole tab
      'symbol.type',                         //   the Type select (chart style)
      'symbol.style.candles',                //   Candles group (also styles Heikin Ashi)
      'symbol.style.candles.body',           //     Body toggle + up/down colors
      'symbol.style.candles.borders',        //     Borders toggle + colors
      'symbol.style.candles.wick',           //     Wick toggle + colors
      'symbol.style.candles.spacing',        //     Spacing
      'symbol.style.bars',                   //   Bars group
      'symbol.style.bars.up-color',          //     Color Up
      'symbol.style.bars.down-color',        //     Color Down
      'symbol.style.bars.spacing',           //     Spacing
      'symbol.style.line',                   //   Line group
      'symbol.style.line.color',             //     Color
      'symbol.style.line.width',             //     Width
      'symbol.style.area',                   //   Area group
      'symbol.style.area.line-color',        //     Line color
      'symbol.style.area.width',             //     Width
      'symbol.style.area.top-fill',          //     Top fill
      'symbol.style.area.bottom-fill',       //     Bottom fill
      'symbol.style.baseline',               //   Baseline group
      'symbol.style.baseline.top-line',      //     Top line
      'symbol.style.baseline.bottom-line',   //     Bottom line
      'symbol.style.baseline.fill-top',      //     Fill top area
      'symbol.style.baseline.fill-bottom',   //     Fill bottom area
      'symbol.style.baseline.base-level',    //     Base level %
      'symbol.style.baseline.width',         //     Width
      'symbol.animation',                    //   Animation group
      'symbol.animation.zoom',               //     Animate zoom (the wheel-zoom glide)
      'symbol.animation.pan',                //     Pan momentum (drag-release inertia + scroll glide)
      'symbol.animation.autoscale',          //     Animate price scale (the autoscale glide)
      'symbol.animation.price-changes',      //     Animate price changes (the live-bar glide)
      'symbol.animation.intro',              //     Reveal on load (the first-paint candle reveal)
      'symbol.timezone',                     //   Time zone group

      // ══ Scales and lines tab ══════════════════════════════════════
      'scales',                              // the whole tab
      'scales.price-scale',                  //   Price scale group
      'scales.price-scale.mode',             //     Regular/Percent/Indexed/Logarithmic
      'scales.price-scale.invert',           //     Invert scale
      'scales.price-scale.last-price-line',  //     Last Price Line
      'scales.price-scale.last-price-label', //     Last price label
      'scales.price-scale.countdown',        //     Countdown to bar close
      'scales.price-scale.axis-labels',      //     Axis labels
      'scales.price-scale.border-color',     //     Scale border color
      'scales.crosshair',                    //   Crosshair group
      'scales.crosshair.color',              //     Color
      'scales.crosshair.width',              //     Width
      'scales.crosshair.style',              //     Solid/Dashed/Dotted

      // ══ Canvas tab ════════════════════════════════════════════════
      'canvas',                              // the whole tab
      'canvas.background',                   //   Background & text group
      'canvas.background.color',             //     Background
      'canvas.background.text-color',        //     Text color
      'canvas.background.text-size',         //     Text size
      'canvas.background.pane-separator',    //     Pane separator color
      'canvas.grid',                         //   Grid group
      'canvas.grid.vertical',                //     Vertical lines toggle + color
      'canvas.grid.horizontal',              //     Horizontal lines toggle + color
      'canvas.margins',                      //   Margins group
      'canvas.margins.top',                  //     Top (% of pane height)
      'canvas.margins.bottom',               //     Bottom (% of pane height)
      'canvas.margins.right',                //     Right (bars after the newest bar)
      'canvas.theme',                        //   Theme group (Dark/Light)

      // ══ Events tab (timeline marks — present once marks name groups) ═
      'events',                              // the whole tab
      'events.groups',                       //   Visible events (one checkbox per mark group)
      'events.groups.<group-id>',            //     a group's checkbox (the group id, kebab-cased)

      // ══ Widget & workspace tabs (shell-contributed) ═══════════════
      'status-line',                         // the whole Status line tab
      'status-line.parts',                   //   Status line group (the five rows below)
      'status-line.logo',                    //     Symbol logo
      'status-line.name',                    //     Symbol name
      'status-line.market',                  //     Market status
      'status-line.ohlc',                    //     OHLC values
      'status-line.change',                  //     Bar change values
      'status-line.indicators',              //   Indicators group (the two rows below)
      'status-line.indicator-titles',        //     Titles
      'status-line.indicator-values',        //     Values
      'advanced',                            // the whole Advanced tab
      'advanced.bars',                       //   Bars to fetch
      'time-zone',                           // the workspace Time zone group in the Symbol tab
      'time-zone.zone',                      //   (same row — UTC, Exchange, then the catalog;
                                             //    it replaces the renderer's `symbol.timezone`)
      'trading-session',                     // the RTH/ETH group in the Symbol tab
      'trading-session.session',             //   Session select
      'trading-session.premarket-color',     //   Pre-market shading color (day-split markets)
      'trading-session.postmarket-color',    //   Post-market shading color (day-split markets)
      'trading-session.extended-color',      //   Extended-hours shading color (overnight markets)
      'watermark',                           // the Watermark group (the two rows below)
      'watermark.visible',                   //   Symbol watermark
      'watermark.replay',                    //   Replay watermark (the line under it while replaying)

      // ══ Plugin chart types (registerChartType) ════════════════════
      'type:<chartTypeId>',                  // the type's settings tab (+ its subsections)
      'type:<chartTypeId>.<key>',            //   a value row, by its settings bag key
      'type:<chartTypeId>.<heading-slug>',   //   a group, by its heading label's slug
      'type:<chartTypeId>.<subsection-slug>',//   a subsection, by its title's slug
      'symbol.style.<chartTypeId>',          // a candle-drawn plugin style's Candles group
                                             //   (rows: .body, .borders, .wick, .spacing)

      // ══ Host sections (setSettingsSections) ═══════════════════════
      '<sectionId>',                         // the section's `id` field, else its title's slug
      '<sectionId>.<rowId>',                 //   a row's `id` field, else its label's slug
    ],
  },
});
```

Conditional entries hide-and-stay-hidden: `trading-session` only appears on symbols
that have sessions, `status-line` only when the shell's status line is on,
`canvas.theme` only when the host wires the theme switch — hiding them is safe either
way. Host sections contributed through `setSettingsSections` need nothing from the
contributor: the `id` fields are optional stability aids, label slugs are the
fallback.

### The `priceAxis` option — custom price-axis ticks [#the-priceaxis-option--custom-price-axis-ticks]

`priceAxis.ticks` replaces the built-in tick ladder of the native renderer's price axes.
It is called for each pane — the price pane and every study pane — and returns the ticks
to draw. The axis labels and the horizontal gridlines both follow the same ticks, so they
always line up.

```js
new Vela('#chart', {
  data: bars,
  priceAxis: {
    // Emphasize the built-in levels and add a muted level between two of them
    // wherever there is room.
    ticks: ({ mode, defaults, priceToY }) => {
      if (mode !== 'price') return null; // keep the built-in percent/indexed ticks
      const out = [];
      defaults.forEach((tick, i) => {
        out.push({ ...tick, major: true });
        const next = defaults[i + 1];
        if (next && Math.abs(priceToY(next.price) - priceToY(tick.price)) > 40) {
          const mid = (tick.price + next.price) / 2;
          out.push({ price: mid, label: mid.toFixed(2), major: false });
        }
      });
      return out;
    },
  },
});
```

Each tick is `{ price, label, major? }`: `price` places the gridline and the label, `label`
is drawn as given, and `major: true` draws the label semibold, `major: false` draws it
muted, while leaving `major` out draws the regular label. Gridlines look the same either
way. A label too close to the top or bottom edge of its pane is skipped, as with the
built-in ticks.

The function receives one context object per pane:

| Field             | Meaning                                                                                            |
| ----------------- | -------------------------------------------------------------------------------------------------- |
| `pane`            | `{ id, kind }` — `kind` is `'price'` or `'study'`.                                                 |
| `min`, `max`      | The pane's visible range, in prices (also in percent and indexed mode).                            |
| `log`             | Whether the pane's scale is logarithmic.                                                           |
| `height`          | The pane height in CSS pixels.                                                                     |
| `mode`            | `'price'`, `'percent'` or `'indexed'` — how the axis labels read this frame.                       |
| `baseline`        | The percent/indexed baseline price (`undefined` in price mode).                                    |
| `mintick`         | The symbol's tick size, when known.                                                                |
| `fontSize`        | The axis font size in pixels.                                                                      |
| `priceToY(price)` | A price's y within the pane, in CSS pixels (log and inverted scales included).                     |
| `defaults`        | The built-in ticks for this frame — return them, or a filtered or extended copy, to build on them. |

* Return `null` or `undefined` to keep the built-in ticks, or an empty array to draw none.
* Entries with a non-finite `price` or a non-string `label` are dropped.
* If the function throws, the pane keeps its built-in ticks and the console shows one
  warning for the chart.
* A pane whose indicator declares its own axis (a blank or categorical axis) draws no
  price ticks and never calls the function. The extra scale column of an indicator merged
  onto its own scale keeps its built-in ticks.
* The function runs again only when a pane's range, height, mode, baseline, tick size or
  font size changes. If your ticks depend on your own state, set the function again to
  recompute them.

The option seeds the native renderer's runtime `priceAxisTicks` feature: change or clear
it later with `chart.renderer.set('priceAxisTicks', fn)` or `null` (see
[Renderer features](/vela/user/renderer-features#axes--scale)). A function is never part of
`getConfig()`. On a [workspace](/vela/user/workspace), the top-level `priceAxis` is the default
of every cell, including cells a later layout change creates.

### Non-obvious defaults, called out [#non-obvious-defaults-called-out]

* **Animations are on** by default (eased zoom, snappy inertial pan).
* **The current-price line is on** by default.
* **The price scale is linear** by default (`logScale: false`).

Instead of `'dark'`/`'light'`, pass a full theme object to control every color and the font — all seven fields are required:

```js
const midnight = {
  background:  '#0b0e14',
  textColor:   '#c9d1d9',
  gridColor:   '#1c2230',
  borderColor: '#30363d',
  upColor:     '#3fb950',
  downColor:   '#f85149',
  fontFamily:  'Inter, system-ui, sans-serif',
};

new Vela('#chart', { data: bars, theme: midnight });
```

The theme can also be swapped at runtime — `chart.setTheme('light')` (or a full theme
object) re-skins the chart live and emits `theme:changed` so your surrounding UI can
follow; users reach the same switch in chart settings → Canvas → Theme. The built-in
dark and light themes share the same candle colors, so switching never recolors the
series. Setting only a background color through the settings dialog (or `applyConfig`)
keeps the app theme: when that background lands in the other luminance class (a white
plot on the dark theme), the derived inks — text, grid, axis border — re-base
automatically so legends and axis labels stay readable, while any explicitly chosen
text color wins.

### Capability-gated options [#capability-gated-options]

Some options only take effect when the active backend supports them. **`glow` is WebGL2-only** — it is silently ignored on the canvas2d backend. If you force `nativeBackend: 'canvas2d'`, glow has no effect.

A native-renderer styling combo: draw price as a glowing line on the GPU backend and make panning instant while keeping the eased zoom.

```js
new Vela('#chart', {
  data: bars,
  priceStyle: 'line',                 // candles | bars | line | area | baseline
  nativeBackend: 'webgl2',            // force the GPU backend
  glow: 0.6,                          // neon bloom on line series (WebGL2 only)
  animations: { zoom: true, pan: false }, // eased zoom, no pan momentum
});
```

***

## Per-indicator options [#per-indicator-options]

The optional second argument to `addIndicator(source, options)` — `runIndicator` and
`runScript` take the same object:

| Option     | Type                         | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ---------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`       | string                       | The indicator's id on the chart — an opaque, non-empty string you own (a document key, an editor tab, a UUID). It is what `handle.id`, `chart.indicators()`, the `indicator:*` events, `script:run` and the legend/pane surfaces carry, so you can address the indicator without keeping a side map. Omit it and the chart mints one — stable while the indicator stays on the chart, not across reloads. An id already live on the chart is rejected, never renamed: `addIndicator` throws, `runIndicator`/`runScript` resolve `{ ok: false, error }`. Removing the indicator frees its id. |
| `language` | string                       | Which registered engine runs this script. Defaults to the chart's `defaultLanguage`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `inputs`   | `Record<string, InputValue>` | Input overrides, keyed by input title or key.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `props`    | `Record<string, InputValue>` | Declaration-property overrides (a strategy's `initial_capital`, an indicator's `precision`, …), keyed like the engine's props schema. Ignored by engines without props support.                                                                                                                                                                                                                                                                                                                                                                                                              |
| `overlay`  | boolean                      | Force overlay vs. separate pane. Default: read from `indicator(overlay=…)`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `pane`     | `'price' \| 'new'`           | Explicit pane placement.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `title`    | string                       | Display title override.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

See [API reference](/vela/user/api-reference) for the `IndicatorHandle` you get back, and [Quickstart](/vela/user/quickstart) for the end-to-end flow.
