Calculate the Sharpe ratio, a measure of risk-adjusted return that evaluates the excess return of an investment portfolio or asset per unit of risk taken.

The Sharpe ratio is calculated as the difference between the expected return of the asset or portfolio and the risk-free rate of return, divided by the standard deviation of the asset or portfolio’s excess return. It quantifies the amount of return generated for each unit of risk assumed, providing insights into the investment’s performance relative to the risk taken.

The formula is as follows:

\[\text{Sharpe Ratio} = \text{Excess Return} / \text{Excess Standard Deviation}\]

By default one Sharpe ratio is reported per period, computed from the daily excess returns falling inside that period. For a given period, for example monthly, this translates into the following:

\[\text{Sharpe Ratio} = \text{Average Daily Excess Return within the Month} / \text{Standard Deviation of the Daily Excess Returns within the Month}\]

For a rolling period, period instead sets the frequency of the returns themselves and the ratio is computed over a rolling window of rolling such returns:

\[\text{Sharpe Ratio} = \text{Average Rolling Excess Return} / \text{Standard Deviation of Rolling Excess Returns}\]

Note that the Risk Free Rate is already subtracted from these returns. The Toolkit’s risk free rate is the 10-year US Treasury yield by default, while Sharpe (1994) and the Ken French factor files use a short-term Treasury bill. Initialise the Toolkit with risk_free_rate=”13w” (the 13-week Treasury bill; “5y”, “10y” and “30y” are the other options) to use a short rate instead.

By default the result is not annualized: it is a per-observation Sharpe ratio, so a value computed from daily returns is roughly SQRT(252) smaller than the annualized figure usually quoted in the literature (SQRT(52), SQRT(12) and SQRT(4) for weekly, monthly and quarterly returns respectively). Set annualize=True to multiply by that factor, to compare against published annualized Sharpe ratios.

The plain Sharpe ratio only looks at the mean and standard deviation of returns, implicitly assuming Gaussian, i.i.d. returns and ignoring how much uncertainty surrounds the estimate itself. The method parameter selects one of four corrections for that, each keeping the same excess returns and therefore the same underlying Sharpe ratio as its starting point:

  • "lo" - the annualized Sharpe ratio of Lo (2002), which corrects the annualization for serially correlated returns. SQRT(q) * SR assumes independent returns; with autocorrelated returns (smoothed prices of illiquid assets, hedge funds, momentum or mean reversion) the variance of a yearly return is no longer q times the variance of one return, and the yearly Sharpe ratio becomes:
\[\operatorname{SR}(q) = \operatorname{η}(q) \cdot \text{SR},\;\; \operatorname{η}(q) = q / \sqrt{q + 2 \cdot \text{Σ\_\{k} = \text{1\}} ^{\text{\{q-1\}}} (q - k) \cdot \rho_{k}}\]

where q is the number of observations in a year and ρ_k the sample autocorrelation of the excess returns at lag k. Positive autocorrelation lowers the annualized ratio below SQRT(q) * SR, negative autocorrelation raises it. Sample autocorrelations at lags close to the sample size rest on a handful of pairs, so the sum runs over lags lags and takes the autocorrelations beyond them as 0. Each ρ_k is corrected for its small-sample bias −(n − k) / (n · (n − 1)) (Moran, 1948), which the (q − k) weights would otherwise turn into an overstated ratio on short samples, and fewer than 30 observations give NaN: a week or a month of daily returns, or a rolling window below 30, so use quarterly or yearly periods or a longer window. The result is always annualized.

  • "adjusted" - the Adjusted Sharpe Ratio (ASR, Pezier & White, 2006) penalizes (or rewards) the Sharpe ratio for negative skewness and excess kurtosis using a Cornish-Fisher-style expansion, so that two strategies with the same Sharpe ratio but different tail shapes are no longer scored identically:
\[\text{ASR} = \text{SR} \cdot \left[1 + (S / 6) \cdot \text{SR} - ((K - 3) / 24) \cdot \text{SR} ^{2}\right]\]
  • "probabilistic" - the Probabilistic Sharpe Ratio (PSR) is the probability that the true (population) Sharpe ratio exceeds benchmark_sharpe_ratio, folding the skewness and (non-excess) kurtosis of the underlying returns into the standard error of the Sharpe ratio so that a short, lumpy sample no longer looks more convincing than it is:
\[\operatorname{PSR}(\text{SR} \cdot) = \Phi((\text{SR̂} - \text{SR} \cdot) \cdot \sqrt{n - 1} / \sqrt{1 - \text{γ₃} \cdot \text{SR̂} + ((\text{γ₄} - 1) / 4) \cdot \text{SR̂} ^{2}})\]
  • "deflated" - the Deflated Sharpe Ratio (DSR) is the Probabilistic Sharpe Ratio corrected for the fact that a reported Sharpe ratio is often the best of many strategy variations, parameter combinations, or lookback windows tried during a backtest (multiple testing / selection bias / “backtest overfitting”). It estimates the Sharpe ratio one would expect to observe purely by chance as the maximum of n_trials independent trials under the null hypothesis of no skill, and uses that expected maximum as the benchmark SR* in the Probabilistic Sharpe Ratio formula instead of a naive benchmark such as 0:
\[\text{SR} \cdot = \sqrt{\text{Var} \left[\text{SR\_trials}\right]} \cdot \left[(1 - \text{γ}) \cdot \operatorname{Phi⁻¹}(1 - 1 / N) + \text{γ} \cdot \operatorname{Phi⁻¹}(1 - 1 / (N \cdot e))\right]\]

Where SR̂ is the observed Sharpe ratio, S (γ₃) is the skewness and K (γ₄) the non-excess (raw) kurtosis of the same returns, n is the number of return observations, N is n_trials, Var[SR_trials] is the variance of the Sharpe ratios observed across those N trials, γ ≈ 0.5772 is the Euler-Mascheroni constant and Φ is the standard normal CDF. Since DSR = PSR(SR*), it is always less than or equal to the Probabilistic Sharpe Ratio computed against a benchmark of 0.

This codebase does not track “N literal strategy trials” - there is no record of how many parameter combinations were tried before arriving at the current Toolkit configuration. As a documented approximation, Var[SR_trials] is estimated from the variance of an auxiliary rolling Sharpe ratio series (see get_rolling_sharpe_ratio) computed over a trials_window-sized window across the full return history, and n_trials defaults to the number of valid (non-NaN) values in that same rolling series. That series is built from the same returns as the Sharpe ratio being deflated, so both are on the same scale: the daily excess returns (the observations within each period) for the Sharpe ratio per period, and the excess returns of period itself for a rolling Sharpe ratio. This treats each rolling window as if it were one “trial” - a reasonable proxy for how dispersed the Sharpe ratio could plausibly have been under different choices, but not a substitute for passing the actual number of variations tried (via n_trials) when that is known, since the quality of the correction depends directly on it.

See definition: https://en.wikipedia.org/wiki/Sharpe_ratio

Also known as: risk-adjusted return, reward-to-variability ratio. The variants are also known as the Pezier and White Adjusted Sharpe Ratio (ASR), the Sharpe ratio significance probability (PSR) and the backtest overfitting or selection-bias-adjusted Sharpe ratio (DSR).

Sharpe Ratio in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_sharpe_ratio as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["SPY", "TLT", "GLD", "BTCUSD"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2021-01-01",
    end_date="2025-12-31",
    benchmark_ticker=None,
)

toolkit.performance.get_sharpe_ratio(annualize=True)

Or, after setting up the Finance Toolkit MCP, ask:

What was the annualized Sharpe ratio of SPY, TLT, GLD and Bitcoin in each year from 2021 to 2025?

Which returns:

Date SPY TLT GLD BTCUSD
2021 1.9355 -0.2283 -0.6241 0.6316
2022 -0.608 -0.9215 0.4971 -1.1891
2023 1.1567 0.7714 0.8362 1.6139
2024 1.5203 -0.6917 1.4238 1.3959
2025 0.3606 0.2664 1.7105 -0.1906

Parameters

get_sharpe_ratio accepts the following parameters.

ParameterTypeDescriptionExample
periodstrThe period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”."quarterly"
rollingintThe rolling period to use for the calculation. If you select period = ‘monthly’ and set rolling to 12 you obtain the rolling 12-month Sharpe Ratio.4
methodstrWhich Sharpe ratio to calculate, one of “standard”, “lo”, “adjusted”, “probabilistic” or “deflated”, as described above. Defaults to “standard”."probabilistic"
benchmark_sharpe_ratiofloatThe hypothesized or benchmark Sharpe ratio (SR*) to test the observed Sharpe ratio against. Only used when method=”probabilistic”. Defaults to 0.0, i.e. testing whether the strategy has any skill at all above doing nothing.0.5
trials_windowintThe window size of the auxiliary rolling Sharpe ratio series that approximates Var[SR_trials] and the default n_trials, see above. Only used when method=”deflated”. It counts observations of the returns the Sharpe ratio is computed from: daily (or intraday) observations for the Sharpe ratio per period, and observations of period when rolling is set. Defaults to None, which uses the median number of observations per period (so each trial spans about one period) for the Sharpe ratio per period, and half of the available return history for a rolling Sharpe ratio so that enough overlapping windows exist regardless of period or date range.8
n_trialsintThe number of independent (or effectively independent) strategy variations, parameter combinations, or lookback windows tried before arriving at the reported Sharpe ratio. Only used when method=”deflated”. Defaults to None, which falls back to the number of valid values in the auxiliary rolling Sharpe ratio series described above. Pass this explicitly whenever the actual number of trials is known.20
lagsintThe number of autocorrelation lags in Lo’s η(q). Only used when method=”lo”. Defaults to None, which uses the Newey and West (1994) rule floor(4 * (n / 100)^(2/9)) on the n observations (4 for a year of daily returns), capped at q − 1.2
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise).2
growthboolWhether to calculate the growth of the ratios. Defaults to False.True
lagint | list[int]The lag to use for the growth calculation. Defaults to 1.4
standardizeboolWhether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.True
annualizeboolWhether to annualize the Sharpe ratio, multiplying it by the square root of the number of observations in a year: 252 for the daily returns within each period, 252 times the median number of bars per day for the intraday returns within a day (period=”daily” with an intraday_period), or the periods in a year for a rolling Sharpe ratio (e.g. 12 for monthly). Only for method=”standard” and “adjusted”, since the probabilistic and deflated methods return probabilities; method=”lo” is annualized either way. Defaults to False.True
Share