ThunderScript
A small language for describing trading strategies.
Introduction
Most trading platforms make you click through a form: pick an indicator, set thresholds, save. ThunderScript flips that. You declare your strategy as data: indicators as variables, conditions as boolean expressions, risk as a few percentages. The compiler validates everything; the runtime executes it.
Three things make ThunderScript different:
Core concepts
Five mental models that make ThunderScript click:
1. The cycle loop
Every cycle_interval (default 5min), the engine runs your strategy once per symbol. It fetches indicators, checks conditions, and either opens a position, closes one, or waits.
2. Entry vs Exit logic
entry when uses AND logic — every condition must pass. exit when uses OR logic — any single condition triggers a close. This matches how humans actually think about trading: "I want all these to align before I buy, but I'll get out for any of these reasons."
3. AI as a final gate
If your strategy includes ai_context, the LLM is called only after all your conditions pass — as a final confidence check. This saves enormous LLM costs vs calling on every cycle.
4. Versioned forever
Every Save creates a new version with a performance snapshot. You never lose history. You can rollback, compare, or branch off any prior version.
5. Risk lives in the script
Stops, take-profits, position sizing, cooldowns — all in the risk block. The supervisor can tweak these alongside conditions; you keep one source of truth.
Syntax & Types
ThunderScript is whitespace-tolerant and uses braces for blocks. Comments start with //.
| Type | Syntax | Examples |
|---|---|---|
| Number | integer or decimal | 14, 1.5, 0.05 |
| Percentage | NUMBER% | 5%, 1.5% |
| Duration | NUMBER + s/m/h/d | 30s, 5m, 2h, 1d |
| Timeframe | candle interval | 1m, 5m, 15m, 1h, 4h, 1d |
| String | double quotes | "deepseek", "BTCUSDT" |
| Array | square brackets | ["BTCUSDT", "ETHUSDT"] |
| Range | LOW..HIGH | 35..65, 0.1..0.5 |
| Boolean | true / false | is_paper: true |
5m) are also valid as durations in conditions.
Strategy Block
Every script starts with a strategy block. The structure is fixed; sub-blocks are optional except entry when and exit when:
strategy "Name" { // required
timeframe: 5m // optional, default 5m
symbols: ["BTCUSDT"] // or top_volume(N)
indicators { ... } // optional
entry when { ... } // REQUIRED — at least one condition
exit when { ... } // REQUIRED
risk { ... } // optional, sensible defaults
ai_context { ... } // optional, LLM gate
schedule { ... } // optional, timing rules
}