DSL reference¶
The qkt strategy language, explained one construct at a time. Each page covers a single concept — what it does, every variant the parser accepts, examples for each, and what it pairs with.
If you want the one-page cheat sheet, see DSL grammar (one-pager). If you want to learn it properly, start at the top of this page and work down.
Structure of a strategy file¶
-
The STRATEGY block
The outer envelope:
STRATEGY name VERSION n, the SYMBOLS / RULES sections, what's required and what's optional. -
Streams: SYMBOLS
Declaring which markets your strategy listens to. Broker prefixes, symbols, timeframes, multiple streams.
-
LET and DEFAULTS
Naming values so you can reuse them. The two ways:
LET(per-strategy aliases) andDEFAULTS(action defaults).
Conditions — when to act¶
-
The WHEN clause
The "if" half of every rule. Edge-triggered vs level-triggered, combining conditions with AND/OR/NOT.
-
Indicators
Every indicator the parser knows — ema, sma, rsi, atr, vwap, macd, bollinger, donchian (highest/lowest), and the math helpers.
-
Expressions
Arithmetic, comparisons, account references (
account.equity), position references (POSITION.stream).
Actions — what to do¶
-
BUY / SELL / CLOSE / CANCEL / LOG
The action verbs. What each does, what they accept, how to combine them.
-
SIZING
Every way to size a position: fixed lots, percent of equity, fixed USD, risk-based, full-position close.
-
:material-bracket-arrow-down:{ .lg .middle } BRACKET
Atomic stop-loss + take-profit groups. Fixed prices, percent offsets, ATR-based, scale-out targets.
-
STACK pyramiding
Layered entries — one signal becomes N price-triggered orders. Time fences, custom per-layer sizing.
-
STACK_AT conditional stacks
Fire independent micro-trades when the primary leg's MFE crosses thresholds within time windows. Each stack tracks as its own leg with its own bracket.
Looping and composition¶
How qkt parses your strategy¶
When you run qkt parse strategy.qkt, the compiler walks the file in this order:
- Header —
STRATEGY name VERSION norPORTFOLIO ... - DEFAULTS (optional) — captures default values for all later actions
- SYMBOLS — declares every stream the strategy listens to
- LET (optional) — name-bound expressions for reuse
- RULES — pairs of
WHEN <condition> THEN <action> - FOR EACH (optional, end of file) — macro expansion that emits additional rules
Errors are line/column tagged. A typo in WHEN or a missing THEN produces a clear error pointing to the line, not a cryptic stack trace.
Quick legal/illegal¶
-- legal: minimum valid strategy
STRATEGY hello VERSION 1
SYMBOLS
btc = BACKTEST:BTCUSDT EVERY 1m
RULES
WHEN btc.close > 0
THEN LOG INFO "tick received"
-- illegal: SYMBOLS must come before RULES
STRATEGY hello VERSION 1
RULES
WHEN btc.close > 0 THEN BUY btc
SYMBOLS
btc = BACKTEST:BTCUSDT EVERY 1m
-- parse error: undefined stream 'btc' in RULES (line 3)
-- illegal: missing VERSION
STRATEGY hello
SYMBOLS ...
-- parse error: expected VERSION after strategy name (line 1)
The parser is strict by design. A strategy file that compiles is one where the engine knows exactly what to do — there's no "interpret loosely and hope" mode.
See also¶
- Examples — every DSL feature used in a real strategy
- Recipes — task-oriented walkthroughs
- CLI commands —
qkt parse,qkt backtest, etc.