Installation and a first result

Install

Install the released package from PyPI:

python -m pip install vanilla-option-pricers

For a source checkout, install the package and the build-only documentation tools separately:

python -m pip install -e ".[docs]"

The package’s runtime dependencies remain NumPy and Numba. Sphinx, MyST Parser, and Furo belong only to the optional docs extra.

Run the authoritative offline example

Open In Colab

The repository’s pricing and IV script is the single source for first success. It uses only the installed package, NumPy, Numba, and deterministic generated inputs; it requires no network, credentials, pandas, or SciPy and creates no files.

From a source checkout with the package installed, run:

python examples/getting_started/pricing_and_iv.py

The wheel intentionally excludes repository examples. After installing from PyPI, download or copy the linked script and run it from any directory.

For a zero-local-setup trial, the Colab notebook installs the latest released distribution from the official PyPI index, prints its distribution version and import path, and runs the exact same workflow below. The committed notebook contains no execution output.

  1"""Offline first-success workflow for vanilla-option-pricers."""
  2
  3from importlib.metadata import version
  4from pathlib import Path
  5from time import perf_counter
  6
  7import numpy as np
  8from numba.typed import List
  9
 10import vanilla_option_pricers as vop
 11
 12forward = 100.0
 13discfactor = 0.98
 14ttm = 0.50
 15strikes = np.array([90.0, 100.0, 100.0, 110.0])
 16option_types = np.array(["P", "P", "C", "C"])
 17solve_types = List(option_types.tolist())
 18lognormal_vols = np.full(strikes.shape, 0.20)
 19
 20
 21def run_bsm_workflow() -> tuple[np.ndarray, np.ndarray]:
 22    """Price one aligned BSM slice and recover its implied volatilities."""
 23    prices = vop.compute_bsm_vanilla_slice_prices(
 24        ttm,
 25        forward,
 26        strikes,
 27        lognormal_vols,
 28        option_types,
 29        discfactor,
 30    )
 31    implied_vols = vop.infer_bsm_ivols_from_slice_prices(
 32        ttm,
 33        forward,
 34        discfactor,
 35        strikes,
 36        solve_types,
 37        prices,
 38    )
 39    return prices, implied_vols
 40
 41
 42cold_started = perf_counter()
 43prices, implied_vols = run_bsm_workflow()
 44cold_seconds = perf_counter() - cold_started
 45
 46warm_repetitions = 10
 47warm_started = perf_counter()
 48for _ in range(warm_repetitions):
 49    warm_prices, warm_implied_vols = run_bsm_workflow()
 50warm_mean_seconds = (perf_counter() - warm_started) / warm_repetitions
 51
 52max_iv_error = float(np.max(np.abs(implied_vols - lognormal_vols)))
 53parity_error = float(prices[2] - prices[1] - discfactor * (forward - strikes[1]))
 54
 55absolute_normal_vol = 5.0
 56normal_strike = 102.0
 57normal_price = vop.compute_normal_price(
 58    forward,
 59    normal_strike,
 60    ttm,
 61    absolute_normal_vol,
 62    discfactor,
 63    "C",
 64)
 65normal_implied_vol = vop.infer_normal_implied_vol(
 66    forward,
 67    ttm,
 68    normal_strike,
 69    normal_price,
 70    discfactor,
 71    "C",
 72)
 73
 74if max_iv_error > 1e-7:
 75    raise RuntimeError(f"BSM implied-volatility round trip failed: {max_iv_error}")
 76if abs(parity_error) > 1e-10:
 77    raise RuntimeError(f"BSM put-call parity failed: {parity_error}")
 78if abs(normal_implied_vol - absolute_normal_vol) > 1e-7:
 79    raise RuntimeError("Bachelier implied-volatility round trip failed")
 80if not (
 81    np.array_equal(prices, warm_prices)
 82    and np.array_equal(implied_vols, warm_implied_vols)
 83):
 84    raise RuntimeError("Warm BSM workflow changed the deterministic result")
 85
 86print(f"distribution_version={version('vanilla-option-pricers')}")
 87print(f"import_path={Path(vop.__file__).resolve()}")
 88print(
 89    "array_shapes="
 90    f"strikes{strikes.shape} option_types{option_types.shape} "
 91    f"prices{prices.shape} implied_vols{implied_vols.shape}"
 92)
 93print("option_types=" + str(option_types.tolist()))
 94print("prices=" + np.array2string(prices, precision=8))
 95print(f"max_iv_error={max_iv_error:.3e} parity_error={parity_error:.3e}")
 96print(
 97    f"cold_first_call_seconds={cold_seconds:.6f} "
 98    f"warm_mean_seconds={warm_mean_seconds:.6f} "
 99    f"warm_repetitions={warm_repetitions}"
100)
101print(
102    f"bachelier_absolute_vol={absolute_normal_vol:.6f} "
103    f"price={normal_price:.8f} iv_error="
104    f"{normal_implied_vol - absolute_normal_vol:.3e}"
105)
106print("bsm_convention=forward, discount factor, years, annualised lognormal volatility")
107print("bachelier_convention=annualised absolute normal volatility in forward units")
108print(
109    "change_first=forward, discfactor, ttm, strikes, option_types, model_convention"
110)

The script prices one aligned BSM slice, recovers all four input volatilities, and checks the same-strike call/put pair against forward put-call parity. It also prices and inverts one Bachelier call with annualised absolute normal volatility in the same units as the forward and strike.

Successful output reports package version and import path; input/output shapes; option codes and prices; maximum IV and parity errors; one cold first-call duration; the mean of ten warm repeats; and the Bachelier result. Timing values are machine-dependent and are not a benchmark. The verified numerical errors are required to remain below the explicit thresholds in the script.

Start adaptation with the final change_first line: forward, discfactor, ttm, strikes, option_types, and model_convention. Preserve the stated units and alignment contracts when substituting market inputs.

Next steps and boundaries

Use the package-root functions for stable user examples. Array helpers have distinct scalar, aligned-array, grid, and per-expiry contracts; arbitrary broadcasting is not promised. The first call to a Numba-compiled signature includes compilation time.

Continue with pricing and Greeks, implied volatility, Bachelier units, and array/Numba behavior. Use the issue tracker for support.