Skip to content

Commit 758929d

Browse files
authored
Fix docs (#35)
1 parent 4783b00 commit 758929d

12 files changed

Lines changed: 314 additions & 191 deletions

File tree

app/poisson_sampling.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import marimo
2+
3+
__generated_with = "0.19.7"
4+
app = marimo.App(width="medium")
5+
6+
7+
@app.cell
8+
def _():
9+
import marimo as mo
10+
from app.utils import nav_menu
11+
nav_menu()
12+
return (mo,)
13+
14+
15+
@app.cell
16+
def _(mo):
17+
mo.md(r"""
18+
# Poisson Sampling
19+
20+
Evaluate the MC simulation for The Poisson process against the analytical PDF.
21+
""")
22+
return
23+
24+
25+
@app.cell
26+
def _():
27+
from quantflow.sp.poisson import PoissonProcess
28+
import pandas as pd
29+
30+
def simulate_poisson(intensity: float, samples: int) -> pd.DataFrame:
31+
pr = PoissonProcess(intensity=intensity)
32+
paths = pr.sample(samples, 1, 1000)
33+
pdf = paths.pdf(delta=1)
34+
pdf["simulation"] = pdf["pdf"]
35+
pdf["analytical"] = pr.marginal(1).pdf(pdf.index)
36+
return pdf
37+
return (simulate_poisson,)
38+
39+
40+
@app.cell
41+
def _(mo):
42+
samples = mo.ui.slider(start=100, stop=10000, step=100, value=1000, debounce=True, label="Samples")
43+
intensity = mo.ui.slider(start=2, stop=5, step=0.1, debounce=True, label="Poisson intensity $\lambda$")
44+
45+
controls = mo.hstack([samples, intensity], justify="start")
46+
controls
47+
return intensity, samples
48+
49+
50+
@app.cell
51+
def _(intensity, samples, simulate_poisson):
52+
df = simulate_poisson(intensity=intensity.value, samples=samples.value)
53+
return (df,)
54+
55+
56+
@app.cell
57+
def _(df):
58+
import plotly.graph_objects as go
59+
simulation = go.Bar(x=df.index, y=df["simulation"], name="simulation")
60+
analytical = go.Bar(x=df.index, y=df["analytical"], name="analytical")
61+
fig = go.Figure(data=[simulation, analytical])
62+
fig
63+
return
64+
65+
66+
@app.cell
67+
def _():
68+
return
69+
70+
71+
if __name__ == "__main__":
72+
app.run()

docs/api/sp/heston.md

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
================
2-
Heston process
3-
================
1+
# Heston process
42

5-
.. currentmodule:: quantflow.sp.heston
3+
::: quantflow.sp.heston.Heston
64

7-
.. autoclass:: Heston
8-
:members:
9-
:member-order: groupwise
10-
:autosummary:
11-
:autosummary-nosignatures:
125

13-
14-
.. autoclass:: HestonJ
15-
:members:
16-
:member-order: groupwise
17-
:autosummary:
18-
:autosummary-nosignatures:
6+
::: quantflow.sp.heston.HestonJ

docs/api/sp/jump_diffusion.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1-
================
2-
Jump diffusions
3-
================
1+
# Jump diffusions
42

53
Jump-diffusions models are a class of stochastic processes that combine a diffusion process with a jump process. The jump process is a Poisson process that generates jumps in the value of the underlying asset. The jump-diffusion model is a generalization of the Black-Scholes model that allows for the possibility of large,
64
discontinuous jumps in the value of the underlying asset.
75

86
The most famous jump-diffusion model is the Merton model, which was introduced by Robert Merton in 1976. The Merton model assumes that the underlying asset follows a geometric Brownian motion with jumps that are normally distributed.
97

10-
.. currentmodule:: quantflow.sp.jump_diffusion
11-
12-
.. autoclass:: JumpDiffusion
13-
:members:
14-
:member-order: groupwise
15-
:autosummary:
16-
:autosummary-nosignatures:
8+
::: quantflow.sp.jump_diffusion.JumpDiffusion

docs/api/sp/poisson.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# Poisson process
22

3+
::: quantflow.sp.poisson.PoissonBase
4+
35
::: quantflow.sp.poisson.PoissonProcess

docs/api/sp/weiner.md

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
===============
2-
Weiner process
3-
===============
4-
5-
.. module:: quantflow.sp.weiner
6-
7-
.. autoclass:: WeinerProcess
8-
:members:
9-
:member-order: groupwise
10-
:autosummary:
11-
:autosummary-nosignatures:
1+
# Weiner process
122

3+
::: quantflow.sp.weiner.WeinerProcess

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ nav:
5656
- Home: index.md
5757
- Examples:
5858
- Gaussian Sampling: examples/gaussian-sampling
59+
- Poisson Sampling: examples/poisson-sampling
5960
- Hurst: examples/hurst
6061
- Supersmoother: examples/supersmoother
6162
- API Reference:

quantflow/sp/base.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
from pydantic import BaseModel, ConfigDict, Field
88
from scipy.optimize import Bounds
9+
from typing_extensions import Annotated, Doc
910

1011
from quantflow.ta.paths import Paths
1112
from quantflow.utils.marginal import Marginal1D, default_bounds
@@ -26,29 +27,33 @@ def sample_from_draws(self, draws: Paths, *args: Paths) -> Paths:
2627
"""Sample :class:`.Paths` from the process given a set of draws"""
2728

2829
@abstractmethod
29-
def sample(self, n: int, time_horizon: float = 1, time_steps: int = 100) -> Paths:
30-
"""Generate random :class:`.Paths` from the process.
31-
32-
:param n: number of paths
33-
:param time_horizon: time horizon
34-
:param time_steps: number of time steps to arrive at horizon
35-
"""
30+
def sample(
31+
self,
32+
n: Annotated[int, Doc("number of paths")],
33+
time_horizon: Annotated[float, Doc("time horizon")] = 1,
34+
time_steps: Annotated[
35+
int, Doc("number of time steps to arrive at horizon")
36+
] = 100,
37+
) -> Paths:
38+
"""Generate random :class:`.Paths` from the process."""
3639

3740
@abstractmethod
3841
def characteristic_exponent(self, t: FloatArrayLike, u: Vector) -> Vector:
3942
"""Characteristic exponent at time `t` for a given input parameter"""
4043

41-
def characteristic(self, t: FloatArrayLike, u: Vector) -> Vector:
44+
def characteristic(
45+
self,
46+
t: Annotated[FloatArrayLike, Doc("Time horizon")],
47+
u: Annotated[Vector, Doc("Characteristic function input parameter")],
48+
) -> Vector:
4249
r"""Characteristic function at time `t` for a given input parameter
4350
4451
The characteristic function represents the Fourier transform of the
4552
probability density function
4653
47-
.. math::
54+
\begin{equation}
4855
\phi = {\mathbb E} \left[e^{i u x_t}\right]
49-
50-
:param t: time horizon
51-
:param u: characteristic function input parameter
56+
\end{equation}
5257
"""
5358
return np.exp(-self.characteristic_exponent(t, u))
5459

@@ -174,14 +179,15 @@ class IntensityProcess(StochasticProcess1D):
174179
r"""Mean reversion speed :math:`\kappa`"""
175180

176181
@abstractmethod
177-
def integrated_log_laplace(self, t: FloatArrayLike, u: Vector) -> Vector:
182+
def integrated_log_laplace(
183+
self,
184+
t: Annotated[FloatArrayLike, Doc("time horizon")],
185+
u: Annotated[Vector, Doc("frequency")],
186+
) -> Vector:
178187
r"""The log-Laplace transform of the cumulative process:
179188
180189
.. math::
181190
e^{\phi_{t, u}} = {\mathbb E} \left[e^{i u \int_0^t x_s ds}\right]
182-
183-
:param t: time horizon
184-
:param u: frequency
185191
"""
186192

187193
def domain_range(self) -> Bounds:

quantflow/sp/dsp.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ class DSP(PoissonBase):
1515
Doubly Stochastic Poisson process.
1616
1717
It's a process where the inter-arrival time is exponentially distributed
18-
with rate :math:`\lambda_t`
18+
with rate $\lambda_t$
1919
2020
:param intensity: the stochastic intensity of the Poisson
2121
"""
2222

23-
intensity: IntensityProcess = Field( # type ignore
23+
intensity: IntensityProcess = Field(
2424
default_factory=CIR, description="intensity process"
2525
)
2626
poisson: PoissonProcess = Field(default_factory=PoissonProcess, exclude=True)
@@ -39,7 +39,7 @@ def characteristic_exponent(self, t: FloatArrayLike, u: Vector) -> Vector:
3939
phi = self.poisson.characteristic_exponent(t, u)
4040
return -self.intensity.integrated_log_laplace(t, phi)
4141

42-
def arrivals(self, t: float = 1) -> list[float]:
42+
def arrivals(self, t: float = 1) -> FloatArray:
4343
paths = self.intensity.sample(1, t, math.ceil(100 * t)).integrate()
4444
intensity = paths.data[-1, 0]
4545
return poisson_arrivals(intensity, t)

0 commit comments

Comments
 (0)