| name | quaq-strategy |
| description | Use when composing, editing, validating, debugging, or running quaq trading strategies. Triggers: creating strategy TOML files, wiring node graphs, configuring backtests, adding indicators/signals/operators/trade blocks, fixing validation errors (E001-E025), choosing data sources (CSV, Parquet, Binance API), setting up outputs/exports, adding quant analysis nodes, running backtest/validate/explain/sweep commands, or any task involving the quaq strategy engine pipeline.
|
Quaq Strategy Composition
Quaq is an agent-native node-graph engine with 150+ node kinds. You compose strategies as TOML: declare nodes, wire edges, validate, run, iterate.
Agent Workflow
- Write
.toml strategy file
- Validate:
cd core && zig build run -- validate path/to/strategy.toml
- Fix any errors, re-validate until clean
- Backtest:
cd core && zig build run -- backtest path/to/strategy.toml
- Analyze results, iterate on hypothesis
Other commands: explain (inspect graph), sweep (parameter search), api (JSON stdin).
TOML Sections
[strategy]
version = "0.1"
name = "Strategy Name"
[data]
path = "./data/BTCUSDT_1m.csv"
symbol = "BTCUSDT"
timeframe = "1m"
[run]
initial_cash = 10000.0
fee_bps = 7.0
slippage_bps = 2.0
warmup_bars = 50
max_bars = 0
[[nodes]]
[[edges]]
[outputs]
log_level = "basic"
[[outputs.series]]
[[outputs.markers]]
[exports]
trades_csv = true
metrics_json = true
chart_json = true
out_dir = "./out"
Data Sources
Local CSV (default): Set path to a .csv file.
Local Parquet: Set path ending in .parquet or .pq. Auto-detected by extension.
Binance API: Set dataset = "binance" with no path. Optional fields:
[data]
dataset = "binance"
symbol = "BTCUSDT"
timeframe = "1m"
market = "spot"
start_date = "2024-01-01"
end_date = "2024-06-01"
Node-Edge Wiring
Nodes connect through typed ports via edges:
[[edges]]
from = "source_node.output_port"
to = "target_node.input_port"
Port types: f64 (float), bool (boolean), ts (timestamp). Mismatched types cause E011.
Core Flow Pattern
data.bars --> indicators --> operators/comparisons --> trade.basic
data.bars outputs: ts, open, high, low, close, volume.
Most indicators take x (f64) and output y. Exception: ind.atr takes high, low, close.
Comparison nodes (op.gt, op.lt, op.eq) accept b_const parameter for constant thresholds instead of wiring a second input.
Combine bool signals with op.and / op.or before feeding to trade.
Formula Blocks (Lightweight Custom Logic)
Use logic.formula for custom arithmetic on existing signals without writing Zig code:
[[nodes]]
id = "composite"
kind = "logic.formula"
expr = "(a - 50) * 0.01 + b"
Wire up to 4 inputs (a, b, c, d). Supports: +, -, *, /, unary -, parentheses, float literals.
Use logic.logical_formula for custom boolean conditions:
[[nodes]]
id = "custom_cond"
kind = "logic.logical_formula"
expr = "a AND (b OR NOT c)"
Use logic.constant for fixed threshold values:
[[nodes]]
id = "threshold"
kind = "logic.constant"
value = 0.5
Auxiliary Data Nodes
For futures strategies, these nodes provide additional market data:
data.spot_close -- spot close price (output: y, f64). Useful for basis/premium calculations.
data.funding_rate -- funding rate (output: y, f64). Negative = shorts paying longs (bullish signal).
[[nodes]]
id = "funding"
kind = "data.funding_rate"
[[nodes]]
id = "spot"
kind = "data.spot_close"
Wire their y output to comparisons or formulas like any other f64 signal.
trade.basic Wiring
Five required price inputs -- always wire these:
[[edges]]
from = "bars.ts"
to = "trader.ts"
[[edges]]
from = "bars.open"
to = "trader.open"
[[edges]]
from = "bars.high"
to = "trader.high"
[[edges]]
from = "bars.low"
to = "trader.low"
[[edges]]
from = "bars.close"
to = "trader.close"
Signal inputs (wire at least one):
enter_long (bool) -- long entry signal
exit_long (bool) -- long exit signal
enter_short (bool) -- short entry signal
exit_short (bool) -- short exit signal
atr (f64) -- required when stop_mode = "atr" or tp_mode = "atr"
Parameters:
[[nodes]]
id = "trader"
kind = "trade.basic"
side = "long"
qty_mode = "percent_equity"
qty_value = 0.10
stop_mode = "pct"
stop_value = 0.02
tp_mode = "pct"
tp_value = 0.04
cooldown_bars = 0
allow_reentry = false
Outputs Configuration
Series
[[outputs.series]]
id = "equity"
label = "Equity Curve"
from = "__portfolio.equity"
panel = "equity"
dtype = "f64"
style = "line"
Built-in portfolio series: __portfolio.equity, __portfolio.drawdown.
Wire any node output as a series: from = "sma_fast.y".
Markers
[[outputs.markers]]
kind = "trade_entry"
Quant Nodes (Post-Run Only)
Quant nodes (P0/P1/P2) execute after the backtest, not in the bar loop. Wiring a quant node output into a bar-loop node produces E022_POST_RUN_ONLY.
Declare quant nodes and wire their inputs from bar-loop data, but never wire their .y output to indicators, operators, or trade.basic.
See references/nodes.md for the full quant node catalog (P0: metrics/stats/sim, P1: models/regime, P2: advanced).
Validation Errors
| Code | Meaning |
|---|
| E001 | Invalid node ID (empty or illegal chars) |
| E002 | Duplicate node ID |
| E003 | Unknown node kind |
| E004 | Missing required parameter |
| E005 | Wrong parameter type |
| E006 | Malformed edge from/to format |
| E007 | Unknown source node in edge |
| E008 | Unknown target node in edge |
| E009 | Unknown output port on source node |
| E010 | Unknown input port on target node |
| E011 | Type mismatch between connected ports |
| E012 | Cycle detected in node graph |
| E013 | No data.bars node found |
| E014 | Multiple data.bars nodes |
| E015 | No trade.basic node found |
| E016 | Unconnected required port |
| E017 | Missing signal port on trade node |
| E018 | Parameter out of valid range |
| E019 | Negative fee/slippage value |
| E020 | Incompatible mode combination |
| E021 | Data requirement not met |
| E022 | Quant node wired into bar loop |
| E023 | Missing symbol (required for Binance) |
| E024 | Missing timeframe (required for Binance) |
| E025 | Invalid date format (expected YYYY-MM-DD) |
References
references/nodes.md -- full node catalog with all ports, parameters, and types
references/examples.md -- complete strategy TOML examples with wiring patterns
Related Skills
quaq-extend -- extending the engine with new block types and custom indicators
quaq-ingest -- data ingestion, format conversion, and ETL pipelines