ProbSurface extends the single-expiry ProbCurve concept to multiple maturities. You construct it from a fitted VolSurface, or use the convenience ProbSurface.from_chain shortcut to go directly from an option chain. Once built, you can evaluate the PDF or CDF within the fitted maturity range, extract individual ProbCurve slices, export a long-format DataFrame, and visualize the distribution with a fan chart.
Constructors
ProbSurface(vol_surface, grid_points, cdf_violation_policy)
Builds a ProbSurface from an already-fitted VolSurface. This is the primary constructor when you want independent control over volatility fitting and probability derivation.
A fitted
VolSurface instance. Must have at least two expiries and a built interpolator. Call VolSurface.fit before passing it here.Native probability grid size per slice.
None uses the adaptive default policy. This controls the resolution of internal materialization, not the export size; use density_results(points=...) to control output resolution.Policy for CDF monotonicity violations during lazy slice materialization.
"warn" repairs and records a diagnostic warning; "raise" fails on material violations.ValueError if vol_surface has not been fitted.
ProbSurface.from_chain
Convenience shortcut that fits the underlying VolSurface internally and returns a ready-to-query ProbSurface.
Multi-expiry option chain DataFrame. Must contain an
expiry column and at least two unique expiry dates.Market inputs providing the risk-free rate, valuation date, and underlying price.
Optional mapping in the form
{"dataframe_column": "oipd_column"}. See Standard columns for the target names.Maximum age of option quotes in calendar days. Rows older than this threshold are filtered before fitting each slice.
Controls how individual expiry calibration failures are handled.
"skip_warn" skips the failing expiry and continues; "raise" propagates the error immediately.Policy for CDF monotonicity violations.
"warn" repairs and warns; "raise" fails on material violations.ValueError if failure_policy is not a supported value. CalculationError if fewer than two expiries remain after filtering, or if calibration fails.
Methods
pdf(price, t)
pdf(price, t)
Evaluate the PDF at given price level(s) and maturity.
Price level or array of price levels to evaluate.
Maturity. Pass a year-fraction float (e.g.,
45/365) or a date-like value (e.g., "2025-06-20"). The surface interpolates to any maturity within the fitted range.Interpolated PDF values at
price for the given maturity. Values outside the domain return 0.0.cdf(price, t)
cdf(price, t)
Evaluate the CDF at given price level(s) and maturity.
Price level or array of price levels to evaluate.
Maturity as a year-fraction float or date-like value.
Cumulative probability values. Returns
0.0 below the domain and 1.0 above.quantile(q, t)
quantile(q, t)
Inverse CDF: returns the price level at quantile Raises:
q for maturity t.Target probability in the open interval (0, 1).
Maturity as a year-fraction float or date-like value.
Price S such that P(Asset < S) = q at maturity t.
ValueError if q is not in (0, 1).slice(expiry)
slice(expiry)
Extract a single-expiry Raises:
ProbCurve for a maturity within the fitted range. If expiry matches a fitted pillar exactly, the method returns a curve built from that pillar’s data. Otherwise, it builds a synthetic curve via total-variance interpolation.Target expiry. Accepts ISO date strings like
"2025-06-20", Python date objects, or pd.Timestamp.Probability curve for the requested maturity.
ValueError if the surface is empty or the maturity is outside the fitted range.density_results(domain, points, start, end, step_days, full_domain)
density_results(domain, points, start, end, step_days, full_domain)
Export a long-format DataFrame of probability slices across expiries.
Optional export price domain as
(min_price, max_price). Takes precedence over full_domain.Number of price points per expiry slice in the output.
Lower expiry bound for the export. Defaults to the first fitted pillar expiry.
Upper expiry bound for the export. Defaults to the last fitted pillar expiry.
Calendar-day sampling interval between exported slices. Fitted pillar expiries are always included. Pass
None to export fitted pillars only.When
True and domain is not set, each slice exports its full native domain without resampling.Long-format DataFrame with columns
expiry, price, pdf, and cdf.plot_fan(figsize, title)
plot_fan(figsize, title)
Plot a fan chart of risk-neutral quantiles across all expiries.Raises:
Figure size as (width, height) in inches.
Custom title. Auto-generated when omitted.
The rendered fan chart figure.
ValueError if the surface has no fitted expiries, or if no valid slices remain after skipping invalid fan slices.Properties
All fitted pillar maturities as a tuple of
pd.Timestamp objects, in ascending order.Structured diagnostic events accumulated across all surface operations. Inspect
.warning_diagnostics.events for data-quality, model-risk, and workflow events.