volsurf
Production-ready volatility surface construction for equity and FX derivatives.
volsurf builds implied volatility surfaces from market data, calibrates parametric smile models (SVI, SABR, SSVI), detects butterfly and calendar arbitrage, and provides sub-20ns vol queries suitable for real-time pricing engines.
Features
Smile Models
- SVI (Gatheral 2006) -- 5-parameter with quasi-explicit calibration (Zeliade 2009), analytical g-function density, butterfly arbitrage detection
- SABR (Hagan 2002) -- 4-parameter with Hagan closed-form, analytic alpha + Nelder-Mead calibration, 12-digit accuracy vs reference values
- Cubic spline -- non-parametric on total variance, Thomas algorithm O(n), flat extrapolation
Surface Construction
- SSVI global parameterization (Gatheral-Jacquier 2014) with two-stage calibration
- eSSVI extended SSVI (Hendriks-Martini 2019) with tenor-dependent rho, calendar-spread no-arb guarantees, 3-stage calibration from market data
- Piecewise per-tenor surfaces with linear variance interpolation
- Builder API with SVI/SABR/spline model selection, dividend yield, per-tenor forward override
- Ragged strike grids -- different strikes per tenor, no rectangular matrix assumption
Arbitrage Detection
- Butterfly arbitrage via analytical g-function (SVI) and numerical density scan (SABR)
- Calendar spread arbitrage via cross-tenor variance monotonicity
- Analytical calendar arbitrage for SSVI surfaces
- Combined
SurfaceDiagnosticsreport
Implied Volatility
- Black (lognormal) implied vol via Jackel rational approximation (near-machine-precision)
- Normal (Bachelier) implied vol and pricing (Jackel 2017) -- supports negative forwards
- Displaced diffusion -- interpolates between normal (beta=0) and Black (beta=1)
Local Volatility
- Dupire local vol extraction (Dupire 1994) from any
VolSurfacevia finite differences
Design
- No global state -- evaluation date is a parameter, not a singleton
- Immutable surfaces -- no observer pattern
- Thread-safe -- all types are
Send + Sync - Zero-alloc vol queries after construction
- Newtypes for type safety (
Vol,Variance,Strike,Tenor) - Serde serialization on all model structs and value types
Installation
[]
= "1.0"
Optional features:
= { = "1.0", = ["parallel", "logging"] }
| Feature | Description |
|---|---|
parallel |
rayon support for parallel surface construction |
logging |
tracing instrumentation in calibration and build paths |
Requires Rust edition 2024 (rustc 1.85+).
Quick Start
Build a surface from market data
use ;
let strikes = vec!;
let vols = vec!;
let surface = new
.spot
.rate
.add_tenor
.add_tenor
.build?;
// Query vol at any (expiry, strike) point
let vol = surface.black_vol?;
Choose a smile model
use ;
let surface = new
.spot
.rate
.model
.add_tenor
.add_tenor
.build?;
Available models: SmileModel::Svi (default, 5+ strikes), SmileModel::CubicSpline (3+ strikes), SmileModel::Sabr { beta } (4+ strikes).
SSVI global surface
use ;
let surface = new?;
let vol = surface.black_vol?;
let smile = surface.smile_at?;
Calibrate eSSVI from market data
use ;
// Per-tenor (strike, implied_vol) pairs
let data_3m: =
.map
.collect;
let data_1y: =
.map
.collect;
let surface = calibrate?;
let vol = surface.black_vol?;
Check for arbitrage
use ;
let smile = new?;
let report = smile.is_arbitrage_free?;
assert!;
// Surface-level diagnostics (butterfly + calendar)
let diagnostics = surface.diagnostics?;
if !diagnostics.is_free
Extract implied vol from option prices
use BlackImpliedVol;
use OptionType;
let vol = compute?;
Architecture
Five-layer pipeline following the natural domain flow:
Option Prices -> Implied Vol -> Smile -> Surface -> Local Vol
(Layer 1) (Layer 2) (Layer 3) (Layer 5)
Arbitrage Detection
(Layer 4)
volsurf
├── conventions StickyKind, log_moneyness, forward_price
├── error VolSurfError, Result<T>
├── implied
│ ├── black BlackImpliedVol, black_price
│ ├── normal NormalImpliedVol, normal_price
│ └── displaced DisplacedImpliedVol, displaced_price
├── smile
│ ├── svi SviSmile (Gatheral 2006)
│ ├── sabr SabrSmile (Hagan 2002)
│ ├── spline SplineSmile (cubic on variance)
│ └── arbitrage ArbitrageReport, ButterflyViolation
├── surface
│ ├── ssvi SsviSurface (Gatheral-Jacquier 2014)
│ ├── essvi EssviSurface, EssviSlice (Hendriks-Martini 2019)
│ ├── piecewise PiecewiseSurface (per-tenor interpolation)
│ ├── builder SurfaceBuilder, SmileModel
│ └── arbitrage SurfaceDiagnostics, CalendarViolation
├── local_vol LocalVol trait, DupireLocalVol (Dupire 1994)
└── types Strike, Tenor, Vol, Variance, OptionType
Benchmarks
Measured with Criterion.rs on Apple Silicon. All performance targets exceeded.
Vol Queries (single point evaluation)
| Operation | Time |
|---|---|
| SVI vol | 4.7 ns |
| Spline vol | 4.6 ns |
| SSVI slice vol | 11 ns |
| SABR vol | 17 ns |
| Piecewise surface vol | 18 ns |
| SSVI surface vol | 20 ns |
Calibration
| Operation | Time |
|---|---|
| SABR calibration | 74 us |
| SVI calibration | 107 us |
| SSVI calibration | 266 us |
Surface Construction
| Operation | Time |
|---|---|
| SABR surface (5 tenors) | 381 us |
| SVI surface (5 tenors) | 553 us |
| SVI surface (20 tenors) | 2.6 ms |
Targets: vol query < 100 ns, SABR calibration < 1 ms, 20-tenor surface < 10 ms.
Bindings
Python
Built with PyO3. See python/ for usage and API docs.
WebAssembly
Built with wasm-bindgen. See wasm/README.md for JavaScript API and usage examples.
Changelog
| Version | Name | Key Features |
|---|---|---|
| v1.0 | Stable | API stability, PyO3 bindings, WASM target |
| v0.4 | Hardening | Coverage gaps, tracing diagnostics, dead code removal |
| v0.3 | Production Grade | eSSVI surface + calibration, parallel construction, dividend yield |
| v0.2.1 | Normal/Displaced IV, Dupire local vol, serde validation, CI | |
| v0.2 | Market Ready | SABR, SSVI, calendar arbitrage, surface diagnostics |
| v0.1 | First Light | SVI smile, cubic spline, ragged grid surface, builder API |
References
- Gatheral, J. The Volatility Surface: A Practitioner's Guide (2006)
- Gatheral, J. & Jacquier, A. "Arbitrage-free SVI Volatility Surfaces" (2014)
- Hagan, P. et al. "Managing Smile Risk", Wilmott (2002)
- Jackel, P. "Let's Be Rational" (2013)
- Zeliade Systems, "Quasi-Explicit Calibration of Gatheral's SVI Model" (2009)
- Hendriks, S. & Martini, C. "The Extended SSVI Volatility Surface" (2019)
- Dupire, B. "Pricing with a Smile", Risk (1994)
- Jackel, P. "Implied Normal Volatility" (2017)
- Breeden, D.T. & Litzenberger, R.H. "Prices of State-Contingent Claims Implicit in Option Prices" (1978)
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.