Changelog¶
All notable changes to this project will be documented here.
The format follows Keep a Changelog, and this project adheres to Semantic Versioning.
Only tagged public releases are recorded here. Development snapshots published
from main to TestPyPI use VCS-derived .devN versions and are not tracked as
separate changelog entries.
[Unreleased]¶
[0.1.7] — 2026-07-03¶
Added¶
- Surface arbitrage-evaluation harness (
fast_vollib.surface) — a generator-agnostic, backend-pluggable, differentiable evaluator for implied -volatility surfaces. Takes an arbitrary surface on an arbitrary(log-moneyness × maturity)mesh and returns calibrated, dimensionless arbitrage diagnostics.IVSurface/SurfaceSequencecontainers withfrom_logmoneyness,from_strikes,from_total_variance, andfrom_call_pricesconstructors; numpy / torch / jax arrays preserved with dtype and device.validate_surface()→ArbitrageReport: price-space discrete checks (convexity / slope / box / calendar; Davis–Hobson 2007) and total-variance checks (∂_T w ≥ 0, Durrlemang ≥ 0; Gatheral–Jacquier 2014), with normalized metrics (ndm,bfly_frac,cal_depth_max,cal_frac,vert_frac,bound_frac) and theSAScomposite (reported only alongside its components).- Artifact-vs-arbitrage separation: violations whose stencil touches an
interpolated node are bucketed as
interpolation_inducedrather than counted as model arbitrage. - Round-trip trust mask: per-node
σ→C→σ'Jäckel LBR fixed-point residual, machine-tight where the quote is well-posed. - Butterfly violations gate on the per-slice-normalized density magnitude
vs the dimensionless tolerance (never raw
density < 0), so O(h²) truncation noise at near-degenerate wings cannot manufacture spurious violations on an arbitrage-free surface. Severity bands key off the normalized magnitude; an empty / all-NaN surface reportspassed=False(context["coverage"]). arbitrage_penalty()— a differentiable soft form of the same checks that stays in the input tensor's namespace (no host round-trip), so it is autograd-traceable on torch/jax and matches the numpy report to machine precision. A reusable replacement for the inline VolGAN / deep-smoothing penalty functions.- Backend parity verified numpy == torch == jax to fp tolerance; SVI
closed-form oracles validate the non-uniform divided-difference stencils
(second-order convergence) and Durrleman
g;models.fast_blackvalidates the surface's own normalized-Black pricing to machine epsilon.
fast_vollib.diagnostics— six publication-quality figures (total-variance slices, Durrlemang, risk-neutral density, violation heatmap, calendar map, round-trip trust map), gated behind a new[viz]extra (pip install "fast-vollib[viz]"). Matplotlib stays out of the numerics core dependencies.
[0.1.6] — 2026-06-27¶
Fixed¶
- CUDA tensor inputs to
fast_implied_volatility— passing a CUDA-residenttorch.Tensor(or any CPU tensor withrequires_grad=True) raisedTypeError: can't convert cuda:0 device type tensor to numpybecauseto_numpy()fell through tonp.asarray(value), which invokedTensor.__array__()→.numpy()— illegal for both cases.to_numpy()now detects torch tensors viatype(value).__module__and calls.detach().cpu().numpy()before the conversion. All other input types (numpy arrays, pandas, scalars, lists, JAX arrays) are unaffected. Note:.detach()means gradients do not flow through IV inversion; the compute still round-trips through host numpy. A fully differentiable GPU- resident IV path remains a separate feature request.
[0.1.5] — 2026-05-29¶
Added¶
- Python 3.10 support — lowered
requires-pythonfrom>=3.11to>=3.10, added theProgramming Language :: Python :: 3.10classifier, and extended the CI test matrix to cover 3.10 alongside 3.11–3.13. - Opt-in shape-aware runtime type checking — pure-annotation layer
(
jaxtyping+beartype) applied to the public API (fast_black,fast_black_scholes,fast_black_scholes_merton,fast_implied_volatility,fast_implied_volatility_black,get_all_greeks,price_dataframe, thevectorized_*Greeks) and to the four backend dispatch entry points (price_*,greeks,implied_volatility).- Annotations are stored as PEP 563 strings (every annotated module uses
from __future__ import annotations) — zero runtime cost when not enabled. - Runtime checking is scoped to the public dispatch layer only via
fast_vollib._typing.enable_runtime_checks(). Innertorch.compileclosures, Triton kernels, Numba@njitfactories, and JAX@jax.jit-traced functions are never decorated or rewritten, so the hot paths are bit-identical to the un-annotated build (verified with sha256 fingerprints of thejackel_ivnumpy / torch / triton outputs before and after). - Install via the new
[typecheck]extra:pip install "fast-vollib[typecheck]"(addsjaxtyping>=0.2andbeartype>=0.18). Default installs do not pull either package intosys.modules.
- Annotations are stored as PEP 563 strings (every annotated module uses
[0.1.4] — 2026-04-10¶
Added¶
fast_vollib.jackelmodule — full implementation of Peter Jäckel's "Let's Be Rational" (2016) algorithm with four backends:jackel_iv_black— NumPy + Numba (six parallel kernels; ~8.5 ms / 100k)jackel_iv_black_torch— PyTorch withtorch.compile(dynamic=True)(~2.7 ms GPU compute)jackel_iv_black_jax— JAXlax.fori_loop+@jax.jit(~2.4 ms GPU compute)jackel_iv_triton— single-pass Triton kernel; entire pipeline in registers (0.056 ms GPU compute / 100k)
- Dedicated test package
tests/test_jackel/with parity tests againstpy_lets_be_rational(oracle); max relative error < 10⁻⁸. py-lets-be-rationaladded to thedevdependency group so CI installs the oracle automatically.-
scripts/jackel_triton_bench.py— correctness + CUDA-event timing script for the Triton kernel. -
Numba backend (
backend="numba"): JIT-compiled CPU kernels via@numba.njit(parallel=True). Pricing, Greeks, and the full Halley+bisection IV solver run as a single native-code dispatch per batch. Enabled bypip install "fast-vollib[numba]"(requiresnumba>=0.60.0). Kernels are compiled on first call and cached to__pycache__for subsequent runs. - Isolated numba test suite under
tests/numba/(skipped automatically when numba is not installed).
Fixed¶
get_all_greeks(..., return_native=True)now returns native torch/JAX arrays instead of formatting the result back into pandas containers.- Below-intrinsic IV handling now honors
on_error=consistently across the NumPy, PyTorch, and JAX backends. - The
compare_against_py_vollib_vectorized.pyhelper now imports the current upstreamvectorized_*entry points correctly.
[0.1.3] — 2026-04-04¶
- Added backend_parity tests for torch
- Updated tutorial notebook with Mac MPS backend (for Apple silicon chips).
0.1.2 — 2026-03-26¶
Release focused on packaging automation, public release channels, and broader compatibility coverage.
Added¶
- Development and nightly-style build publishing to TestPyPI from
mainusing trusted publishing via GitHub Actions OIDC. - Additional test coverage for backend parity, packaging consistency, and release workflow support.
- Monkey-patching support for baseline replacement workflows, including
py_vollib_vectorizedcompatibility-oriented patch helpers.
Changed¶
- Versioning is now derived from Git tags via VCS-based build metadata, so
stable PyPI releases are tag-driven and development snapshots use
.devNversions automatically.
0.1.1 — 2026-03-26¶
First public release after the initial beta version. This release improves runtime correctness, tightens packaging and typing metadata, and aligns backend behaviour across NumPy, PyTorch, and JAX.
Fixed¶
price_dataframenow raises explicitValueErrorexceptions instead of relying on bareassertguards.- The JAX implied-volatility backend now returns
NaNfor below-intrinsic and zero-price inputs, matching NumPy and PyTorch behaviour. - Backend configuration is now standardized on
FAST_VOLLIB_BACKEND;
Added¶
py.typedmarker for PEP 561-compatible downstream type-checking.- Packaging metadata improvements, including explicit mypy configuration and updated Python version support metadata.
0.1.0 — 2026-03-22¶
Features¶
- Pricing —
fast_black,fast_black_scholes,fast_black_scholes_mertonwith full NumPy vectorization and broadcasting. - Implied Volatility —
fast_implied_volatilityandfast_implied_volatility_blackusing Halley's method with a compiled bisection fallback (~10 M solves / s on CPU). - Greeks —
vectorized_delta,vectorized_gamma,vectorized_theta,vectorized_rho,vectorized_vega, andget_all_greeks. - Backend routing — pluggable NumPy, PyTorch, and JAX backends with
automatic resolution (
FAST_VOLLIB_BACKENDenv var,set_backend(), per-callbackend=kwarg). - DataFrame helper —
price_dataframefor end-to-end pricing, IV solving, and Greek computation on apandas.DataFrame. - Compatibility — patch helpers for
py_vollibandpy_vollib_vectorizednamespaces at runtime.
Fixed¶
- Corrected Black-76 forward pricing formula (
q = r, notq = 0). - Added below-intrinsic NaN guard in the PyTorch IV solver.
Performance¶
- Pre-computed CDF symmetry (
N(-x) = 1 - N(x)) eliminating 5 redundant CDF evaluations per option in the Greeks hot path. - Reduced CDF calls in pricing hot path using the same symmetry identity.
- Compiled bisection fallback yields a 16× throughput improvement on large WRDS-scale datasets compared to the pure Python fallback.