STS Script AST¶
STS Script source code is parsed into an internal AST before validation and compilation.
The AST is not the public user-facing language, but it defines how the runtime understands script source.
Top-Level Program¶
{
type: "Program",
body: []
}
The body array contains statements.
Statement Types¶
| Type | Purpose |
|---|---|
Input |
Declares an input constant |
VarDecl |
Declares a local variable |
Assign |
Assigns a calculated series |
If |
Conditional branch |
For |
Bounded loop |
ExprStmt |
Function call statement |
Event |
Robot lifecycle event body |
Script Declaration¶
The first statement must be a script(...) expression statement.
script("MA Crossover", kind="robot")
{
type: "ExprStmt",
expr: {
type: "Call",
name: "script",
args: [
{ type: "Str", value: "MA Crossover" }
],
named: {
kind: { type: "Str", value: "robot" }
}
}
}
Input¶
input length = 20
{
type: "Input",
name: "length",
value: { type: "Num", value: 20 }
}
Series Assignment¶
ma = ta.sma(close, length)
{
type: "Assign",
name: "ma",
expr: {
type: "Call",
name: "ta.sma",
args: [
{ type: "Var", value: "close" },
{ type: "Var", value: "length" }
]
}
}
Event¶
onBar {
trade.buy(symbol="BTCUSD", volume=0.01)
}
{
type: "Event",
name: "onBar",
body: {
type: "Block",
body: []
}
}
Expressions¶
| Type | Purpose |
|---|---|
Num |
Numeric literal |
Str |
String literal |
Var |
Variable or series reference |
History |
Historical access, for example close[1] |
Bin |
Binary expression |
Unary |
Unary expression |
Cond |
Conditional expression |
Call |
Function call |
Validation¶
Validation checks that:
- unknown variables are rejected;
- indicator scripts cannot use robot-only functions;
- robot scripts can only use allowed trade bridge functions;
- inputs cannot be reassigned;
- series history access is used only on series values;
plotTextis a standalone indicatorExprStmt, allowed insideIfbut rejected in loops, assignments, nested expressions, and robot events;plotTexthas exactly one positional price argument and only the documented named options;ta.crossoverandta.crossunderreceive exactly two positional named-series references, without history offsets or inline expressions.
The compiler emits plotText at its original per-candle execution point, so conditional branches remain conditional. It does not hoist text-label calls into one-time plot registration. Option types and limits are checked when their values are evaluated. See Chart API.
Extended language contracts¶
The existing AST shapes also represent the newer APIs; there is no executable JavaScript escape hatch.
nais a missing-value literal;na(value)andnz(value, replacement)are calls.barIndexandisClosedare built-in series.- History indices must be nonnegative safe integers; negative/fractional/non-finite indices are rejected, including dynamically evaluated indices.
For.fromandFor.tomay be expressions. Bounds are captured once per loop entry and validated at runtime; a reversed range is empty.array.*calls accept positional scalar arguments and can be used in expressions or statements, including loops.draw.*calls are indicator statements, including in loops. They are rejected as expression values and in robots.plotShape,barcolorandalertconditionare per-candle indicator statements, allowed inifbut not in loops, expressions or robot events.- Named options on once-registered
plot,hline,fill,bgcolorandcolorcalls must be literals or scalar inputs. Calculate named source/condition series separately.
See the exact signatures and limits in Chart API, Series and Runtime.