Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.quanux.org/llms.txt

Use this file to discover all available pages before exploring further.

Crucible is QuanuX’s backtesting engine, written in C++20. It executes your Python and Cython strategies at native speeds by bypassing standard memory copies, SQL overhead, and Python object serialization entirely. Under the hood, Crucible uses the native duckdb::Appender API to inject vectorized blocks of trade data directly into DuckDB’s in-memory columnar engine, with the Python boundary bridged exclusively via Cython. The result is throughput approaching 100x that of traditional pandas-based backtesters. You control Crucible entirely through quanuxctl. The engine runs as an isolated background process so it does not block your terminal or compete with other research workloads.

Before you start

Crucible expects a Foundry-generated test harness to exist at server/backtests/<strategy>_v<version>/ before you run start. If that directory is missing, generate your strategy with the Foundry first, or create the harness manually following the expected layout.
Crucible writes its state to server/backtests/<strategy>_v<version>/crucible.duckdb. Do not delete or modify this file while the engine is running — doing so will produce a fatal segmentation fault in the C++ appender.

Backtesting workflow

1

Start the engine

Launch a Crucible simulation for your strategy. Replace my_strategy with your strategy name and supply the version string that matches the Foundry-generated harness.
quanuxctl crucible start my_strategy --version 1.0.0
Crucible forks from the terminal via os.setsid() and writes the OS process ID to /tmp/quanux_crucible.pid. The simulation runs entirely in the background.
2

Monitor resource usage

Check CPU and memory consumption while the simulation is running.
quanuxctl crucible status
status reads the PID from /tmp/quanux_crucible.pid and uses psutil to return real-time CPU load and RAM consumption inside the C++ 128-byte aligned memory pools.For live streaming telemetry, subscribe to the NATS topic directly:
nats sub "sys.crucible.report.my_strategy"
3

Pull the metrics report

Extract the instantaneous metrics payload from the running engine.
quanuxctl crucible report my_strategy
report bypasses the Python pandas pipeline entirely. It loads the compiled Cython extension from QuanuX-Backtesting-Engine/python and calls the native DuckDBFeeder::get_metrics_json() method directly through the C++ DuckDB API, reading from the live .duckdb state file.You can also target a specific version:
quanuxctl crucible report my_strategy --version 1.0.0
4

Stop the engine

Gracefully terminate the simulation when you are done.
quanuxctl crucible stop
stop sends a POSIX SIGTERM to the engine PID and waits five seconds. If the process has not exited after that window, it sends SIGKILL to halt runaway algorithms.

L3 execution metrics

Unlike basic backtesters that only track P&L, Crucible enforces institutional-grade L3 (Market By Order) metric collection natively. Every trade record is stored as a CrucibleTrade struct aligned to 128 bytes for optimal CPU cache line saturation.
MetricDescription
Latency Slippage (bps)Slippage measured in basis points, calculated automatically from execution delay relative to the signal timestamp.
Queue Position at EntryEstimated position in the order queue, determined by simulated volume-ahead tracking in the FifoMatcher.
MAEMaximum Adverse Excursion — the worst intra-trade drawdown from entry price, tracked per tick.
MFEMaximum Favorable Excursion — the best intra-trade unrealized gain from entry price, tracked per tick.
MAE and MFE together give you a clear picture of whether your exit logic is leaving money on the table (high MFE, low capture) or cutting losses late (high MAE). Review these alongside win rate before promoting a strategy to C++.

Backtest state files

Crucible stores all persistent state in the following locations:
PathContents
server/backtests/<strategy>_v<version>/crucible.duckdbLive DuckDB state file written natively by the C++ engine. Contains all CrucibleTrade records for the current run.
/tmp/quanux_crucible.pidOS process ID of the currently running simulation. Cleared automatically on stop.
You can query the .duckdb file directly with the DuckDB CLI after stopping the engine for ad-hoc analysis:
duckdb server/backtests/my_strategy_v1.0.0/crucible.duckdb \
  "SELECT symbol, COUNT(*) as trades, AVG(latency_slippage_bps) as avg_slip FROM crucible_trades GROUP BY symbol"

Architecture note

Crucible’s CrucibleTrade struct is explicitly aligned to 128 bytes to maintain memory locality inside CPU L1 and L2 data caches. If you are extending Crucible and modify this struct, you must propagate the changes down to the Cython header at QuanuX-Backtesting-Engine/python/quanux_crucible.pxd. Mismatches between the C++ struct and the Cython header produce fatal segmentation faults at runtime.