Tutorial

Sharpe ratio: formula, what counts as good, and how to calculate it in Python

Over the year to 9 October 2026, the Sharpe ratio rated a near-record US500 at 0.88, under the rule-of-thumb mark of 1, and silver at 0.57 despite a 51.6% drawdown.

On this page
  1. The Sharpe ratio formula
  2. What is a good Sharpe ratio?
  3. Which risk-free rate to use
  4. How to calculate the Sharpe ratio in Python
  5. What the Sharpe ratio hides: max drawdown, Sortino and Calmar
  6. Why the same data gives different Sharpe ratios
  7. Sharpe ratio vs Sortino ratio, Calmar, Treynor and information ratio
  8. Questions

Key takeaways

  • The Sharpe ratio is annualized return minus the risk-free rate, divided by annualized volatility: 0.88 for US500 over the year to 9 October 2026, against that day’s 4.25% Treasury bill yield.
  • The usual rule of thumb calls 1 good, 2 very good and 3 excellent, but a one-year Sharpe ratio has a standard error of about 1.0, too wide to separate US:KO’s 1.37 from US500’s 0.88.
  • A Sharpe ratio turns negative when the mean return falls short of the risk-free rate: BTCUSD scored -0.73 for the year to 9 October 2026, when its price fell 32.1%.
  • Volatility does not show how losses arrive: silver scored 0.57 while falling 51.6% from its January high, and US:XOM, top of the eight at 1.53, fell 20.7%.
  • Unlabeled choices move a Sharpe ratio: US500 scored 0.88 from the 9 October 2025 close and 1.12 from the next day’s.

The Sharpe ratio, named after the economist William F. Sharpe, measures return per unit of risk: an asset’s annualized return minus the risk-free rate, divided by the annualized volatility of its returns. A Sharpe ratio of 1 means one percentage point of return above cash for each point of volatility, which lets traders compare assets, funds and strategies that carry different risk. US500, the US 500 large-cap benchmark, closed 9 October 2026 near its record yet scored 0.88 for the year, against the 4.25% a 3-month Treasury bill yielded that day.

Gold scored 0.16: its daily returns beat the bill by only 4.4 points a year, against 27.5% volatility. Below, one script scores eight assets on Sharpe, Sortino, max drawdown and Calmar; a second recomputes US500 and BTCUSD ten ways.

The Sharpe ratio formula

Worked example: US500 over the year to 9 October 2026:

Sharpe ratio = (Rp − Rf) ÷ σp

Rp
Annualized return: the mean daily return × 252, or × 365 for an asset that trades every day.
Rf
Risk-free rate: the 3-month Treasury bill yield, 4.25% on 9 October 2026.
σp
Annualized volatility: the standard deviation of daily returns × √252, or × √365.
US500, daily closes from 9 October 2025 to 9 October 2026: mean daily return 0.06245% × 252 = 15.74%; minus 4.25% = 11.49%; volatility 0.8213% × √252 = 13.04%; Sharpe = 11.49 ÷ 13.04 = 0.88.

The return is the mean daily return times 252, not the price change, and for a volatile asset the two drift apart: silver averaged 38.2% a year against a 23.1% price gain, which would score 0.32 instead of 0.57. For US500 the gap is small, 0.88 against 0.90.

Annualizing treats daily returns as independent: the mean scales with the number of periods, the standard deviation with its square root. Weekday markets use 252 by convention, BTCUSD 365; the trading days guide shows how far real calendars stray from 252.

A Sharpe ratio is a slope

Plot volatility across and mean return up, then draw a line from the risk-free rate to each asset. Each line’s slope is that asset’s Sharpe ratio:

Risk and return, 9 October 2025 to 9 October 2026

  • Asset, with its Sharpe ratio
  • 3-month Treasury bill, 4.25%

Across: annualized volatility of daily returns. Up: annualized mean daily return (mean × 252, or × 365 for BTCUSD).

Each line runs from the 3-month bill at 4.25% to an asset, and its slope is that asset’s Sharpe ratio: the steeper the line, the more return per unit of volatility. The height is the arithmetic mean of daily returns, annualized, not the price change, which is why silver plots at 38% while its price rose 23% over the year.Daily closes from TickerLayer /indices/agg, /stocks/agg, /commodities/agg, /forex/agg and /crypto/agg; risk-free rate from /bond/snapshot/US:3M (4.25%, 9 Oct 2026).

US:XOM and US:KO have the steepest rising lines; EURUSD and BTCUSD sit below the bill, so theirs point down. Slope matters more than height because mixing an asset with cash slides it along its own line: a mix kept at half US:KO and half bills at 4.25% would have averaged 17.2% with 9.5% volatility, beating US500 on both, and still scored 1.37.

What is a good Sharpe ratio?

The bands repeated across finance sites call a Sharpe ratio below 1 weak, 1 to 2 good, 2 to 3 very good and above 3 excellent. They are a rule of thumb, not a standard:

One-year Sharpe ratios against the usual rule-of-thumb bands

  1. -1.39EURUSD
  2. -0.73BTCUSD
  3. 0.16XAUUSD
  4. 0.57XAGUSD
  5. 0.88US500
  6. 1.0Good
  7. 1.37US:KO
  8. 1.53US:XOM
  9. 2.0Very good
  10. 3.0Excellent
Daily closes from 9 October 2025 to 9 October 2026, risk-free rate 4.25%. The 1, 2 and 3 marks are the rule-of-thumb bands: US:KO and US:XOM clear 1, and none of the eight reaches 2. US:GS (0.46) is left off beside silver.

Is 1.2 a good Sharpe ratio?

The bands call 1.2 good, but one year of data cannot tell it from 0.2 or 2.2. A Sharpe ratio from 251 daily returns has a standard error of about 1.0: the 95% range around US500’s 0.88 runs from -1.08 to 2.85. Even US:KO’s 1.37 is not statistically different from that 0.88: a Jobson-Korkie test with Memmel’s correction gives z = 0.32, far below 1.96.

At 0.88 the error falls to 0.71 with two years, 0.50 with four and 0.32 with ten: halving it takes four times the data. The approximation (Lo, 2002) assumes independent, normal returns, so skewed silver’s true error is larger.

What does a 2.5 Sharpe ratio mean?

A Sharpe ratio of 2.5 means 2.5 points of return above cash per point of volatility: rare over a year, where none of these eight reached 2, but common over a quarter. The trailing 63-session ratio was above 2.5 on 12% of the year’s US500 sessions and 30% of gold’s, whose one-year figure was 0.16:

Sharpe ratio of the trailing 63 sessions

  • US500, one-year Sharpe 0.88
  • XAUUSD, one-year Sharpe 0.16

63-session Sharpe ratio, annualized

Each point is the Sharpe ratio of the 63 sessions, about one quarter, ending that day, at a 4.25% risk-free rate; points are weekly from 9 October 2025, at each week’s last US session or the session of a plotted high or low. Over the year the quarterly figure ran from -3.00 to 4.38 for US500 and from -3.24 to 6.35 for gold; the full-year ratios were 0.88 and 0.16.Computed from TickerLayer /indices/agg and /commodities/agg daily bars from 1 July 2025.

Can a Sharpe ratio be negative?

Yes, whenever the mean return falls short of the risk-free rate: BTCUSD scored -0.73 after a 32.1% fall. EURUSD’s -1.39 subtracts the US bill rate from a spot return that leaves out the interest euros earn; against a zero rate it is -0.57. Below zero the ranking can mislead, because more volatility makes a shortfall look smaller: BTCUSD outscores EURUSD despite a far bigger loss.

Which risk-free rate to use

The risk-free rate is what cash earns without risk: the yield on a short government bill in the asset’s currency, over the same window. The script reads it from the bond snapshot endpoint for US:3M, the 3-month US Treasury bill at the short end of the yield curve, which returned "rate": 4.25 for "date": "2026-10-09".

The snapshot returns the latest observation, so the script applies 9 October’s 4.25% to every day, an approximation; set RISK_FREE=4.25 to reproduce these numbers later. A zero rate, a common shortcut, lifts US500 from 0.88 to 1.21.

How to calculate the Sharpe ratio in Python

sharpe.py pulls a year of daily closes for eight assets from the aggregate bars endpoints and prints Sharpe, Sortino, max drawdown and Calmar, then beta, R², Treynor and the information ratio for two stocks against US500. It needs Python 3.9 or newer, pip install pandas requests and a TICKERLAYER_API_KEY environment variable, and makes 9 requests.

sharpe.pyPython
"""Sharpe, Sortino, max drawdown and Calmar ratios from one year of daily closes."""
import math
import os

import pandas as pd
import requests

BASE_URL = "https://api.tickerlayer.com"
API_KEY = os.environ["TICKERLAYER_API_KEY"]
START, END = "2025-10-09", "2026-10-09"  # first and last daily close

ASSETS = {  # symbol: (asset class, return periods a year)
    "US500": ("indices", 252),
    "US:KO": ("stocks", 252),
    "US:XOM": ("stocks", 252),
    "US:GS": ("stocks", 252),
    "XAUUSD": ("commodities", 252),
    "XAGUSD": ("commodities", 252),
    "EURUSD": ("forex", 252),
    "BTCUSD": ("crypto", 365),  # trades every day of the year
}


def get(path, **params):
    """GET a REST path. Returns None when the key's plan does not include it (403)."""
    resp = requests.get(BASE_URL + path, params=params, headers={"x-api-key": API_KEY}, timeout=30)
    if resp.status_code == 403:
        return None
    resp.raise_for_status()
    return resp.json()


def risk_free():
    """Annual risk-free rate as a decimal, and where it came from."""
    if os.environ.get("RISK_FREE"):  # a fixed rate in percent, e.g. RISK_FREE=4.25
        return float(os.environ["RISK_FREE"]) / 100, "RISK_FREE"
    bill = get("/bond/snapshot/US:3M")  # latest 3-month Treasury bill yield
    if bill is None:
        raise SystemExit("This key has no bond data: set RISK_FREE, for example RISK_FREE=4.25")
    return bill["rate"] / 100, f"US:3M on {bill['date']}"


def daily_closes(asset, symbol, start=START, end=END):
    """Daily closes from start to end, or None when the plan does not include the asset."""
    day_before = (pd.Timestamp(start) - pd.Timedelta(days=1)).strftime("%Y-%m-%d")
    path = f"/{asset}/agg/{symbol}/1/day/{day_before}/{end}"  # one extra day, trimmed below
    params, rows = {"sort": "asc", "limit": 5000, "offset": 0}, []
    while True:
        body = get(path, **params)
        if body is None:
            return None
        rows += body["results"]
        if body.get("next_offset") is None:
            break
        params["offset"] = body["next_offset"]
    if not rows:
        raise SystemExit(f"No bars for {symbol}: check the symbol and the dates")
    dates = pd.to_datetime([r["t"] for r in rows], unit="ms")
    closes = pd.Series([r["c"] for r in rows], index=dates)
    if asset != "crypto":
        closes = closes[closes.index.dayofweek < 5]  # weekday sessions only
    return closes[closes.index >= start]


def sharpe(returns, rf, n):
    """Annualized Sharpe ratio of periodic returns, with n periods a year."""
    excess = returns - rf / n
    return excess.mean() / excess.std() * math.sqrt(n)


def metrics(closes, rf, n):
    """Return, mean, volatility, Sharpe, Sortino, max drawdown and Calmar of daily closes."""
    r = closes.pct_change().dropna()
    excess = r - rf / n
    downside = math.sqrt((excess.clip(upper=0) ** 2).mean())  # shortfall below the risk-free rate
    drawdown = closes / closes.cummax() - 1
    one_year = closes.iloc[-1] / closes.iloc[0] - 1
    return {
        "return": one_year,
        "mean": r.mean() * n,
        "vol": r.std() * math.sqrt(n),
        "sharpe": sharpe(r, rf, n),
        "sortino": excess.mean() / downside * math.sqrt(n),
        "max_dd": drawdown.min(),
        "calmar": one_year / -drawdown.min(),
    }


def main():
    rf, source = risk_free()
    print(f"Risk-free rate {rf:.2%} ({source}), daily closes {START} to {END}\n")
    print(f"{'symbol':<8}{'return':>8}{'mean':>8}{'vol':>7}"
          f"{'sharpe':>8}{'sortino':>9}{'max dd':>8}{'calmar':>8}")
    closes = {}
    for symbol, (asset, n) in ASSETS.items():
        c = daily_closes(asset, symbol)
        if c is None:
            print(f"{symbol:<8}not in this key's plan, skipped")
            continue
        closes[symbol] = c
        m = metrics(c, rf, n)
        print(f"{symbol:<8}{m['return']:>8.1%}{m['mean']:>8.1%}{m['vol']:>7.1%}{m['sharpe']:>8.2f}"
              f"{m['sortino']:>9.2f}{m['max_dd']:>8.1%}{m['calmar']:>8.2f}")

    if "US500" not in closes:
        return
    print("\nAgainst US500")
    for symbol in ("US:KO", "US:GS"):
        if symbol not in closes:
            continue
        both = pd.concat([closes[symbol], closes["US500"]], axis=1, join="inner")
        returns = both.pct_change().dropna()  # same dates for stock and index
        stock, market = returns.iloc[:, 0], returns.iloc[:, 1]
        beta = stock.cov(market) / market.var()
        treynor = (stock.mean() * 252 - rf) / beta
        active = stock - market
        info = active.mean() / active.std() * math.sqrt(252)
        print(f"{symbol:<8}beta {beta:5.2f}  R2 {stock.corr(market) ** 2:4.2f}  "
              f"Treynor {treynor:6.2f}  information ratio {info:5.2f}")


if __name__ == "__main__":
    main()
Output
Risk-free rate 4.25% (US:3M on 2026-10-09), daily closes 2025-10-09 to 2026-10-09

symbol    return    mean    vol  sharpe  sortino  max dd  calmar
US500      16.0%   15.7%  13.0%    0.88     1.27   -9.1%    1.76
US:KO      32.7%   30.2%  19.0%    1.37     2.29   -8.5%    3.84
US:XOM     49.6%   43.8%  25.9%    1.53     2.26  -20.7%    2.40
US:GS      14.8%   19.0%  32.2%    0.46     0.67  -23.4%    0.63
XAUUSD      5.2%    8.7%  27.5%    0.16     0.22  -25.4%    0.20
XAGUSD     23.1%   38.2%  59.1%    0.57     0.75  -51.6%    0.45
EURUSD     -3.1%   -2.9%   5.1%   -1.39    -1.88   -6.5%   -0.48
BTCUSD    -32.1%  -28.6%  44.8%   -0.73    -1.03  -51.8%   -0.62

Against US500
US:KO   beta -0.23  R2 0.02  Treynor  -1.15  information ratio  0.59
US:GS   beta  1.60  R2 0.42  Treynor   0.09  information ratio  0.13

return is the price change from first close to last, used by Calmar; mean is the annualized average daily return, used by Sharpe and Sortino.

For gold, silver and EURUSD the script keeps one close per weekday, 262 each, so a weekend move lands in Monday’s return. US bars are raw prices: no split fell in the window, so they need no split adjustment, but dividends are left out, which understates the ratios of payers such as US:KO and US:XOM.

What the Sharpe ratio hides: max drawdown, Sortino and Calmar

Volatility treats gains and losses alike and ignores the order in which they arrive. Maximum drawdown measures the fall a holder sat through: the largest drop from a running peak close to a later trough, the figure the golden cross backtest prints next to annual growth.

Drawdown from the highest close so far

  • XAGUSD, Sharpe 0.57
  • US:XOM, Sharpe 1.53
  • US500, Sharpe 0.88

% below the highest close since 9 October 2025

From 9 October 2025, one point a week at the week’s last US session, except that the weeks holding a trough show the trough session instead (30 March, 29 June, 16 July). US500 never fell more than 9.1% and was back at its high by 15 April. Silver fell from its 28 January high to a 16 July low and was still 47.1% below that high on 9 October.Daily closes from TickerLayer /indices/agg, /stocks/agg and /commodities/agg, 9 Oct 2025 to 9 Oct 2026.

US:XOM, the highest Sharpe ratio of the eight at 1.53, lost 20.7% between 30 March and 29 June and was still 1.5% below that peak on 9 October. Silver, at 0.57, fell 51.6%, including 24.2% on 30 January alone. Sortino and Calmar put losses back into the ratio:

Sortino ratio = (Rp − Rf) ÷ σdMax drawdown = min over t of (Pt ÷ highest P so far − 1)Calmar ratio = one-year return ÷ |max drawdown|

σd
Downside deviation: the square root of the mean squared shortfall of daily returns below the risk-free rate (days above it count as zero), × √252. The other common recipe, the standard deviation of below-target days only, gives US:KO 2.58 instead of 2.29.
Pt
The close on day t; the highest P so far is the running peak since the start of the window.
US:KO: Sortino = 25.93% ÷ 11.32% = 2.29; max drawdown -8.5% (81.56 on 27 Feb to 74.63 on 22 Apr); Calmar = 32.67% ÷ 8.50% = 3.84. Silver: 55.518 ÷ 114.594 − 1 = -51.6%.
SymbolSharpeMax drawdownCalmar
US5000.88-9.1%1.76
US:KO1.37-8.5%3.84
US:XOM1.53-20.7%2.40
US:GS0.46-23.4%0.63
XAUUSD0.16-25.4%0.20
XAGUSD0.57-51.6%0.45
EURUSD-1.39-6.5%-0.48
BTCUSD-0.73-51.8%-0.62
Daily closes from 9 October 2025 to 9 October 2026, risk-free rate 4.25%. Calmar here is the one-year price return divided by the maximum drawdown, not the classic three-year version. Sortino ratios are in the script output. US prices exclude dividends.

Rank by Calmar instead of Sharpe and the order changes: US:KO (3.84) overtakes US:XOM (2.40), and US:GS (0.63) overtakes silver (0.45).

Why the same data gives different Sharpe ratios

A published Sharpe ratio often omits how it was computed, and the choices can move it further than the 0.49 that separates US:KO from US500. sharpe_traps.py recomputes US500 and BTCUSD ten ways:

Same data, different Sharpe ratio

  • US500 daily, from Oct 90.88
  • US500 daily, from Oct 101.12
  • US500 weekly, from Oct 101.18
  • US500 last 6 months1.94
  • US500 last 3 months0.90
  • US500, risk-free 0%1.21
  • BTCUSD, 365-day year-0.73
  • BTCUSD, 252-day year-0.65
  • BTCUSD last 6 months0.82
  • BTCUSD last 3 months2.81
Daily closes to 9 October 2026, risk-free rate 4.25% unless stated. The two accented bars are the figures used everywhere else in this article; every other bar changes one choice, and the weekly bar also starts a day later.Computed with sharpe_traps.py from TickerLayer /indices/agg and /crypto/agg daily bars.
  • Start date. US500 scores 0.88 from the 9 October 2025 close and 1.12 from the next: the return between them, -2.71% on 10 October, was the window’s worst.
  • Sampling. Weekly closes, each week’s last session, give 1.18 but start after that fall too: frequency moves the ratio by 0.06, the start date by 0.24.
  • Window. US500 scores 1.94 over six months; BTCUSD flips from -0.73 over the year to 2.81 over three months.
  • Annualization. Stock settings, 252 periods and √252, turn BTCUSD’s -28.6% mean and 44.8% volatility into -19.8% and 37.2%: -0.65 instead of -0.73.
sharpe_traps.pyPython
"""Same asset, different Sharpe ratio: start date, sampling, window, annualization and Rf.

Save next to sharpe.py, which provides the helpers.
"""
import math

from sharpe import daily_closes, risk_free, sharpe


def since(closes, start):
    """Daily returns of the closes from `start` on."""
    return closes[closes.index >= start].pct_change().dropna()


rf, source = risk_free()
us500 = daily_closes("indices", "US500")
btc = daily_closes("crypto", "BTCUSD")
if us500 is None or btc is None:
    raise SystemExit("This script needs the Indices and Crypto feeds")
weekly = us500.resample("W-FRI").last().pct_change().dropna()  # each week's last close

rows = [
    ("US500", "daily, from the 2025-10-09 close", sharpe(since(us500, "2025-10-09"), rf, 252)),
    ("US500", "daily, from the 2025-10-10 close", sharpe(since(us500, "2025-10-10"), rf, 252)),
    ("US500", "weekly, from the 2025-10-10 close", sharpe(weekly, rf, 52)),
    ("US500", "last 6 months", sharpe(since(us500, "2026-04-09"), rf, 252)),
    ("US500", "last 3 months", sharpe(since(us500, "2026-07-09"), rf, 252)),
    ("US500", "risk-free rate 0%", sharpe(since(us500, "2025-10-09"), 0.0, 252)),
    ("BTCUSD", "daily, 365 days a year", sharpe(since(btc, "2025-10-09"), rf, 365)),
    ("BTCUSD", "daily, 252 days a year", sharpe(since(btc, "2025-10-09"), rf, 252)),
    ("BTCUSD", "last 6 months", sharpe(since(btc, "2026-04-09"), rf, 365)),
    ("BTCUSD", "last 3 months", sharpe(since(btc, "2026-07-09"), rf, 365)),
]
print(f"Risk-free rate {rf:.2%} ({source})")
for symbol, label, value in rows:
    print(f"{symbol:<8}{label:<35}{value:6.2f}")

daily = since(us500, "2025-10-09")
sr = sharpe(daily, rf, 252)
se = math.sqrt((1 + sr**2 / 252 / 2) * 252 / len(daily))  # Lo (2002), independent returns
print(f"\nUS500 one-year Sharpe {sr:.2f}, standard error {se:.2f}, "
      f"95% range {sr - 1.96 * se:.2f} to {sr + 1.96 * se:.2f}")
Output
Risk-free rate 4.25% (US:3M on 2026-10-09)
US500   daily, from the 2025-10-09 close     0.88
US500   daily, from the 2025-10-10 close     1.12
US500   weekly, from the 2025-10-10 close    1.18
US500   last 6 months                        1.94
US500   last 3 months                        0.90
US500   risk-free rate 0%                    1.21
BTCUSD  daily, 365 days a year              -0.73
BTCUSD  daily, 252 days a year              -0.65
BTCUSD  last 6 months                        0.82
BTCUSD  last 3 months                        2.81

US500 one-year Sharpe 0.88, standard error 1.00, 95% range -1.08 to 2.85

The choices moved US500 by up to 1.06, about one standard error. None is wrong, but each needs its window, sampling and rate printed beside it.

Sharpe ratio vs Sortino ratio, Calmar, Treynor and information ratio

Each divides a return by a different measure of risk. Sharpe, Sortino and Calmar stand alone; Treynor and the information ratio need a benchmark, here US500:

FeatureDividesExampleMisleads when
Sharpe ratioExcess return ÷ volatilityUS500 0.88, US:KO 1.37Losses come in rare, deep falls: silver 0.57 with a 51.6% drawdown
Sortino ratioExcess return ÷ downside deviationUS:KO 2.29Down days are few, so the divisor is tiny
Calmar ratioReturn ÷ maximum drawdownUS:KO 3.84, silver 0.45One bad stretch sets the divisor
Treynor ratioExcess return ÷ betaUS:GS 0.09, US500 0.11Beta is near zero: US:KO’s -0.23 gives -1.15
Information ratioReturn over a benchmark ÷ tracking errorUS:KO 0.59The benchmark explains little: R² 0.02 for US:KO
One year of daily closes to 9 October 2026, risk-free rate 4.25%, benchmark US500.

Both benchmark ratios assume US500 explains the stock. It explained 42% of US:GS’s daily moves, so its Treynor ratio of 0.09, 9.2% excess return per unit of beta against the index’s 11.5%, means something; for US:KO, at 2%, the -1.15 does not. The stock beta tutorial computes beta and R² over its own window.

Before you publish a Sharpe ratio

  • Mean of daily returns, not the price change: silver’s price change gives 0.32 instead of 0.57
  • √252 for weekday markets, √365 for crypto: BTCUSD is -0.73, or -0.65 on 252
  • Window and first close stated: US500 scores 0.88 from 9 October 2025, 1.12 from the next day
  • Risk-free rate in the asset’s currency: EURUSD is -1.39 against the US bill, -0.57 against zero
  • Sortino convention named: US:KO is 2.29 with every day in the downside deviation, 2.58 with below-target days only
  • Dividends stated: these US bars are price-only
  • Max drawdown and standard error (about 1.0 for one year) published next to the ratio

Questions

What is a good Sharpe ratio?

By the usual rule of thumb, below 1 is weak, 1 to 2 good, 2 to 3 very good and above 3 excellent, though a one-year figure carries a standard error of about 1.0.

How do you calculate the Sharpe ratio?

Divide the mean of daily excess returns (each return minus the daily risk-free rate) by their standard deviation and multiply by √252, or √365 for crypto. In pandas: excess.mean() / excess.std() * math.sqrt(252).

Is 1.2 a good Sharpe ratio?

By the bands it is good, but one year of daily data cannot tell 1.2 from 0.2 or 2.2: in the year to 9 October 2026, US:KO’s 1.37 and US500’s 0.88 were not statistically different.

What does a 2.5 Sharpe ratio mean?

It means 2.5 points of return above cash for each point of volatility: rare over a year, common over a quarter. BTCUSD scored 2.81 over the three months to 9 October 2026 and -0.73 over the year.

Can a Sharpe ratio be negative?

Yes, whenever the mean return is below the risk-free rate. BTCUSD scored -0.73 for the year to 9 October 2026, after a 32.1% fall.

What is the difference between the Sharpe ratio and the Sortino ratio?

Sharpe divides excess return by the volatility of all returns; Sortino divides it by the downside deviation, so gains do not count as risk. In the year to 9 October 2026, US:KO scored 1.37 on Sharpe and 2.29 on Sortino.

Keep reading

Ready to integrate?

Start with the free tier, explore the docs, and connect via REST or WebSocket in minutes.