macrosynergy.pnl.sharpe_stability_ratio#

Sharpe Stability Ratio: HAC-robust t-stat for the mean rolling Sharpe, accounting for sample size and serial dependence.

sharpe_stability_ratio(returns, window=252, benchmark_sr=0.0, annualization_factor=252, min_periods=None)[source]#

The SSR is the ratio between an average (rolling) Sharpe ratio and its estimated deviation from a true mean (“estimated parameter error”). Thus, it accounts not only for the risk-adjusted return of a strategy but also for its uncertainty given the sample size, seasonality, and autocorrelation.

By default, Sharpe ratios and their estimated errors are calculated using rolling 252-trading-day windows on a daily return series. The error is estimated using the HAC (Heteroskedasticity and Autocorrelation Consistent) Newey-West (1987) variance estimator, which adjusts the variance of the sample mean for serial dependence in the rolling Sharpe series.

The SSR can be interpreted as a signal-to-noise measure, indicating how strongly the Sharpe ratios deviate from zero after accounting for their serial dependence. If the SSR is above 1, its value exceeds its estimated noise, providing evidence of a non-zero mean. Under standard regularity conditions, the SSR approximates a t-statistic for the mean of the Sharpe ratio: a value of 1 corresponds to ~68% confidence in a non-zero mean, 1.64 to ~90%, 1.96 to ~95%, and 2.58 to ~99%.

For non-daily inputs, window and annualization_factor must be set together to match the input frequency (monthly: 12/12, weekly: 52/52).

Parameters:
  • returns (pd.Series or np.ndarray) – Return series at the frequency implied by window / annualization_factor. NaNs are dropped.

  • window (int, default 252) – Rolling window length (number of observations) for computing the Sharpe ratio series. Must be >= 2.

  • benchmark_sr (float, default 0.0) – Benchmark Sharpe ratio (SR*) the mean rolling Sharpe is tested against.

  • annualization_factor (int, default 252) – Periods per year. Must match input frequency.

  • min_periods (int or None, default None) – Minimum non-NaN observations per window. Defaults to window.

Returns:

SSR, or NaN if data is insufficient or the rolling Sharpe series has zero variance.

Return type:

float