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 to0, 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:
ris a continuously compounded risk-free rate and defaults to0.0. Withr = 0the formulas reduce to the classic zero-rate Black-Scholes, the convention used for coin-margined / futures-style crypto options. Passr=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) andV = 0are valid and yield the discounted intrinsic value with deterministic greeks; other invalid inputs (S ≤ 0,K ≤ 0,V < 0,T < 0, unknowndType) raiseValueError. - 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)
| File | Size | Uploaded | |
|---|---|---|---|
| option_calculator-0.1.0.tar.gz | 15.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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