{"slug":"risk-free-rate-in-the-sharpe-ratio","qid":"subtract_order","label":"Annualized risk premium: subtract monthly, or annualize each leg first","post_title":"Risk-free rate in the Sharpe ratio","post_url":"/blog/risk-free-rate-in-the-sharpe-ratio#q-subtract_order","columns":["horizon","excess_first_pct","annualize_first_pct","gap_pct"],"rows":[{"horizon":"1-year","excess_first_pct":17.31,"annualize_first_pct":18.13,"gap_pct":0.814},{"horizon":"3-year","excess_first_pct":3.01,"annualize_first_pct":3.09,"gap_pct":0.088},{"horizon":"5-year","excess_first_pct":9.94,"annualize_first_pct":10.17,"gap_pct":0.233},{"horizon":"10-year","excess_first_pct":9.08,"annualize_first_pct":9.23,"gap_pct":0.151},{"horizon":"20-year","excess_first_pct":6.49,"annualize_first_pct":6.59,"gap_pct":0.099}],"shape":"ranking","sql":"WITH\n    monthly_px AS\n    (\n        SELECT\n            toStartOfMonth(date)           AS m,\n            argMax(toFloat64(close), date) AS month_close\n        FROM global_markets.stocks_daily_aggs\n        WHERE ticker = 'SPY'\n          AND date >= '2004-12-01'\n          AND date <  '2025-01-01'\n        GROUP BY m\n    ),\n    prior_px AS\n    (\n        SELECT\n            addMonths(m, 1) AS m,\n            month_close     AS prev_close\n        FROM monthly_px\n    ),\n    monthly_rf AS\n    (\n        SELECT\n            toStartOfMonth(date)                                       AS m,\n            pow(1 + avg(toFloat64(yield_3_month)) / 100, 1.0 / 12) - 1 AS rf_month\n        FROM global_markets.treasury_yields\n        WHERE date >= '2004-12-01'\n          AND date <  '2025-01-01'\n          AND yield_3_month IS NOT NULL\n        GROUP BY m\n    ),\n    excess AS\n    (\n        SELECT\n            cur.m                                             AS m,\n            cur.month_close / prv.prev_close - 1              AS ret,\n            rf.rf_month                                       AS rf_month,\n            cur.month_close / prv.prev_close - 1 - rf.rf_month AS exc\n        FROM monthly_px AS cur\n        INNER JOIN prior_px AS prv ON prv.m = cur.m\n        INNER JOIN monthly_rf AS rf ON rf.m = cur.m\n    )\nSELECT\n    concat(toString(intDiv(count(), 12)), '-year')            AS horizon,\n    round(100 * (exp(12 * avg(log(1 + exc))) - 1), 2)         AS excess_first_pct,\n    round(100 * ((exp(12 * avg(log(1 + ret))) - 1)\n               - (exp(12 * avg(log(1 + rf_month))) - 1)), 2)  AS annualize_first_pct,\n    round(100 * ((exp(12 * avg(log(1 + ret))) - 1)\n               - (exp(12 * avg(log(1 + rf_month))) - 1)\n               - (exp(12 * avg(log(1 + exc))) - 1)), 3)       AS gap_pct\nFROM excess\nCROSS JOIN (SELECT arrayJoin([1, 3, 5, 10, 20]) AS years) AS hz\nWHERE m >= subtractYears(toDate('2025-01-01'), years)\nGROUP BY years\nORDER BY years","computed_at":"2026-08-14T15:41:54.785527+00:00","elapsed":0.147899492}