QTQuant Terminal
A2-04A2·intro·~17 min

The Sharpe ratio

statisticssharpe-ratiorisk-adjusted-returns

▸ Pretest — guess, even if you don't know

A strategy has annualized return of 20% and annualized volatility of 10%. The risk-free rate is 4%. What's its Sharpe ratio?

The formula

Annualized Sharpe ratio:

Sharpe=E[r]rfσr\text{Sharpe} = \frac{E[r] - r_f}{\sigma_r}

Where:

It's a per-unit-of-volatility excess return. A unitless quantity. Higher is better (most of the time — caveats below).

How to compute it from a return series

import numpy as np

def annual_sharpe(daily_returns, rf_annual=0.04, trading_days=252):
    rf_daily = rf_annual / trading_days
    excess = daily_returns - rf_daily
    return (excess.mean() / excess.std(ddof=1)) * np.sqrt(trading_days)

The 252\sqrt{252} factor annualizes because:

Benchmarks — what's a good Sharpe?

For long-horizon strategies:

For shorter horizons (daily reallocation, intraday), Sharpe can be higher because the high turnover lets the strategy compound smaller edges more often. But after honest cost modeling, even those rarely sustain above ~3 in production.

Renaissance Technologies' Medallion Fund allegedly runs Sharpe ~7+. They are a unique outlier; do not benchmark yourself against them.

The standard error of an estimated Sharpe (this is huge)

Estimating Sharpe from a finite sample is noisy. The approximate standard error (Lo 2002) for an iid normal series of NN observations, stated in per-period units:

SE(SR^per-period)1+12SR^per-period2N\text{SE}(\widehat{\text{SR}}_\text{per-period}) \approx \sqrt{\frac{1 + \tfrac{1}{2}\widehat{\text{SR}}_\text{per-period}^2}{N}}

Units matter here. The Sharpe in this formula is the per-period (e.g., daily) Sharpe, and NN is the number of those periods. To get the SE of the annualized Sharpe, compute in daily units first, then multiply by 252\sqrt{252}.

Worked example — annual Sharpe = 1.0, five years of daily data (N=1260N = 1260):

  1. Daily Sharpe: SRd=1.0/2520.063\text{SR}_d = 1.0 / \sqrt{252} \approx 0.063.
  2. Per-period SE: (1+12(0.063)2)/12600.028\sqrt{(1 + \tfrac{1}{2}(0.063)^2)/1260} \approx 0.028.
  3. Annualized SE: 0.0282520.450.028 \cdot \sqrt{252} \approx 0.45.

So with 5 years of data, a strategy with measured annual Sharpe = 1.0 has a 95% confidence interval of roughly 1.0±20.45=[0.1,1.9]1.0 \pm 2 \cdot 0.45 = [0.1, 1.9]. You barely have evidence that the true Sharpe is positive. With 10 years, the interval tightens roughly to [0.4, 1.6]. With 30 years, [0.6, 1.4].

A convenient shortcut: for modest Sharpe values, the annualized SE is approximately (1+12SRannual2)/years\sqrt{(1 + \tfrac{1}{2}\text{SR}_\text{annual}^2) / \text{years}} — the same formula with NN counted in years. That's why 5 years of a Sharpe-1 strategy gives SE ≈ 1.5/50.55\sqrt{1.5/5} \approx 0.55 (close to the exact 0.45; the shortcut is slightly conservative).

This is why short backtests can't validate a strategy. A 2-year backtest showing Sharpe of 1.0 is consistent with a true Sharpe of zero (i.e., no edge).

Sharpe's failure modes

  1. Assumes returns are roughly normal. A strategy that earns small premia steadily while occasionally suffering catastrophic losses (selling out-of-the-money options before they blow up) can show high Sharpe right up until the blowup. Sharpe doesn't see the fat tail. This is the single most important caveat.

  2. Compares strategies with different timescales unfairly. A high-frequency strategy with 10× the number of independent trades naturally has a √10 ≈ 3.2× higher Sharpe than a daily strategy with the same per-trade edge.

  3. Ignores higher moments. Skewness and kurtosis don't enter the formula. Sortino (denominator = downside deviation only) and Calmar (denominator = max drawdown) partially correct for this.

  4. In-sample optimism bias. A backtest Sharpe that was selected from many candidates (parameter tuning, strategy search) is biased upward — this is what the deflated Sharpe ratio corrects for (López de Prado 2018). We'll see deflated Sharpe later in D4 (backtest methodology).

Try it

Implement the Sharpe computation from the code sketch above, from memory if you can:

▮ EXERCISE · a2-04-ex1

Implement sharpe(daily_returns, rf_annual): convert the annual risk-free rate to daily (rf_annual / 252), subtract it from the daily returns to get excess returns, then return excess.mean() / excess.std(ddof=1) * sqrt(252).

Predict and pace yourself

Before the next lesson:

⧉ Review card
What is the Sharpe ratio formula?
(E[r] − r_f) / σ_r. Annualized excess return divided by annualized volatility. Unitless.
⧉ Review card
What's a typical Sharpe for buy-and-hold SPY?
~0.4 over long history. Anything above ~1 is impressive sustained; above ~2 is exceptional and warrants serious audit of the backtest.
⧉ Review card
What is the approximate SE of an annualized Sharpe estimate, and what CI does 5 years of data give a Sharpe-1 strategy?
Lo (2002), in per-period units: SE ≈ √((1 + SR²/2)/N), then × √252 to annualize. Shortcut: ≈ √((1 + SR²/2)/years). For 5 years and annual Sharpe 1: SE ≈ 0.45–0.55, so the 95% CI is roughly [0.1, 1.9] — barely distinguishable from zero.
⧉ Review card
What's Sharpe's biggest blind spot?
It assumes returns are roughly symmetric. Strategies with rare catastrophic losses (e.g., short vol, selling tail options) look great by Sharpe right up until they blow up. Use Sortino, max drawdown, and stress testing alongside.

◈ Calibration check

Could you compute a Sharpe ratio from a return series, and explain its standard error?

1 = guessing · 5 = could teach it

⏻ End of lesson

Mark it read to book its 4 review cards into your deck.

Sources & further reading