VolSurface calibrates individual SVI smiles for each expiry in a multi-expiry option chain and builds a total-variance interpolator across maturities. Once fitted, you can retrieve a VolCurve for maturities within the fitted range, including dates that fall between fitted pillars. You can also export the surface as a long-format DataFrame or derive a ProbSurface of risk-neutral distributions.
Constructor
str
default:"svi"
Calibration algorithm. Currently
"svi" is the supported method.Literal['black76', 'bs']
default:"black76"
Pricing model used for implied volatility inversion. Use
"black76" for options on futures or forwards, and "bs" for spot options (Black-Scholes).Literal['mid', 'last']
default:"mid"
Quote type to fit against per slice.
"mid" uses the bid-ask midpoint, falling back to last_price when the mid is unavailable. "last" fits against last_price.int
default:"3"
Maximum age of option quotes in calendar days, relative to the valuation date. Stale rows are excluded before fitting each slice.
Methods
fit(chain, market, column_mapping, horizon, failure_policy)
fit(chain, market, column_mapping, horizon, failure_policy)
Calibrate all expiries in the chain and build the surface interpolator. Returns Raises:
self for chaining.pd.DataFrame
required
Multi-expiry option chain DataFrame. Must contain an
expiry column and at least two unique expiry dates after filtering.MarketInputs
required
Market inputs providing the risk-free rate, valuation date, and underlying price.
dict[str, str] | None
default:"None"
Optional mapping in the form
{"dataframe_column": "oipd_column"}. See Standard columns for the target names.str | date | pd.Timestamp | None
default:"None"
Optional fit horizon that filters out expiries beyond the cutoff. Accepts human-readable strings like
"30d" or "12m", or an explicit date. Expiries after the cutoff are dropped before fitting.Literal['skip_warn', 'raise']
default:"skip_warn"
Slice-level failure handling policy.
"skip_warn" skips failing expiries and continues; "raise" propagates the first error immediately.VolSurface
The fitted
VolSurface instance (self).ValueError if failure_policy is not a supported value. CalculationError if the expiry column is missing or invalid, if fewer than two unique expiries remain after filtering, or if calibration fails.fit requires at least two unique expiries. Pass a single-expiry chain to VolCurve.fit instead.slice(expiry)
slice(expiry)
Return a Raises:
VolCurve for the requested maturity. If expiry matches a fitted pillar exactly, the original parametric curve is returned. Otherwise, a synthetic curve is derived from the total-variance interpolator.str | date | pd.Timestamp
required
Target expiry. Accepts ISO date strings like
"2025-06-20", Python date objects, or pd.Timestamp. Interpolated maturities between fitted pillars are supported.VolCurve
A
VolCurve for the requested maturity.ValueError if fit has not been called or if the maturity is outside the fitted range.iv_results(domain, points, include_observed, start, end, step_days)
iv_results(domain, points, include_observed, start, end, step_days)
Return a long-format DataFrame of fitted IV results across expiries.
tuple[float, float] | None
default:"None"
Optional
(min_strike, max_strike) range per slice.int
default:"200"
Number of fitted-curve evaluation points per expiry slice.
bool
default:"True"
Whether to include observed market IV columns.
str | date | pd.Timestamp | None
default:"None"
Lower expiry bound. Defaults to the first fitted pillar.
str | date | pd.Timestamp | None
default:"None"
Upper expiry bound. Defaults to the last fitted pillar.
int | None
default:"1"
Calendar-day sampling interval. Fitted pillar expiries are always included. Pass
None to export fitted pillars only.pd.DataFrame
Long-format DataFrame with an
expiry column and per-slice IV data.total_variance(K, t)
total_variance(K, t)
implied_vol(K, t)
implied_vol(K, t)
Return the interpolated implied volatility at strike
K and maturity t. surface(K, t) is a callable alias.float
Implied volatility in decimal form.
forward_price(t)
forward_price(t)
price(strikes, t, call_or_put)
price(strikes, t, call_or_put)
atm_vol(t)
atm_vol(t)
Return the at-the-money implied volatility at maturity
t, where ATM is defined at the forward price.float
Interpolated ATM implied volatility.
implied_distribution(grid_points, cdf_violation_policy)
implied_distribution(grid_points, cdf_violation_policy)
Derive a
ProbSurface from the fitted volatility surface.ProbSurface
Risk-neutral probability surface.
delta, gamma, vega, theta, rho, greeks
delta, gamma, vega, theta, rho, greeks
Compute Greeks at a strike grid and maturity.
np.ndarray | pd.DataFrame
Individual Greek methods return arrays.
greeks returns a DataFrame with strike, delta, gamma, vega, theta, and rho.plot, plot_3d, plot_term_structure
plot, plot_3d, plot_term_structure
Properties
tuple[pd.Timestamp, ...]
Sorted tuple of fitted pillar expiry timestamps. Returns an empty tuple if
fit has not been called.WarningDiagnostics
Structured diagnostic events accumulated during fitting. Inspect
.warning_diagnostics.events for data-quality issues (e.g., stale quotes, price fallbacks), model-risk warnings (butterfly arbitrage), and skipped expiries.dict[pd.Timestamp, Any]
Fitted parameter dictionary for each expiry pillar.