Your first run
This walkthrough takes you from an empty folder to an EMA indicator that has run on 30 days of BTC and is saved to your account. You need the CLI installed and signed in.
1. Set up a folder
$ mkdir my-scripts && cd my-scripts
$ chartnaut init
chartnaut.json: created
indicators/: created
definitions/: created
studies/: created
CLAUDE.md: created
AGENTS.md: created
next: chartnaut new indicator my-first-indicatorinit makes one folder per script type and a chartnaut.json holding the defaults run uses when you leave out a flag:
{
"defaults": {
"instrument": "BTC",
"timeframe": "5m",
"window": "90d"
}
}Edit them here, or pass --instrument, --tf and --window to init. CLAUDE.md and AGENTS.md are for coding agents: Working with Claude Code and Codex.
2. Create the indicator
$ chartnaut new indicator my-ema
wrote indicators/my-ema/script.json and indicators/my-ema/main.ts
next: chartnaut docs, edit main.ts, then chartnaut validate indicators/my-emascript.json names the script and its entry file. The main.ts it writes holds only comments. Replace them with this EMA:
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" });
function onBar(ctx) {
const k = 2 / (ctx.params.length + 1);
const st = ctx.accum("ema", () => ({ t: 0, prev: null, cur: null }), (s) => {
if (s.t !== ctx.time) { s.prev = s.cur; s.t = ctx.time; }
s.cur = s.prev == null ? ctx.close : s.prev + k * (ctx.close - s.prev);
return s;
});
ctx.plot("ema", st.cur);
}The First indicator guide explains each part. chartnaut docs lists every page of the scripting reference, and chartnaut docs series-outputs prints one in the terminal.
3. Validate it
$ chartnaut validate indicators/my-ema
ok: my-ema (indicator)
SETTING TYPE DEFAULT
length number 20
OUTPUT KIND PANE
ema line pricevalidate runs the checks the app runs when you save, without saving or running anything, and it is free. It lists the settings and outputs Chartnaut read from the script, so you can see it understood what you meant.
A script with a problem prints one line per problem, as file:line: severity: message [rule], then invalid: my-ema (indicator), and exits with code 1. Fix every error line and validate again. Warnings do not stop a run. Lint and error codes
4. Run it
$ chartnaut run indicators/my-ema --on BTC --tf 1h --last 30d
run run_4k2m9x7q1b8z3n5p succeeded indicator inline HYPERLIQUID:BTC 1h 2026-08-27 10:00 → 2026-09-26 10:00
bars: 720
OUTPUT LAST MIN MAX COUNT
ema 63412.18 58120.44 66890.03 720
usage: 720 bars, 0.72 CUThe script ran on Chartnaut's servers and the CLI waited for it to finish. Running a folder sends the files on your disk as they are now, shown as inline, and saves nothing.
The first line is the run: its id, status, script type, what ran, the full instrument symbol, the timeframe and the window it covered.
barsis how many bars the script saw: 30 days of 24 hourly bars.The table has one row per output: its last, lowest and highest value, and how many bars have one. A
-inLASTor aCOUNTof 0 means the output never plotted, which points at the script.usagecounts the bars evaluated, dependencies included. A compute unit (CU) is 1,000 bars.
The window can also be --from 2026-01-01 --to 2026-03-01 or --bars 2000. Leave a flag out and the value in chartnaut.json is used. To try another setting without editing the file, add --set length=50.
5. Widen it
$ chartnaut run indicators/my-ema --on BTC,ETH --tf 1h --last 90dA list of instruments starts one run each and prints one row per instrument, so you can compare them side by side. chartnaut instruments eth finds the symbol for a market. --out results.csv writes every value, not only the summary. Runs and results
6. Save it
$ chartnaut push indicators/my-ema -m "first version"
pushed my-ema@1
app: https://terminal.chartnaut.com/morpheus/indicator-builder/1234push saves the files as version 1 of a new indicator in your account, and the app: link opens it in the indicator builder. Each push after this saves the next version. Saving and versions
Definitions and studies
chartnaut new definition <slug> and chartnaut new study <slug> start the other two types, and the First definition guide and First study guide have scripts to paste in.
A definition runs from its folder the same way and prints events_total and a count per event. A study cannot run from its folder: push it first, then run it by its slug, such as chartnaut run my-study --on BTC --tf 5m --last 90d. Studies read their definitions' events, so the run first runs those definitions over the window. Definition events
