{"slug":"etf-relative-strength-alpha-attribution","qid":"rs_ranking","label":"20-session return versus SPY across a nine-fund ETF universe","post_title":"ETF Relative Strength and Alpha Attribution","post_url":"/blog/etf-relative-strength-alpha-attribution#q-rs_ranking","columns":["etf","return_pct","excess_vs_spy_pct"],"rows":[{"etf":"GLD","return_pct":13.36,"excess_vs_spy_pct":9.71},{"etf":"XLE","return_pct":6.83,"excess_vs_spy_pct":3.18},{"etf":"XLV","return_pct":6.03,"excess_vs_spy_pct":2.38},{"etf":"XLK","return_pct":4.9,"excess_vs_spy_pct":1.25},{"etf":"QQQ","return_pct":4.62,"excess_vs_spy_pct":0.97},{"etf":"EFA","return_pct":4.58,"excess_vs_spy_pct":0.93},{"etf":"IWM","return_pct":3.07,"excess_vs_spy_pct":-0.58},{"etf":"XLF","return_pct":1.55,"excess_vs_spy_pct":-2.1},{"etf":"XLU","return_pct":-5.24,"excess_vs_spy_pct":-8.89}],"shape":"ranking","sql":"WITH bounds AS\n(\n    SELECT\n        min(d) AS first_day,\n        max(d) AS last_day\n    FROM\n    (\n        SELECT date AS d\n        FROM global_markets.stocks_daily_aggs\n        WHERE ticker = 'SPY'\n          AND date >= today() - 120\n        GROUP BY d\n        ORDER BY d DESC\n        LIMIT 21\n    )\n)\nSELECT\n    sleeve.ticker                            AS etf,\n    sleeve.ret_pct                           AS return_pct,\n    round(sleeve.ret_pct - bench.ret_pct, 2) AS excess_vs_spy_pct\nFROM\n(\n    SELECT\n        ticker,\n        round((argMax(toFloat64(close), date) / argMin(toFloat64(close), date) - 1) * 100, 2) AS ret_pct\n    FROM global_markets.stocks_daily_aggs\n    WHERE ticker IN ('QQQ', 'IWM', 'XLK', 'XLE', 'XLF', 'XLV', 'XLU', 'GLD', 'EFA')\n      AND date >= (SELECT first_day FROM bounds)\n      AND date <= (SELECT last_day FROM bounds)\n    GROUP BY ticker\n) AS sleeve\nCROSS JOIN\n(\n    SELECT\n        round((argMax(toFloat64(close), date) / argMin(toFloat64(close), date) - 1) * 100, 2) AS ret_pct\n    FROM global_markets.stocks_daily_aggs\n    WHERE ticker = 'SPY'\n      AND date >= (SELECT first_day FROM bounds)\n      AND date <= (SELECT last_day FROM bounds)\n) AS bench\nORDER BY excess_vs_spy_pct DESC","computed_at":"2026-08-22T04:05:28.987338+00:00","elapsed":0.083850241}