Expand description
Core vectorized portfolio simulation engine (Rust + Polars long format).
This crate provides the foundation for QuantWave’s backtesting capabilities under epic quantwave-gwx / task quantwave-1hr + quantwave-ug9t (streaming simulation + full batch-vs-streaming parity verification).
§Batch vs Streaming Parity (quantwave-ug9t)
BacktestEngine::run/backtest_simple_bool_signal: pure vectorized batch path (pre-computed signals in DF column; fast for research sweeps). Signal f64 value now interpreted as signed exposure (0=flat, >0=long, <0=short units).run_streaming_simulation: streaming path driven by anyNext<&Bar, Output=StrategySignal>generator (closer to live trading loop, supports rich metadata from features/PA/regimes).- Shared internal
run_simulationcore guarantees identical execution semantics (costs, fills, equity, trade recording) when fed equivalent signals. - Mandatory parity tests (in this file) enforce equity curves, trade counts/pnls/stats match within documented tolerance for strategies using regime filters + feature thresholds + rich PA structs (pole height sizing).
Design principles (per project AGENTS.md):
- Long-format multi-symbol first-class (symbol, timestamp, ohlcv, signals).
- Ready for rich Struct signals (e.g. from future PA detectors containing
pole_height,strength, etc. for dynamic sizing/conviction). - Basic realistic execution: commission + slippage.
- T+1 execution via
BacktestConfig.execution_delay(SameBardefault,NextBarfor polars-backtest-style next-bar fills — quantwave-cr6v.8). - Stop-loss / take-profit / trailing via
BacktestConfig.stop_config(RaptorBT-inspired clean-room — quantwave-cr6v.9). - Struct
signal_colauto-parse with pole_height sizing (quantwave-cr6v.11). - Param sweep helper
run_param_sweep/SweepVariant(quantwave-cr6v.12). - Criterion benches vs naive row-loop (
benches/backtest_vs_naive.rs, cr6v.13). - Walk-forward OOS + trade bootstrap Monte Carlo (cr6v.14).
- Cross-sectional factor panel rank/long-short (sigc-inspired, cr6v.15).
LiveBridgetrait for future Nautilus adapter (LGPL — cr6v.16).- Vectorized foundation now; streaming parity (Next
from quantwave-core) and full rich PA/ML integration in sibling tasks (ug9t, 06sz). - All new code will eventually carry batch-vs-streaming proptests.
Sources (recorded per AGENTS + 366 research):
- Primary alignment: Yvictor/polars-backtest (native Polars long-format multi-symbol with realistic costs/execution model).
- Vectorized portfolio concepts (clean-room): vectorbt (Apache-2 + Commons Clause) patterns for signal->position->pnl vectorization; RaptorBT analogs.
- Rich signal metadata readiness: MQL5 PA series (Parts 69-70, 67) via quantwave-366 notes — structured outputs (pole_height etc.) for backtester consumption, not just viz. quantwave-06sz complete for integration (batch exposure + streaming StrategySignal.metadata + verified parity with pole sizing + regime/feature filters; batch native Struct col is extension point).
- Current thin steel-thread: docs/examples/notebooks/strategy_backtest.py (synthetic + SuperTrend struct only; no PnL/costs/trades yet).
- Parity framework pattern: modeled on quantwave-core/src/test_utils.rs
check_batch_streaming_parity+ indicator proptests (e.g. kinematic_kalman.rs). - Regime: quantwave-core/src/regimes/tar.rs (TAR for simple filter in parity test).
- Features: quantwave-core/src/features/cyber_cycle.rs (CyberCycleFeatureExtractor).
- Synthetic PA pole for test (non-production): concept from MQL5 PA + Ehlers turning points (see artifacts/anticipating_turning_points*.txt); recorded here per AGENTS “if no source validate”.
Universal Indicator / Next
Tolerance policy (documented for ug9t verification):
- Equity curve values: relative + abs epsilon 1e-8 (float accum).
- Trade count: exact.
- PnL / final equity / stats: 1e-6 tolerance (costs/rounding).
- Prices in trades: 1e-8.
- Failure modes: unsorted data, NaNs in prices, generator state drift, mismatched exposure semantics, open position at end handling, regime/feature init bias on first bars (warmup NaNs tolerated in features).
NO root-level tests/ dirs created. Tests live inside this crate (#[cfg(test)]). Respects quantwave-core/tests/ rule for gold-standard indicator work.
Structs§
- Backtest
Config - Configuration for a backtest run.
- Backtest
Engine - Core vectorized engine (MVP).
- Backtest
Report - Bundle of raw backtest output plus computed analytics.
- Backtest
Result - Rich result bundle returned by the engine (Polars DataFrames + summary stats).
- Bar
- A minimal bar struct for driving streaming simulation (timestamp + close sufficient for price-action + feature driven strategies in MVP).
- BpsCommission
Model - BpsSlippage
Model - Cost
Model - Basic execution cost model.
- Cross
Sectional Config - Factor panel long/short configuration.
- Equity
Point - Per-bar equity snapshot (for the equity curve DF).
- Fixed
PerShare Commission Model - Initial
Risk Position Sizer - Rich-Metadata-Aware Position Sizer (n1yc.1). Inspired by QF-Lib InitialRiskPositionSizer + Signal.fraction_at_risk. Supports PA structs via “pole_height_atr” or explicit “fraction_at_risk” in StrategySignal.metadata (populated by 06sz PAEvent integration and feature extractors).
- Live
Signal Event - One exportable decision event for external live engines.
- Monte
Carlo Config - Bootstrap simulation settings.
- Monte
Carlo Path Summary - Monte
Carlo Return Config - Monte
Carlo Summary - Summary of bootstrap terminal equity distribution.
- PAEvent
- Simple struct for rich PA detector outputs (placeholder/stub for integration; full detectors in future PA work). Can be turned into StrategySignal or serialized into Polars Struct column for batch runs. Per quantwave-06sz.
- Performance
Metrics - Summary performance statistics for a completed backtest run.
- Recording
Live Bridge - In-memory stub for tests and notebooks — records events, no network I/O.
- Square
Root Market Impact Slippage - Stop
Config - Fixed / trailing stop and take-profit knobs (RaptorBT-inspired, clean-room).
- Strategy
Signal - Rich signal output produced by a
Next<&Bar, Output = StrategySignal>generator. Enables the streaming simulation mode (quantwave-ug9t) while carrying rich metadata (pole height sizing, regime, features) into Trade records. - Sweep
Variant - One grid point: parameter values and the signal column to backtest.
- Tearsheet
Options - Options for HTML tear sheet rendering.
- Trade
- A completed (or open) trade record. Rich enough for later PA metadata.
- Walk
Forward Config - Rolling walk-forward configuration (bar counts on the unique timestamp index).
Enums§
- Backtest
Error - Errors from the simulation engine.
- Execution
Delay - When a signal observed at bar t may be executed (clean-room polars-backtest T+1).
- Execution
Model - Execution model config (n1yc.2/3). Supports simple + high-fidelity with realistic models.
- Live
Bridge Error - Errors from live bridge adapters.
Traits§
- Commission
Model - Pluggable commission model (n1yc.2, QF-Lib inspired).
- Live
Bridge - Trait implemented by future live adapters (e.g. a separate
quantwave-nautiluscrate). - Slippage
Model - Pluggable slippage model (n1yc.2/3).
Functions§
- apply_
signal_ modifiers - Apply optional entry filter (false → flat) and size multiplier to a raw signal.
Shared semantics for batch
run()and streaming parity tests (quantwave-cr6v.3). - assign_
long_ short_ exposure - Assign signed exposure from cross-sectional factor ranks per timestamp.
- backtest_
simple_ bool_ signal - Convenience function for the most common “simple boolean signal” use case on synthetic or small data (exactly as required for quantwave-1hr MVP).
- monte_
carlo_ return_ paths - monte_
carlo_ trade_ bootstrap - Bootstrap closed-trade PnLs with replacement; return terminal equity stats.
- neutralize_
factor - Demean a factor within groups (e.g. sectors or timestamps).
- parse_
struct_ signal_ row - Parse one Polars Struct signal row into exposure + metadata (quantwave-cr6v.11).
- pole_
height_ to_ exposure - Map PA pole height to exposure units (matches ug9t streaming parity test).
- render_
tearsheet_ html - Render a self-contained HTML tear sheet from a completed backtest report.
- run_
cross_ sectional_ backtest - Rank factor panel → exposure column → multi-symbol backtest report.
- run_
param_ sweep - Run backtests for each variant and return a param × metrics DataFrame.
- run_
streaming_ simulation - Run simulation in streaming mode driven by a Next
signal generator. The generator receives &Bareach step (price + ts) and returnsStrategySignal(exposure for sizing + rich metadata e.g. pole_height). - run_
walk_ forward - Run walk-forward OOS backtests; returns fold × metrics DataFrame.
- run_
walk_ forward_ optimize - Run walk-forward optimization: sweep on train fold, pick best by objective, backtest OOS.
- single_
param_ variants - Build variants for a single-parameter grid (e.g.
hurst_period→ signal columns). - winsorize_
factor - Clip outliers in a factor per timestamp beyond the given percentiles (0.0 to 1.0).
- zscore_
factor - Cross-sectional z-score (demean and divide by std deviation per timestamp).