Real-data examples

The repository ships a top-level examples/ directory: five runnable scripts that take a real SPY option chain (fetched via yfinance) from raw quotes to a priced, verified, serialized surface. Together they exercise the complete public API — every endpoint and every parameter — on one shared market snapshot, so they double as living documentation of the library surface.

Script

Covers

01_fetch_chain_yfinance.py

Snapshot discipline: a contemporaneous chain with no lookahead; a four-pillar Treasury curve fitted with interest-rate-models; parse_ticker_info

02_implied_vol_and_forwards.py

calculate_implied_forward (flat and term-structure rates), choose_leg, compute_ivs_vectorized, prepare_slice; implied-vol inversion methods with sources

03_single_slice_models.py

All seven parametrizations, apply_slice, the module-level total-variance functions, the raw/natural bijection, derivatives/density/wing slopes, check_slice_arbitrage

04_calibration_controls.py

Every objective, loss, f_scale, initialization; ArbitrageFreedom flags; the numba toggles

05_surface_pipeline.py

OptionChain, calibrate_surface, VolSurface evaluation and interpolation, diagnose, Black-76 Greeks, save/load

06_trading_workflows.py

Prior-anchored recalibration, quote-to-surface Jacobians, variance events, MarketContext (dates and day counts), evaluation status, economic arbitrage classification

Only script 01 needs the network; a committed sample snapshot lets 02–05 run immediately:

uv run --with yfinance --with interest-rate-models     examples/01_fetch_chain_yfinance.py                      # optional refresh
uv run examples/02_implied_vol_and_forwards.py               # ... through 05

Rates are a real curve, not a constant: script 01 fits a four-pillar Treasury zero curve (13w/5y/10y/30y) with interest-rate-models (import interest_rate_models as irm; irm.DiscountCurve) and persists it densely in the snapshot metadata; the offline scripts rebuild the same irm.DiscountCurve from the file. interest-rate-models is a core dependency of svi-py – rate inputs accept its curves and models directly, alongside flat floats and any callable T -> r(T) such as a cubic spline; yfinance stays examples-only.

No lookahead

A volatility surface is a picture of the market at one instant; mixing quotes observed at different times produces phantom arbitrage and unstable fits. The examples enforce contemporaneity mechanically: script 01 records a single snapshot timestamp, fetches quotes, spot, and rates in one pass, filters staleness using only information available at that timestamp, and persists everything to disk. The other scripts read the files and compute time-to-expiry against the recorded timestamp — never the wall clock. Apply the same discipline to production calibration: only data observable at the valuation time.

Implied-vol inversion methods

There is no closed-form inverse of the Black-Scholes price, so every implied vol is the output of an inversion algorithm:

  • Black-76 root-finding — the textbook route (Newton/Brent on the pricing formula); fragile near intrinsic value.

  • “Let’s Be Rational” (Peter Jäckel, Wilmott 2015) — the de facto standard: rational approximations plus at most two Householder steps reach full machine precision at roughly the cost of two price evaluations. Paper (journal), reference implementation. This is what svi-py uses internally: compute_ivs_vectorized and OptionChain invert through py_vollib, whose engine is py_lets_be_rational.

  • Volfi (Wolfgang Schadner — also the author of the DirectSVI parametrization shipped in this library) — newer still: an explicit, non-iterative inverse via a generalized-inverse-Gaussian quantile representation with an optional single Halley refinement. Paper, code. See also fast-vollib for vectorized LBR at scale.

Maintenance policy

The examples are part of the API contract: whenever the public API changes, examples/ and the documentation change in the same pull request. Drift between the examples and the library is a bug.