Files
vault-dash/docs/BT-002_HISTORICAL_OPTIONS_SNAPSHOT_PROVIDER.md
2026-03-27 18:31:28 +01:00

67 lines
2.5 KiB
Markdown

# BT-002 Historical Options Snapshot Provider
## What shipped
BT-002 adds a point-in-time historical options snapshot provider for backtests.
The new provider lives in `app/services/backtesting/historical_provider.py` and plugs into the same `BacktestService` / engine flow as the existing synthetic provider.
## Provider contract
The snapshot provider exposes the same backtest-facing behaviors as the synthetic provider:
- load underlying daily closes for the scenario window
- validate `ProviderRef`
- open positions at scenario start using only the entry-day snapshot
- mark open positions later using the exact same contract identity
This lets backtests swap:
- synthetic pricing: `synthetic_v1 / synthetic_bs_mid`
- observed snapshot pricing: `daily_snapshots_v1 / snapshot_mid`
## Contract-selection rules
The provider uses explicit, deterministic, point-in-time rules:
1. filter to the entry-day option chain only
2. keep contracts with expiry at or beyond the target expiry date
3. choose the nearest eligible expiry
4. within that expiry, choose the nearest strike to the target strike
5. on equal-distance strike ties:
- puts prefer the higher strike
- calls prefer the lower strike
These rules avoid lookahead bias because later snapshots are not consulted for entry selection.
## Daily mark-to-market rules
After entry, the provider marks positions using the exact same `contract_key`.
It does **not** silently substitute a different strike or expiry when the original contract is missing.
Current fallback policy:
1. use the exact same contract from the same-day snapshot
2. if missing before expiry, carry forward the previous mark for that same contract and emit a warning
3. if the valuation date is at or after expiry, settle to intrinsic value and close the position
## Data-quality tradeoffs
The current BT-002 slice intentionally keeps the data model simple:
- snapshots are assumed to provide a precomputed daily `mid`
- the provider does not currently derive mids from bid/ask pairs
- missing exact-contract marks are explicit warnings, not silent substitutions
- the engine currently still supports `continuous_units` sizing for snapshot-backed runs
## Known limitations / follow-up
This slice does **not** yet include:
- file-backed or external ingestion of real historical snapshot datasets
- listed-contract rounding / contract-size-aware position sizing
- persistent run-status objects beyond template-level warnings
Those follow-ups should remain explicit roadmap work rather than being implied by BT-002.