Volatility¶
Surface and handoff layer
The volatility namespace covers implied-vol inversion, smile and surface objects, local-vol extraction, and the eSSVI toolbox used by the proof-path pages.
This page stays reference-first. Use it for the raw objects and entry points; the proof-path guides explain the engineering decisions around them.
Implied volatility inversion¶
These functions cover scalar Black-Scholes/Black-76 implied-vol inversion.
Scalar implied volatility computation for individual options.
implied_vol_bs ¶
implied_vol_bs(mkt_price: float, spec: OptionSpec, market: MarketData | PricingContext, *, cfg: ImpliedVolConfig | None = None, t: float = 0.0, sigma0: float | None = None) -> float
Compute Black-Scholes implied volatility.
Convenience wrapper around :func:implied_vol_bs_result that returns only the
implied volatility.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mkt_price
|
float
|
Observed market option price. |
required |
spec
|
OptionSpec
|
Option specification (kind, strike, expiry). |
required |
market
|
MarketData
|
Market observables (spot, rate, dividend yield). |
required |
cfg
|
ImpliedVolConfig or None
|
Configuration for implied-vol inversion. If |
None
|
t
|
float
|
Valuation time in the same units as |
0.0
|
sigma0
|
float or None
|
Initial volatility guess. If |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Implied volatility. |
Raises:
| Type | Description |
|---|---|
InvalidOptionPriceError
|
If the input price violates no-arbitrage bounds. |
ValueError
|
If expiry is not strictly greater than |
ValueError
|
If |
implied_vol_bs_result ¶
implied_vol_bs_result(mkt_price: float, spec: OptionSpec, market: MarketData | PricingContext, *, cfg: ImpliedVolConfig | None = None, t: float = 0.0, sigma0: float | None = None) -> ImpliedVolResult
Compute Black-Scholes implied volatility and return diagnostics.
This function inverts the Black-Scholes price for volatility by solving:
BS_price(sigma) - mkt_price = 0
using a root-finding method selected by cfg.root_method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mkt_price
|
float
|
Observed market option price. |
required |
spec
|
OptionSpec
|
Option specification (kind, strike, expiry). |
required |
market
|
MarketData
|
Market observables (spot, rate, dividend yield). |
required |
cfg
|
ImpliedVolConfig or None
|
Configuration for implied-vol inversion. If
|
None
|
t
|
float
|
Valuation time in the same units as |
0.0
|
sigma0
|
float or None
|
Initial volatility guess. If
|
None
|
Returns:
| Type | Description |
|---|---|
ImpliedVolResult
|
Container with implied volatility and root-finder diagnostics. |
Raises:
| Type | Description |
|---|---|
InvalidOptionPriceError
|
If the input price violates no-arbitrage bounds (see :func: |
ValueError
|
If expiry is not strictly greater than |
ValueError
|
If |
Exception
|
Any exception raised by the root solver is propagated. |
Notes
This function is intentionally "config-driven": bounds, tolerances, and the
solver method are taken from cfg.
One-off overrides should be done by creating a modified config, e.g.::
from dataclasses import replace
cfg2 = replace(cfg, sigma_hi=10.0)
iv = implied_vol_bs_result(
price,
spec,
market,
cfg=cfg2,
)
The objective uses :func:option_pricing.bs_greeks for both price and vega.
Vega is clamped below by cfg.numerics.min_vega for robustness.
Volatility surfaces and smiles¶
These are the common surface objects exposed near the pricing API and used throughout the guides.
Core volatility surface implementation.
This module contains the main VolSurface class for managing implied volatility surfaces with per-expiry smiles and time interpolation.
VolSurface
dataclass
¶
Total-variance volatility surface over expiry.
Within each expiry slice (Smile), total variance is interpolated using: - Fritsch-Carlson on monotone (or split-monotone) data, else linear fallback.
Across expiry, total variance is linearly interpolated in time between smiles.
from_grid
classmethod
¶
from_grid(rows: Iterable[tuple[float, float, float]], forward: ScalarFn, *, expiry_round_decimals: int = 10) -> VolSurface
Build a surface from market quotes (T, K, iv) on a grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
Iterable[tuple[float, float, float]]
|
Iterable of (T, K, iv) market data points. |
required |
forward
|
ScalarFn
|
Callable forward(T) -> float. |
required |
expiry_round_decimals
|
int
|
Number of decimals to round each T for bucketing (default: 10). |
10
|
Returns:
| Type | Description |
|---|---|
VolSurface
|
Surface with Smile slices per unique expiry. |
from_svi
classmethod
¶
from_svi(rows: Iterable[tuple[float, float, float]], forward: ScalarFn, *, expiry_round_decimals: int = 10, calibrate_kwargs: dict | None = None) -> VolSurface
Build a surface by calibrating an SVI smile per expiry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
Iterable[tuple[float, float, float]]
|
Iterable of (T, K, iv) market points. |
required |
forward
|
ScalarFn
|
forward(T) -> float. |
required |
expiry_round_decimals
|
int
|
Bucketing tolerance for float maturities. |
10
|
calibrate_kwargs
|
dict | None
|
Optional kwargs forwarded to |
None
|
Returns:
| Type | Description |
|---|---|
VolSurface
|
A surface whose slices are analytic SVI smiles. |
Notes
This keeps VolSurface itself dependency-light: SciPy is only imported
if you call this method.
slice ¶
slice(T: float, method: Literal['no_arb'] = 'no_arb') -> SmileSlice
slice(T: float, method: Literal['linear_w']) -> DifferentiableSmileSlice
slice(T: float, method: TimeInterp = 'no_arb') -> SmileSlice
Return a callable single-expiry smile slice at maturity T.
- Node expiry: returns the stored slice (grid or SVI).
- Off-node: returns
InterpolatedSmileSlice, linear in total variance.
Notes
The surface is defined in log-moneyness y = ln(K/F(T)). Interpolating in y between expiries corresponds to constant log-moneyness interpolation.
iv ¶
iv(K: ArrayLike, T: float) -> FloatArray
Implied volatility at given strikes and maturity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
ArrayLike
|
Strike price(s). |
required |
T
|
float
|
Maturity time. |
required |
Returns:
| Type | Description |
|---|---|
FloatArray
|
Implied volatility at (K, T). |
w ¶
w(y: ArrayLike, T: float) -> FloatArray
Total variance at given log-moneyness and maturity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y
|
ArrayLike
|
Log-moneyness y = ln(K/F). |
required |
T
|
float
|
Maturity time. |
required |
Returns:
| Type | Description |
|---|---|
FloatArray
|
Total variance w(y, T) = T * iv(y, T)^2. |
Smile grid interpolation and manipulation helpers.
This module provides the Smile class and supporting functions for interpolating total-variance grids using adaptive interpolation strategies (Fritsch-Carlson for monotone regions, piecewise stitching for non-monotone smiles, linear fallback).
Smile
dataclass
¶
Total-variance smile at a single expiry on a log-moneyness grid.
The smile is represented in terms of total variance:
w(y) = T * iv(y)^2
on a strictly increasing log-moneyness grid:
y = ln(K / F(T)).
Interpolation:
- Uses Fritsch-Carlson monotone cubic interpolation when w(x) is monotone
or can be split into two monotone pieces (common U-shape).
- Falls back to linear interpolation with flat extrapolation otherwise.
w_at ¶
w_at(xq: ArrayLike) -> FloatArray
Interpolate total variance at given log-moneyness points.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xq
|
ArrayLike
|
Log-moneyness point(s) at which to evaluate total variance. |
required |
Returns:
| Type | Description |
|---|---|
FloatArray
|
Total variance w(x) = T * iv(x)^2 at xq. |
iv_at ¶
iv_at(xq: ArrayLike) -> FloatArray
Interpolate implied volatility at given log-moneyness points.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xq
|
ArrayLike
|
Log-moneyness point(s) at which to evaluate implied volatility. |
required |
Returns:
| Type | Description |
|---|---|
FloatArray
|
Implied volatility iv(x) = sqrt(w(x) / T) at xq. |
Local volatility surface derived from implied volatility.
This module provides the LocalVolSurface class for computing local volatility from an implied surface using Gatheral's formula.
LocalVolSurface
dataclass
¶
Local-vol surface computed from an implied surface in total variance.
For nodal implied surfaces, this class falls back to piecewise-time
interpolation and is best treated as a research/audit tool. For Dupire
production usage, prefer a continuous time-differentiable implied surface
such as ESSVISmoothedSurface.
Requirements
The underlying implied surface must provide, per expiry slice: - w_at(y) - dw_dy(y) - d2w_dy2(y)
i.e. analytic (or otherwise smooth) derivatives in log-moneyness.
Time derivative w_T
w_T is approximated by the same piecewise-linear interpolation you use for implied vols: w_T(y,T) pprox (w(y,T1) - w(y,T0)) / (T1 - T0)
which is piecewise-constant in T between expiries and can create visible "bands" in local vol.
from_implied
classmethod
¶
from_implied(implied: VolSurface | TimeDifferentiableImpliedSurface, *, forward: ScalarFn | None = None, discount: ScalarFn | None = None) -> LocalVolSurface
Convenience constructor from an implied volatility surface.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
implied
|
VolSurface | TimeDifferentiableImpliedSurface
|
Implied volatility surface (:class: |
required |
forward
|
ScalarFn | None
|
Forward price function. If None, uses implied.forward. |
None
|
discount
|
ScalarFn | None
|
Discount factor function. If None, uses flat df=1.0. |
None
|
Returns:
| Type | Description |
|---|---|
LocalVolSurface
|
Local volatility surface derived from implied. |
local_var ¶
local_var(K: ArrayLike, T: float, *, eps_w: float = 1e-12, eps_denom: float = 1e-12) -> FloatArray
Local variance sigma_loc^2(K, T).
Computed from implied surface using Gatheral's one-dimensional local-volatility formula in log-moneyness coordinates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
ArrayLike
|
Strike price(s). |
required |
T
|
float
|
Maturity time. |
required |
eps_w
|
float
|
Small value to avoid numerical issues near w=0 (default: 1e-12). |
1e-12
|
eps_denom
|
float
|
Small value for denominator regularization (default: 1e-12). |
1e-12
|
Returns:
| Type | Description |
|---|---|
FloatArray
|
Local variance at (K, T). |
local_var_diagnostics ¶
local_var_diagnostics(K: ArrayLike, T: float, *, eps_w: float = 1e-12, eps_denom: float = 1e-12) -> GatheralLVReport
Diagnostics for local variance computation.
Returns intermediate quantities (w derivatives, local vol, etc.) useful for analysis and debugging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
ArrayLike
|
Strike price(s). |
required |
T
|
float
|
Maturity time. |
required |
eps_w
|
float
|
Small value to avoid numerical issues near w=0 (default: 1e-12). |
1e-12
|
eps_denom
|
float
|
Small value for denominator regularization (default: 1e-12). |
1e-12
|
Returns:
| Type | Description |
|---|---|
GatheralLVReport
|
Report object containing w, derivatives, local vol, and other diagnostics. |
local_vol ¶
local_vol(K: ArrayLike, T: float, *, eps_w: float = 1e-12, eps_denom: float = 1e-12) -> FloatArray
Local volatility sigma_loc(K, T).
Square root of local variance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
ArrayLike
|
Strike price(s). |
required |
T
|
float
|
Maturity time. |
required |
eps_w
|
float
|
Small value to avoid numerical issues near w=0 (default: 1e-12). |
1e-12
|
eps_denom
|
float
|
Small value for denominator regularization (default: 1e-12). |
1e-12
|
Returns:
| Type | Description |
|---|---|
FloatArray
|
Local volatility at (K, T). |
eSSVI toolbox¶
The main eSSVI entrypoints are re-exported from option_pricing.vol and grouped under option_pricing.vol.ssvi.
Package-level exports for the eSSVI toolbox.
ThetaTermStructure
dataclass
¶
Bases: MaturityTermStructure
Primary maturity term structure for theta(T).
PsiTermStructure
dataclass
¶
Bases: MaturityTermStructure
Primary maturity term structure for psi(T).
EtaTermStructure
dataclass
¶
Bases: MaturityTermStructure
Primary maturity term structure for eta(T).
ESSVITermStructures
dataclass
¶
Primary eSSVI maturity parametrization in theta(T), psi(T), eta(T).
ESSVINodeSet
dataclass
¶
Discrete eSSVI node representation on calibrated expiries.
ESSVIImpliedSurface
dataclass
¶
Continuous analytic implied surface driven by an eSSVI parameter surface.
ESSVINodalSurface
dataclass
¶
Exact arbitrage-safe nodal eSSVI surface from Mingone interpolation.
ESSVISmoothedSurface
dataclass
¶
ESSVIFitResult
dataclass
¶
ESSVIProjectionConfig
dataclass
¶
ESSVIProjectionResult
dataclass
¶
build_theta_term_from_quotes ¶
build_theta_term_from_quotes(*, y: NDArray[float64], T: NDArray[float64], price_mkt: NDArray[float64], market: MarketData | PricingContext, is_call: NDArray[bool_] | None = None, atm_y_tol: float = 1e-08, iv_cfg: ImpliedVolConfig | None = None) -> tuple[SampledThetaTermStructure, ATMThetaDiagnostics]
calibrate_essvi ¶
calibrate_essvi(*, y: NDArray[float64], T: NDArray[float64], price_mkt: NDArray[float64], market: MarketData | PricingContext, sqrt_weights: NDArray[float64] | None = None, weights: NDArray[float64] | None = None, is_call: NDArray[bool_] | None = None, cfg: ESSVIGlobalCalibrationConfig | None = None) -> ESSVIFitResult
project_essvi_nodes ¶
project_essvi_nodes(nodes: ESSVINodeSet, *, cfg: ESSVIProjectionConfig | None = None) -> ESSVIProjectionResult
evaluate_essvi_constraints ¶
evaluate_essvi_constraints(params: ESSVITermStructures, expiries: ArrayLike, *, tol: float = 1e-10) -> ESSVIConstraintReport
validate_essvi_nodes ¶
validate_essvi_nodes(nodes: ESSVINodeSet, *, strict: bool = False, tol: float = 1e-10) -> ESSVINodeConstraintReport
validate_essvi_continuous ¶
validate_essvi_continuous(params: ESSVITermStructures, market: MarketData | PricingContext, *, expiries: ArrayLike | None = None, y_grid: ArrayLike | None = None, strict: bool = False, tol: float = 1e-10) -> ESSVIValidationReport
Notes¶
- Implied-vol inversion configuration lives in
ImpliedVolConfigon the Public API page. - The eSSVI objects are available from
option_pricing.vol, not from the package rootoption_pricing. LocalVolSurfaceremains demo-grade for generic slice-stack interpolation, but it can also consume a time-differentiable surface such asESSVISmoothedSurface.