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
- Piecewise per-tenor surfaces with linear variance interpolation
- Builder API with SVI/SABR/spline model selection
- 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 (3 ULP accuracy)
- Black-Scholes pricing
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
[]
= "0.2"
Optional features:
= { = "0.2", = ["logging"] }
| Feature | Description |
|---|---|
logging |
tracing instrumentation in calibration and build paths |
parallel |
rayon support for parallel surface construction (v0.3) |
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?;
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 (v0.3)
│ └── displaced DisplacedImpliedVol (v0.3)
├── 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 (v0.3)
│ ├── piecewise PiecewiseSurface (per-tenor interpolation)
│ ├── builder SurfaceBuilder, SmileModel
│ └── arbitrage SurfaceDiagnostics, CalendarViolation
├── local_vol LocalVol trait, DupireLocalVol (v0.3)
└── 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.
Roadmap
| Version | Name | Key Features |
|---|---|---|
| v0.1 | First Light | SVI smile, cubic spline, ragged grid surface, builder API |
| v0.2 | Market Ready | SABR, SSVI, calendar arbitrage, surface diagnostics |
| v0.3 | Production Grade | eSSVI, Dupire local vol, parallel construction |
| v1.0 | Stable | API stability, PyO3 bindings, WASM target |
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)
- 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.