Appearance

Personalize your experience

Mode
Accent Color
Direction
Strategy DSL — The Engine

Strategy DSL — The Engine

Reference

The native C++ engine (dslx) that parses, validates, backtests and runs strategy DSL: its modules, the catalog the editors are generated from, indicator sharing, the command line, and how the platform calls it.

One engine

Every -DSL execution — a builder backtest, an API backtest, a deployed strategy — runs in apps/hft/dsl. There is no second implementation in to from it. The browser only validates (with a mirror of the parser's checks) and compiles the builder's state into the engine's JSON.

ModuleResponsibility
dsl/, the (JSON paths, suggestions, warnings) and the never-true checks
indicators/The catalog: 94 indicators with their parameters, outputs, ranges and kernels; the CustomFormula language; QuaScript indicators (linked from packages/quascript)
engine/SeriesTable (higher timeframes, , offsets) and the — positions, stops, targets, layers, , costs,
cache/Indicator outputs shared between strategies over the same candles
scheduler/ api/Work-stealing pool; single runs, batches and matrices of (, candles) jobs
live/StrategyHub ( strategies on shared feeds) and the --serve server
io/ cli/Candle loading (CSV / JSON), result JSON, the dslx_cli command

The catalog is the source of truth

Each indicator is registered once, in src/indicators/library.cpp, together with its editor . dslx_cli --catalog exports it and scripts/sync-catalog.mjs writes it into the web app, where the form, node and JSON editors, the validator and these knowledge-base reference tables are generated from it. Adding an indicator to the engine therefore adds it everywhere; a CI check (--check) fails if the web copy is stale.

Computing series once

Before stepping bars, the collects every distinct operand (indicator, parameters, output, timeframe, candle type) and computes each series once over the whole history. Offsets read the same series shifted; a higher-timeframe operand is computed on resampled bars and aligned so a bar only sees that timeframe's closed bars.

The indicator cache is keyed by the candle set, timeframe, , indicator and parameters, and is single-flight: strategies in one batch (or on one feed) that need (20) wait for one computation instead of repeating it. On the live server, 1,000 strategies reading the same on a symbol compute it once per bar.

Execution shapes

ShapeTypeDescription
run1 strategy × 1 candle setA single backtest.
runBatchN strategies × 1 candle set on the pool, one shared indicator cache — the for parameter sweeps.
runMatrixN (strategy, candles) jobsIndependent jobs in ; a job that throws returns its error without stopping the others.
live hubmany strategies × live feedsStrategies and removed at any time, when their feed confirms a bar. See “ Engine”.
ℹ
Note: are deterministic: the same document and candles give byte-identical results on any count, and a streamed bar by bar makes the same as its backtest.

Command line

dslx_cli
# validate (errors and warnings with JSON paths)
dslx_cli --validate -s strategy.json

# backtest one strategy, or a batch over the same candles
dslx_cli -c candles.json -s a.json -s b.json -o results.json

# the vocabulary the editors use (indicators, operators, timeframes, limits)
dslx_cli --catalog

# the series and params a QuaScript indicator exposes
dslx_cli --quascript my_indicator.qs

# the long-running engine: live strategies + backtests over one connection
dslx_cli --serve --stdio
dslx_cli --serve --socket /tmp/dslx.sock --ws-port 8095 --token "$DSLX_TOKEN"

How the platform calls it

CallerPath
Builder backtest step, API backtestsbot-api dsl.runner → runDslxBacktest → a backtest request on the shared engine (dslx_cli --serve --stdio, one process). QUATICK_DSLX_SPAWN=1 runs one process per backtest instead.
Deployed strategiesStrategyRunnerService → EngineStrategyHost → the same engine ; market from the market-data hub
Separate engine hostSet DSLX_ENGINE_URL=ws://host:port (and DSLX_TOKEN) to use a running engine over instead of a child process
Binary locationQUATICK_DSLX_BIN, else apps/hft/dsl/build/dslx_cli found upward from the API

Building and testing

build and checks
cmake -S apps/hft/dsl -B apps/hft/dsl/build -DCMAKE_BUILD_TYPE=Release
cmake --build apps/hft/dsl/build -j
(cd apps/hft/dsl/build && ctest --output-on-failure)

node apps/hft/dsl/scripts/sync-catalog.mjs --check     # web catalog matches the engine
npx tsx apps/hft/dsl/scripts/verify-builder.mts        # presets compile, validate and run
npx tsx apps/hft/dsl/scripts/verify-conditions.mts     # random condition trees, engine vs client vs reference
npx tsx apps/hft/dsl/scripts/verify-bots.mts           # every bot in apps/hft/dsl/bots
node apps/hft/dsl/scripts/verify-serve.mjs 500 600     # the live server end to end

See also

Related articles

  • Strategy DSL — Conditions That Can Never Be True

    Coding / Strategy DSL

    Which conditions the engine and the editors reject because no bar could ever satisfy them, how the check works, what it deliberately does not reject, and…

  • Strategy DSL — Execution Model

    Coding / Strategy DSL

    What the engine does on every bar: protective exits, exit signals, entries, layers and re-entries, sizing and costs, and where every statistic in the result…

  • Strategy DSL — Language Reference

    Coding / Strategy DSL

    The strategy JSON the C++ engine executes: every top-level block, signals and flow, operands and the 94-indicator catalog, the eleven operators, and the…

  • Strategy DSL — The Live Engine

    Coding / Strategy DSL

    How deployed DSL strategies run: one engine process, one connection per client, shared bar feeds and indicators per symbol and timeframe, the request…

  • Writing DSL by Hand

    Coding / Strategy DSL

    Authoring strategy JSON directly: the minimum document, small constructors that keep it readable, validating before anything runs, generating variants, and…

  • Engines — Python vs C++

    Automation / Predefined Strategies

    Two independent implementations of the same grid semantics, consuming the same config and the same command channel. The choice is a runtime choice, not a…

  • Evaluation Performance

    Coding / Performance

    Why a backtest is slow and what actually fixes it: condition ordering, indicator reuse, incremental computation, and the difference between an O(n) and an…

  • Step 1 — Particulars

    Automation / Predefined Strategies / Wizard Steps

    Identity of the strategy: where it trades, what it trades, which way it leans, and which engine runs it. These fields are fixed once deployed.

  • Strategy Builder — Overview

    Automation / Strategy Builder

    A nine-step wizard for designing, testing and deploying automated trading strategies without writing code. Conditions are built from 100+ indicators,…

Browse all knowledge base articles →