Skip to main content
Python 3.9+

Vanilla Option Calculator

Black-Scholes-Merton pricing and greeks for vanilla options, written in pure Python — no NumPy, no SciPy, no other numerical dependencies. The only external dependency is matplotlib, and only for the optional plotting layer.

  • Theoretical price and greeks: Theo, Delta, Theta, Vega, Gamma
  • Portfolio aggregation and mark-to-market P&L across many positions
  • Price-grid visualisation (P&L / Delta / Theta / Vega / Gamma)
  • Delta-neutral price search
  • Optional risk-free rate r (defaults to 0, the rates-free crypto convention)

Installation

pip install .            # core only (standard library)
pip install ".[plot]"    # + matplotlib for the plotting layer
pip install ".[dev]"     # + pytest and ruff for development

Or, for development, install in editable mode:

pip install -e ".[plot,dev]"

Quick start

Price and greeks of a single option

from option_calculator import BSM

calc = BSM()

S = 19500          # underlying price
K = 19000          # strike
V = 0.45           # implied volatility as a fraction (45%)
T = 30 / 365       # time to expiry in years
dType = "P"        # 'C' call, 'P' put, 'F' future

print("Theo: ", round(calc.theo(S, K, V, T, dType), 2))
print("Delta:", round(calc.delta(S, K, V, T, dType), 2))
print("Theta:", round(calc.theta(S, K, V, T, dType), 2))
print("Vega: ", round(calc.vega(S, K, V, T), 2))
print("Gamma:", round(calc.gamma(S, K, V, T), 2))

See examples/example_greeks.py.

Portfolio aggregation and plotting

from option_calculator import Plot

plot = Plot()
exp = 30 / 365
params = [
    {"dType": "F", "price": 20000, "quant": 1,  "strike": 0,     "vola": 0,    "exp": exp},
    {"dType": "C", "price": 500,   "quant": 1,  "strike": 25000, "vola": 0.75, "exp": exp},
    {"dType": "P", "price": 100,   "quant": 1,  "strike": 15000, "vola": 0.75, "exp": exp},
]

plot.plotPL(13500, 28500, params, exp, step=10)

print("Delta:", plot.deltaFull(21000, params, exp))
print("P&L:  ", plot.p_l(21000, params, exp))

See examples/example_plot.py.

Position format

A position is either an OptionPosition dataclass or a plain dictionary with the same fields:

Field Meaning
dType 'C' call, 'P' put, 'F' linear future
strike strike price (> 0 for options; use 0 for futures)
vola implied volatility as a fraction (e.g. 0.45)
exp time to expiry in years
quant signed quantity (positive = long, negative = short)
price entry premium / price, used for P&L
from option_calculator import OptionPosition, Pricing

pricing = Pricing()
positions = [OptionPosition("C", 25000, 0.75, 30 / 365, quant=1, price=500)]
print(pricing.deltaFull(21000, positions))

Passing a positional exp to the aggregators overrides every position's expiry (and exp=0 is honoured). Inputs are never mutated.

Conventions and limitations

  • Rate: r is a continuously compounded risk-free rate and defaults to 0.0. With r = 0 the formulas reduce to the classic zero-rate Black-Scholes, the convention used for coin-margined / futures-style crypto options. Pass r= to use the discounted model.
  • Vega is scaled per 1 percentage point of volatility (VEGA_SCALE = 100).
  • Theta is expressed per calendar day (DAYS_PER_YEAR = 365).
  • Degenerate inputs: T = 0 (expired) and V = 0 are valid and yield the discounted intrinsic value with deterministic greeks; other invalid inputs (S ≤ 0, K ≤ 0, V < 0, T < 0, unknown dType) raise ValueError.
  • Only European vanilla options are supported. No dividends, no American exercise, no volatility smile.

Project layout

src/option_calculator/
├── bsm.py         # Black-Scholes-Merton core (pure stdlib)
├── position.py    # OptionPosition dataclass
├── pricing.py     # portfolio aggregation (greeks, P&L, price grid)
├── plot.py        # optional matplotlib layer
└── searching.py   # delta-neutral price search
examples/          # runnable demo scripts
tests/             # pytest suite

Development

pip install -e ".[plot,dev]"
ruff check src tests examples   # lint
ruff format --check src tests examples # formatting
pytest                          # tests

Changelog and releases

See CHANGELOG.md. Releases follow Semantic Versioning; see CONTRIBUTING.md for the release checklist.

License

MIT © 2017 yzoz

Metadata

Release files for option-calculator 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for option-calculator 0.1.0
File Size Uploaded
option_calculator-0.1.0.tar.gz 15.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for option-calculator 0.1.0
File Interpreter ABI Platform
option_calculator-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 28.9 kB

Release files / option_calculator-0.1.0.tar.gz

Download URL option_calculator-0.1.0.tar.gz
Size 15.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5c05ad19a774ceb63afaf0381c3c02fca41a15118d3bc518e84ffd01f2dc4717
BLAKE2b-256 checksum
How to use checksums
cbe1cc8741e797a8948fcb067cf18b355a4122f520cf70217176d5a9f7f5aea2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / option_calculator-0.1.0-py3-none-any.whl

Download URL option_calculator-0.1.0-py3-none-any.whl
Size 13.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c857c9a7be7d44e74605ebddfd2e83e7b766e33b315ac4234060a41cc8a810a2
BLAKE2b-256 checksum
How to use checksums
b7c74e6b80c594e021718f30b2b5ff44b6db5afe4d33fef41b96262780329ad8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page