The shape of a script
A script is one TypeScript file with no imports. Its globals are the API. The top level runs once, when the script loads (setup). It may contain only:indicator(name, options), first;constdeclarations whose values come from the API’s constructors (input.*,bars(),trades()and the other streams,state.*,series,tally,tallyBy,ta.*,plot.*,alert,draw.table), from literals, or from other constants and helper functions;plot.level(...)calls;- function declarations: pure helpers, or factories called at setup;
- handler registrations:
stream.onBar(fn),stream.onClose(fn),trades.onTrade(fn),liquidations.onLiquidation(fn).
What the compiler enforces
- Constructors only at the top level; handlers registered only at the top level, unconditionally.
- Each state object, series and indicator belongs to the one stream whose handler updates it.
- Event handlers (
onTrade,onLiquidation) may change only tallies and live state. - Tallies are filled only by event handlers.
- Plots, markers and drawings are set only in the chart’s own
bars()handlers. - No
importorexport,eval,with,async, generators, classes, top-levelletorvar, top-level collections that change, dynamic indexing of API objects,Date, timers,fetchor other globals. Mathis the engine’s own:exp,log,pow, the trigonometric functions and the rest give the same bits in every browser, which can differ in the last bit from a browser console. There is noMath.random: userandom(seed).
The order things run in
For chart bari, in history:
- Everything that happened before the bar closed, merged by time: trades and liquidations with a time before its close, and other bar streams’ bars that close at or before it (their
onBarwithconfirmedtrue,onClose, then their commit). At equal times a bar close comes first, and a longer interval before a shorter one. - The chart’s
onBar, withconfirmedtrue, then itsonClose. - The commit. Tallies empty for the next bar.
confirmed false. Only the latest update matters, so updates can be skipped without changing the result.
Another stream read from a handler gives its last closed value, “as of” that moment: there is no lookahead.
.forming on a stream reads its developing bar live, which repaints; on history it is the last closed bar. See data and timeframes.update runs, so update it on every bar. Missing numbers are na: arithmetic with na is na, and comparisons with it are false. See missing values.