A Rust workspace of quantitative-finance models, organized the way a quant desk actually divides the discipline: pricing derivatives, modeling rates, managing portfolio risk, credit risk, the stochastic math underneath all of it, the numerical methods that make it computable, and the statistical-arbitrage layer that turns all of the above into trading signals. Eight crates, 249 unit tests, four dependencies total (rand, thiserror, nalgebra, rustfft) — everything else is written from scratch specifically so the math, not a library call, is what's on display.
This README is the field map: essentially every major branch of quantitative finance, explained, with a pointer to exactly which struct/function implements it and why it's built the way it is. A short "still simplified" section near the end is the honest account of where a model trades some generality for tractability (documented in the code itself, not hidden), and a short "deliberately out of scope" section names the handful of adjacent fields (ML-driven alpha research, real options, crypto-native quant) that aren't part of this repo's scope on purpose. The docs/ folder has one file per original six domains with additional narrative depth; this README is now the more complete and current reference.
| Crate | What it covers |
|---|---|
core |
Foundational primitives everything else builds on: Black-Scholes, Monte Carlo option pricing, a limit order book (with market/stop orders and a microstructure signal), return/risk statistics, rolling time-series indicators |
options-pricing |
Everything beyond plain Black-Scholes: futures options, American exercise, jumps, stochastic volatility, local volatility, exotics, baskets, variance swaps, FX/quanto, convertibles |
interest-rate-models |
Short-rate models, multi-factor models, the HJM/LMM frameworks, yield curve construction, cap/floor/swaption pricing, bond risk metrics |
portfolio-risk |
CAPM, APT, factor models, Markowitz/Black-Litterman/risk-parity portfolio construction, three flavors of VaR, PCA factor models, stress testing |
stochastic-processes |
The random-process building blocks used throughout the other crates, including jump/long-memory/regime-switching processes and asymmetric GARCH |
numerical-methods |
How models without closed forms actually get computed: PDE grids (1D and 2D), Monte Carlo variance reduction and quasi-Monte Carlo, FFT and cosine-series pricing, least-squares Monte Carlo |
statistical-arbitrage |
Turning price relationships into trading signals: cointegration (pairwise and multivariate), Kalman/particle filtering, momentum, execution |
credit-risk |
The probability and cost of a counterparty failing to pay: structural and reduced-form default models, ratings transitions, simplified regulatory capital |
options-pricing, portfolio-risk, numerical-methods, and credit-risk depend on core (for MarketInputs, OptionType, black_scholes_price, stats::historical_var, and so on, so nothing is defined twice); statistical-arbitrage depends on stochastic-processes (its mean-reversion model reuses ornstein_uhlenbeck::fit).
cargo test --workspace # all 249 tests across every crate
cargo run -p core # demo walkthrough: options, Monte Carlo, order book, stats, time series
cargo test -p credit-risk # just one crateBlack-Scholes itself, the Greeks, and implied volatility (Newton-Raphson with a bisection fallback) live in core::options; Monte Carlo pricing with antithetic variates lives in core::monte_carlo. options-pricing covers where Black-Scholes' assumptions break down: black76 (futures/forward options), binomial_tree (CRR lattice, American early exercise), jump_diffusion (Merton's Poisson-driven jumps), heston (stochastic volatility via Euler-Maruyama Monte Carlo), and sabr (Hagan's closed-form implied-vol approximation for quoting an entire smile as four parameters).
Beyond that baseline, options-pricing now also has: local_vol — Dupire's formula, sigma_local(K,T)^2 = (dC/dT + rK dC/dK) / (0.5 K^2 d2C/dK2), computed via finite differences on a call-price surface, with a round-trip test recovering a known flat volatility from a synthetic flat-vol surface; exotic_options — Asian (arithmetic-average), barrier (up-and-out), lookback, and digital/binary payoffs, each priced via Monte Carlo except the digital, which has a Black-Scholes closed form (e^{-rT} N(d2)) used to cross-check the Monte Carlo version; basket_options — a European option on several correlated underlyings, simulated via Cholesky-decomposed correlated draws (nalgebra), checked against plain Black-Scholes in the single-asset degenerate case; variance_swap — realized-variance calculation from a price path, payoff, and a fair-strike formula for the flat-vol special case (documented explicitly as the degenerate case of the full log-contract replication argument, not the general one); fx_options — Garman-Kohlhagen (Black-Scholes with the spot discounted at the foreign rate) plus the quanto drift adjustment -rho * sigma_fx * sigma_asset; and convertible_bond — a CRR-style lattice where the bondholder value at each node is max(straight-bond continuation, conversion_ratio * stock price).
Two more pieces belong here conceptually but live in numerical-methods because they're general numerical techniques: finite_difference (Crank-Nicolson PDE solver, Thomas-algorithm tridiagonal solve, handles American exercise) and its 2D generalization adi_method (Alternating-Direction-Implicit scheme for a European option on two correlated assets, with the cross-derivative term handled explicitly as a documented simplification of full ADI); fft_pricing (Carr-Madan, pricing an entire strip of strikes in one FFT call from a model's characteristic function) and its faster sibling fourier_cosine (the Fang-Oosterlee COS method, converging to high precision from the same characteristic-function input); longstaff_schwartz (least-squares Monte Carlo for American exercise inside a simulation, using a hand-rolled quadratic-basis OLS regression at each exercise date); and quasi_monte_carlo (Halton low-discrepancy sequences through an inverse-normal-CDF transform, in place of pseudo-random draws, for often-faster convergence than plain Monte Carlo's 1/sqrt(N) rate).
interest-rate-models has the standard short-rate progression: vasicek (mean-reverting short rate, closed-form bond prices, allows negative rates), cir (volatility scaled by sqrt(r) to stay non-negative, with a satisfies_feller_condition() check), hull_white (time-varying mean-reversion target fitted to today's curve via a MarketDiscountCurve trait), and yield_curve (bootstrapping discount factors and zero rates from par-rate instruments).
On top of that: hjm implements the Heath-Jarrow-Morton umbrella framework for a tractable exponential volatility structure, where the drift of every forward rate is fully determined by its volatility (the no-arbitrage constraint that makes Vasicek/CIR/Hull-White recoverable as special cases); libor_market_model simulates a set of correlated forward rates directly (BGM/LMM, using a frozen-drift log-Euler scheme and Cholesky-correlated shocks) — the market-standard approach because its state variables are rates people actually observe quoted, unlike an abstract instantaneous short rate; two_factor_hull_white (G2++) adds a second correlated mean-reverting factor so the short and long end of the curve can decorrelate, which no single-factor model can do, with a curve-fitting term phi(t) supplied by the caller rather than re-deriving full calibration machinery (a documented simplification); swaption_pricing implements Black's formula for caplets, floorlets, and payer/receiver swaptions — the industry-standard quoting convention, independent of whichever short-rate model actually generates the underlying forward; and bond_risk_metrics computes price, Macaulay/modified duration, convexity, and DV01 (both via the duration approximation and via direct finite-difference yield bumping) from a stream of cash flows.
portfolio-risk has capm (beta, expected return, Jensen's alpha), fama_french (general multi-factor OLS via nalgebra, with a three-factor convenience wrapper), markowitz (closed-form mean-variance optimization via the Lagrangian conditions), and risk_ratios (Sortino, Treynor, alongside core::stats's Sharpe/historical VaR/CVaR/max drawdown).
Now also: apt frames Arbitrage Pricing Theory as its own conceptual entry point (a one-factor case reduces exactly to CAPM, which the tests confirm directly); black_litterman blends market-implied equilibrium returns with an investor's subjective views via the standard closed-form Bayesian posterior, the standard fix for mean-variance optimization's well-known sensitivity to raw return estimates; risk_parity builds an equal-risk-contribution portfolio via iterative rescaling (for uncorrelated assets this recovers the known closed-form inverse-volatility weighting, which the tests check directly); var_parametric and var_monte_carlo add the other two standard VaR flavors alongside the historical method already in core::stats — parametric assumes normality and uses a z-table, Monte Carlo simulates correlated scenarios and hands them to the same historical-VaR quantile logic (both cross-checked against each other for consistency); pca_factor_model builds a Barra-style statistical factor model from the eigendecomposition of a covariance matrix rather than named macro factors; and stress_testing applies named hypothetical factor shocks to a portfolio's factor exposures and reports the worst-case scenario.
stochastic-processes has brownian_motion, gbm, ornstein_uhlenbeck (simulate and fit, the same math underneath Vasicek and every pairs-trade spread), jump_process (Poisson-arriving discontinuous jumps), and garch (volatility clustering).
Now also: variance_gamma — a pure-jump Levy process (Brownian motion time-changed by a Gamma clock, sampled via a hand-rolled Marsaglia-Tsang Gamma variate generator) with infinite jump activity, unlike Merton's finite-rate Poisson jumps, which better matches the high kurtosis seen in real short-horizon returns (confirmed directly by measuring simulated kurtosis); fractional_brownian_motion — a long-memory Gaussian process built via Cholesky factorization of its covariance matrix, recovering ordinary Brownian motion's uncorrelated increments at Hurst exponent 0.5 and showing clear positive autocorrelation above it (relevant to "rough volatility" research); regime_switching — a two-state Markov model where mean and volatility themselves jump between hidden states, a qualitatively different mechanism from GARCH's continuous volatility evolution; and egarch/gjr_garch — the two standard asymmetric-GARCH variants that let a negative shock raise future volatility by more than an equal-sized positive one (the "leverage effect"), each with a test that isolates the asymmetry directly at the single-step level rather than relying on noisy full simulations.
Beyond the Crank-Nicolson/ADI, Carr-Madan/COS, and control-variate/importance-sampling pairs already described above, numerical-methods also has longstaff_schwartz and quasi_monte_carlo (both described in section 1, since they're specifically options-pricing techniques even though they live here methodologically alongside the rest of this crate).
statistical-arbitrage has cointegration (Engle-Granger pairwise test), kalman_filter (scalar dynamic hedge ratio), mean_reversion (OU-fit z-score signals), and momentum (cross-sectional ranking); core::orderbook has a full price-time-priority limit order book.
Now also: johansen generalizes cointegration testing beyond pairs — a simplified but genuine generalized-eigenvalue construction (via nalgebra) over S00/S11/S01 covariance matrices from N series at once, discriminating a constructed cointegrated system from N independent random walks; vecm estimates the adjustment-speed vector of a Vector Error Correction Model given a cointegrating relationship, recovering the correct sign (reversion toward equilibrium) and ballpark magnitude on synthetic data; arima implements exact-round-trip differencing/undifferencing, AR(p) fitting via OLS and simulation, and MA(q) simulation (fitting an MA model has no closed form and is honestly left as simulation-only rather than faked); vector_kalman_filter generalizes the scalar Kalman filter to arbitrary state/observation dimension via nalgebra, cross-checked against the simpler scalar filter on an equivalent problem; particle_filter is a bootstrap particle filter for non-linear/non-Gaussian state estimation, validated on a linear-Gaussian problem where the Kalman filter's answer is independently known to be correct; optimal_execution implements the closed-form Almgren-Chriss trading trajectory, trading off market impact against timing risk (verified to front-load more aggressively as risk aversion increases, and to degenerate to a straight-line schedule as risk aversion vanishes); execution_benchmarks computes VWAP, TWAP, and implementation shortfall; and pca_stat_arb builds eigenportfolios from a return covariance matrix's principal components, the natural many-assets generalization of pairwise cointegration trading.
core::orderbook itself was extended with market orders (walking through resting price levels until filled) and stop orders (inactive until the last-traded price crosses a trigger, then firing as a market order), and core::order_book_signals adds order-book imbalance, (bid_depth - ask_depth) / (bid_depth + ask_depth), the standard microstructure signal for short-term price pressure.
Fully covered by core::orderbook (matching engine, market/stop orders) and core::order_book_signals (imbalance), described just above. Execution-specific pieces (Almgren-Chriss optimal execution, VWAP/TWAP benchmarking) live in statistical-arbitrage, described in section 6.
A new crate, credit-risk, covers the branch of the field almost entirely absent before this round: merton_structural treats a firm's equity as a call option on its assets struck at its debt (reusing quant_lab::options::black_scholes_price directly), deriving distance-to-default and default probability — and documents KMV's equity-implied-asset-value calibration as a known, unimplemented refinement; reduced_form models default as a hazard-rate arrival process, with survival/default probabilities, a discretized CDS par-spread calculation, and the standard "credit triangle" approximate inverse (hazard rate ~= spread / (1 - recovery)); ratings_transition implements a Markov ratings-transition matrix with an absorbing default state and n-year transition probabilities via matrix powers; and regulatory_capital has simplified, clearly-labeled Basel-style risk-weighted-assets, capital-requirement, and CVA-capital-charge calculations that capture the shape of the real formulas (more exposure, more default probability, or more loss-given-default all raise required capital) without claiming to be a full regulatory implementation.
Spread across crates: core::timeseries (returns, rolling/EWMA volatility), portfolio-risk::fama_french::ols_regression (general linear factor regression), statistical-arbitrage::cointegration/johansen (unit-root and multivariate cointegration testing), statistical-arbitrage::arima (differencing, AR fitting), stochastic-processes::garch/egarch/gjr_garch (symmetric and asymmetric conditional heteroskedasticity), and statistical-arbitrage::vector_kalman_filter/particle_filter (linear and non-linear state-space filtering).
Every module above is real, tested code — but several make an explicit, documented tradeoff between full generality and a tractable, correct, well-tested scope, rather than silently cutting a corner. Worth naming honestly: variance_swap's fair-strike formula covers the flat-volatility special case of the full log-contract replication argument; hjm/libor_market_model/two_factor_hull_white use tractable parametric or frozen-drift simplifications rather than fully general calibration machinery; adi_method treats the cross-asset-correlation term explicitly rather than fully implicitly; johansen's cointegration-rank test and cointegration::adf_test_statistic's unit-root test both use approximate thresholds rather than true asymptotic critical-value tables; arima fits AR(p) but only simulates MA(q) (no closed-form MA fit exists); merton_structural takes asset value/volatility as given rather than backing them out from observed equity data (the KMV refinement); regulatory_capital is an explicitly labeled stand-in for the much more elaborate real Basel III/IV formulas; and quasi_monte_carlo uses Halton sequences rather than Sobol (a simpler low-discrepancy sequence with the same qualitative advantage over pseudo-random sampling).
Three adjacent fields are worth naming rather than leaving as a silent gap: machine-learning-based alpha research (gradient-boosted trees, neural networks trained on engineered features) is a different toolchain and discipline from the closed-form-and-simulation math this repo is built around; real options and corporate-finance capital budgeting is quantitative finance in the broad sense but a different practitioner audience than derivatives/trading desks; and crypto/DeFi-native quant topics (AMM bonding-curve math, perpetual-funding-rate arbitrage) are a related but separate newer field.
| Crate | Tests |
|---|---|
core |
29 |
options-pricing |
39 |
interest-rate-models |
31 |
portfolio-risk |
40 |
stochastic-processes |
34 |
numerical-methods |
23 |
statistical-arbitrage |
38 |
credit-risk |
15 |
| Total | 249 |
Every model is checked against something independent of its own implementation wherever one exists: closed forms cross-checked against Monte Carlo (or vice versa), put-call parity, convergence as discretization steps increase, known statistical properties (mean reversion, kurtosis, autocorrelation), parameter recovery from simulated data with a known ground truth, or one new model reducing exactly to an existing, already-tested one in a degenerate special case (APT to CAPM, Garman-Kohlhagen to Black-Scholes at equal rates, the vector Kalman filter to the scalar one).