sharpebench-stats 0.0.11

Deterministic backtest-honesty statistics: PSR, deflated Sharpe, the data-snooping family (White RC / Hansen SPA / Romano-Wolf), and selection robustness. Extracted from sharpebench-core.
Documentation
  • Coverage
  • 94.44%
    68 out of 72 items documented1 out of 38 items with examples
  • Size
  • Source code size: 61.02 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 997.3 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 3s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • general-liquidity/sharpebench
    2 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • ReverseZoom2151

sharpebench-stats — deterministic backtest-honesty statistics

The pure statistics core extracted from sharpebench-core: moment and normal primitives ([stats]), the deflated / probabilistic Sharpe family ([deflated_sharpe]), the data-snooping bootstrap family — White's Reality Check, Hansen's SPA, and Romano-Wolf step-down ([significance]) — and selection-axis luck control ([selection]).

Design invariants carried over verbatim from the original modules:

  • Pure. No I/O, no system clock, no ambient randomness. Any randomness (the significance bootstrap) takes an explicit seed argument.
  • Deterministic. Plain f64 math, fixed reduction order, no parallel float sums. The same input yields byte-identical output on any platform.
  • No unsafe.

Example: is this Sharpe real?

use sharpebench_stats::{deflated_sharpe_ratio, probabilistic_sharpe_ratio, sharpe_ratio};

// A per-period (NOT annualized) excess-return series.
let returns = [0.012, -0.004, 0.009, 0.011, -0.002, 0.008, 0.010, -0.001];

let sr = sharpe_ratio(&returns); // observed, per-period
let psr = probabilistic_sharpe_ratio(&returns, 0.0); // P(true Sharpe > 0)
// Deflate for the 200 strategies tried, with ~0.5 cross-trial Sharpe dispersion:
let dsr = deflated_sharpe_ratio(&returns, 200, 0.5); // P(skill survives the search)

assert!(sr > 0.0);
assert!((0.0..=1.0).contains(&psr));
assert!((0.0..=1.0).contains(&dsr));
assert!(dsr <= psr); // deflating for the search never raises the probability