Skip to content

Commit dfd42f6

Browse files
committed
Docs
1 parent 74695a1 commit dfd42f6

27 files changed

Lines changed: 825 additions & 98 deletions

.github/copilot-instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ applyTo: '/**'
1212

1313
* Always run `make lint` after code changes — runs taplo, isort, black, ruff, and mypy
1414
* Never edit `readme.md` directly — it is generated from `docs/index.md` via `make docs`
15+
* To install all dependencies (including all optional extras) run `make install-dev` — runs `uv sync --all-extras`
1516
* To run all tests use `make test` — runs all tests in the `tests/` directory using pytest
1617
* To run a specific test file, use `uv run pytest tests/path/to/test_file.py`
1718

@@ -28,6 +29,7 @@ applyTo: '/**'
2829
* Documentation is built using [mkdocs](https://www.mkdocs.org/) and stored in the `docs/` directory. The documentation source files are written in markdown format.
2930
* Do not use em dashes (—) in documentation files or docstrings. Use colons, parentheses, or restructure the sentence instead.
3031
* Math in documentation and docstrings uses `$...$` for inline and `$$...$$` or `\begin{equation}...\end{equation}` for block equations. Do not use `.. math::` or `:math:` (RST syntax).
32+
* Glossary entries in `docs/glossary.md` must be kept in alphabetical order.
3133
* To rebuild doc examples run `uv run ./dev/build-examples` — runs all scripts in `docs/examples/` and writes their output to `docs/examples_output/`
3234

3335
## Package structure

app/volatility_surface.py

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import marimo
22

3-
__generated_with = "0.20.4"
3+
__generated_with = "0.22.0"
44
app = marimo.App(width="medium")
55

66

@@ -42,58 +42,47 @@ def _(mo):
4242
return
4343

4444

45+
@app.cell
46+
def _():
47+
kwargs = dict()
48+
return
49+
50+
4551
@app.cell
4652
def _(mo):
53+
asset = mo.ui.dropdown(["btc", "eth", "sol"], value="btc", label="asset")
4754
inverse = mo.ui.checkbox(value=True, label="Inverse options")
48-
inverse
49-
return (inverse,)
55+
mo.hstack([asset, inverse])
56+
return asset, inverse
5057

5158

5259
@app.cell
53-
async def _(inverse):
60+
async def _(asset, inverse):
5461
import pandas as pd
5562
from quantflow.data.deribit import Deribit
5663

5764
async with Deribit() as cli:
58-
loader = await cli.volatility_surface_loader("eth", exclude_open_interest=0, inverse=inverse.value)
65+
loader = await cli.volatility_surface_loader(
66+
asset.value,
67+
inverse=inverse.value,
68+
use_perp=not inverse.value
69+
)
5970

6071
# build the volatility surface
6172
surface = loader.surface()
6273
# calculate black implied volatilities
6374
surface.bs()
6475
# disable outliers
6576
surface.disable_outliers()
66-
# display inputs - only options with converged implied volatility
67-
surface_inputs = surface.inputs(converged=True)
68-
pd.DataFrame([i.model_dump() for i in surface_inputs.inputs])
69-
return (surface,)
70-
71-
72-
@app.cell(hide_code=True)
73-
def _(mo):
74-
mo.md(r"""
75-
##Volatility Surface
76-
""")
77-
return
78-
79-
80-
@app.cell
81-
def _(surface):
8277
surface.plot3d()
83-
return
84-
85-
86-
@app.cell(hide_code=True)
87-
def _(mo):
88-
mo.md(r"""
89-
## Term Structure
90-
""")
91-
return
78+
return pd, surface
9279

9380

9481
@app.cell
95-
def _(surface):
96-
surface.term_structure()
82+
def _(pd, surface):
83+
# display inputs - only options with converged implied volatility
84+
surface_inputs = surface.inputs(converged=True)
85+
pd.DataFrame([i.model_dump() for i in surface_inputs.inputs])
9786
return
9887

9988

docs/api/index.md

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,71 @@
1-
# API
1+
# API Reference
22

3-
Here's the reference or code API, the classes, functions, parameters, attributes, and all the quantflow parts you can use in your applications.
3+
Complete reference for all public classes, functions, and parameters in the quantflow library.
4+
5+
## Modules
6+
7+
### [Data](data/index.md)
8+
9+
Clients for fetching market data from external sources. Requires the optional `data` extra:
10+
11+
```
12+
pip install quantflow[data]
13+
```
14+
15+
| Module | Description |
16+
|---|---|
17+
| [Deribit](data/deribit.md) | Crypto options and futures from the Deribit exchange |
18+
| [Financial Modeling Prep](data/fmp.md) | Equity prices, profiles, and sector data |
19+
| [FRED](data/fred.md) | US macroeconomic time series from the St. Louis Fed |
20+
| [Federal Reserve](data/fed.md) | Federal Reserve H.15 interest rate data |
21+
22+
### [Options](options/index.md)
23+
24+
Option pricing, volatility surface construction, and model calibration.
25+
26+
| Module | Description |
27+
|---|---|
28+
| [Black-Scholes](options/black.md) | Black-76 pricing formula and implied volatility inversion |
29+
| [Pricer](options/pricer.md) | Model-based option pricer supporting any stochastic process |
30+
| [Volatility Surface](options/vol_surface.md) | Build and serialise implied volatility surfaces from market data |
31+
| [Calibration](options/calibration.md) | Calibrate Heston and Heston-jump-diffusion models to a surface |
32+
| [Deep IV Factor Model](options/divfm.md) | Neural-network option pricing via the DIVFM architecture |
33+
34+
### [Stochastic Processes](sp/index.md)
35+
36+
Continuous-time stochastic processes used as underlying models for option pricing and simulation.
37+
38+
| Module | Description |
39+
|---|---|
40+
| [Weiner Process](sp/weiner.md) | Geometric Brownian motion (constant volatility) |
41+
| [Heston Model](sp/heston.md) | Stochastic volatility with optional jump component (HestonJ) |
42+
| [Jump Diffusion](sp/jump_diffusion.md) | Compound Poisson jump processes |
43+
| [CIR Process](sp/cir.md) | Cox-Ingersoll-Ross mean-reverting process |
44+
| [Ornstein-Uhlenbeck](sp/ou.md) | Ornstein-Uhlenbeck mean-reverting process |
45+
| [Poisson Process](sp/poisson.md) | Homogeneous Poisson process |
46+
| [Compound Poisson](sp/compound_poisson.md) | Poisson arrivals with a jump-size distribution |
47+
| [Doubly Stochastic Poisson](sp/dsp.md) | Poisson process with stochastic intensity |
48+
49+
### [Technical Analysis](ta/index.md)
50+
51+
Time series filters and indicators for financial data.
52+
53+
| Module | Description |
54+
|---|---|
55+
| [EWMA](ta/ewma.md) | Exponentially weighted moving average |
56+
| [Kalman Filter](ta/kalman.md) | Kalman filter for state estimation |
57+
| [Supersmoother](ta/supersmoother.md) | Ehlers two-pole supersmoother filter |
58+
| [OHLC](ta/ohlc.md) | OHLC bar utilities and resampling |
59+
| [Paths](ta/paths.md) | Simulated path containers and statistics |
60+
61+
### [Utilities](utils/index.md)
62+
63+
Low-level building blocks used throughout the library.
64+
65+
| Module | Description |
66+
|---|---|
67+
| [Distributions](utils/distributions.md) | Jump-size distributions (Normal, DoubleExponential) |
68+
| [Marginal 1D](utils/marginal1d.md) | Marginal distribution via characteristic function inversion |
69+
| [Bins](utils/bins.md) | Histogram binning helpers |
70+
| [Numbers](utils/numbers.md) | Decimal and float numeric utilities |
71+
| [Types](utils/types.md) | Shared type aliases |

docs/api/options/vol_surface.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131

3232
::: quantflow.options.surface.OptionSelection
3333

34-
::: quantflow.options.inputs.OptionType
34+
::: quantflow.options.surface.surface_from_inputs
3535

3636
## Vol Surface Inputs
3737

38+
::: quantflow.options.inputs.OptionType
39+
3840
::: quantflow.options.inputs.VolSurfaceInputs
3941

4042
::: quantflow.options.inputs.VolSurfaceInput

docs/api/sp/copula.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copulas
2+
3+
::: quantflow.sp.copula.Copula
4+
5+
6+
::: quantflow.sp.copula.IndependentCopula
7+
8+
9+
::: quantflow.sp.copula.FrankCopula
10+
34.6 KB
Loading
35.1 KB
Loading
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import json
2+
3+
from quantflow.options.calibration import HestonCalibration
4+
from quantflow.options.pricer import OptionPricer
5+
from quantflow.options.surface import VolSurface, VolSurfaceInputs, surface_from_inputs
6+
from quantflow.sp.heston import Heston
7+
8+
# Load a saved volatility surface snapshot and build the surface
9+
with open("quantflow_tests/volsurface.json") as fp:
10+
surface: VolSurface = surface_from_inputs(VolSurfaceInputs(**json.load(fp)))
11+
12+
surface.bs()
13+
surface.disable_outliers()
14+
15+
# Create a Heston pricer with initial parameters
16+
pricer = OptionPricer(model=Heston.create(vol=0.5, kappa=1, sigma=0.8, rho=0))
17+
18+
# Set up the calibration, dropping the first (very short) maturity and high-vol wings
19+
calibration = HestonCalibration(
20+
pricer=pricer,
21+
vol_surface=surface.trim(len(surface.maturities) - 1),
22+
moneyness_weight=1.0,
23+
).remove_implied_above(quantile=0.95)
24+
25+
result = calibration.fit()
26+
print(result.message)
27+
params = calibration.get_params()
28+
model = calibration.model
29+
print(f"vol: {model.variance_process.rate**0.5:.4f}")
30+
print(f"theta: {model.variance_process.theta**0.5:.4f}")
31+
print(f"kappa: {model.variance_process.kappa:.4f}")
32+
print(f"sigma: {model.variance_process.sigma:.4f}")
33+
print(f"rho: {model.rho:.4f}")
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import json
2+
from pathlib import Path
3+
4+
from quantflow.options.calibration import HestonCalibration
5+
from quantflow.options.pricer import OptionPricer
6+
from quantflow.options.surface import VolSurface, VolSurfaceInputs, surface_from_inputs
7+
from quantflow.sp.heston import Heston
8+
9+
# Load a saved volatility surface snapshot and build the surface
10+
with open("quantflow_tests/volsurface.json") as fp:
11+
surface: VolSurface = surface_from_inputs(VolSurfaceInputs(**json.load(fp)))
12+
13+
surface.bs()
14+
surface.disable_outliers()
15+
16+
# Create a Heston pricer and calibrate
17+
pricer = OptionPricer(model=Heston.create(vol=0.5, kappa=1, sigma=0.8, rho=0))
18+
calibration = HestonCalibration(
19+
pricer=pricer,
20+
vol_surface=surface.trim(len(surface.maturities) - 1),
21+
moneyness_weight=1.0,
22+
).remove_implied_above(quantile=0.95)
23+
calibration.fit()
24+
25+
# Plot the calibrated smile for the second maturity and save as PNG
26+
fig = calibration.plot(index=1, max_moneyness_ttm=1.5, support=101)
27+
fig.update_layout(
28+
xaxis_title="Moneyness / sqrt(T)",
29+
yaxis_title="Implied Volatility",
30+
title="Heston Calibrated Smile — Maturity 2",
31+
)
32+
33+
out_path = Path("docs/assets/heston_calibrated_smile.png")
34+
fig.write_image(str(out_path), width=900, height=500)
35+
print(f"saved {out_path}")
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import json
2+
3+
from quantflow.options.calibration import HestonJCalibration
4+
from quantflow.options.pricer import OptionPricer
5+
from quantflow.options.surface import VolSurface, VolSurfaceInputs, surface_from_inputs
6+
from quantflow.sp.heston import HestonJ
7+
from quantflow.utils.distributions import DoubleExponential
8+
9+
# Load a saved volatility surface snapshot and build the surface
10+
with open("quantflow_tests/volsurface.json") as fp:
11+
surface: VolSurface = surface_from_inputs(VolSurfaceInputs(**json.load(fp)))
12+
13+
surface.bs()
14+
surface.disable_outliers()
15+
16+
# Create a HestonJ pricer with initial parameters
17+
pricer = OptionPricer(
18+
model=HestonJ.create(
19+
DoubleExponential,
20+
vol=0.5,
21+
kappa=2,
22+
rho=-0.2,
23+
sigma=0.8,
24+
jump_fraction=0.3,
25+
jump_asymmetry=0.2,
26+
)
27+
)
28+
29+
# Set up the calibration, dropping the first (very short) maturity and high-vol wings
30+
calibration = HestonJCalibration(
31+
pricer=pricer,
32+
vol_surface=surface.trim(len(surface.maturities) - 1),
33+
moneyness_weight=1.0,
34+
).remove_implied_above(quantile=0.95)
35+
36+
result = calibration.fit()
37+
print(result.message)
38+
model = calibration.model
39+
print(f"vol: {model.variance_process.rate**0.5:.4f}")
40+
print(f"theta: {model.variance_process.theta**0.5:.4f}")
41+
print(f"kappa: {model.variance_process.kappa:.4f}")
42+
print(f"sigma: {model.variance_process.sigma:.4f}")
43+
print(f"rho: {model.rho:.4f}")
44+
print(f"jump intensity: {model.jumps.intensity:.4f}")
45+
print(f"jump variance: {model.jumps.jumps.variance():.6f}")
46+
print(f"jump asymmetry: {model.jumps.jumps.asymmetry():.4f}")

0 commit comments

Comments
 (0)