2 Commits (190e395d66d57542ceeced02eabe243b30996504)

Author SHA1 Message Date
I Luk Kim 784c581f19 Enhance backtest engine: v11 scoring, selector expansion, snapshot store improvements
Extends selector with new scoring model support, adds execution
enhancements, and improves snapshot store loading and split handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 months ago
I Luk Kim 2f4d9f61f7 feat: implement Phase 4 -- event-driven backtester
Full backtesting engine that reads Parquet snapshots and simulates a
swing-trading strategy with no look-ahead bias.

## New modules (libs/backtest/)
- domain.py: All Pydantic v2 models (Candidate, PlannedOrder, FilledTrade,
  OpenPosition, DailyPortfolioState, MetricsBundle, BacktestConfig, etc.)
- calendar.py: Thin wrappers over time_utils + reaction_date
- manifests.py: Config load/deep-merge/validate, run-ID generation
- metrics.py: 21 pure-function metrics (no pandas, stdlib statistics only)
- selector.py: build_candidate(), rank_candidates() (score↓ ADV↓ symbol↑)
- allocator.py: 7-gate run_entry_gates(), ATR stop, floor() shares
- execution.py: simulate_entry/exit(), update_trailing_stop() (ratchet-up only)
- splits.py: Walk-forward windows, year/regime split utilities
- snapshot_store.py: Sync load() → asyncio.run(_async_load()), no look-ahead
- artifacts.py: Full run-dir writer (Parquet, CSV, JSON)

## App modules (apps/backtester/)
- run.py: BacktestRunner (exit-first→entry simulation, 25% kill switch) + CLI
- replay.py: Double-run determinism checker

## Config files
- configs/backtest/defaults.json: Base strategy defaults
- configs/experiments/baseline_v1.json: First experiment manifest

## Tests: 142 new tests, all passing
- 132 unit tests (no DB/HTTP required)
- 8 integration tests (synthetic SnapshotStore)
- 3 backtest determinism/replay tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 months ago