A Python library for simulating stochastic processes in finance.
Project description
FinStoch
A Python library for simulating stochastic processes in finance.
Installation
pip install FinStoch
Development
pip install -e ".[dev]"
# Run tests
python -m unittest discover -s tests -p "*_test.py"
# Format / lint / type check
ruff format
flake8 --max-line-length 127
mypy . --exclude venv --ignore-missing-imports
Processes
Geometric Brownian Motion
- SDE
$$ dS_t = \mu S_t dt + \sigma S_t dW_t $$
-
A stochastic process where the logarithm of the variable follows a Brownian motion with drift, representing continuous growth with random fluctuations.
-
Euler-Maruyama Discretization
$$ S_{t+\Delta t} = S_t.e^{\left(\mu-\frac{\sigma^2}{2}\right)\Delta t+\sigma\sqrt{\Delta t}\epsilon_t} $$
Where $\epsilon_t \sim \mathcal{N}(0, 1)$.
import numpy as np
from FinStoch.processes import GeometricBrownianMotion
S0 = 100 # Initial value
mu = 0.05 # Annualized Drift coefficient (expected return rate)
sigma = 0.2 # Annualized Volatility (standard deviation of returns)
num_paths = 10 # Number of paths to simulate
start_date = '2023-09-01' # Start date for the simulation
end_date = '2024-09-01' # End date for the simulation
granularity = 'D' # Granularity in daily intervals
# Create the GBM model
gbm = GeometricBrownianMotion(S0, mu, sigma, num_paths, start_date, end_date, granularity)
# Simulate the GBM process
simulated_paths = gbm.simulate()
# Plot the simulated paths
gbm.plot(paths=simulated_paths,
title='Stock Price under Geometric Brownian Motion Assumption',
ylabel='Stock Price',
fig_size=(15,5)
)
Merton's Jump Diffusion Model
- SDE
$$ dS_t = \left(\mu - \lambda_j\left( e^{\mu_j+\frac{\sigma_j^2}{2}} - 1\right) \right) S_t dt + \sigma S_t dW_t + S_t \left( \prod_{i=1}^{dN_t} Y_i - 1\right) $$
-
An extension of the geometric Brownian motion that incorporates sudden, discrete jumps $ J_t $ in addition to continuous diffusion, capturing both regular volatility and occasional large shocks.
-
Euler-Maruyama Discretization
$$ S_{t+\Delta t} = S_t . e^{\left( \mu - \frac{1}{2} \sigma^2 -\lambda_j\left( e^{\mu_j+\frac{\sigma_j^2}{2}} - 1\right)\right) \Delta t + \sigma \sqrt{\Delta t} \epsilon_t + J_t } $$
Where $\epsilon_t \sim \mathcal{N}(0, 1)$ and $J_t$ is the jump component at time $t$.
import numpy as np
from FinStoch.processes import MertonJumpDiffusion
# Parameters
S0 = 100 # Initial process value
mu = 0.05 # Drift coefficient
sigma = 0.2 # Volatility
lambda_j = 1 # Jump intensity
mu_j = 0.0 # Mean of jump size
sigma_j = 0.15 # Standard deviation of jump size
num_paths = 10 # Number of simulated paths
start_date = '2023-09-01' # Start date for the simulation
end_date = '2024-09-01' # End date for the simulation
granularity = 'D' # Granularity in daily intervals
# Create Merton model instance and plot
merton = MertonJumpDiffusion(S0, mu, sigma, lambda_j, mu_j, sigma_j, num_paths, start_date, end_date, granularity)
# Simulate the Merton process
simulated_paths = merton.simulate()
# Plot the simulated paths
merton.plot(paths=simulated_paths,
title='Stock Price under the Merton Model Assumption',
ylabel='Stock Price',
fig_size=(15,5)
)
Ornstein-Uhlenbeck model
- SDE
$$ dS_t = \theta (\mu - S_t) dt + \sigma dW_t $$
-
A mean-reverting stochastic process where the variable fluctuates around a long-term mean with a tendency to revert back, driven by continuous noise.
-
Euler-Maruyama Discretization
$$ S_{t+\Delta t} = S_t + \theta (\mu - S_t) \Delta t + \sigma \sqrt{\Delta t} \epsilon_t $$
Where $\epsilon_t \sim \mathcal{N}(0, 1)$.
import numpy as np
from FinStoch.processes import OrnsteinUhlenbeck
# Parameters
S0 = 100 # Initial value
mu = 100 # Annualized drift coefficient
sigma = 0.2 # Anualized volatility
theta = 0.5 # Annualized mean reversion rate
num_paths = 10 # Number of paths to simulate
start_date = '2023-09-01' # Start date for the simulation
end_date = '2024-09-01' # End date for the simulation
granularity = 'D' # Granularity in daily intervals
# Create Ornstein-Uhlenbeck model instance and plot
ou = OrnsteinUhlenbeck(S0, mu, sigma, theta, num_paths, start_date, end_date, granularity)
# Simulate the OU process
simulated_paths = ou.simulate()
# Plot the simulated paths
ou.plot(paths=simulated_paths,
title='Stock Price under the Ornstein Uhlenbeck model Assumption',
ylabel='Stock Price',
fig_size=(15,5)
)
Cox-Ingersoll-Ross Model
- SDE
$$ dS_t = \kappa (\theta - S_t) dt + \sigma \sqrt{S_t} dW_t $$
-
A mean-reverting process with volatility that depends on the current level of the variable, ensuring the values are always non-negative.
-
Euler-Maruyama Discretization
$$ S_{t+\Delta t} = S_t + \kappa (\theta - S_t) \Delta t + \sigma \sqrt{S_t} \sqrt{\Delta t} \epsilon_t $$
Where $\epsilon_t \sim \mathcal{N}(0, 1)$.
import numpy as np
from FinStoch.processes import CoxIngersollRoss
# Parameters
S0 = 0.03 # Initial value
mu = 0.03 # Long-term mean
sigma = 0.1 # Volatility
theta = 0.03 # Speed of reversion
num_paths = 10 # Number of simulation paths
start_date = '2023-09-01' # Start date for the simulation
end_date = '2024-09-01' # End date for the simulation
granularity = 'D' # Granularity in daily intervals
# Create an instance of the CoxIngersollRoss class
cir = CoxIngersollRoss(S0, mu, sigma, theta, num_paths, start_date, end_date, granularity)
# Simulate the CIR process
simulated_paths = cir.simulate()
# Plot the simulated paths
cir.plot(paths=simulated_paths,
title='Rate under the CIR model Assumption',
ylabel='Rate',
fig_size=(15,5)
)
Constant Elasticity of Variance Model
- SDE
$$ dS_t = \mu S_t dt + \sigma {S_t}^\gamma dW_t $$
-
A stochastic process that extends the Geometric Brownian Motion process.
-
Euler-Maruyama Discretization
$$ S_{t+\Delta t} = S_t + \mu S_t \Delta t + \sigma {S_t}^\gamma \sqrt{\Delta t} \epsilon_t $$
Where $\epsilon_t \sim \mathcal{N}(0, 1)$.
import numpy as np
from FinStoch.processes import ConstantElasticityOfVariance
S0 = 100 # Initial value
mu = 0.05 # Annualized Drift coefficient (expected return rate)
sigma = 0.2 # Annualized Volatility (standard deviation of returns)
gamma = 1.2 # Elasticity coefficient
num_paths = 10 # Number of paths to simulate
start_date = '2023-09-01' # Start date for the simulation
end_date = '2024-09-01' # End date for the simulation
granularity = 'D' # Granularity in daily intervals
# Create the CEV model
cev = ConstantElasticityOfVariance(S0, mu, sigma, gamma, num_paths, start_date, end_date, granularity)
# Simulate the CEV process
simulated_paths = cev.simulate()
# Plot the simulated paths
cev.plot(paths=simulated_paths,
title='Stock Price under the Constant Elasricity of Variance Model Assumption',
ylabel='Stock Price',
fig_size=(15,5)
)
Heston Stochastic Volatility Model
- SDEs
$$ dS_t = \mu S_t dt + \sqrt{v_t} S_t dW_{S,t} $$
$$ dv_t = \kappa (\theta - v_t) dt + \sigma_v \sqrt{v_t} dW_{v,t} $$
$$ dW_{S,t}\times dW_{v,t}=\rho dt $$
-
A stochastic volatility model where the volatility of a variable follows its own mean-reverting process, allowing for time-varying volatility that evolves over time.
-
Euler-Maruyama Discretization
$$ S_{t+\Delta t} = S_t.e^{\left(\mu-\frac{v_t}{2}\right)\Delta t+\sqrt{v_t}\sqrt{\Delta t}\epsilon_{S,t}} $$
$$ v_{t+\Delta t} = v_t + \kappa (\theta - v_t) \Delta t + \sigma_v \sqrt{v_t} \sqrt{\Delta t} \epsilon_{v,t} $$
$$ Corr(\epsilon_{S,t},\epsilon_{v,t})=\rho $$
Where $\epsilon_S$ and $\epsilon_v$ are correlated standard normal variables.
import numpy as np
from FinStoch.processes import HestonModel
# Parameters
S0 = 100 # Initial value
v0 = 0.02 # Initial volatility
mu = 0.05 # Long-term mean of the value
theta = 0.04 # Long-term mean of the volatility
sigma = 0.3 # Volatility of the volatility
kappa = 1.5 # Speed of reversion
rho = -0.7 # Correlation between shocks
num_paths = 10 # Number of simulation paths
start_date = '2023-09-01' # Start date for the simulation
end_date = '2024-09-01' # End date for the simulation
granularity = 'D' # Granularity in daily intervals
# Initialize Heston model
heston = HestonModel(S0, v0, mu, sigma, theta, kappa, rho, num_paths, start_date, end_date, granularity)
# Simulate the Heston model
simulated_paths = heston.simulate()
# Plot the simulated paths
heston.plot(paths=simulated_paths,
title='Asset Price under the Heston model Assumption',
ylabel='Asset Price',
fig_size=(15,5)
)
heston.plot(paths=simulated_paths,
title='Asset Volatility under the Heston model Assumption',
ylabel='Asset Volatility',
variance=True,
fig_size=(15,5)
)
Seed Control
All processes accept an optional seed parameter for reproducible simulations:
from FinStoch.processes import GeometricBrownianMotion
gbm = GeometricBrownianMotion(100, 0.05, 0.2, 10, '2023-09-01', '2024-09-01', 'D')
# Reproducible simulation
paths_a = gbm.simulate(seed=42)
paths_b = gbm.simulate(seed=42)
# paths_a and paths_b are identical
Data Conversion
Convert simulation output to a pandas DataFrame with to_dataframe():
paths = gbm.simulate(seed=42)
df = gbm.to_dataframe(paths)
# DataFrame with DatetimeIndex columns and path indices as rows
# For Heston (tuple output), select price or variance
heston_paths = heston.simulate(seed=42)
df_prices = heston.to_dataframe(heston_paths, variance=False)
df_variance = heston.to_dataframe(heston_paths, variance=True)
Analytics
All processes inherit analytics methods from the base class, operating on simulation output:
paths = gbm.simulate(seed=42)
# Summary statistics (mean, std, skew, kurtosis, min, max) at each time step
stats = gbm.summary_statistics(paths)
# Mean path across all simulations
mean_path = gbm.expected_path(paths)
# 95% confidence bands
lower, upper = gbm.confidence_bands(paths, level=0.95)
# Value at Risk at terminal time step (5th percentile)
var_95 = gbm.var(paths, alpha=0.05)
# Conditional VaR / Expected Shortfall
cvar_95 = gbm.cvar(paths, alpha=0.05)
# Maximum drawdown per path (peak-to-trough decline as fraction)
drawdowns = gbm.max_drawdown(paths)
# Histogram of terminal values with fitted normal overlay
gbm.terminal_distribution(paths, bins=50)
License
This project is licensed under the MIT license found in the LICENSE file.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file finstoch-0.6.0.tar.gz.
File metadata
- Download URL: finstoch-0.6.0.tar.gz
- Upload date:
- Size: 13.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7499e60714e8872dfef9f26ca611f4d1ddc5ff9d961c3e49967a8fd19cd03791
|
|
| MD5 |
ec9cc8034a6a345874969a257849becf
|
|
| BLAKE2b-256 |
94cf0b33d02d92f85844c18ebb02db8762125d79124c35c81c3d01055241111d
|
Provenance
The following attestation bundles were made for finstoch-0.6.0.tar.gz:
Publisher:
cd.yml on Yosri-Ben-Halima/FinStoch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
finstoch-0.6.0.tar.gz -
Subject digest:
7499e60714e8872dfef9f26ca611f4d1ddc5ff9d961c3e49967a8fd19cd03791 - Sigstore transparency entry: 1195500750
- Sigstore integration time:
-
Permalink:
Yosri-Ben-Halima/FinStoch@224f7ca48d4138a8d1963c01c1a8c41ca317ab8c -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/Yosri-Ben-Halima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@224f7ca48d4138a8d1963c01c1a8c41ca317ab8c -
Trigger Event:
push
-
Statement type:
File details
Details for the file finstoch-0.6.0-py3-none-any.whl.
File metadata
- Download URL: finstoch-0.6.0-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82522fcd22cea673ae8ec8335e7008c20c8421595bd73f96960305a04c29936f
|
|
| MD5 |
5412e68dc890e7cba3d5de7ef25d6594
|
|
| BLAKE2b-256 |
35fc141dbfb831bb286f13660057d19d2730dcbd634f064e1f81b32bcf47eb36
|
Provenance
The following attestation bundles were made for finstoch-0.6.0-py3-none-any.whl:
Publisher:
cd.yml on Yosri-Ben-Halima/FinStoch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
finstoch-0.6.0-py3-none-any.whl -
Subject digest:
82522fcd22cea673ae8ec8335e7008c20c8421595bd73f96960305a04c29936f - Sigstore transparency entry: 1195500760
- Sigstore integration time:
-
Permalink:
Yosri-Ben-Halima/FinStoch@224f7ca48d4138a8d1963c01c1a8c41ca317ab8c -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/Yosri-Ben-Halima
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@224f7ca48d4138a8d1963c01c1a8c41ca317ab8c -
Trigger Event:
push
-
Statement type: