feature
First indicator guide
This walkthrough builds a small overlay indicator in the Code tab — an EMA with a length setting that draws on price.
Follow it if you have never authored an indicator script before. When you finish, you will know how meta, inputs, output.*, and onBar fit together.
What you need first
Access to Research → Indicators
Comfort opening the Code tab
Skim Build an indicator for the product path
Steps
Create or open an indicator under Research → Indicators.
Open Code and replace the body with the script below.
Preview on a chart. Change Length in the settings dialog.
Save / snapshot when the plot looks right.
Full script
meta({ shortName: "EMA Cross", kind: "overlay" });
dialog({ title: "EMA Cross" });
const length = input.number({
id: "length",
label: "Length",
default: 20,
min: 1,
});
const color = input.color({
id: "color",
label: "Color",
default: "#2196f3",
});
const emaLine = output.line({ id: "ema", color: "#2196f3" });
output.markers({ id: "cross_up", on: emaLine, color: "#26a69a" });
layout(
tab({ id: "main", title: "Main" },
section({ id: "params", title: "Parameters" }, length, color))
);
function onBar(ctx) {
const len = ctx.params.length;
const k = 2 / (len + 1);
const ema = ctx.accum("ema", null, (prev) =>
prev == null ? ctx.close : prev + k * (ctx.close - prev)
);
ctx.plot("ema", ema);
const prevClose = ctx.accum("prevClose", null, (prev) => ctx.close);
const prevEma = ctx.accum("prevEma", null, (prev) => ema);
if (prevClose != null && prevEma != null && prevClose <= prevEma && ctx.close > ema) {
ctx.mark("cross_up", { price: ctx.close, text: "↑" });
}
}What each part does
Piece | Job |
|---|---|
| Draw on the price pane |
| Settings the trader can change |
| Declared series the chart can render |
| Settings dialog structure |
| Cross-bar memory (EMA state) |
| Emit values for declared outputs |
Common mistakes
Plotting an id you never declared with
output.*Using module-level
let emainstead ofctx.accumSetting
kind: "pane"when you meant an overlay on price
