Skip to main content

regit_svi/
lib.rs

1// Copyright 2026 Regit.io — Nicolas Koenig
2// SPDX-License-Identifier: Apache-2.0
3
4//! Arbitrage-free SVI volatility surfaces in pure Rust.
5//!
6//! `regit-svi` parametrises the implied volatility smile and surface with the
7//! Stochastic Volatility Inspired (SVI) family — Raw SVI (Gatheral 2004),
8//! SVI Jump-Wings, and the Surface SVI (SSVI) of Gatheral & Jacquier (2014) —
9//! together with calibration to market quotes and explicit static-arbitrage
10//! checks (butterfly and calendar-spread).
11//!
12//! Designed for auditability: every formula is hand-rolled from primary paper
13//! sources with no external dependencies. A regulator, quant auditor, or new
14//! engineer can trace every number to a citable derivation in [`MATH.md`].
15//!
16//! [`MATH.md`]: https://github.com/org-regit-io/regit-svi/blob/main/MATH.md
17//!
18//! # Quick start
19//!
20//! ```
21//! use regit_svi::{Quote, calibration::quasi_explicit};
22//!
23//! // Market quotes for one maturity: (log-moneyness, total variance, weight).
24//! let quotes = [
25//!     Quote::new(-0.20, 0.0512, 1.0).unwrap(),
26//!     Quote::new(-0.10, 0.0432, 1.0).unwrap(),
27//!     Quote::new( 0.00, 0.0400, 1.0).unwrap(),
28//!     Quote::new( 0.10, 0.0420, 1.0).unwrap(),
29//!     Quote::new( 0.20, 0.0480, 1.0).unwrap(),
30//! ];
31//!
32//! // Calibrate a raw SVI slice (quasi-explicit, de Marco-Martini).
33//! let fit = quasi_explicit::calibrate(&quotes).unwrap();
34//!
35//! // Evaluate total variance and implied volatility anywhere on the slice.
36//! let w = fit.slice.total_variance(0.05);
37//! let vol = fit.slice.implied_vol(0.05, 1.0).unwrap();
38//! assert!(w > 0.0 && vol > 0.0);
39//!
40//! // Certify the slice is free of butterfly arbitrage.
41//! assert!(fit.butterfly_free);
42//! ```
43//!
44//! # Architecture
45//!
46//! ```text
47//! types          log-moneyness, total variance, market quotes (Quote)
48//! errors         typed errors for parametrisation, conversion, calibration
49//! math           numerical primitives — Nelder-Mead, Levenberg-Marquardt,
50//!                linear least-squares (Cholesky), Brent root-finder
51//!
52//! raw            Raw SVI w(k) = a + b(rho(k-m) + sqrt((k-m)^2 + sigma^2))
53//! jw             SVI Jump-Wings parametrisation (trader-facing parameters)
54//! ssvi           Surface SVI w(k, theta) — arbitrage-free whole-surface form
55//! convert        conversions between Raw, Jump-Wings, and SSVI slices
56//!
57//! arbitrage      butterfly (g(k) >= 0) and calendar-spread checks
58//! density        risk-neutral density implied by a slice
59//!
60//! calibration/
61//!   quasi_explicit   de Marco-Martini / Zeliade quasi-explicit slice fit
62//!   least_squares    direct Levenberg-Marquardt slice fit
63//!   ssvi             joint SSVI surface calibration
64//!
65//! surface        multi-slice surface assembly and interpolation
66//! ```
67//!
68//! Part of [Regit OS](https://www.regit.io) — the operating system for
69//! investment products. From Luxembourg.
70
71#![forbid(unsafe_code)]
72
73pub mod arbitrage;
74pub mod calibration;
75pub mod convert;
76pub mod density;
77pub mod errors;
78pub mod jw;
79pub mod math;
80pub mod raw;
81pub mod ssvi;
82pub mod surface;
83pub mod types;
84
85// ─── Re-exports for ergonomic top-level access ─────────────────────────────
86
87pub use arbitrage::{ButterflyReport, CalendarReport};
88pub use calibration::CalibrationResult;
89pub use convert::{jw_to_raw, raw_to_jw, ssvi_to_raw};
90pub use density::DensityReport;
91pub use errors::{CalibrationError, ConvertError, ParamError};
92pub use jw::SviJw;
93pub use raw::RawSvi;
94pub use ssvi::{Phi, Ssvi};
95pub use surface::Surface;
96pub use types::{Quote, log_moneyness, quotes_from_triples, total_variance_from_vol};