The Analyst's Path

Deflated Sharpe ratio

The deflated Sharpe ratio (DSR) is the probability that a strategy's Sharpe ratio holds up once you allow for how many strategies you tried to find it. The best Sharpe you'd expect from N strategies with no skill rises every time N grows. A DSR near 1.0 says the observed Sharpe genuinely clears the bar that N trials of pure luck would set; a DSR near or below 0.5 says the observed Sharpe is unremarkable, or worse, once the search is honestly priced in.

5 min readPart of Performance & Attribution Analytics in CodeOpen in course mode

Advertisement

This is the module's centerpiece, and QD1.03 already showed you why it matters: run enough independent, genuinely edge-less strategies and the best one will post an eye-catching Sharpe ratio purely from search, with nothing behind it. This section builds the same machinery QD1.03 built (unchanged) but repurposes it. QD1.03 uses it as a gate: a pass/fail check wired into a backtesting engine, deciding whether a discovered strategy is even allowed to proceed to the next stage of research. Here, the identical formula is a reporting statistic: the number that belongs in the memo you hand to someone who was not there for the search, stating plainly how much of the impressive headline number survives once the search is admitted.

How is the expected maximum Sharpe ratio calculated?

Step 1, the expected maximum Sharpe ratio of N trials. If you ran N independent trials, each with zero true skill, the estimated Sharpe ratio of each is approximately a draw from a mean-zero distribution with some standard deviation σ_SR. Extreme-value theory gives the expected value of the maximum of N such draws:

E[max SR_N] ≈ σ_SR × [ (1−γ)·Φ⁻¹(1 − 1/N) + γ·Φ⁻¹(1 − 1/(N·e)) ]

where γ ≈ 0.5772156649 is the Euler–Mascheroni constant, e ≈ 2.71828 is Euler's number, and Φ⁻¹ is the inverse standard normal CDF (scipy.stats.norm.ppf). Under the simplifying null that each trial's return series is i.i.d. and mean-zero, σ_SR ≈ 1/sqrt(T−1), T being the track-record length in periods. The point to hold onto: this expected maximum grows (without any real skill anywhere) every time N grows. At N=1 it is exactly 0 (there is nothing to select from); by N=1,000 it is a real, substantial number, purely from the arithmetic of taking the best of many noisy draws.

Advertisement

What is the deflated Sharpe ratio formula?

Step 2, the deflated Sharpe ratio itself. Deflating means using that expected maximum as the benchmark inside the PSR formula from the probabilistic Sharpe ratio section, rather than the usual SR*=0:

DSR = PSR( SR* = E[max SR_N] )

A DSR near 1.0 says the observed Sharpe genuinely clears the bar that N trials of pure luck would set; a DSR near or below 0.5 says the observed Sharpe is unremarkable, or worse, once the search is honestly priced in.

The one law that governs both steps, stated once because getting it wrong is the single most common way this statistic is misreported (QD1.03 names it too, in identical words): every Sharpe ratio inside this formula (SR̂, SR*, σ_SR) is per-observation, never annualized. Annualizing is a separate, purely cosmetic reporting step, applied only at the very end, to the final DSR-adjusted conclusion if at all, the DSR itself is a probability, already unit-free, and does not get annualized. Divide an annualized Sharpe by sqrt(periods_per_year) before it goes anywhere near this formula, or the whole statistic is corrupted, silently, by a scale factor of roughly 16 (for daily data).

Exercise QD2.03-e06 grades both expected_max_sharpe(n_trials, sr_std) and deflated_sharpe_ratio(returns, n_trials, ddof); its hidden tests check that the formula is monotonically increasing in n_trials (more trials, harder to look skilled), that n_trials=1 reduces deflated_sharpe_ratio to the plain PSR benchmarked at zero exactly, and that the extreme-value formula lands within a stated tolerance of an actual brute-force simulation of 1,000 zero-skill trials, a from-scratch numerical confirmation that the closed-form approximation is not just algebra, it matches what genuinely happens when you run the experiment.

{
  "skill": "Building and independently cross-checking a deflated Sharpe ratio implementation",
  "use": "Have an assistant draft a second, independent implementation of expected_max_sharpe and the deflated Sharpe ratio -- from the formula alone, not from your code -- so you can diff the two against each other and catch a transcription error in either one before either is trusted.",
  "tools": ["Chat assistants with code execution -- Claude, ChatGPT, Gemini", "Jupyter or a plain script for the side-by-side numeric diff"],
  "prompt": "Here is the Bailey-Lopez de Prado expected-maximum-Sharpe formula and the deflated Sharpe ratio formula (paste both). Write a second, independent Python implementation using numpy and scipy.stats, without looking at any code I give you. Then write a small script that runs both implementations on the same three test cases (n_trials=1, 15, 1000, with a stated per-period Sharpe and standard deviation) and prints both outputs side by side so I can compare them by eye.",
  "verify": "Trace every constant (0.5772156649 for gamma, np.e for e) to a named source -- Bailey and Lopez de Prado (2014) -- rather than accepting the assistant's recollection of the constant. Recompute at least one case entirely by hand with a calculator: Phi-inverse values are tabulated, this is not exotic. Confirm the assertion that DSR falls as n_trials rises actually fires in the diff script on real numbers, not just in prose. Run this module's own hidden tests against BOTH implementations before trusting either one -- an assistant's code that merely LOOKS like the formula is not evidence it matches it (Primary-Source Guardrail: Trace, Recompute).",
  "diy": "You must already be able to state, from memory and without notes, why deflating against E[max SR_N] rather than 0 is the correct response to 'I tried many things and kept the best' -- that is this section's entire content, and it is the judgment call an assistant cannot make for you: it does not know how many things you actually tried.",
  "market": "IN"
}

Advertisement

Part of the course

This page is part of Performance & Attribution Analytics in Code (QD2.03), in Phase 12: Finance Plus, AI and the quant-code track. The module's flashcards and its quiz are in the app.