Skip to main content

Fast options pricing, Greeks, and implied volatility for Black-76, Black-Scholes, and Black-Scholes-Merton. Rust core.

Project description

OpenGreeks

Fast options pricing & Greeks for Python — Rust core, drop-in for vollib / py_vollib.

pip install opengreeks

Up to 183× faster than vollib. Bit-identical Greeks. One dependency.

OpenGreeks reimplements the Black-76, Black-Scholes, and Black-Scholes-Merton pricing paths in zero-dependency Rust, exposed through PyO3 with the same function names and signatures as py_vollib / vollib. Migration is a one-line import swap; the math is unchanged.

And it goes further than vollib ever did: alongside the first-order Greeks, OpenGreeks ships a complete second- and third-order Greek surface — vanna, charm, vomma, speed, zomma, color, veta, ultima, dual delta, dual gamma — on all three models, each validated to ~1e-13 against automatic differentiation.

Headline speedups vs vollib==1.0.7 (latest canonical)

Workload vollib 1.0.7 OpenGreeks Speedup
Black-76 chain — vega × 177 strikes 795 µs 4.3 µs 183×
Black-76 chain — delta × 177 strikes 695 µs 6.3 µs 110×
Black-76 chain — all-5 Greeks × 200 options ~4.2 ms ~45 µs ~94×
Black-76 chain — price × 177 strikes 812 µs 9.4 µs 86×
Implied volatility, single call 28.75 µs 0.50 µs 58×
Black-76 IV × 177-strike chain 4.37 ms 0.26 ms 17×
Black-76 theta (scalar) 11.38 µs 0.33 µs 34×
Black-Scholes IV (scalar) 18.88 µs 0.50 µs 38×
BSM IV (scalar) 18.83 µs 0.50 µs 38×

A full NIFTY option chain refresh (~200 options, all 5 Greeks + IV) drops from ~9 ms in vollib to ~0.3 ms in OpenGreeks — the difference between "saturates a core at 100 Hz" and "uses ~3% of one core."

Parity that lets you trust the swap

29 edge cases × 3 models × 7 functions each, validated against vollib==1.0.7:

Greek max abs error vs vollib
delta, gamma, vega, theta, rho 0.0e+00 — bit-for-bit identical
price 1.4e-12 (rel 1.7e-14, ~14 digits)
IV (well-conditioned) 8.6e-10

Textbook anchors (Hull 13.6, Hull 17.1, Haug page 4) all pass. Full report: bench/RESULTS.md.

One dependency, not seven

Package Runtime dependencies
pip install vollib py_lets_be_rational, cody_special, piecewise_rational, simplejson, numpy, pandas, scipy
pip install opengreeks numpy

No pandas, no scipy, no Cython build hell, no _testcapi import errors on minimal Python distributions.


Inspired by py_vollib and vollib by Gammon Capital LLC — same function names, same argument order, same numerical conventions. OpenGreeks reimplements the pricing math in Rust to deliver the speed and dependency wins above without changing any of the math.

Model OpenGreeks submodule vollib equivalent
Black-76 (futures options) opengreeks.black76 vollib.black
Black-Scholes (no dividends) opengreeks.black_scholes vollib.black_scholes
Black-Scholes-Merton (dividends) opengreeks.black_scholes_merton vollib.black_scholes_merton

Function names, argument order, and numerical conventions (vega × 0.01, theta / 365, rho × 0.01) match vollib exactly.


Quick start

Black-76 (futures / NIFTY options)

from opengreeks.black76 import black, implied_volatility, delta, gamma, vega, theta, rho

F, K, t, r, sigma = 22000.0, 22000.0, 30/365, 0.07, 0.18
price = black('c', F, K, t, r, sigma)        # 450.27
iv    = implied_volatility(price, F, K, r, t, 'c')   # 0.18
d     = delta('c', F, K, t, r, sigma)
g     = gamma('c', F, K, t, r, sigma)
v     = vega ('c', F, K, t, r, sigma)
th    = theta('c', F, K, t, r, sigma)
rh    = rho  ('c', F, K, t, r, sigma)

Black-Scholes (equity, no dividend)

from opengreeks.black_scholes import black_scholes, implied_volatility, delta

price = black_scholes('c', 100.0, 90.0, 0.5, 0.01, 0.20)  # 12.111581

Black-Scholes-Merton (equity with continuous dividend yield)

from opengreeks.black_scholes_merton import black_scholes_merton, implied_volatility, delta

price = black_scholes_merton('p', 100.0, 95.0, 0.5, 0.10, 0.20, 0.05)  # 2.4648 (Haug p.4)

Chain-wide computation (NumPy batch)

For option-chain analytics, use the *_array variants — one PyO3 boundary crossing, internal tight loop:

import numpy as np
from opengreeks import black76

K = np.linspace(20000.0, 24000.0, 200)
F = np.full_like(K, 22000.0)
t = np.full_like(K, 30/365)
s = np.full_like(K, 0.18)

prices = black76.black_array('c', F, K, t, 0.07, s)
ivs    = black76.implied_volatility_array(prices, F, K, 0.07, t, 'c')
deltas = black76.delta_array('c', F, K, t, 0.07, s)

Second- & third-order Greeks (what vollib never had)

Risk that first-order Greeks miss — how your delta drifts as vol moves, where gamma is about to spike, how vega bleeds into expiry — lives in the higher-order Greeks. OpenGreeks exposes all of them, on every model, with the same (flag, F/S, K, t, r, sigma[, q]) signature as the first-order Greeks:

from opengreeks.black76 import vanna, charm, vomma, speed, zomma, color, veta, ultima

F, K, t, r, sigma = 22000.0, 22000.0, 30/365, 0.07, 0.18
vanna('c', F, K, t, r, sigma)   # ∂delta/∂σ  — how your delta moves when IV moves
charm('c', F, K, t, r, sigma)   # ∂delta/∂τ  — delta bleed per year of time decay
vomma('c', F, K, t, r, sigma)   # ∂vega/∂σ   — vega convexity (vol-of-vol exposure)

Every Greek has a NumPy batch twin (vanna_array, charm_array, …) for whole-chain analytics in a single call.

Greek What it tells a trader Definition
vanna How delta shifts as IV moves (and how vega shifts as spot moves) ∂²V/∂S∂σ
charm Delta decay — how your hedge drifts purely from time passing ∂delta/∂τ
vomma Vega convexity — whether long-vol positions get longer as vol rises ∂²V/∂σ²
speed How fast gamma changes with spot — gamma-of-gamma ∂³V/∂S³
zomma How gamma changes as IV moves ∂gamma/∂σ
color Gamma decay — how gamma changes as expiry approaches ∂gamma/∂τ
veta Vega decay — how vega bleeds with time ∂vega/∂τ
ultima Sensitivity of vomma to vol — third-order vol risk ∂³V/∂σ³
dual delta Risk-neutral prob. of finishing ITM (strike sensitivity) ∂V/∂K
dual gamma Density of the terminal price at the strike ∂²V/∂K²

Conventions: raw mathematical partials (no per-day / per-1% rescaling); τ-derivatives (charm, color, veta) are per year of time-to-expiry. The same engine powers opengreeks.black_scholes and opengreeks.black_scholes_merton.

Validated against automatic differentiation

vollib ships no second-order Greeks, so there is no library oracle to match. Instead every formula is checked against autograd automatic differentiation of the option price — exact partials, zero hand-derivation risk:

max relative error vs autograd
all 10 Greeks × 3 models < 1.2e-13 — machine precision

Speed vs pure Python

There is nothing in vollib to race against here, so the baseline is a hand-written pure-Python (math) implementation of the identical closed forms:

Workload pure Python OpenGreeks Speedup
Higher-order Greek — scalar call ~0.7–1.1 µs ~0.42 µs ~2×
Higher-order Greek — 177-strike chain (*_array) ~95–165 µs ~4–8 µs 20–31×

The batch path crosses the Python↔Rust boundary once and loops in native code — so a full chain of second-order Greeks costs single-digit microseconds. Reproduce with bench/bench_second_order.py.


Migrating from py_vollib / vollib

The function signatures are byte-identical. Migration is a one-line import swap.

Before:

from py_vollib.black.implied_volatility import implied_volatility as black_iv
from py_vollib.black.greeks.analytical import delta as black_delta, gamma as black_gamma

After:

from opengreeks.black76 import implied_volatility as black_iv
from opengreeks.black76 import delta as black_delta, gamma as black_gamma

The aliases (as black_iv etc.) keep the rest of your code unchanged.

Old import New import
from py_vollib.black import black from opengreeks.black76 import black
from py_vollib.black.implied_volatility import implied_volatility from opengreeks.black76 import implied_volatility
from py_vollib.black.greeks.analytical import delta, gamma, vega, theta, rho from opengreeks.black76 import delta, gamma, vega, theta, rho
from py_vollib.black_scholes import black_scholes from opengreeks.black_scholes import black_scholes
from py_vollib.black_scholes_merton import black_scholes_merton from opengreeks.black_scholes_merton import black_scholes_merton

Reproducing the benchmarks

Want to verify the speedups on your hardware before you commit? Two-command repro:

# Install the baseline + opengreeks itself
pip install 'vollib>=1.0.7' 'py_lets_be_rational>=1.0.1' numpy opengreeks

# Run the bench against your CPU
python -c "import urllib.request; exec(urllib.request.urlopen('https://raw.githubusercontent.com/marketcalls/opengreeks/main/bench/bench_parity.py').read())"

Or clone the repo and run bench/bench_parity.py — prints a full parity + performance report in ~30 seconds. Headline numbers above are reproducible.

Full report including all 29 edge cases and chain-wide tables: bench/RESULTS.md.


Project layout

OpenGreeks/                          # this monorepo
├── pyproject.toml                   # name = "opengreeks"   →   pip install opengreeks
├── Cargo.toml                       # Rust workspace
├── src/lib.rs                       # PyO3 cdylib  _opengreeks
├── python/opengreeks/
│   ├── __init__.py
│   ├── black76.py                   # opengreeks.black76 — vollib.black equivalent
│   ├── black_scholes.py             # opengreeks.black_scholes
│   └── black_scholes_merton.py      # opengreeks.black_scholes_merton
├── black76_rust/                    # pure-Rust Black-76 core (zero deps)
├── bsm_rust/                        # pure-Rust BSM (BS via q=0); depends on black76_rust
├── bench/
│   ├── bench_parity.py              # first-order parity + performance vs vollib
│   ├── bench_second_order.py        # higher-order Greeks: autograd correctness + pure-Python speed
│   └── RESULTS.md                   # full report
└── .github/workflows/CI.yml         # cargo test + wheel matrix + PyPI publish

Future pricing models (Heston stochastic vol, SABR, American/Bermudan via tree, etc.) slot in as new <model>_rust/ crates + opengreeks.<model> submodules without breaking the published API.


Build from source

# Toolchain
rustup default stable
pip install maturin

# Develop install into a venv
cd OpenGreeks/
maturin develop --release

# Or build a wheel
maturin build --release
pip install target/wheels/opengreeks-*.whl

Run tests

# Rust crates
cargo test --release

# Python parity + performance bench (first-order, vs vollib)
pip install 'vollib>=1.0.7' 'py_lets_be_rational>=1.0.1' numpy
python bench/bench_parity.py

# Second/third-order Greeks: correctness (autograd) + speed (vs pure Python)
pip install autograd numpy
python bench/bench_second_order.py

Dependencies

Layer Dependencies
Rust core (black76_rust, bsm_rust) None — std math only
PyO3 wrapper (build-time) pyo3, numpy Rust crates
Python runtime numpy only

Compare to vollib==1.0.7 which pulls in py_lets_be_rational, cody_special, piecewise_rational, simplejson, numpy, pandas, scipy (7 packages including pandas & scipy).


Credits & inspiration

OpenGreeks is a Rust reimplementation that takes its public API directly from py_vollib / vollib (© 2017 Gammon Capital LLC, MIT-licensed) — function names, argument orders, return-value conventions, and per-day theta / per-1% vega-rho scaling. The vollib code base is the canonical Python reference for these formulas and we recommend it as the parity oracle when validating any port.

Algorithmic credit:

  • Peter Jäckel — "Let's Be Rational" (jaeckel.org). The IV inversion algorithm used by py_lets_be_rational and by future versions of OpenGreeks.
  • W. J. Cody — "Rational Chebyshev approximations for the error function" (Math. Comp., 1969). Used for the normal CDF in both libraries.
  • A. R. Wichura — "Algorithm AS 241" (Appl. Stat., 1988). Inverse normal CDF.
  • John Hull and Espen Haug — textbook formula references; their Black-76 / BS / BSM examples are the validation anchors in bench/bench_parity.py.

License

MIT — Copyright (c) 2026 Marketcalls / Rajandran R. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opengreeks-0.2.0.tar.gz (39.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

opengreeks-0.2.0-cp39-abi3-win_amd64.whl (248.2 kB view details)

Uploaded CPython 3.9+Windows x86-64

opengreeks-0.2.0-cp39-abi3-manylinux_2_28_x86_64.whl (295.2 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ x86-64

opengreeks-0.2.0-cp39-abi3-manylinux_2_28_aarch64.whl (277.0 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

opengreeks-0.2.0-cp39-abi3-macosx_11_0_arm64.whl (264.6 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

opengreeks-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl (281.2 kB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file opengreeks-0.2.0.tar.gz.

File metadata

  • Download URL: opengreeks-0.2.0.tar.gz
  • Upload date:
  • Size: 39.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for opengreeks-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7367aff980cbb48346b9d9a25da04122bc1bc8f19b3203cd94af2bfae0cbe15b
MD5 2f9ac10fd3a2bc8617515620c744132b
BLAKE2b-256 1e31d7886e613d822b92556dde7c132a598585d8f50c2c89be4323021ffa11d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for opengreeks-0.2.0.tar.gz:

Publisher: CI.yml on marketcalls/opengreeks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opengreeks-0.2.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: opengreeks-0.2.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 248.2 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for opengreeks-0.2.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5a4ff92ddd6bd9268b5cf0b94a3e4069b5170445604fe91e9303a5ae896bdda2
MD5 8e55ccc20175a31ec3b50fa95dbe1506
BLAKE2b-256 08a7e27dd79c3ef892ac955084e91de85764ad924fc845a9d7de37d96668066f

See more details on using hashes here.

Provenance

The following attestation bundles were made for opengreeks-0.2.0-cp39-abi3-win_amd64.whl:

Publisher: CI.yml on marketcalls/opengreeks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opengreeks-0.2.0-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for opengreeks-0.2.0-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bb832b3bfeaa89d9b4bd698d738d44a69eff1e7006ee84ec9cc49f3cd3d8bd21
MD5 2da52832cf1741a3bc1168e2a9f67d12
BLAKE2b-256 8ef92a01f49db7771bf1c112ef94c9732dbd36bf2a0f81c4c8efea87745b6f50

See more details on using hashes here.

Provenance

The following attestation bundles were made for opengreeks-0.2.0-cp39-abi3-manylinux_2_28_x86_64.whl:

Publisher: CI.yml on marketcalls/opengreeks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opengreeks-0.2.0-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for opengreeks-0.2.0-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0302759a7ea17c023923ae02e20f7f4fb53033ee11c3b69dd026db11f6c31ffb
MD5 6d5c86e68929a89b6b81561bf9fc4af2
BLAKE2b-256 152f61f158c13c4d48a7dca84fd0976331612166eb1e6e7571f2d97b67651965

See more details on using hashes here.

Provenance

The following attestation bundles were made for opengreeks-0.2.0-cp39-abi3-manylinux_2_28_aarch64.whl:

Publisher: CI.yml on marketcalls/opengreeks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opengreeks-0.2.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for opengreeks-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7379af064ace12513a9a945ea8757e5a2fe231f6b77abf175994f2353a457b8e
MD5 483421eed6bdc937619a7bbe1ce137f2
BLAKE2b-256 e67b6716bf5ebcd22a579cb036d415a547ae55a4f7729114e089ba9588799844

See more details on using hashes here.

Provenance

The following attestation bundles were made for opengreeks-0.2.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: CI.yml on marketcalls/opengreeks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opengreeks-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for opengreeks-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 648ffb8f1bf52458f19c8457a3761fd78b5c44281e20715e4ca47f0f5bb80f3f
MD5 037a983fc298bb3ce33370ad046fb6a9
BLAKE2b-256 936d1a5566c1816d9c40782c1094b696934517cf1ac1e4063f5f995ac8feac52

See more details on using hashes here.

Provenance

The following attestation bundles were made for opengreeks-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: CI.yml on marketcalls/opengreeks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page