v2.0.0-rc.1
Second release candidate of stochastic-rs v2.
Quant module fixes
- Heston stoch-corr —
slsqp::minimizereturn value was discarded; calibrator returned the initial guess as if calibrated. Now captures the slsqp tuple;HscmCalibrationResultgainsconverged+final_objective. - Lévy / NIG —
LevyModel::Nigwrapped NIG params inCGMYFourierwith hardcodedy=0.5. NewNigFourier(Barndorff-Nielsen 1997 char fn) wired through the calibrator; round-trip test added. - HSCM / rBergomi — both pricers silently dropped
q; HSCM also usediu·rinstead ofiu·(r-q)in the ODE drift. q now threaded through; newRBergomiCalibrator::with_dividend_yield(q)builder + parity-with-q tests. - Carr-Madan —
price_callreturned0.0silently for log-strikes outside the FFT grid; now returnsNaNso calibration objectives detect the failure rather than zero-residualing the wings. - CIR ZCB — closed-form bond formula sign error (
A·exp(+B·r)→A·exp(-B·r)). Field doc-comments swappedtheta/muto match Vasicek's workspace convention. - Hull-White ZCB — used
Utc::now().year()(non-determinism) and a hardcoded flat zero curve. Rewritten against Brigo & Mercurio §3.3.2 with aDiscountCurve-projected representation;HullWhite::from_curvebuilder + no-arbitrage + determinism regression tests added. - Multi-period Kyle 1985 — backward recursion was non-canonical (
β·λ = 0.25vs canonical0.5atn_periods=1). Re-derived against Cetin-Larsen 2023 (cubic γ-recursion + forward Σ-recursion). - SSVI calendar-spread free — only checked the ATM term structure; full Gatheral-Jacquier 2014 Theorem 4.2 condition now enforced over the smile grid. ATM-only check retained as
is_atm_calendar_spread_free. - CVaR alpha-axis —
empirical_cvarnow assertsalpha < 0.5so users who pass confidence-style0.95crash loudly instead of averaging nearly the full distribution. - SABR ↔ DVector round-trip — silently forced
β=1.0;Fromimpls now use a 4-vec[α, β, ν, ρ](lossless). Internal LM solver uses a privateas_lm_vec()3-vec helper. - TimeExt panic-on-missing —
tau_or_from_dates/tau_with_dccnow returnf64::NAN(matchingGreeks::default) instead of panicking. - Heston Cui (2017) Jacobian test — tolerance tightened from
2e-1(20%) to5e-3. Cui math is correct line-for-line; loose tolerance would have masked 5–10% regressions. CgmysvCalibrator/HKDECalibrator/HscmCalibratornow implement the unifiedCalibratortrait withResult<Output, Error>so they compose with generic pipelines.
P0 release-blocker fixes
fbm.rsduplicateArray2import (E0252) on thepython+gpucombo.cargo check --workspace --all-featuresclean. CI matrix expanded with the combo.interest::bgmhonestly scoped as parallel forward-Euler multiplicative martingales (not BGM/LMM, paths can go negative). A proper drift-coupled LIBOR Market Model is nowinterest::lmm::Lmm(spot-LIBOR measure, log-Euler positivity-preserving stepping, optional Cholesky correlation).theta/mudoc-swap onOU/CIR/Vasicek:thetais mean-reversion speed,muis the long-run mean.copulas::multivariate::{Tree, Vine}scope-doc — these are Gaussian-collapsed implied-correlation copulas, not real R-vine pair-copula constructions.stats::fou_estimator::FilterType::Classicalremoved (was panic-only).tests/debug_fukasawa.rs#[ignore]-d (was a no-assertion diagnostic polluting workspace test output).
P1 fixes
- 17 production
panic!s instochastic-rs-stochasticmoved to constructor-side validation (validate_drift_args,validate_n_or_tmax). stats::fd::FractalDimreturnsResult<FdResult, FdError>(6-variant error enum) instead of panicking on degenerate input.stats::fou_estimatorV1/V2/V4 refactored from struct API to free fns overArrayView1<f64>(zero-copy boundary). 786 → 562 LoC, 2 → 11 tests, 3 bit-exact regression guards.- 12 bench-style tests
#[ignore]-d in distributions:cargo test -p stochastic-rs-distributions119s → 0.03s. - 4
rand::random::<f64>()call-sites incopulas::multivariate::{Tree, Vine}replaced withSimdNormal::fill_slice_fastso seeded usage is deterministic. - PyPI macOS x86_64 (Intel) wheels back:
macos-13builder added alongsideaarch64. - CI: 8-element feature matrix (
"",ai,openblas,yahoo,python,gpu,python,gpu,openblas,ai,yahoo) + newlintjob (cargo fmt --check+clippy --workspace -D warnings).actions-rs/toolchain@v1→dtolnay/rust-toolchain@stable. publish.shpre-publish gate (fmt + clippy + workspace test); optional--skip-gatebypass.bergomi.rs/rbergomi.rshonest scope-doc (variance-matched scaled-Brownian-motion approximations, not true Volterra integrals). Pointers tocrate::rough::MarkovLift/rl_heston::RlHeston/rl_bs::RlBs/process::volterra::Volterra.Gbm::samplex0 default0.0→1.0(0 is an absorbing fixed point).stochastic-rs-core/src/python.rsnow#[cfg(feature = "python")]-gated.
Added
interest::lmm::Lmm— drift-coupled LIBOR Market Model.examples/calibration_demo.rs— end-to-end multi-maturity calibration (BSM + Heston).Vasicek::from_fou_estimate— stats↔quant adapter fromFouEstimateResult.StochVolNn::predict_implied_vol_surface+ thin wrappers forHestonNn/OneFactorNn/RBergomiNn(gated on thequantfeature ofstochastic-rs-ai).HypothesisTesttrait + 8 implementations (ADF, KPSS, ERS, PhillipsPerron, LeybourneMcCabe, JarqueBera, AndersonDarling, ShapiroFrancia).VariableDimensional<T>+ComplexPathOutput<T>marker traits for processes returningVec<Array1<T>>and complex-valued paths.- Frank copula
compute_theta— Brent root-finding + chunked Gauss-Legendre quadrature (prior custom Newton solver had a math bug in the Frank tau formula). stochastic-rs-vizsplit intoplottable.rs+grid_plotter.rs+convenience.rs; newPlottable<T>trait +GridPlotterbuilder +plot_process/plot_distribution/plot_vol_surfaceconvenience fns.
Python bindings — 102 → 210 entries
96 new PyO3 classes + 12 pyfunctions. Every wrapper accepts seed=None routed through Deterministic::new(seed). AI bindings intentionally deferred to 2.x.
- Quant pricers (~20): BSM, Heston, Sabr, Merton1976, Asian, Barrier, Compound, Chooser, Cliquet, Gap, SuperShare, CashOrNothing, AssetOrNothing, Floating-/Fixed-Lookback, BjerksundStensland2002, DoubleBarrier, MCBarrier, VarianceSwap, KirkSpread.
- Quant Fourier (8 + Carr-Madan engine): BSM, Heston, DoubleHeston, HKDE, Bates, Kou, MertonJD, CGMY, VG.
- Bonds: Vasicek, CIR.
- Calibrators (10): BSM, Heston, Sabr, SVJ, DoubleHeston, HKDE, RBergomi, Levy, SabrCaplet, Cgmysv.
- Vol surface (5): SviRawParams, SsviParams, SviCalibrator, SsviCalibrator, ImpliedVolSurface (FFT).
- Risk (3): VaR, ExpectedShortfall, DrawdownStats.
- Microstructure (3 class + 5 fn): AlmgrenChrissPlan, KyleEquilibrium, OrderBook +
multi_period_kyle, roll/effective/corwin_schultz spread, propagator price impact. - Curves (3): DiscountCurve, NelsonSiegel, ZeroCouponInflationCurve.
- Factors (2 fn + 3 openblas-gated):
ledoit_wolf_shrinkage,sample_covariance, PCA, FamaMacBeth, PairsStrategy. - Copulas (5 class + 4 fn): Clayton, Gumbel, Frank, Independence, EmpiricalCopula2D +
kendall_tau_matrix,tau_matrix_to_corr_matrix,tau_to_corr,corr_to_tau. - Stats — Normality (3), Stationarity (5, openblas-gated), Hurst (2), Heston (2), Realised (6), Spectral/Changepoint (3), Density (3), Econometrics (4, openblas-gated), MCMC (1 fn).
Breaking from rc.0
stats::fou_estimator::FilterType::Classicalremoved (was panic-only). Enum is nowenum FilterType { Daubechies }.stats::fou_estimator::FOUParameterEstimationV{1,2,4}structs → free fnsestimate_fou_v{1,2,4}(path: ArrayView1<f64>, ...). V3 retained as a sim+est round-trip helper.stats::fd::FractalDim::estimatereturnsResult<FdResult, FdError>instead of panicking.Gbm::samplex0 default0.0→1.0.
Full Changelog: v2.0.0-rc.0...v2.0.0-rc.1