A sequential walkthrough of an options-pricing pipeline: from a raw option chain to forward recovery, implied vol, an SVI smile per expiry, static arbitrage guardrails, a global SSVI surface, and a Dupire local-vol surface — each stage computed live in the browser from the same bundled sample chain.
Forward & discount via put–call parity
lib/forward.ts → recoverForward()
Pairs each expiry's call and put quotes at matching strikes and regresses (C − P) against strike; the slope recovers the discount factor DF and the intercept recovers the forward F, in one weighted least-squares pass. The forward isn't assumed from spot and a rate — it's observed directly from market prices via put–call parity.
Assumptions / limitations — European-style, cash-settled options with matched call/put strikes; dividends and financing costs are absorbed into the implied (F, DF) pair rather than modelled separately.
Black-76 & implied vol (Newton)
lib/bs.ts → black76Call(); lib/impliedVol.ts → impliedVol()
Every OTM quote is priced under Black-76 (lognormal forward, so no separate drift assumption is needed once F and DF are known), then inverted for the implied volatility that reproduces its market mid, using Newton's method seeded from a Brenner–Subrahmanyam ATM estimate, falling back to bisection if Newton stalls or vega is too small.
Assumptions / limitations — Black-76 is used purely as an inversion device, not a claim of constant vol; prices outside the model's no-arbitrage bounds are rejected rather than forced to a volatility.
Coordinates
lib/volSurface.ts → impliedVolPoints()
Converts each expiry's (strike, implied vol) pairs into the coordinates the rest of the pipeline fits in: log-moneyness k, which normalises strikes across expiries and spot levels, and total variance w = σ²τ, the additive quantity across time that SVI and SSVI are parameterised in.
Assumptions / limitations — Only the OTM leg (calls above the forward, puts below) is used per strike, since OTM quotes carry the least discretisation/pinning noise; wide or crossed quotes were already dropped upstream during cleaning.
SVI slice fit
lib/svi.ts → fitSVISlice()
Fits the five-parameter raw SVI curve to one expiry's (k, w) points at a time by weighted least squares (Nelder–Mead over an unconstrained reparameterisation, with random restarts), giving a smooth, closed-form smile with analytic derivatives that the arbitrage checks and Dupire formula later depend on.
Assumptions / limitations — A per-expiry fit only constrains that one slice — nothing stops adjacent expiries from crossing in time until the calendar check (or the global SSVI fit) is applied.
Butterfly & implied density
lib/arbitrage.ts → butterflyG(), riskNeutralDensity()
g(k) is the Gatheral–Jacquier butterfly-arbitrage indicator, built from the SVI slice's analytic first and second derivatives; g(k) < 0 anywhere implies a negative implied density there — a butterfly-spread arbitrage. p(k) is that implied risk-neutral density itself.
Assumptions / limitations — Evaluated on the strikes actually spanned by the fit — extrapolating g(k) or p(k) far outside the calibrated k-range isn't a claim the fit is making.
showing 2026-08-21Calendar / no-crossing
lib/arbitrage.ts → checkCalendar()
Total variance must be non-decreasing in time at fixed log-moneyness, or a shorter-dated option would be arbitrageable against a longer-dated one at the same strike. checkCalendar scans every pair of adjacent-tau slices across a shared k-grid and flags any point where a longer expiry's w dips below a shorter one's.
Assumptions / limitations — Checked over each pair's shared, data-supported k-range for independent per-expiry slices, since raw extrapolation there isn't trustworthy; the global SSVI surface instead satisfies this by construction via its penalised fit.
SSVI global surface
lib/ssvi.ts → fitSSVI()
Instead of one SVI curve per expiry, SSVI fits a single global (ρ, η, γ) across every expiry's points at once, driven by the ATM total-variance term structure θ(τ) built from the per-slice fits. The no-butterfly-arbitrage bound θ·φ(θ)·(1+|ρ|) < 4 is penalised directly inside the fit, so the surface is arbitrage-free by construction rather than by checking after the fact.
Assumptions / limitations — One skew/curvature shape is shared across the whole surface; if the true smile shape changes materially by tenor, a single (ρ, η, γ) fits some expiries less tightly than an independent per-slice SVI would.
Per-expiry: independent SVI vs. SSVI slice
Dupire local vol
lib/dupire.ts → localVolSurface()
Dupire's formula recovers the instantaneous local volatility consistent with the entire fitted implied-vol surface, expressed here in (k, τ) coordinates via the same pieces used above: ∂w/∂τ by finite differences along θ(τ), and g(k) analytically from the SSVI-equivalent slice at that τ.
Assumptions / limitations — Local vol reproduces every vanilla price the surface implies, but it flattens the forward smile going forward in time — it is not the same object as the market's future implied-vol smile — and is only reliable strictly inside the calibrated tau range, since θ(τ) is clamped flat outside it.
Glossary
- k
- Log-moneyness: k = ln(K/F).
- w
- Total variance: w = σ²τ; additive across time, the coordinate SVI/SSVI fit in.
- θ(τ)
- ATM total-variance term structure, θ(τ) = w(0, τ); the backbone SSVI's slices are anchored to.
- φ(θ)
- SSVI's power-law curvature, φ(θ) = ηθ^(−γ); controls how sharply the smile bends at each maturity.
- g(k)
- The Gatheral–Jacquier butterfly indicator; g(k) < 0 signals a negative (arbitrageable) implied density.
- F
- The forward price of the underlying for a given expiry, recovered from put–call parity.
- DF
- The discount factor to a given expiry, recovered alongside F from the same regression.
- ρ
- The correlation/skew parameter controlling the smile's tilt; |ρ| < 1.
- SVI
- The five-parameter (a, b, ρ, m, σ) raw parametrisation of one expiry's total-variance smile.
- SSVI
- "Surface SVI": one global (ρ, η, γ) plus a term structure θ(τ), giving one consistent surface across all expiries.
- Local vol
- The Dupire instantaneous volatility σ_loc(k, τ) consistent with the whole fitted implied-vol surface.