v2.0.0
stochastic-rs v2.0.0
First stable 2.0 release. Six prereleases (beta.1 → beta.2 → beta.3 → rc.0 → rc.1 → rc.2) consolidated; the surface and numerics are identical to v2.0.0-rc.2. Changes since v2.0.0-rc.2 are docs-site and CI polish only (commits cd4f874 → 405f094).
What v2 brings
Workspace. Single stochastic-rs crate split into a 9-crate Cargo workspace at edition 2024 (stochastic-rs-core, -distributions, -stochastic, -copulas, -stats, -quant, -ai, -viz, -py). The umbrella stochastic-rs re-exports everything — every existing import path still works. Sub-crate-only consumers can now skip the quant/stats/ai compilation cost.
New trait surface.
preludewith 20 items in 5 groups (trait core / pricing / calibration / instrument-engine / option types).Calibrator/CalibrationResultare nowResult-based withtype Paramsandtype Error = anyhow::Error. 9Calibrator+ 12CalibrationResultimpls.GreeksExtcovers first- and second-order Greeks (vanna/charm/volga/veta), aggregated into a named-fieldGreeksstruct; MC pricers overridegreeks()for single-pass consistency.Instrument/PricingEngine(AnalyticBSEngine,AnalyticHestonEngine) — QuantLib-style decoupling between payoff and valuation.DistributionExtdefaults flipped from silent0.0tounimplemented!(). 18/19 distributions provide closed-form pdf / cdf / cf / moments.PricerExt::implied_volatilitydefault0.0→f64::NAN.
New primitives.
- Reactive market cache (
Cached<T>/MarketObserver). - FX module (delta conventions, ATM conventions, Vanna-Volga smile).
- Variance swap (Carr-Madan replication + Brockhaus-Long Heston closed form + Bernard-Cui discrete correction).
- Total Return Swap (proper TR forward
F_TR(t) = S · exp(r t)). interest::lmm::Lmm— drift-coupled LIBOR Market Model (spot-LIBOR measure, log-Euler positivity-preserving).numericsnamespace (HaltonSeq,SobolSeq,RlKernel,MarkovLift,Mlmc).HypothesisTesttrait + 8 implementations (ADF, KPSS, ERS, PhillipsPerron, LeybourneMcCabe, JarqueBera, AndersonDarling, ShapiroFrancia).
Python (stochastic-rs-py). 210-entry PyO3 surface (was 102 in rc.0): 198 classes + 12 pyfunctions across distributions, stochastic, quant pricers, Fourier engines, calibrators, vol surface, risk, microstructure, curves, factors, copulas, stats. All wrappers seed-aware via Deterministic::new(seed). AI bindings deferred to 2.x.
Silent-correctness fixes
If you held cached results from 1.x or any 2.0.0-beta.*, please re-compute:
tau * 365-vs-years bug inBSMPricer/HestonPricer/SabrPricer/HestonStochCorrPricer/AsianPricer/ Vasicek-bond implied vols (v1 IVs were understated by√365).variance_swap::fair_strike_replicationsign error onrTandln(K0/S0)correction.bonds/cir.rsclosed form:A·exp(+B·r)→A·exp(-B·r)(ZCB was increasing with the short rate).bonds/hull_white.rsrewritten against Brigo-Mercurio §3.3.2 / Hull-White (1990) extended-Vasicek using aDiscountCurve(v1 usedUtc::now().year()in the price — non-deterministic).calibration/heston_stoch_corr.rs—let _ = slsqp::minimize(...)discarded the calibrated params;HscmCalibrationResultreturned the initial guess. Now carries realconverged+final_objective.calibration/levy.rsNIG calibration wrapped NIG params inCGMYFourierwith hardcodedy = 0.5. NewNigFourier(Barndorff-Nielsen 1997 ChF) and rewired NIG path.pricing/heston_stoch_corr.rscharacteristic function usediu·rin the drift instead ofiu·(r−q). Threaded q through the ODE drift +ModelPricerimpl.pricing/rbergomi.rsdiscarded the dividend yield. Drift now uses(r-q-0.5·v)·dt;RBergomiCalibrator::with_dividend_yield(q)builder added.microstructure/kyle.rsmulti-period Kyle 1985 backward recursion was non-canonical (disagreed withsingle_period_kyleatn_periods = 1). Re-derived against Cetin-Larsen 2023 (arXiv:2307.09392).vol_surface/ssvi.rs::is_calendar_spread_freeonly checked the ATM term structure; missed off-ATM violations. Now verifies the full Gatheral & Jacquier 2014 Theorem 4.2 over a strike grid.pricing/fourier.rs::CarrMadanPricer::price_callsilently returned0.0for out-of-grid log-strikes — now returnsf64::NANso calibration objectives are poisoned and detection is forced; newstrike_in_grid()helper.portfolio/optimizers.rs::empirical_cvaralphais the tail proportion (0.05= worst 5%).assert!(alpha < 0.5)so users passing confidence-style0.95crash loudly.traits/time.rs::tau_or_from_dates/tau_with_dccreturnf64::NAN(was panic) when neither tau nor dates are set.- Heston switched to "Little Heston Trap" form (Albrecher-Mayer-Schoutens-Tistaert 2007) for long-maturity high-|ρ| principal-branch logarithm continuity.
Build & packaging
- Edition 2024 across the workspace.
- Feature flags propagate correctly:
gpu,cuda-native,metal,accelerate,openblas,python. If you previously built with--features gpuon v1 expecting GPU samplers, re-build on v2 — you'll now actually get them. docs.rsconfig pinned to["openblas", "ai", "yahoo"](all-features = truewas pulling native GPU SDKs and breaking the docs build).statrsis gone from production dependencies (closed-form rewrites instochastic-rs-distributions); kept as[dev-dependencies]for cross-validation tests only.- PyPI workflow now builds
macos-13 + x86_64alongsideaarch64— Intel Mac users canpip install stochastic-rsagain.
SKILLs
16 maintenance SKILLs shipped in .claude/skills/ to keep extensions consistent:
- Tier 1 (release-level):
release-checklist,feature-flag-management,calibration-pattern,greeks-pattern. - Tier 2 (domain):
add-diffusion-process,add-fractional-process,add-jump-process,adding-distribution,adding-python-binding,stats-estimator. - Tier 3 (niche):
copula-bivariate,add-gpu-sampler,add-mc-variance-reduction,vol-surrogate-nn,integration-test-writing,bench-writing.
Migration checklist
- Bump
stochastic-rs = "2.0"inCargo.toml. - Add
?after everycalibrator.calibrate(None)(nowResult). - Replace
pricer.derivatives()[i]reads withpricer.greeks().delta/.gamma/.vega/ etc. - Replace
iv == 0.0checks withiv.is_nan(). - If you implement
CalibrationResult: addtype Paramsandfn params(&self). - If you implement
DistributionExt: override every method you call (defaults nowunimplemented!()). - If you stored implied vols from
BSMPricer/HestonPricer/SabrPricer: recompute (v1 IVs were understated by√365).
Install
[dependencies]
stochastic-rs = "2.0"pip install stochastic-rs==2.0.0Per-rc rollup: rc.0 · rc.1 · rc.2
Full Changelog: v1.5.0...v2.0.0