Skip to content

heki1224/stocha

Repository files navigation

stocha

High-performance random number and financial simulation library for Python, powered by Rust.

PyPI License

日本語版 README

Features

  • Fast PRNG: PCG64DXSM (NumPy default algorithm)
  • Quasi-random sequences: Sobol (Joe & Kuo 2008) and Halton sequences
  • Stochastic models: GBM, multi-asset correlated GBM, Heston, Merton Jump-Diffusion, Hull-White
  • Risk metrics: VaR and CVaR (Expected Shortfall)
  • Copulas: Gaussian and Student-t copulas for multivariate dependence
  • Volatility: SABR implied volatility (Hagan 2002) with negative-rate support
  • Option pricing: Longstaff-Schwartz LSMC for American options; Barrier, Asian, and Lookback exotics (analytical + MC)
  • Greeks: Bump-and-revalue finite difference (all models) + pathwise IPA (GBM)
  • Calibration: SABR (Projected LM) and Heston (COS method + Projected LM)
  • Parallel: Rayon-powered path generation
  • Reproducible: block-split RNG streams guarantee identical results across thread counts

Installation

PyPI (coming soon):

pip install stocha

From source (current):

git clone https://github.com/heki1224/stocha.git
cd stocha
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install maturin
maturin develop --release

Once available on PyPI, no Rust compiler is required — pip install stocha handles everything.

Quick Start

import stocha
import numpy as np

# ── Random number generation ──────────────────────────────────────────────
rng = stocha.RNG(seed=42)
samples = rng.normal(size=10_000, loc=0.0, scale=1.0)

# ── GBM stock price simulation ────────────────────────────────────────────
paths = stocha.gbm(
    s0=100.0, mu=0.05, sigma=0.20,
    t=1.0, steps=252, n_paths=100_000, seed=42,
)
# paths.shape == (100_000, 253)

# ── Multi-asset correlated GBM ────────────────────────────────────────────
corr = np.array([[1.0, 0.6, 0.3],
                 [0.6, 1.0, 0.5],
                 [0.3, 0.5, 1.0]])
multi_paths = stocha.multi_gbm(
    s0=[100.0, 50.0, 200.0], mu=[0.05, 0.08, 0.03],
    sigma=[0.2, 0.3, 0.15], corr=corr,
    t=1.0, steps=252, n_paths=10_000, seed=42,
)
# multi_paths.shape == (10_000, 253, 3)
# Portfolio terminal value: (multi_paths[:, -1, :] * weights).sum(axis=1)

# ── Quasi-random sequences (low-discrepancy) ─────────────────────────────
pts = stocha.sobol(dim=2, n_samples=1024)    # (1024, 2), values in [0, 1)
pts = stocha.halton(dim=2, n_samples=1024)   # (1024, 2), values in (0, 1)

# ── Heston stochastic volatility ─────────────────────────────────────────
paths_h = stocha.heston(
    s0=100.0, v0=0.04, mu=0.05,
    kappa=2.0, theta=0.04, xi=0.3, rho=-0.7,
    t=1.0, steps=252, n_paths=10_000, seed=42,
)
# paths_h.shape == (10_000, 253)

# ── Merton jump-diffusion ─────────────────────────────────────────────────
paths_m = stocha.merton_jump_diffusion(
    s0=100.0, mu=0.05, sigma=0.20,
    lambda_=1.0, mu_j=-0.05, sigma_j=0.10,
    t=1.0, steps=252, n_paths=10_000, seed=42,
)
# paths_m.shape == (10_000, 253)

# ── VaR / CVaR ────────────────────────────────────────────────────────────
returns = paths[:, -1] / paths[:, 0] - 1
var, cvar = stocha.var_cvar(returns, confidence=0.95)
print(f"95% VaR={var:.4f}  CVaR={cvar:.4f}")

# ── Gaussian copula ───────────────────────────────────────────────────────
corr = np.array([[1.0, 0.8], [0.8, 1.0]])
u = stocha.gaussian_copula(corr, n_samples=10_000)
# u.shape == (10_000, 2),  values in (0, 1)

# ── Student-t copula (heavier joint tails) ────────────────────────────────
u_t = stocha.student_t_copula(corr, nu=5.0, n_samples=10_000)

# ── Hull-White short-rate model ───────────────────────────────────────────
rates = stocha.hull_white(
    r0=0.05, a=0.1, theta=0.005, sigma=0.01,
    t=1.0, steps=252, n_paths=10_000,
)
# rates.shape == (10_000, 253)

# ── SABR implied volatility ───────────────────────────────────────────────
iv = stocha.sabr_implied_vol(
    f=0.05, k=0.05, t=1.0,
    alpha=0.20, beta=0.5, rho=-0.3, nu=0.4,
)
print(f"SABR ATM implied vol: {iv:.4f}")

# ── SABR calibration: recover (alpha, rho, nu) from a market smile ───────
strikes = np.array([0.04, 0.045, 0.05, 0.055, 0.06])
market_vols = np.array([0.244, 0.218, 0.201, 0.190, 0.184])
fit = stocha.sabr_calibrate(strikes, market_vols, f=0.05, t=1.0, beta=0.5)
print(f"calibrated: alpha={fit['alpha']:.4f}, rho={fit['rho']:.4f}, nu={fit['nu']:.4f}")

# ── American option via LSMC ──────────────────────────────────────────────
price, std_err = stocha.lsmc_american_option(
    s0=100.0, k=100.0, r=0.05, sigma=0.20,
    t=1.0, steps=50, n_paths=50_000,
)
print(f"American put: {price:.4f} ± {std_err:.4f}")

# ── Heston analytical pricing (COS method) ───────────────────────────────
prices = stocha.heston_price(
    strikes=np.array([90.0, 100.0, 110.0]),
    is_call=[True, True, True],
    s0=100.0, v0=0.04, r=0.05,
    kappa=2.0, theta=0.04, xi=0.3, rho=-0.7, t=1.0,
)
print(f"Heston call prices: {prices}")

# ── Heston calibration ───────────────────────────────────────────────────
fit = stocha.heston_calibrate(
    strikes=np.array([90.0, 95.0, 100.0, 105.0, 110.0]),
    maturities=np.array([1.0, 1.0, 1.0, 1.0, 1.0]),
    market_prices=prices_from_market,  # your observed prices
    is_call=[True]*5,
    s0=100.0, r=0.05,
)
print(f"v0={fit['v0']:.4f}, kappa={fit['kappa']:.2f}, rho={fit['rho']:.2f}")

# ── Monte Carlo Greeks ───────────────────────────────────────────────────
greeks = stocha.greeks_fd(
    model="gbm",
    params={"s0": 100.0, "r": 0.05, "sigma": 0.2, "t": 1.0},
    payoff="call", strike=100.0,
    n_paths=100_000, n_steps=252,
    greeks=["delta", "gamma", "vega", "theta", "rho"],
)
print(f"Delta={greeks['delta']:.4f}  Gamma={greeks['gamma']:.4f}  Vega={greeks['vega']:.2f}")

# Pathwise method (GBM only, higher accuracy)
pw = stocha.greeks_pathwise(
    s0=100.0, r=0.05, sigma=0.2, t=1.0,
    strike=100.0, is_call=True,
    n_paths=100_000, n_steps=252,
    greeks=["delta", "vega"],
)
print(f"Pathwise Delta={pw['delta']:.4f}  Vega={pw['vega']:.2f}")

# ── Barrier option ──────────────────────────────────────────────────────
bp = stocha.barrier_price(
    s=100.0, k=100.0, r=0.05, sigma=0.2, t=1.0,
    barrier=120.0, barrier_type="up-and-out",
)
print(f"Up-and-out call: {bp:.4f}")

# ── Asian option (arithmetic average) ────────────────────────────────────
ap = stocha.asian_price(s=100.0, k=100.0, r=0.05, sigma=0.2, t=1.0)
print(f"Asian arithmetic call: {ap:.4f}")

# ── Lookback option (floating strike) ────────────────────────────────────
lp = stocha.lookback_price(s=100.0, r=0.05, sigma=0.2, t=1.0)
print(f"Lookback floating call: {lp:.4f}")

API Reference

Random Number Generation

Function / Class Description
RNG(seed) PCG64DXSM PRNG; seed accepts integers up to 128-bit
RNG.standard_normal(size) Sample from N(0, 1)
RNG.normal(size, loc, scale) Sample from N(loc, scale²)
RNG.uniform(size) Sample from Uniform[0, 1)
RNG.save_state() Serialize full RNG state to JSON (supports mid-stream checkpointing)
RNG.from_state(json) Restore RNG from JSON; accepts full-state (v1.2+) and legacy seed-only format
sobol(dim, n_samples) Sobol low-discrepancy sequence (Joe & Kuo 2008). For high-dim or large-N use cases, scipy.stats.qmc.Sobol is significantly faster.
halton(dim, n_samples, skip) Halton low-discrepancy sequence

Stochastic Price Models

Function Description
gbm(s0, mu, sigma, t, steps, n_paths, ...) Geometric Brownian Motion (Euler-Maruyama, Rayon-parallel)
multi_gbm(s0, mu, sigma, corr, t, steps, n_paths, ...) Correlated multi-asset GBM (Cholesky decomposition); returns (n_paths, steps+1, n_assets)
heston(s0, v0, mu, kappa, theta, xi, rho, ..., scheme) Heston stochastic volatility ("euler" Full Truncation or "qe" Andersen QE)
merton_jump_diffusion(s0, mu, sigma, lambda_, ...) Merton Jump-Diffusion with lognormal jumps
hull_white(r0, a, theta, sigma, t, steps, n_paths) Hull-White 1-factor short rate (Exact Simulation)

Risk & Derivatives

Function Description
var_cvar(returns, confidence) Value-at-Risk and Conditional VaR
gaussian_copula(corr, n_samples) Gaussian copula samples
student_t_copula(corr, nu, n_samples) Student-t copula samples
sabr_implied_vol(f, k, t, alpha, beta, rho, nu, shift) SABR Black implied volatility
sabr_calibrate(strikes, market_vols, f, t, beta, shift, ...) Calibrate SABR (α, ρ, ν) to an observed IV smile (Projected Levenberg-Marquardt + 1-D ATM Brent root-find on α)
lsmc_american_option(s0, k, r, sigma, t, steps, n_paths, ...) American option price via Longstaff-Schwartz LSMC
greeks_fd(model, params, payoff, strike, n_paths, n_steps, greeks, ...) MC Greeks via bump-and-revalue finite difference (GBM/Heston/Merton)
greeks_pathwise(s0, r, sigma, t, strike, is_call, n_paths, n_steps, greeks) MC Greeks via pathwise IPA (GBM only; delta, vega)
heston_price(strikes, is_call, s0, v0, r, kappa, theta, xi, rho, t, n_cos) Heston analytical pricing via COS method (Fang & Oosterlee 2008)
heston_calibrate(strikes, maturities, market_prices, is_call, s0, r, ...) Calibrate Heston (v0, κ, θ, ξ, ρ) to market prices (Projected LM + Vega-weighted COS repricing)
ssvi_calibrate(log_moneyness, theta, market_total_var, ...) Calibrate SSVI surface (η, γ, ρ) — calendar-arbitrage-free by construction
ssvi_implied_vol(log_moneyness, theta, t, eta, gamma, rho) Implied volatility from SSVI surface
ssvi_local_vol(log_moneyness, theta_values, t_values, eta, gamma, rho) Dupire local volatility via SSVI analytical derivatives (no finite differences)
barrier_price(s, k, r, sigma, t, barrier, barrier_type, ..., n_monitoring, rebate, rebate_at_hit) Barrier option pricing: Reiner-Rubinstein analytical (8 types) + MC fallback. n_monitoring enables Broadie-Glasserman-Kou (1997) continuity correction; rebate / rebate_at_hit apply Haug §4.17 rebate formulas (paid-at-hit or paid-at-expiry)
asian_price(s, k, r, sigma, t, n_steps, average_type, ..., running_avg, time_elapsed) Asian option pricing: Kemna-Vorst analytical (geometric) + MC with geometric CV (arithmetic). Pass running_avg and time_elapsed for mid-life (seasoned) valuation via the K* = (T·K − t1·A_spent)/(T−t1) transformation
lookback_price(s, r, sigma, t, n_steps, strike_type, ..., running_max, running_min) Lookback option pricing: Goldman-Sosin-Gatto / Conze-Viswanathan analytical + MC, unified by the T_3(S, X) helper. Pass running_max / running_min for seasoned mid-life pricing

Performance (Apple M4, release build)

Operation Throughput vs baseline
Normal sampling (Ziggurat) ~300M samples/sec 1.0× vs NumPy
GBM (252 steps, 100k paths) ~370M steps/sec 3.0× vs NumPy
Halton (dim=4) ~105M samples/sec 2.9× vs SciPy
Heston COS pricing (100 strikes) ~765K prices/sec 31× vs QuantLib

Tutorials

File Contents
examples/01_basic_rng.py RNG basics, reproducibility, performance benchmark
examples/02_stock_gbm.py GBM path simulation, European option pricing, antithetic variates
examples/03_quasi_random.py Sobol/Halton sequences, QMC vs MC convergence comparison
examples/04_stochastic_vol.py Heston stochastic volatility, Merton jump-diffusion
examples/05_risk_copula.py VaR/CVaR, Gaussian/Student-t copula tail dependence
examples/06_interest_rate.py Hull-White short-rate model, SABR volatility smile
examples/07_american_option.py LSMC American option pricing, early exercise premium
examples/08_multi_asset.py Multi-asset correlated GBM, portfolio VaR, correlation verification
examples/09_heston_calibration.py Heston COS pricing, implied vol smile, single/multi-maturity calibration
examples/10_local_vol.py SSVI surface, Dupire local vol, continuous dividends
examples/11_exotic_options.py Barrier, Asian, and Lookback option pricing
examples/12_exotic_enhancements.py BGK discrete-monitoring correction, seasoning for Asian / Lookback, barrier rebate (v1.7.1)

Each example has a Japanese counterpart (*.ja.py).

Who Is This For?

  • Students and researchers in quantitative finance and financial engineering
  • Quantitative analysts and risk management practitioners
  • AI/ML engineers working on diffusion models or MCMC

Roadmap

Version Features
v0.1 PCG64DXSM, normal distribution, GBM, antithetic variates
v0.2 Sobol (Joe & Kuo 2008), Halton, Heston model, Merton Jump-Diffusion
v0.3 VaR/CVaR, Gaussian/Student-t copula, Hull-White, SABR, LSMC
v1.0 Ziggurat sampler (~3× faster normal sampling)
v1.1 SABR calibration (sabr_calibrate)
v1.2 Full RNG state serialization, Heston QE scheme
v1.3 Multi-asset correlated simulation
v1.4 Greeks (bump-and-revalue FD + pathwise IPA)
v1.5 Heston calibration (COS method pricing + Projected LM)
v1.6 Local Volatility: SSVI surface, Dupire local vol (analytical), continuous dividends
v1.7 Exotic Options: Barrier (Reiner-Rubinstein), Asian (Kemna-Vorst + MC/CV), Lookback (Goldman-Sosin-Gatto)
v1.7.1 Exotic Enhancements: Rebate (Haug §4.17), seasoning for Asian / Lookback, Broadie-Glasserman-Kou discrete-monitoring correction. Lookback analytical formulas rewritten to match Hull / Haug §4.18.
v1.8 Hybrid Models: Heston-Hull-White (stochastic equity + interest rates)
v1.9 Advanced Sensitivities: Likelihood Ratio Method (LRM) for discontinuous payoffs
v2.0 AI Ecosystem: DLPack zero-copy interop (PyTorch/JAX) for Deep Hedging

License

Licensed under the MIT License.

Copyright (c) 2026 Shigeki Yamato

About

High-performance random number and financial simulation library for Python, powered by Rust

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors