Skip to content

v2.0.0-rc.1

Choose a tag to compare

@dancixx dancixx released this 10 May 09:28
· 159 commits to main since this release
21446df

Second release candidate of stochastic-rs v2.

Quant module fixes

  • Heston stoch-corrslsqp::minimize return value was discarded; calibrator returned the initial guess as if calibrated. Now captures the slsqp tuple; HscmCalibrationResult gains converged + final_objective.
  • Lévy / NIGLevyModel::Nig wrapped NIG params in CGMYFourier with hardcoded y=0.5. New NigFourier (Barndorff-Nielsen 1997 char fn) wired through the calibrator; round-trip test added.
  • HSCM / rBergomi — both pricers silently dropped q; HSCM also used iu·r instead of iu·(r-q) in the ODE drift. q now threaded through; new RBergomiCalibrator::with_dividend_yield(q) builder + parity-with-q tests.
  • Carr-Madanprice_call returned 0.0 silently for log-strikes outside the FFT grid; now returns NaN so 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 swapped theta/mu to 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 a DiscountCurve-projected representation; HullWhite::from_curve builder + no-arbitrage + determinism regression tests added.
  • Multi-period Kyle 1985 — backward recursion was non-canonical (β·λ = 0.25 vs canonical 0.5 at n_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-axisempirical_cvar now asserts alpha < 0.5 so users who pass confidence-style 0.95 crash loudly instead of averaging nearly the full distribution.
  • SABR ↔ DVector round-trip — silently forced β=1.0; From impls now use a 4-vec [α, β, ν, ρ] (lossless). Internal LM solver uses a private as_lm_vec() 3-vec helper.
  • TimeExt panic-on-missingtau_or_from_dates / tau_with_dcc now return f64::NAN (matching Greeks::default) instead of panicking.
  • Heston Cui (2017) Jacobian test — tolerance tightened from 2e-1 (20%) to 5e-3. Cui math is correct line-for-line; loose tolerance would have masked 5–10% regressions.
  • CgmysvCalibrator / HKDECalibrator / HscmCalibrator now implement the unified Calibrator trait with Result<Output, Error> so they compose with generic pipelines.

P0 release-blocker fixes

  • fbm.rs duplicate Array2 import (E0252) on the python+gpu combo. cargo check --workspace --all-features clean. CI matrix expanded with the combo.
  • interest::bgm honestly scoped as parallel forward-Euler multiplicative martingales (not BGM/LMM, paths can go negative). A proper drift-coupled LIBOR Market Model is now interest::lmm::Lmm (spot-LIBOR measure, log-Euler positivity-preserving stepping, optional Cholesky correlation).
  • theta / mu doc-swap on OU / CIR / Vasicek: theta is mean-reversion speed, mu is 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::Classical removed (was panic-only).
  • tests/debug_fukasawa.rs #[ignore]-d (was a no-assertion diagnostic polluting workspace test output).

P1 fixes

  • 17 production panic!s in stochastic-rs-stochastic moved to constructor-side validation (validate_drift_args, validate_n_or_tmax).
  • stats::fd::FractalDim returns Result<FdResult, FdError> (6-variant error enum) instead of panicking on degenerate input.
  • stats::fou_estimator V1/V2/V4 refactored from struct API to free fns over ArrayView1<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-distributions 119s → 0.03s.
  • 4 rand::random::<f64>() call-sites in copulas::multivariate::{Tree, Vine} replaced with SimdNormal::fill_slice_fast so seeded usage is deterministic.
  • PyPI macOS x86_64 (Intel) wheels back: macos-13 builder added alongside aarch64.
  • CI: 8-element feature matrix ("", ai, openblas, yahoo, python, gpu, python,gpu, openblas,ai,yahoo) + new lint job (cargo fmt --check + clippy --workspace -D warnings). actions-rs/toolchain@v1dtolnay/rust-toolchain@stable.
  • publish.sh pre-publish gate (fmt + clippy + workspace test); optional --skip-gate bypass.
  • bergomi.rs / rbergomi.rs honest scope-doc (variance-matched scaled-Brownian-motion approximations, not true Volterra integrals). Pointers to crate::rough::MarkovLift / rl_heston::RlHeston / rl_bs::RlBs / process::volterra::Volterra.
  • Gbm::sample x0 default 0.01.0 (0 is an absorbing fixed point).
  • stochastic-rs-core/src/python.rs now #[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 from FouEstimateResult.
  • StochVolNn::predict_implied_vol_surface + thin wrappers for HestonNn / OneFactorNn / RBergomiNn (gated on the quant feature of stochastic-rs-ai).
  • HypothesisTest trait + 8 implementations (ADF, KPSS, ERS, PhillipsPerron, LeybourneMcCabe, JarqueBera, AndersonDarling, ShapiroFrancia).
  • VariableDimensional<T> + ComplexPathOutput<T> marker traits for processes returning Vec<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-viz split into plottable.rs + grid_plotter.rs + convenience.rs; new Plottable<T> trait + GridPlotter builder + plot_process / plot_distribution / plot_vol_surface convenience 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::Classical removed (was panic-only). Enum is now enum FilterType { Daubechies }.
  • stats::fou_estimator::FOUParameterEstimationV{1,2,4} structs → free fns estimate_fou_v{1,2,4}(path: ArrayView1<f64>, ...). V3 retained as a sim+est round-trip helper.
  • stats::fd::FractalDim::estimate returns Result<FdResult, FdError> instead of panicking.
  • Gbm::sample x0 default 0.01.0.

Full Changelog: v2.0.0-rc.0...v2.0.0-rc.1