{"slug":"52-week-highs-and-lows","qid":"index_range","label":"Where five broad-market ETFs sit inside their own 52-week range","post_title":"Stocks at 52-Week Highs and Lows","post_url":"/blog/52-week-highs-and-lows#q-index_range","columns":["label","pct_below_high","pct_above_low","ytd_return_pct"],"rows":[{"label":"S&P 500 equal weight (RSP)","pct_below_high":0.38,"pct_above_low":21.8,"ytd_return_pct":15.9},{"label":"Dow 30 (DIA)","pct_below_high":1.69,"pct_above_low":18.2,"ytd_return_pct":11},{"label":"S&P 500 (SPY)","pct_below_high":1.85,"pct_above_low":20.8,"ytd_return_pct":12},{"label":"Russell 2000 (IWM)","pct_below_high":2.33,"pct_above_low":30.1,"ytd_return_pct":21},{"label":"Nasdaq 100 (QQQ)","pct_below_high":5.34,"pct_above_low":26.5,"ytd_return_pct":15}],"shape":"ranking","sql":"WITH last_session AS (\n    SELECT max(date) AS d FROM global_markets.stocks_daily_aggs\n    WHERE ticker = 'SPY' AND date >= today() - 12 AND date < today()\n),\ndaily AS (\n    SELECT ticker, date AS dt, toFloat64(close) AS c\n    FROM global_markets.stocks_daily_aggs\n    WHERE date < today()\n      AND ticker IN ('SPY', 'QQQ', 'DIA', 'IWM', 'RSP')\n      AND date > (SELECT d FROM last_session) - 365\n),\nranged AS (\n    SELECT ticker,\n           argMax(c, dt) AS last_close,\n           max(c) AS hi,\n           min(c) AS lo,\n           argMaxIf(c, dt, dt <= toDate('2025-12-31')) AS base_close,\n           count() AS n_sessions,\n           min(dt) AS first_dt,\n           max(dt) AS last_dt\n    FROM daily\n    GROUP BY ticker\n    HAVING n_sessions >= 200\n       AND countIf(dt <= toDate('2025-12-31')) > 0\n       AND last_dt = (SELECT d FROM last_session)\n       AND first_dt <= (SELECT d FROM last_session) - 350\n)\nSELECT multiIf(ticker = 'SPY', 'S&P 500 (SPY)',\n               ticker = 'QQQ', 'Nasdaq 100 (QQQ)',\n               ticker = 'DIA', 'Dow 30 (DIA)',\n               ticker = 'RSP', 'S&P 500 equal weight (RSP)',\n               'Russell 2000 (IWM)') AS label,\n       round((1 - last_close / hi) * 100, 2) AS pct_below_high,\n       round((last_close / lo - 1) * 100, 1) AS pct_above_low,\n       round((last_close / base_close - 1) * 100, 1) AS ytd_return_pct\nFROM ranged\nORDER BY pct_below_high ASC","computed_at":"2026-08-25T13:16:23.805698+00:00","elapsed":0.272584669}