volkit.estimate

volkit.estimate.estimate_vol_from_option_prices(C, F, K, T, r, cp=1, tol=1e-08, max_iter=100, price_tol=1e-10, sigma_max=10.0)[source]

Implied Black volatility for European options on futures (bisection).

Guardrails include no-arbitrage checks, cap detection, and one Newton polish.

Parameters:
  • C (float or array-like) – Observed option price (present value).

  • F – As in price_euro_future().

  • K – As in price_euro_future().

  • T – As in price_euro_future().

  • r – As in price_euro_future().

  • cp – As in price_euro_future().

  • tol (float, optional) – Tolerance on volatility bracket width. Default is 1e-8 (per-year vol).

  • max_iter (int, optional) – Maximum bisection iterations. Default is 100.

  • price_tol (float, optional) – Tolerance on price mismatch when declaring convergence. Default 1e-10.

  • sigma_max (float, optional) – Upper bound during bracket growth (fail if still too cheap). Default 10.0.

Returns:

Implied vol array. Special values: - np.inf if price is at the theoretical cap, - np.nan on failures (e.g., price outside no-arb bounds).

Return type:

numpy.ndarray

Notes

  • No-arb lower bound: PV >= DF * max(cp*(F-K), 0).

  • No-arb upper cap: PV <= DF * (F if call else K).

volkit.estimate.estimate_future_from_option_quotes(K, call_bid, call_ask, put_bid, put_ask, *, eps=1e-12, plot=False, ax=None)[source]

Robust single-expiry inference with minimal exclusions + max-width future band.

Returns:

resultImpliedFutureResult or None

No feasible subset if fewer than 2 distinct strikes.

valid_maskndarray of bool, shape (len(K),)

In ORIGINAL input order. True for strikes used by the solution; False otherwise.

Return type:

(result, valid_mask)

Parameters:

Notes

  • If result is None, valid_mask may still mark one “best” row only in the case of Ds == ∅ and there exist ≥2 distinct strikes among valid rows. If all valid rows share the same strike (e.g., duplicates-only situation), the mask is all False.

  • Duplicate-K subsets are rejected when selecting the final subset (they do not define a future band).

  • Selection across depths: we try the highest feasible depth first, then fall back to lower depths (≥2). Within a depth, we choose the subset/D that maximizes width.

volkit.estimate.estimate_future_from_option_prices(K, call, put, *, eps=1e-12, plot=False, ax=None, slope_quantiles=(0.25, 0.75), clip_D=(1e-06, 1.0), trim_mad_mult=3.5, max_trim_iters=5, tol_sigma=None, rel_tol=None, abs_tol=None, day=None, t=None)[source]

Infer future F and discount factor D from single option prices.

Returns:

resultImpliedFutureResult or None

None if fewer than 2 distinct strikes (after filtering) or no feasible band could be established.

valid_maskndarray of bool, shape (len(K),)

In ORIGINAL input order. True if a strike was used in the solution.

Return type:

(result, valid_mask)

Parameters: