Skip to content

How to Calculate the Deflated Sharpe Ratio After Multiple Trials

Original question

Can you show me how to calculate the deflated Sharpe ratio and explain why it matters when testing multiple strategies?
The deflated Sharpe ratio applies the probabilistic Sharpe ratio formula with a benchmark reflecting the expected best Sharpe from multiple trials under a zero-skill null. A winning strategy must clear a higher bar if it was selected from a large search. To calculate it, use the selected strategy's per-period Sharpe, sample length, skewness and kurtosis, plus an estimate of trial Sharpe dispersion and the effective number of trials.
When you run many backtests, some combinations of features and parameters will look promising from sampling variation alone. The more opportunities you had to choose a winner, the less you can learn from the winning Sharpe in isolation. A one-sided probability-style score from 0 to 1 expresses how much evidence the winner offers above the search-adjusted benchmark under the formula's assumptions.

The effective number of trials is smaller than the raw count when nearby strategies make similar trades. Preserve the full research log, including discarded signals and settings. Ten nearly identical parameter choices and ten unrelated strategies generate different opportunities for a chance winner.

Let σtrials\sigma_{\mathrm{trials}} be the standard deviation of the candidate Sharpes in per-observation units. For N>1N>1 effectively independent trials, Bailey and López de Prado approximate the expected maximum under a zero-mean Gaussian trial model by
S0=σtrials[(1−γ)Φ−1(1−1N)+γΦ−1(1−1Ne)],S_0 = \sigma_{\mathrm{trials}} \left[(1-\gamma)\Phi^{-1}\left(1-\frac1N\right) +\gamma\Phi^{-1}\left(1-\frac1{Ne}\right)\right],

with Euler's constant γ≈0.5772\gamma\approx0.5772. For one trial under a zero-Sharpe null, use S0=0S_0=0. With observed Sharpe S^\widehat S, TT return observations, sample skewness γ^3\widehat\gamma_3 and raw kurtosis γ^4\widehat\gamma_4, compute

DSR⁡=Φ((S^−S0)T−11−γ^3S^+(γ^4−1)S^2/4).\operatorname{DSR}=\Phi\left( \frac{(\widehat S-S_0)\sqrt{T-1}} {\sqrt{1-\widehat\gamma_3\widehat S+(\widehat\gamma_4-1)\widehat S^2/4}} \right).

The shape correction changes the uncertainty estimate for Sharpe. Strong serial dependence and overlapping observations call for a different inference treatment or additional dependence-aware checks.

There are two sources of uncertainty here. The variation across trials helps determine how high the winning estimate could be by selection alone. The sampling uncertainty of the winning strategy determines how convincingly its Sharpe clears that threshold. The first enters the benchmark and the second enters the probabilistic Sharpe calculation. Use daily units for both in this example. Annualising the winner without also changing the benchmark and inference formula gives a comparison with incompatible scales.

The maximum grows with the number of effectively independent draws, but returns from neighbouring parameter variants are often closely related. Fifty thresholds applied to the same signals are a different search from fifty unrelated strategies. A sensitivity calculation can report the deflated probability under several plausible effective trial counts. That makes the dependence assumption visible instead of burying it in a precise-looking answer. The statistic still assesses evidence from the observed search. It does not undo leakage or make a final test independent if that test was used repeatedly.

Calculate the penalty on a daily Sharpe

Suppose you select a daily Sharpe of 0.10 from 50 effectively independent trials whose daily Sharpe estimates have standard deviation 0.03. With 756 returns, skewness −0.5 and raw kurtosis 4, the approximate selection threshold is 0.068 in daily units. The adjusted score is about 0.80. The same formula with a zero benchmark yields a score above 0.99. The search history materially changes the evidence even though the reported strategy returns stay the same.

Compute the benchmark and probability

from math import e, sqrt from scipy.stats import norm def deflated_sharpe(sharpe, count, skew, raw_kurtosis, trials, trial_sd): gamma = 0.5772156649015329 benchmark = 0.0 if trials > 1: benchmark = trial_sd * ( (1 - gamma) * norm.isf(1 / trials) + gamma * norm.isf(1 / (trials * e)) ) denominator = sqrt(1 - skew * sharpe + (raw_kurtosis - 1) * sharpe**2 / 4) return benchmark, norm.cdf((sharpe - benchmark) * sqrt(count - 1) / denominator) print(deflated_sharpe(0.10, 756, -0.5, 4.0, 50, 0.03))

References and next steps