📈 mcrisk

Monte Carlo · VaR / CVaR · Option pricing · CPU optimization

A Monte Carlo risk engine — with speedups you can reproduce.

Simulate correlated multi-asset portfolio P&L, compute Value-at-Risk and Conditional VaR, and price options by Monte Carlo against an analytic Black-Scholes check. The hot loop is written four ways so the optimization is measured, not asserted.

Honest about hardware. This was benchmarked on a machine with no GPU, so there are no GPU numbers anywhere — every figure here is a real CPU measurement. The headline is the real CPU speedup; a CuPy GPU backend is included as a clearly-marked drop-in stub (it falls back to NumPy here). No "192×" claim, because none was measured.
Asian-call pricing race · 2M paths × 50 steps0.0s
naive Python loop BASELINE0%
numba @njit(parallel) FASTEST CPU0%
Real measured times: 41.6s (naive) vs 0.085s (numba) on this machine.

↑ Animation paced from the project's real measured CPU times (best of 7 runs).

01 — The engine

What it computes.

🧮

Correlated returns

Cholesky factor of the correlation matrix drives correlated normal draws; simulated correlation matches the target to atol=0.01.

📉

VaR & CVaR

Empirical Value-at-Risk and Conditional VaR (Expected Shortfall), cross-checked against the closed-form normal quantile and ES.

🎯

Option pricing

European call by Monte Carlo with antithetic variates, validated against the analytic Black-Scholes value.

📦

Portfolio P&L

Arithmetic-normal or GBM returns over a horizon, aggregated across long/short holdings into scenario P&L.

🧪

Tested

15 pytest tests: convergence to Black-Scholes, analytic VaR/CVaR match, backend agreement, correlation recovery.

🟩

GPU-ready

A CuPy backend slots into the same interface — runs on-device where a GPU exists, falls back to NumPy here, never fakes a number.

02 — Measured speedups

Four implementations of one hot loop.

A path-dependent Asian (average-price) call, 50 steps/path, 2,000,000 paths, 16 logical CPUs. All four backends agree on the price (~5.86), so the speedup is genuine. Speedup is relative to the naive pure-Python loop (mean of 7 runs).

All values are real measurements on this machine. Multiprocessing shows run-to-run variance on Windows; its best-case reaches ~40×.

03 — Risk numbers

Validated against analytic formulas.

Single normal asset (holding €1,000,000, 2% daily vol, 1,000,000 paths): Monte Carlo VaR/CVaR vs the closed-form normal values.

ConfidenceVaR (MC)VaR (analytic)CVaR (MC)CVaR (analytic)
95%32,87932,89741,26841,254
99%46,54746,52753,31053,304
€98,976
99% VaR · 3-asset correlated portfolio (€4.5M gross)
€113,373
99% CVaR · same portfolio (worst-1% mean loss)
1.28σ
MC call (7.1442) vs Black-Scholes (7.1281)

04 — Stack

Built with.

🐍 Python 3.12 🔢 NumPy 📐 SciPy ⚡ numba (@njit parallel) 🧵 multiprocessing 📊 matplotlib ✅ pytest 🟩 CuPy (optional GPU drop-in)