This repository is a production-style Python pipeline for listed-options surface construction, local-vol derivation, pricing, and hedging analysis.
It turns representative option quotes into arbitrage-free eSSVI total-variance surfaces, derives Dupire local volatility, prices with a Crank-Nicolson PDE solver, and validates selected benchmark contracts with Monte Carlo.
The public evidence surface is a checked-in canonical sample for SPY, QQQ, and IWM, with report bundles, tables, figures, benchmark profiles, and metadata covering 2025-04-03 through 2025-04-17.
It matters because the repo is reviewable end to end: model construction, numerical validation, and historical hedging evidence are all visible in one public codebase.
- Quickest reviewer path: canonical
SPYreport bundle with11trade dates,194fitted slices,7summary tables,12figures, and all4stored SPY benchmark regimes. - Full checked-in evidence index: data/live_smoke/results/README.md for the cross-symbol sample covering
SPY,QQQ, andIWM. - Benchmark sample set: data/live_smoke/results/benchmarks for the selected PDE-vs-MC regime profiles referenced by the canonical bundles.
| Item | Value |
|---|---|
| Symbols | SPY, QQQ, IWM |
| Evidence window | 2025-04-03 through 2025-04-17 |
| Benchmark rows | 444 |
| Raw ` | PDE - MC |
| Statistically significant PDE-vs-MC breaches | 0 |
Aggregate median abs_err_pde_mc |
0.010321921420370916 |
| Dense-grid arbitrage violations | calendar=0, density / butterfly=0 |
| Hedging evidence | 1d, 5d, 10d horizons with transaction costs and turnover |
The core objective is to turn listed-option quotes into a smooth, arbitrage-free state representation that is usable for pricing and hedging. The repo does not stop at fitting an implied-volatility surface. It also enforces static no-arbitrage, derives local volatility from the fitted surface rather than raw quotes, validates the numerical pricer against Monte Carlo on selected benchmark contracts, and checks hedge behavior historically with transaction costs included.
The end product is a reproducible report bundle with stored tables, figures, benchmark profiles, and metadata, rather than a notebook-only result.
snapshot / representative quotes: filter option NBBO quotes in the15:40:00to15:50:00America/New_York window, require at least3valid observations with one near15:45:00, and build representative option and underlying mids/spreads.forward / parity cleaning: pair calls and puts by expiry, estimate forward and discount terms with robust put-call-parity regression, and keep one OTM implied-vol point per strike/expiry.arbitrage-free eSSVI surface fit: calibrate eSSVI in total-variance space and enforce dense-grid calendar and density/butterfly checks before local-vol generation.Dupire local vol derivation: compute local volatility from the smooth fitted surface, and record unstable local-vol points explicitly instead of treating them as trusted diagnostics.PDE pricing: price options with a backward Crank-Nicolson PDE solver in log-spot.Monte Carlo validation: reprice selected stable OTM benchmark contracts with Monte Carlo, retain MC uncertainty, and only tag breaches that remain material after reruns.historical transaction-cost-aware hedging: compare Black-Scholes delta and local-vol delta over1d,5d, and10dhorizons with cash accrual, turnover, and transaction-cost accounting.report bundle generation: export per-symbol report bundles with tables, figures, benchmark regime profiles,index.md,index.html, andmetadata.json.
Implementation detail and validation logic are documented in docs/architecture.md, docs/methodology.md, and docs/validation_plan.md.
- The checked-in evidence covers
SPY,QQQ, andIWMover the same11-trading-day window, with alignedpricing_validationand backtest coverage from2025-04-03through2025-04-17. - Selected benchmark checks record dense-grid calendar violations=
0and density / butterfly violations=0. - PDE-vs-MC validation covers
444benchmark rows across the checked-in sample;225raw rows exceed0.01, but after reruns there are statistically significant breaches=0. - The aggregate benchmark-row median
abs_err_pde_mcis0.010321921420370916, inside the documented<= 0.0125target in docs/validation_plan.md. - The checked-in benchmark tree stores all
12selected regime profiles across the three symbols. - Canonical report bundles include hedge summaries for
1d,5d, and10dhorizons with transaction-cost and turnover fields alongside surface-fit and pricing-validation tables.
For the fastest visual pass, start with the canonical SPY bundle and the four figures below: the fitted total-variance surface, the derived local-vol surface, the hedge error distribution, and turnover versus tail risk.
04_surface_heatmap_total_variance
|
06_dupire_local_vol_heatmap
|
10_hedge_error_distribution
|
11_turnover_vs_tail_risk
|
python -m venv .venv
. .venv/Scripts/activate
pip install -e .[dev]These commands are for local rebuilds only. The checked-in sample above is the public evidence surface.
Fresh offline rebuild from a local source root that already contains the needed raw inputs:
$env:ARBFREE_DATA_ROOT = "<LOCAL_OUTPUT_ROOT>"
$env:ARBFREE_SOURCE_DATA_ROOT = "<LOCAL_SOURCE_DATA_ROOT>"
arbfree-lv run-full --config configs/pipeline_quoted_strict_backfill.yaml --universe-config configs/universe.yaml --symbol SPY --start-date 2025-04-03 --end-date 2025-04-17 --executeSelected benchmark rerun on that same local root:
$env:ARBFREE_DATA_ROOT = "<LOCAL_OUTPUT_ROOT>"
python scripts/profile_pde.py --config configs/pipeline_quoted_strict_backfill.yaml --symbol SPY --trade-date 2025-04-08 --repeat-count 3If ARBFREE_SOURCE_DATA_ROOT is absent and the local root is missing raw inputs, live snapshot still requires Theta Terminal at http://127.0.0.1:25503.
- Report bundles are written to
data/.../results/reports/symbol={SYMBOL}/run_id={RUN_ID}/. - PDE benchmark outputs are written to
data/.../results/benchmarks/symbol={SYMBOL}/trade_date={YYYY-MM-DD}/. - The public/shareable repo surface is the source tree plus checked-in derived sample artifacts under
data/live_smoke/results/**. - Raw vendor data, API caches, staging/processed partitions, and scratch outputs remain local-only and are not checked into
data/.