Overview
An indicator is a script that draws on Charts: moving averages, oscillators, bands, markers, custom overlays. This section covers what indicators add on top of the shared runtime: where outputs draw, which series types exist, and how onBar ties them together.

The minimal indicator
meta({ shortName: "EMA", kind: "overlay" });
dialog({ title: "EMA" });
const length = input.number({ id: "length", label: "Length", default: 20, min: 1 });
warmup((w) => w.ema(length));
output.line({ id: "ema", color: "#2196f3" });
layout(tab({ id: "main", title: "Main" }, section({ id: "p", title: "Parameters" }, length)));
export function onBar(ctx) {
const k = 2 / (ctx.params.length + 1);
const ema = ctx.accum("ema", () => ({ t: 0, prev: null, cur: null }), (s) => {
if (s.t !== ctx.time) { s.prev = s.cur; s.t = ctx.time; } // a new bar: commit the last one
s.cur = s.prev == null ? ctx.close : s.prev + k * (ctx.close - s.prev);
return s;
});
ctx.plot("ema", ema.cur);
}Every piece is required for a reason:
Call | Why |
|---|---|
| Legend label and where it draws. Call it once. |
| The settings window. The script does not build without it. |
| Settings, read in |
| Any script that keeps state in |
| Every series the script may emit, by id. |
| Runs once per bar, and again for the forming bar on every tick. The EMA above is written so a repeated tick replaces the tip instead of stacking on it. See onBar. |
Write indicators in Tools → Indicators, in the code editor or with the indicator authoring agent.
In this section
Page | Covers |
|---|---|
Every | |
Routing outputs to subpanes, price scales, checking the layout | |
Every | |
The per-bar function, the forming bar, state that survives ticks | |
| |
Canvas2D and WebGL painting, layout, hit testing, gestures | |
Ten public library indicators, simple to complex |
Covered in Shared runtime
Topic | Page |
|---|---|
Bar fields, | |
| |
| |
| |
| |
| |
|
