STS Script Runtime¶
STS Script runtime is responsible for parsing, validating, compiling, and executing user scripts in a controlled environment.
Pipeline¶
source code
-> preprocess
-> parse AST
-> require script declaration
-> validate AST
-> extract input metadata from AST
-> compile
-> run in platform runtime
-> return result/actions/logs
Indicators and robots share the same language syntax, but they run with different capabilities.
The script declaration is the source of truth for runtime kind:
script("Title", kind="indicator")
script("Title", kind="robot")
UI and backend metadata are derived from this declaration.
Indicator Runtime¶
Indicator scripts calculate series and expose drawing instructions to the chart.
When an indicator script is started, the platform registers it in the chart indicator list under the CUSTOM category. The user can then add or remove it from the chart like any other indicator.
Stopping the script removes it from the custom indicator registry.
Runtime behavior:
- calculation is performed in a worker; the chart renderer consumes the returned series and drawing instructions;
- calculation results are cached and reused while their source/data signature remains unchanged;
- indicators cannot call
trade.*; - indicators can use line/step plots, fills, backgrounds, conditional colors, labels, shapes, keyed drawing objects, candle colors and local alert conditions;
plotTextis evaluated per candle, including insideif, and retains at most 200 labels across all calls;- text labels are recalculated from source and candle data, rather than persisted as independently editable drawing objects.
Text Label Result Contract¶
Indicator results include ui.labels, an array of declarative label records (empty when there are no labels):
{
"ui": {
"labels": [{
"barIndex": 52,
"time": 1792065600,
"price": 1.08423,
"text": "Cross up: {price}",
"callId": 0,
"options": {
"color": "#2962FF",
"position": "below",
"fontSize": 12
}
}]
}
}
barIndex is the zero-based candle index, time is its Unix timestamp in seconds, and callId identifies a static plotText call site. The chart verifies the candle index/timestamp and places the label using its price. Price formatting and viewport placement belong to the renderer; the worker returns the unformatted template and numeric anchor.
Label nodes/textures are reused while visible and released when no longer needed or when the indicator is removed. See Chart API for argument validation and forming-candle behavior.
Compiler and AI Compatibility¶
A backend/headless compiler and an AI StScript knowledge package must support the same language revision as the terminal. A deployment that adds plotText must update the compiler, validation/reference examples, and advertised runtime identity together. The terminal's runtime compatibility check must remain enabled; updating documentation alone does not update a deployed backend.
ui.labels extends the existing indicator result; it does not require a new AI HTTP/TCP envelope. Headless validation consumes declarative data and must not start the chart renderer.
Robot Runtime¶
Robot scripts run inside a worker and interact with the terminal through a controlled bridge.
Robots do not access the platform store, DOM, tokens, or arbitrary network requests directly.
Variables And State¶
input values are immutable configuration constants.
var declares mutable script variables:
var counter = 0
onTick {
counter = counter + 1
}
For indicators, var is local to one chart calculation pass.
For robots, top-level var values are stored in the worker runtime state and persist between onBar and onTick events of the same running script. The state is reset by Stop, by a new Run, and by application reload/autostart.
Events¶
| Event | When it runs |
|---|---|
onBar |
After historical candles are loaded, and later for bar-based logic |
onTick |
On each live quote event |
onInit |
Reserved lifecycle event |
onStop |
Reserved lifecycle event |
Market Data Flow¶
On Run, the platform loads historical candles through:
GET /quotes/candles
The response rows:
[open, high, low, close, volume, time]
are normalized to candle objects and passed to the script worker.
Live quotes are received through the client stream and delivered to the robot runtime as onTick events. Each quote updates the latest candle or creates a new candle based on timeFrame.
Dry Run¶
Use dryRun = 1 to test robot logic without sending real trade requests.
input dryRun = 1
In dry-run mode:
trade.buyandtrade.sellare written to the script log;- simulated positions are stored in the current runtime session;
trade.positionsCountincludes simulated positions;- no real order is sent to the trading API.
Use dryRun = 0 for real trading.
Runtime Guards¶
Robot runtime applies guard settings before sending trade actions to the terminal.
| Input | Default | Description |
|---|---|---|
maxPositions |
1 |
Skips buy/sell when open positions for the symbol already reached the limit |
cooldownSeconds |
0 |
Skips buy/sell while cooldown after the previous trade action is active |
maxActionsPerEvent |
1 |
Skips actions after the per-event limit is reached |
These values are stored as STS Script input declarations so they are persisted with the script source and do not require extra backend fields.
Runtime Notes¶
- Historical robot data is loaded from the backend, not from the active chart state.
- Runtime settings such as
symbol,timeFrame,historyCount,dryRun, and guards are extracted from AST inputs. - Live robot quotes are delivered through the platform event stream.
Runstarts/registers a script.Runperformsparse -> validate -> extract declaration/inputsbefore touching runtime.- For existing scripts,
Runupdates the backend first and starts the saved source version. - If parser or validator fails on
Run, the editor shows a validation error dialog and the script is not started. - Parser errors include
line:columnand are mirrored into Monaco markers. - If source is edited while the script is running, the editor marks it as edited while running; the active runtime keeps using the launched source version until the next
Run. Stopremoves runtime subscriptions and stops the worker.- Autostart scripts are started after platform initialization.
Replay state, dynamic loops and visual limits¶
Indicator calculations replay the loaded history. Named arrays, TA call-site caches and keyed drawing objects are reset per evaluation, then accumulate during that replay. Robot arrays also reset per evaluation; use top-level robot var state for values that must persist between events.
for j in from..to { ... } evaluates the two bounds once on entry. Both bounds must be finite safe integers with a difference at most 10,000. The range is inclusive and empty when to < from; there is no descending-loop syntax. Bounds can be calculated expressions, including array sizes. Use reverse indexing to remove array entries safely. Nested loops share a 1,000,000-step budget per evaluation.
| Resource | Limit |
|---|---|
| Source | 64,000 characters |
| AST | 10,000 nodes; depth 64 |
| Indicator history | 10,000 bars |
| Worker calculation | 5 seconds |
| Arrays | 64 names; 256 entries each; 4096 entries total |
| Keyed drawing objects | 500; oldest ID evicted for new objects at capacity |
| Forward coordinates | At most current bar index + 500 |
| Text/shape records | Latest 200 plotText labels and latest 200 shapes |
| Rendered text | Up to 200 combining keyed captions and plotText |
| Local alert records | 64 per evaluation; latest closed candle only |
| Candle color records | 10,000 per evaluation |
Worker results extend ui with shapes, alerts, barcolors and objects, in addition to plots, fills, backgrounds, colors and labels. An object has id, type, coordinates, options, knownAt (first creation bar) and updatedAt. Backdating a pivot's visual anchor does not backdate knownAt.
The chart coalesces pending calculations, rejects stale results and invalidates results when earlier candle data changes. Hiding/removing indicators or destroying the chart disposes workers and drawing resources. Restoring a chart after reload populates its indicator list without user interaction.
The terminal runtime, headless/marketplace validator and AI compiler must use the same language revision and runtime fingerprint. Updating these documents does not deploy or update another service. See series and arrays, technical analysis and chart output.
Independent pane result¶
pane(...) adds ui.pane = {title, height, min, max, note, noteWhen} to indicator output. It is declarative metadata consumed before chart price geometry is rebuilt. Min/max are null for autoscaling. The renderer reserves a separate panel, routes all script visuals to its numeric scale and keeps its runtime height non-enumerable in settings. Hide/remove/resize/reload follow the normal indicator lifecycle.
The current runtime also supports plot(style="histogram") and draw.label(badge=1, background="#76F7B8"). Backend/headless/AI/marketplace validators must accept the same DSL revision and runtime fingerprint before claiming compatibility; documentation changes do not update those services.
Lorentzian model runtime¶
ML models use dedicated bounded training rings and cached neighbor searches; they do not expand the scalar array.* limits. The new native feature/distance code is included in the runtime fingerprint. Backend/headless/AI/marketplace services must deploy the same revision before accepting compatible scripts.
The client ships an independent causal classifier, not a reproduction of Premium or exact Pine ANN signals. Technical component formulas are validated against the public AI Edge reference. See ML classifier for training eligibility, cache invalidation and resource limits.
Dynamic color series¶
Line/fill options may include a colorSeries field containing the name of a calculated result series. Runtime validates all referenced color series after calculation and before posting the indicator result: valid entries are #RRGGBB strings or missing values. The chart reads each bar's color; missing entries break interpolated output. Cell fills render independent rectangles and consume no keyed-object budget. New MFI/VWMA helpers, color-series contracts and diamond/square markers are included in the runtime fingerprint and local Reference Manual.