Build trading strategies with code, not clicks.
ThunderScript is a domain-specific language for AiTrade bots. Write a strategy in plain English-like syntax. Deploy in seconds. The AI Supervisor improves it while you sleep.
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:
Live editing
Save a new version. The next bot cycle picks it up. No restart, no downtime.
Self-improving
The AI Supervisor reviews performance hourly and proposes improvements.
Auto-revert
Bad version losing money? Rolls back to your best automatically.
Quickstart
The fastest path to a running ThunderScript bot:
- Open AiTrade and create a wallet (testnet recommended for first time)
- Right-click the Bots panel → Create Bot
- Pick a name + your wallet, set capital, click Create Bot
- Click the new bot → ThunderScript Editor button (⚡ icon)
- Replace the default with the example below, click Validate, then Save & Deploy
- Press Start Bot on the bot card
Your first strategy
Here's a minimal but real strategy. It buys when EMA(9) crosses above EMA(21) with healthy momentum, and exits with a 1.5% trailing stop or RSI overbought:
strategy "Hello Momentum" { timeframe: 5m symbols: ["BTCUSDT"] indicators { rsi = RSI(14) ema_fast = EMA(9) ema_slow = EMA(21) atr = ATR(14) } entry when { ema_fast crosses_above ema_slow rsi in 35..65 adx > 20 } exit when { trailing_stop(callback: 1.5%) or rsi > 75 } risk { max_position_pct: 5% stop_loss_atr: 1.5 take_profit_atr: 4 } }
That's the entire strategy. The runtime fills in sensible defaults for everything else: AI Supervisor enabled, default model, no cooldown, etc.
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 }
Indicators
Declare what you measure. Each line creates a variable you can reference in conditions:
indicators { rsi = RSI(14) ema_fast = EMA(9) ema_slow = EMA(21) atr = ATR(14) vwap = VWAP() }
| Indicator | Args | Returns | Best for |
|---|---|---|---|
RSI(period) | period (14) | 0–100 | overbought/oversold |
EMA(period) | 9, 21, 50… | price level | trend |
SMA(period) | period | price level | baseline |
ADX(period) | period (14) | 0–100 | trend strength |
ATR(period) | period (14) | price units | volatility |
VWAP() | — | price level | fair value |
MACD(f, s, sig) | 12, 26, 9 | MACD line | momentum |
Bollinger(p, std) | 20, 2 | {lower, upper, pct_b} | range/breakout |
rsi, adx) even without declaring them. Declaring just gives you a custom alias.
Conditions
Entry conditions (AND)
Every condition must evaluate to true:
entry when { ema_fast > ema_slow // trend rsi in 35..65 // not extreme adx > 25 // directional price > vwap // above fair value not_in_cooldown(2h) // no recent loss fee_ratio_ok(30%) // fees won't kill profit }
Exit conditions (OR)
Any single condition triggers a close:
exit when { trailing_stop(callback: 1.5%) or rsi > 75 or ema_fast crosses_below ema_slow }
Operators
| Operator | Meaning | Example |
|---|---|---|
> < >= <= == != | Numeric comparison | rsi > 70 |
in | Range check (inclusive) | rsi in 30..70 |
crosses_above | Crossed above this cycle | ema9 crosses_above ema21 |
crosses_below | Crossed below this cycle | ema9 crosses_below ema21 |
or | OR (only valid in exit when) | or rsi > 80 |
Risk Management
risk { max_position_pct: 5% // max 5% of capital per trade position_size_score_3: 25% // score 3 → 25% of max position_size_score_4: 65% // score 4 → 65% of max position_size_score_5: 100% // score 5 → full max stop_loss_atr: 1.5 // SL at 1.5x ATR below entry take_profit_atr: 4 // TP at 4x ATR above entry cooldown_after_loss: 2h // wait after a loss max_daily_loss: 5% // stop trading if -5% today }
Schedule
schedule { cycle_interval: 5m // minimum 1m cautious_hours: [20,21,0,1] // UTC hours: tighter rules cautious_confidence: 0.65 // vs 0.5 default cautious_adx: 30 // vs 20 default cautious_size_penalty: 50% // half size in cautious hours dead_hours: [3,4] // no entries (existing positions managed) }
AI Context
ai_context { model: "deepseek" // or "user.my-llm" prompt: "Trade only momentum setups." min_confidence: 0.5 // LLM gate threshold temperature: 0.3 // LLM creativity }
System models: deepseek, openai, anthropic, meta. User models prefixed with user.
Built-in Functions
| Function | Block | Description |
|---|---|---|
top_volume(n, quote) | symbols | Top N pairs by 24h volume on the given quote |
trailing_stop(callback: %) | exit | Dynamic trailing stop, % from peak |
not_in_cooldown(duration) | entry | Returns true if no loss in the duration |
min_time_since_last_entry(d) | entry | Min time between entries on same symbol |
fee_ratio_ok(percent) | entry | True if expected fees ≤ % of expected profit |
dynamic_adx_floor() | entry | Returns 20 normally, 30 in cautious hours |
dynamic_confidence_floor() | entry | Returns 0.5 / 0.65 in cautious hours |
Built-in Variables
Available without declaring:
| Variable | Type | Notes |
|---|---|---|
price | number | Current symbol price |
capital | number | Bot's current cash |
leverage | number | 1 = spot, >1 = futures |
rsi, adx, atr, vwap, macd | number | Default-period indicators |
ema_fast, ema_slow | number | EMA(9) and EMA(21) |
volume | string | "normal", "elevated", "low" |
spread | number | Bid-ask spread % |
funding_rate | number | Futures funding rate |
confidence | number | 0–1, set by LLM gate |
hour | integer | Current UTC hour 0–23 |
Example: Conservative BTC
Holds spot BTC with strict trend + momentum filters. Big stops, slow cycles.
strategy "BTC Conservative" { timeframe: 1h symbols: ["BTCUSDT"] indicators { rsi = RSI(14) ema_fast = EMA(21) ema_slow = EMA(50) atr = ATR(14) } entry when { ema_fast > ema_slow rsi in 40..60 adx > 30 not_in_cooldown(4h) } exit when { trailing_stop(callback: 2%) or rsi > 80 } risk { max_position_pct: 3% stop_loss_atr: 2 take_profit_atr: 6 } ai_context { model: "deepseek" prompt: "Only enter on strong weekly trends." min_confidence: 0.7 } schedule { cycle_interval: 1h dead_hours: [2,3,4,5] } }
Example: Aggressive Scalper
Hunts top-volume pairs on 5m. Many small trades, tight stops. Higher leverage allowed.
strategy "Scalp Machine" { timeframe: 5m symbols: top_volume(12, quote: "USDT") indicators { rsi = RSI(7) ema_fast = EMA(5) ema_slow = EMA(13) atr = ATR(7) } entry when { ema_fast > ema_slow rsi in 30..70 adx > 20 min_time_since_last_entry(15m) fee_ratio_ok(20%) } exit when { trailing_stop(callback: 0.8%) or rsi > 80 or ema_fast crosses_below ema_slow } risk { max_position_pct: 8% stop_loss_atr: 1 take_profit_atr: 3 } schedule { cycle_interval: 5m cautious_hours: [0,1,2,22,23] cautious_size_penalty: 40% } }
Example: Mean Reversion
Buys oversold, sells back to mean. Best in ranging markets (low ADX).
strategy "Range Hunter" { timeframe: 15m symbols: ["ETHUSDT", "SOLUSDT"] indicators { rsi = RSI(14) bb = Bollinger(20, 2) atr = ATR(14) } entry when { rsi < 35 price < bb.lower adx < 25 // not trending fee_ratio_ok(25%) } exit when { rsi > 55 or price > bb.upper or trailing_stop(callback: 1%) } risk { max_position_pct: 4% stop_loss_atr: 1.5 take_profit_atr: 3 } }
Example: DCA + Grid
For non-ThunderScript modes, AiTrade also supports DCA (deterministic interval buys) and Grid (fixed-spacing rungs). Both are deterministic — no AI needed. Configure via the bot create form's Mode dropdown.
AI Supervisor
Every hour (configurable), the supervisor reviews each active bot's performance and optionally proposes a new ThunderScript version. It pulls:
- Last 24h trades, P&L, win rate, avg win/loss
- Per-symbol breakdown
- Last 5 versions' performance snapshots
- Top failing entry conditions
- Current market regime (volatile/trending/range)
- Your custom prompt (per-bot, max 500 chars)
It calls your bot's configured LLM with a structured prompt and parses a JSON response. If a valid ThunderScript is returned, it either auto-applies (default) or saves as a draft requiring your approval.
/system → AI Supervisor.
Auto-Revert
If a version loses >$500 with >5 trades in 24h, the engine auto-reverts to the best historical version. The new active version's baseline is reset, so subsequent checks measure from this point forward (no thrashing). A persistent notification + push alert explains exactly why.
Versioning
Every Save creates a new version. The runtime keeps a performance_snapshot attached:
| Field | Description |
|---|---|
total_pnl | Bot's lifetime P&L at version creation |
total_trades | Trades count at creation |
winning_trades | Wins at creation |
created_by | user, supervisor, or auto_revert |
Marketplace
Publish your strategies for the community. From the editor toolbar:
- Share — opens publish dialog. Title, description, tags, public toggle. Performance snapshot auto-attached.
- Export — downloads a
.tscriptfile you can store anywhere.
From the Bots panel right-click menu: Marketplace. Browse by sort (Downloads / Upvotes / Recent / Performance), search, filter by tags. Each strategy:
- One-click Import → bot creation form pre-filled
- Toggle Upvote (community ranking signal)
- Copy Share Link → embed anywhere
Embed in your blog
Two ways to share strategies on external sites:
| Method | URL Format |
|---|---|
| By marketplace ID | aitrade.thundera.eu/import?id=<uuid> |
| Embedded source | aitrade.thundera.eu/import?source=<base64>&name=My+Strategy |
Clicking the link opens AiTrade with the import flow ready: review source, pick wallet, set capital, create bot.
MCP / API Tools
AiTrade exposes the supervisor's tools as HTTP endpoints (and over MCP for AI agent integration):
| Endpoint | Purpose |
|---|---|
GET /api/ai-tools/strategy/:bot_id | Read current active ThunderScript |
POST /api/ai-tools/strategy/:bot_id/propose | Create a draft proposal |
GET /api/ai-tools/strategy/:bot_id/performance | Performance summary (window=hours) |
POST /api/ai-tools/strategy/:bot_id/revert | Manual revert to best |
POST /api/ai-tools/explain | Explain a specific bot decision |
FAQ
How is my capital protected?
Multiple layers. Each strategy has stop-losses (ATR-based or fixed-%). Bot-level max_daily_loss halts trading after a bad day. Auto-revert pulls back losing versions. Pre-AI veto pipeline blocks trades in extreme volatility, low-edge setups, and book-thin markets.
Do I need an LLM API key?
Not necessarily. AiTrade ships with system providers. You can also bring your own (BYO-AI) — your key, your billing, but full control. Configure in My LLMs.
What if the supervisor proposes a bad strategy?
Three safeguards: 1) The proposed script must compile + validate (syntax & semantics) before being saved. 2) Auto-revert kicks in if performance drops. 3) You can disable auto-apply per bot — every proposal becomes an approval request you must review.
Can I run multiple ThunderScripts on the same bot?
No — one bot, one active script. But you can create multiple bots on the same wallet, each with its own script. They share capital but operate independently.
How do I migrate from another platform?
If your existing strategy is logic-based, translating to ThunderScript is usually 10-30 minutes. Indicators map directly. Conditions become entry when / exit when. Risk parameters fit the risk block. Reach out via hello@thundera.eu for help.
Is testnet supported?
Yes — Binance testnet for spot and futures. Paper bots use real prices but place no real orders. Recommended for first-time strategies.
Glossary
| Term | Definition |
|---|---|
| ThunderScript | The DSL for defining trading strategies in AiTrade. |
| Cycle | One iteration of the engine loop. Runs every cycle_interval. |
| Veto Pipeline | Pre-AI checks (volatility, edge, depth) that block bad setups before LLM call. |
| AI Gate | Final LLM confidence check after all conditions pass. |
| Score | Number of true entry conditions (3-5). Drives position sizing. |
| Cautious Hours | UTC hours where rules are tightened (smaller size, higher confidence floor). |
| Dead Hours | UTC hours where no new entries are taken. |
| Supervisor | Autonomous AI that reviews performance and proposes script changes. |
| BYO-AI | Bring Your Own LLM. User-managed API key + endpoint. |
Changelog
v2.0 — May 2026
- AI Supervisor with approval workflow
- Strategy Marketplace + import/export
- Landing page
- iOS app v1.3+ (TradingView charts, ThunderScript editor, Live Activities)
v1.5 — April 2026
- ThunderScript DSL launched
- Auto-revert on performance degradation
- Tiered position sizing