-
Notifications
You must be signed in to change notification settings - Fork 0
Backtesting
Backtests let you validate the strategy offline with deterministic inputs and configurable friction. The engine lives in src/trading_system/backtest/__init__.py and is invoked through the CLI.
poetry run ts backtest run \
--config configs/sample-config.yml \
--start 2018-01-01 \
--end 2024-09-23 \
--output reports/backtests/baseline \
--label baselineOutputs:
-
metrics.json– strategy-level statistics. -
equity_curve.parquet– daily NAV, drawdowns, returns. -
trades.parquet– fills with timestamps, direction, size, slippage, commission. -
chart.html– optional Plotly equity curve ifbacktest.include_chartis true.
Compare two runs with:
poetry run ts backtest compare \
--baseline reports/backtests/baseline \
--candidate reports/backtests/new-signalsmetrics.json is stable and human-readable. Key fields:
-
total_return,cagr– compound growth over the requested window. -
volatility,sharpe,sortino– risk-adjusted performance using annualisation frombacktest.trading_days_per_yearandbacktest.annual_risk_free_rate. -
max_drawdown,hit_rate,turnover_total,turnover_average. -
rebalance_events,trades_executed,slippage_cost.
Use ts observability manifest --run reports/backtests/<run> to confirm the manifest recorded each artifact and hash.
To avoid overfitting:
- Split history into in-sample (70–80%) and out-of-sample (20–30%) segments.
- Iterate on strategy parameters only within the in-sample period.
- Lock parameters, run a single OOS backtest, and accept/reject based on pre-defined success criteria (Sharpe ≥ target, drawdown ≤ guardrail, etc.).
- If the OOS run fails, reset to hypothesis stage—do not tweak on OOS data.
- Perform rolling walk-forward tests (e.g., 2-year IS, 6-month OOS) once the base strategy is stable. The preprocessor and risk modules are deterministic, so you can automate these loops in notebooks.
- Align backtest rebalances with
rebalance.cadenceto reflect operational behaviour.
-
backtest.slippage_pct(default 0.1%) applies per trade by shifting execution prices. -
backtest.commission_per_tradeapplies a fixed commission per order. -
backtest.initial_cashsets the starting portfolio value; adjust for realistic brokerage balances.
⚠️ Caution: Higher Sharpe in backtests does not guarantee real-world performance. Bias creeps in via survivorship errors, data snooping, and parameter hunts. Lock down your data provenance (see Data-and-Provenance), keep hypothesis notes, and require live/paper validation before trading capital.
The project’s learning plan (docs/trading guid book/Quantitative Trading Learning & Implementation Plan.pdf) condenses risk-adjusted metrics, validation checklists, and monitoring practices. Use it alongside this page when designing new strategies.
Trading System Wiki © 2025 · MIT License · https://github.com/aryeko/trading-system