Sharpe ratio

Also written reward-to-variability, sharpe_ratio

Average return in excess of a benchmark, divided by the standard deviation of that excess return. Sharpe introduced it in 1966 as the reward-to-variability ratio, measured on annual returns against a fixed riskless rate. The formula is one line, but each input is a choice: which risk-free rate, which return frequency, which annualisation factor, and whether the mean is arithmetic or compounded. Tools that choose differently report different ratios for the same history.

How it works

Sharpe's 1966 paper, "Mutual Fund Performance", ranked thirty-four open-end funds on their annual returns for 1954–63. The numerator was a fund's average annual return minus a pure interest rate — he used 3 per cent, because a ten-year US government bond bought in 1953 would have guaranteed slightly less than that to maturity — and the denominator was the standard deviation of those annual returns. He named it the reward-to-variability ratio: the reward for bearing risk, per unit of risk actually borne.

The 1994 restatement, "The Sharpe Ratio", generalised both halves. The ex post ratio is the average differential return — fund minus benchmark, period by period — divided by the standard deviation of that differential. The benchmark was originally a riskless security, and the paper allows a benchmark portfolio in its place. It also writes down the time dependence: the ratio "is not independent of the time period over which it is measured", and scaling a one-period ratio to T periods by the square root of T assumes the differential returns have zero serial correlation. Sharpe's own recommendation is to measure over fairly short periods, such as months, and then annualise for the sake of standardisation.

So the definition fixes the shape and leaves four decisions open, and every implementation has to make all four:

  • The risk-free leg. Zero, a constant, or a historical rate series — and if a series, which one, in which currency, and in what units the function expects it.
  • The return frequency. Daily, monthly or annual returns are three different samples of one history, not three resolutions of one number.
  • The annualisation factor. The per-period ratio is multiplied by the square root of the periods in a year, and a year is 252, 365, 12 or 1 depending on who is counting.
  • The mean. Both papers take an arithmetic average of period excess returns. A compounded growth rate in the numerator is a different quantity.

Why it matters here

The tools in analysis libraries and backtesting frameworks all report "the Sharpe ratio", and read against their own source code and documentation on 26 September 2026 they settle those four decisions differently.

The risk-free leg. QuantStats, empyrical-reloaded, VectorBT and Backtesting.py default it to zero, as do PyPortfolioOpt's max_sharpe() and portfolio_performance(). Backtrader's SharpeRatio analyzer defaults to 1 per cent a year. Portfolio Visualizer uses historical three-month Treasury bill rates published by FRED, testfolio a risk-free proxy chosen by the reporting currency, and QuantConnect defaults to the primary credit rate. The units differ as well as the values. QuantStats and ffn take an annual rate and de-annualise it themselves; empyrical-reloaded documents risk_free as a constant daily return. The same 0.04 passed to both subtracts about 0.016 per cent a day in one and 4 per cent a day in the other.

Frequency and annualisation. Portfolio Visualizer computes risk metrics from monthly returns and multiplies the monthly ratio by the square root of 12; testfolio uses daily excess returns. QuantStats and empyrical-reloaded default to 252 periods a year. VectorBT's default year is 365 days, so a daily series is annualised by the square root of 365, which puts its figure about 20 per cent above the 252-day one on identical returns. Backtesting.py picks 252 or 365 depending on whether the data contains weekend bars. Backtrader's analyzer defaults to annual returns, so a ten-year run yields a ratio from ten numbers, with a population rather than a sample standard deviation unless stddev_sample is set. ffn's calc_stats().display() prints a daily, a monthly and a yearly Sharpe for one series side by side, which is the whole of this page in a single table.

Arithmetic or compounded. QuantStats, empyrical-reloaded, ffn and testfolio average the period excess returns arithmetically, as the papers do. Backtesting.py does not: it annualises the geometric mean daily return, pairs it with a matching compounded volatility, and its source carries a comment saying its Sharpe mismatches empyrical's for exactly that reason. PyPortfolioOpt's default expected return, mean_historical_return, is a compound annual growth rate unless compounding=False — and the ratio it reports is ex ante, of forecast returns under chosen weights, not of a realised record.

To compare two of these figures, feed one returns series to both tools with every parameter set explicitly, and check what the series is before that. A price-only series understates a dividend-paying asset's excess return, which is why the adjusted-close guide asks for total return before a Sharpe ratio is quoted. A series built from account balances that include deposits is not a return series at all until the cash flows are taken out, which is the time-weighted return problem. A universe of names that still exist leaves out the returns that ended at zero — see survivorship bias. And a ratio read off a rule chosen on the same rows it is measured on is an in-sample figure however it is computed, which is what walk-forward testing is built to separate.

Where you will meet this

The cards where this changes a decision, then the rest that use the word.

Sources

  1. Mutual Fund Performance (The Journal of Business, Vol. 39, No. 1, Part 2, pp. 119–138) — The University of Chicago Press, . The paper that defined the ratio; cited for what it measured in 1966, which the 1994 restatement generalised rather than withdrew.
  2. The Sharpe Ratio (reprinted from The Journal of Portfolio Management, Fall 1994) — William F. Sharpe, Stanford University, read
  3. Portfolio Visualizer Documentation — Portfolio Visualizer, read
  4. Help, Methodology, and Tool Guides — testfolio, read
  5. quantstats/stats.py, sharpe() — QuantStats (GitHub), read
  6. empyrical/stats.py, sharpe_ratio() and annualization_factor() — empyrical-reloaded (GitHub), read
  7. ffn/core.py, PerformanceStats and calc_sharpe() — ffn (GitHub), read
  8. backtesting/_stats.py, compute_stats() — Backtesting.py (GitHub), read
  9. vectorbt/_settings.py, returns settings — vectorbt (GitHub), read
  10. backtrader/analyzers/sharpe.py, SharpeRatio — Backtrader (GitHub), read
  11. Risk Free Interest Rate, Key Concepts — QuantConnect, read
  12. pypfopt/expected_returns.py, mean_historical_return() — PyPortfolioOpt (GitHub), read

FAQ

Can one tool's Sharpe ratio be converted into another's?

Only where the two differ in the annualisation factor alone. With the same daily returns, the same risk-free leg and the same arithmetic mean, a ratio annualised over 365 days is the one annualised over 252 multiplied by the square root of 365/252, about 1.20. A monthly ratio is not a converted daily one: it is computed from a different sample of the same history, and nothing but the returns themselves will reproduce it.

Which of a tool's settings decide the number?

Four, and a help page or a function signature should state each: the risk-free rate and the units it is expected in, the frequency of the returns, the number of periods per year used to annualise, and whether the numerator is an arithmetic average of period returns or a compounded growth rate. If any of the four is unstated, the figure cannot be compared with anything.

Updated