Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ applyTo: '/**'

* Always document Pydantic fields with `Field(description=...)` — never use a docstring below a field assignment
* Split long description strings across lines using implicit string concatenation rather than shortening the text
* When a docstring line exceeds the line length limit, split it across multiple lines rather than shortening the text

## Package structure

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ build
dist
.venv
.mypy_cache
.hypothesis
.pytest_cache
.ruff_cache
.python-version
Expand All @@ -37,3 +38,5 @@ _build

# builds
app/docs
docs/assets/examples
docs/examples/output
9 changes: 8 additions & 1 deletion dev/quantflow.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@ FROM ghcr.io/astral-sh/uv:python3.14-bookworm-slim AS builder

WORKDIR /build

# Install Chromium for kaleido (Plotly static image export used by docs examples)
RUN apt-get update && apt-get install -y --no-install-recommends \
chromium \
&& rm -rf /var/lib/apt/lists/*

# Copy dependency files
COPY pyproject.toml uv.lock readme.md ./

# Install dependencies (no root package, with needed extras)
RUN uv sync --frozen --no-install-project --extra ai --extra book --extra docs --extra data

# Copy source and build docs
# Copy source, generate example outputs and images, then build docs
COPY mkdocs.yml ./
COPY dev/ ./dev/
COPY docs/ ./docs/
COPY quantflow/ ./quantflow/
RUN uv run ./dev/build-examples
RUN uv run mkdocs build

# Stage 2: Runtime stage
Expand Down
6 changes: 6 additions & 0 deletions docs/api/sp/heston.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@


::: quantflow.sp.heston.HestonJ


::: quantflow.sp.heston.DoubleHeston


::: quantflow.sp.heston.DoubleHestonJ
45 changes: 43 additions & 2 deletions docs/api/sp/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
# Stochastic Process
# Stochastic Processes

This page gives an overview of all Stochastic Processes available in the library.
This page gives an overview of all stochastic processes available in the library.

## Available processes

### Diffusion

| Process | Description |
|---|---|
| [WeinerProcess][quantflow.sp.weiner.WeinerProcess] | Standard Brownian motion |

### Mean-reverting (intensity)

| Process | Description |
|---|---|
| [CIR][quantflow.sp.cir.CIR] | Cox-Ingersoll-Ross square-root diffusion |
| [Vasicek][quantflow.sp.ou.Vasicek] | Gaussian Ornstein-Uhlenbeck process |
| [GammaOU][quantflow.sp.ou.GammaOU] | Non-Gaussian OU process driven by a Gamma subordinator |

### Jump processes

| Process | Description |
|---|---|
| [PoissonProcess][quantflow.sp.poisson.PoissonProcess] | Homogeneous Poisson process |
| [CompoundPoissonProcess][quantflow.sp.poisson.CompoundPoissonProcess] | Poisson process with random jump sizes |
| [DSP][quantflow.sp.dsp.DSP] | Doubly stochastic (Cox) Poisson process |

### Stochastic volatility

| Process | Description |
|---|---|
| [Heston][quantflow.sp.heston.Heston] | Classical square-root stochastic volatility model |
| [HestonJ][quantflow.sp.heston.HestonJ] | Heston model with compound Poisson jumps |
| [DoubleHeston][quantflow.sp.heston.DoubleHeston] | Two independent Heston variance processes |
| [DoubleHestonJ][quantflow.sp.heston.DoubleHestonJ] | Double Heston with compound Poisson jumps on the second component |

### Jump diffusion

| Process | Description |
|---|---|
| [JumpDiffusion][quantflow.sp.jump_diffusion.JumpDiffusion] | Diffusion with compound Poisson jumps |

## Base classes

::: quantflow.sp.base.StochasticProcess

Expand Down
Binary file removed docs/assets/heston_calibrated_smile.png
Binary file not shown.
Binary file removed docs/assets/hestonj_calibrated_smile.png
Binary file not shown.
48 changes: 10 additions & 38 deletions docs/bibliography.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,22 @@

---

### carr_madan
#### carr_madan

Peter Carr, Dilip Madan
Peter Carr, Dilip Madan, [Option Valuation Using the Fast Fourier Transform](https://doi.org/10.21314/JCF.1999.043), Journal of Computational Finance, 2(4):61-73, 1999

[Option Valuation Using the Fast Fourier Transform](https://doi.org/10.1002/(SICI)1097-0261(199904)2:1<61::AID-FUT4>3.0.CO;2-4)
#### carr_wu

Journal of Computational Finance, 2(4):61-73, 1999
Peter Carr, Liuren Wu, [Time-Changed Lévy Processes and Option Pricing](https://doi.org/10.1016/S0304-405X(03)00171-5), Journal of Financial Economics, 71(1):113-141, 2004

---

### carr_wu

Peter Carr, Liuren Wu

[Time-Changed Lévy Processes and Option Pricing](https://doi.org/10.1016/S0304-405X(03)00171-5)

Journal of Financial Economics, 71(1):113-141, 2004

---

### chourdakis

Kyriakos Chourdakis
#### chourdakis

[Option Pricing Using the Fractional FFT](https://doi.org/10.21314/JCF.2005.102)

Journal of Computational Finance, 8(2):1-18, 2005

---

### molnar

Peter Molnar

[Volatility modeling and forecasting: utilization of realized volatility, implied volatility and the highest and lowest price of the day](https://drive.google.com/file/d/1zCU1OZyrKQLpxaypPv9U5UPbReBDXcMf/view)

Master's thesis, University of Economics in Prague, 2020

---
Kyriakos Chourdakis, [Option Pricing Using the Fractional FFT](https://doi.org/10.21314/JCF.2005.137),Journal of Computational Finance, 8(2):1-18, 2005

### Gauthier
#### molnar

Gauthier Godin & Legros
Peter Molnar, [Volatility modeling and forecasting: utilization of realized volatility, implied volatility and the highest and lowest price of the day](https://drive.google.com/file/d/1zCU1OZyrKQLpxaypPv9U5UPbReBDXcMf/view), Master's thesis, University of Economics in Prague, 2020

[Deep Implied Volatility Factor Models for Stock Options](https://drive.google.com/file/d/1Rjypn1IqnhpiZz08s0hxl5ISQDC8KeWk/view?usp=sharing)
#### Gauthier

2025
Gauthier Godin & Legros, [Deep Implied Volatility Factor Models for Stock Options](https://drive.google.com/file/d/1Rjypn1IqnhpiZz08s0hxl5ISQDC8KeWk/view?usp=sharing), 2025
9 changes: 8 additions & 1 deletion docs/examples/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from pydantic import BaseModel

EXAMPLE_DIR = Path(__file__).parent
OUT_DIR = EXAMPLE_DIR.parent / "examples_output"
OUT_DIR = EXAMPLE_DIR / "output"
ASSET_DIR = EXAMPLE_DIR.parent / "assets" / "examples"


def print_model(model: BaseModel) -> None:
Expand All @@ -15,9 +16,15 @@ def print_model(model: BaseModel) -> None:
print("\n".join(text_data))


def assets_path(filename: str) -> str:
"""Helper function to get the path to an asset file in the docs"""
return f"docs/assets/examples/{filename}"


def build_examples() -> list[Path]:
failed = []
OUT_DIR.mkdir(exist_ok=True)
ASSET_DIR.mkdir(exist_ok=True)
for script in sorted(EXAMPLE_DIR.glob("*.py")):
if script.stem.startswith("_"):
continue
Expand Down
22 changes: 22 additions & 0 deletions docs/examples/fft.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from docs.examples._utils import assets_path
from quantflow.sp.weiner import WeinerProcess
from quantflow.utils import plot

p = WeinerProcess(sigma=0.5)
m = p.marginal(0.2)

fig = plot.plot_characteristic(m)
fig.update_layout(title="Weiner Process Characteristic Function")
fig.write_image(assets_path("weiner_characteristic.png"))

fig = plot.plot_marginal_pdf(m, n=128, use_fft=True, max_frequency=20)
fig.update_layout(title="Weiner Process PDF via FFT with n=128")
fig.write_image(assets_path("weiner_fft_128.png"))

fig = plot.plot_marginal_pdf(m, n=128 * 8, use_fft=True, max_frequency=8 * 20)
fig.update_layout(title="Weiner Process PDF via FFT with n=1024")
fig.write_image(assets_path("weiner_fft_1024.png"))

fig = plot.plot_marginal_pdf(m, 64)
fig.update_layout(title="Weiner Process PDF via FRFT with n=64")
fig.write_image(assets_path("weiner_64.png"))
7 changes: 2 additions & 5 deletions docs/examples/vol_surface_heston_calibration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
from pathlib import Path

from docs.examples._utils import print_model
from docs.examples._utils import assets_path, print_model
from quantflow.options.heston_calibration import HestonCalibration
from quantflow.options.pricer import OptionPricer
from quantflow.options.surface import VolSurfaceInputs, surface_from_inputs
Expand Down Expand Up @@ -30,6 +29,4 @@
# Plot the calibrated smile for all maturities and save as PNG
fig = calibration.plot_maturities(max_moneyness_ttm=1.5, support=101)
fig.update_layout(title="Heston Calibrated Smiles")

out_path = Path("docs/assets/heston_calibrated_smile.png")
fig.write_image(str(out_path), width=1200)
fig.write_image(assets_path("heston_calibrated_smile.png"), width=1200)
7 changes: 2 additions & 5 deletions docs/examples/vol_surface_hestonj_calibration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
from pathlib import Path

from docs.examples._utils import print_model
from docs.examples._utils import assets_path, print_model
from quantflow.options.heston_calibration import HestonJCalibration
from quantflow.options.pricer import OptionPricer
from quantflow.options.surface import VolSurface, VolSurfaceInputs, surface_from_inputs
Expand Down Expand Up @@ -42,6 +41,4 @@
# Plot the calibrated smile for all maturities and save as PNG
fig = calibration.plot_maturities(max_moneyness_ttm=1.5, support=101)
fig.update_layout(title="HestonJ Calibrated Smiles")

out_path = Path("docs/assets/hestonj_calibrated_smile.png")
fig.write_image(str(out_path), width=1200)
fig.write_image(assets_path("hestonj_calibrated_smile.png"), width=1200)
1 change: 1 addition & 0 deletions docs/examples/vol_surface_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
inputs = surface.inputs(converged=True)
option_inputs = [i for i in inputs.inputs if isinstance(i, OptionInput)]
df = pd.DataFrame([i.model_dump() for i in option_inputs])
print("\n\n10 Converged option inputs")
print(
df[["maturity", "strike", "option_type", "bid", "ask", "iv_bid", "iv_ask"]]
.head(10)
Expand Down
20 changes: 0 additions & 20 deletions docs/examples_output/heston_volatility_pricer.out

This file was deleted.

14 changes: 0 additions & 14 deletions docs/examples_output/vol_surface_heston_calibration.out

This file was deleted.

22 changes: 0 additions & 22 deletions docs/examples_output/vol_surface_hestonj_calibration.out

This file was deleted.

24 changes: 0 additions & 24 deletions docs/examples_output/vol_surface_inputs.out

This file was deleted.

20 changes: 0 additions & 20 deletions docs/examples_output/weiner_volatility_pricer.out

This file was deleted.

11 changes: 10 additions & 1 deletion docs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ If $x$ is a continuous random variable, than the characteristic function is the
\end{equation}


## Characteristic Exponent

The characteristic exponent $\phi_{x,u}$ is defined from the
[characteristic function](#characteristic-function) $\Phi_{x,u}$ by

\begin{equation}
\Phi_{x,u} = e^{-\phi_{x,u}}
\end{equation}

## Cumulative Distribution Function (CDF)

The cumulative distribution function (CDF), or just distribution function,
Expand Down Expand Up @@ -46,7 +55,7 @@ In the [Heston model][quantflow.sp.heston.Heston] the variance process $v_t$ is
process, so the same condition applies with $\sigma$ being the vol of vol. The
[CIR.is_positive][quantflow.sp.cir.CIR.is_positive] property checks whether the
condition holds. The
[HestonCalibration][quantflow.options.calibration.HestonCalibration] class provides a
[HestonCalibration][quantflow.options.heston_calibration.HestonCalibration] class provides a
`feller_enforce` flag (default `True`) that imposes this as a hard inequality constraint
during optimisation.

Expand Down
Loading
Loading