Fifteen independent option-pricing and risk methods, hand-built from the Black-Scholes PDE up through reverse-mode AAD, Heston stochastic vol, and Bates jump-diffusion, calibrated against a real Deribit BTC options chain and backtested against 16 years of real BTC price history — not synthetic data.
data/btc_chain_snapshot.json, 904 contracts), recovers the market's own quoted IV to within 0.3 percentage points for a typical contract (median), converging on 96.8% of contracts. The snapshot is committed so the test suite stays reproducible — no live API calls in CI.
Every method is checked against at least one independent method or real data, not just against itself.
| Method | What it's for | Validated against |
|---|---|---|
| Black-Scholes | Closed-form European price & Greeks; ground truth | Derived directly from the PDE — provably exact under GBM |
| Binomial tree | American exercise, discrete-time convergence | Converges to Black-Scholes: ~2% gap at 10 steps, ~0.1% at 500 |
| Trinomial tree | A second, independently-derived lattice (3 branches/node vs. binomial's 2) | Agrees with the binomial tree at high step counts; ~5-10% lower error at equal steps, measured directly |
| Monte Carlo | GBM path simulation, variance reduction | Matches closed-form within sampling error; antithetic variates reduce variance |
| Reverse-mode AAD | All Greeks in ~one backward pass over a hand-built tape | Delta cross-checked against seeded bump-and-revalue (0.6376 vs 0.6363) |
| Delta-hedging sim | Realized P&L of a rebalanced hedge vs. theoretical price | Mean P&L ≈ 0 across 2,000 paths post-fix (see bug log) |
| Longstaff-Schwartz | American Monte Carlo via regression-based continuation value | Least-squares fit solved by hand (Gaussian elimination, partial pivoting) |
| Crank-Nicolson PDE | Finite-difference solver, tridiagonal system | Stays stable where the explicit scheme provably diverges |
| IV calibration | Newton-Raphson solve for implied vol using vega, bisection fallback near zero vega | 96.8% convergence / 0.3pp typical gap vs. real Deribit quotes |
| Heston (stochastic vol) | COS-method pricing under vol-of-vol, mean reversion, and spot-vol correlation | Collapses exactly to Black-Scholes in the deterministic-variance limit; put-call parity holds directly on Heston prices (independent of BS) |
| Bates (Heston + jumps) | Adds discontinuous jumps on top of Heston's diffusion, reusing its characteristic function | Collapses exactly to Heston at zero jump intensity; collapses to closed-form Merton (1976) in the deterministic-variance limit; cross-checked against a full SDE Monte Carlo |
| Historical backtest | Do BS/Heston/Bates hedge ratios track real BTC price history, day by day | Rolling 30-day delta-hedged calls over 16 years of real BTC prices (195 windows) — try it live below |
| Portfolio VaR & stress test | Real historical simulation and Monte Carlo (Bates SDE) VaR, cross-validated against each other | Agree within ~2.3x at 99%; both catch the delta-normal baseline's blind spot to gamma — try it live below |
| P&L attribution | Taylor-decomposes realized hedge P&L into delta/gamma/vega/theta, the "P&L explain" a sell-side desk runs daily | Components sum exactly to total P&L by construction; unexplained residual <2% for a small isolated move — try it live below |
| Basic CVA | Prices counterparty default risk via expected exposure simulated under the calibrated Bates SDE | Zero when recovery=100% or hazard=0 or exposure is one-sided; monotonic in hazard rate — try it live below |
Solved IV per strike for the ~99-day expiry, from the calibration pass over the committed Deribit snapshot. Shape reflects the smile/skew Black-Scholes assumes away.
Each caught by a test that expected a specific numeric property, not just "does it compile."
REQUIRE(std::isfinite(price)) test.std::mt19937 — the two runs used unrelated random paths, producing a 3.2-unit discrepancy against AAD's delta.Reverse-mode AAD is the resume-defining piece of this engine — a hand-rolled computation tape with operator overloading, not a library like XAD or CoDiPack, specifically so the mechanism can be defended under questioning rather than cited. It's correct — delta from the tape's backward pass agrees with seeded bump-and-revalue to four significant figures — and its speed advantage only shows up once you need multiple Greeks: bump-and-revalue re-runs the full simulation once per Greek (N+1 simulations for N Greeks), while AAD computes all of them in roughly one extra backward pass, regardless of N. For a single Greek, the tape's overhead makes it a wash.
This isn't a JS reimplementation — wasm_bridge.cpp compiles the real C++ (Black-Scholes, trees, Monte Carlo, Heston, the Asian/Barrier exotics simulator, and Bates) to WebAssembly via Emscripten. Every number below comes out of your actual compiled engine. One live-data fetch (below) feeds every calculator on this page — pricing, VaR/P&L, and CVA alike — so you only ever look up real numbers once.
Rolls a fresh at-the-money call every window_days and delta-hedges it daily against the real BTC price path — not a simulation (src/backtest.cpp). Runs live, right here, over the full committed 16-year history (data/btc_price_history.csv), for all three models.
tools/calibrate_heston.cpp's fit to the real Deribit snapshot — the same numbers the README's Phase 15 table used, held fixed across the whole backtest while each window re-estimates its own volatility from trailing realized vol.A short strangle/straddle book, partially delta-hedged (make_example_market_maker_book in src/portfolio.cpp) — real short-gamma risk, not a toy. VaR/stress testing measures the risk on this book directly; P&L attribution explains a realized move on the same book after the fact.
A single call bought OTC from a risky counterparty (src/cva.cpp) — simulates forward exposure under the calibrated Bates SDE and prices in what their possible default costs you. Deliberately simplified: unilateral (no DVA), a single flat hazard rate, no wrong-way risk, no netting or collateral — see the note below.
hazard_rate_from_cds_spread()), not JavaScript. Set the CDS spread to 0, or recovery to 99%, to confirm CVA collapses to exactly 0 — the same identities the test suite checks. Out of scope, and documented as such: wrong-way risk (a counterparty's default is modeled as independent of your exposure to them, which understates risk for correlated names), netting/collateral, and the other XVA family members (FVA/MVA/KVA) a full desk computes alongside this.Every other card above prices whatever numbers you type in — this one pulls Bitcoin's real live price and the real live BTC options order book directly from Deribit's public API (confirmed CORS-open from a browser, no backend or API key needed), finds the closest real, currently-tradeable contract to your target, and reprices it two ways: this engine's calibrated Heston model, with its variance level set from a real SVI curve fit to that whole expiry's live chain (not just this one contract's own quote), and a plain Black-Scholes price at that same fitted curve's vol for this exact strike. This is the actual "does my model agree with the real market" check, not a hypothetical one.
Every other card on this page prices off ONE vol number. This one fits a real, separate 5-parameter SVI (Gatheral, 2004) curve to EVERY real expiry currently live on Deribit at once — the same curve-fitting approach real crypto and equity vol desks quote off of day to day, distinct from the stochastic-process story Heston/Bates (sections 06/09) tell. Each fitted curve is checked live against two real no-arbitrage conditions, not assumed valid.
svi_calibration.hpp. Before fitting, a median/MAD outlier filter (k=4) drops any quote whose mark IV is wildly off the rest of that expiry's chain — a small number of illiquid, deep-wing contracts near expiry get an extrapolated mark IV from Deribit even with no real market behind them, and left in, they can drag a least-squares fit away from the tradeable part of the smile entirely. "Butterfly OK" means the fitted curve never implies a negative risk-neutral density anywhere it was checked; a real, sampled check, not an assumption. Very short-dated expiries (under ~2 weeks) are still the hardest part of any real chain for a 5-parameter curve to fit tightly — if one shows a high error or a failed butterfly check after outlier trimming, that's an honest, documented property of raw SVI on steep, narrow short-dated smiles, not a bug being hidden.