{"slug":"what-is-a-stock-split","qid":"post_split_returns","label":"After the split: median forward returns for 2025's whole-number forward splits vs SPY over the same sessions","post_title":"What Is a Stock Split? Ratios and Mechanics","post_url":"/blog/what-is-a-stock-split#q-post_split_returns","columns":["splits_measured","median_5_session_pct","median_21_session_pct","pct_up_after_21_sessions","median_spy_21_session_pct"],"rows":[{"splits_measured":44,"median_5_session_pct":-0.9,"median_21_session_pct":-1.5,"pct_up_after_21_sessions":45,"median_spy_21_session_pct":1.6}],"shape":"scalar","sql":"WITH events AS (\n    SELECT ticker, execution_date\n    FROM global_markets.stocks_splits\n    WHERE execution_date >= '2025-01-01' AND execution_date <= '2025-12-31'\n      AND adjustment_type = 'forward_split' AND split_from = 1\n      AND split_to >= 2 AND split_to = round(split_to)\n),\ndaily AS (\n    SELECT ticker,\n           toDate(toTimeZone(window_start, 'America/New_York')) AS d,\n           argMaxIf(toFloat64(close), window_start,\n                    (toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959) AS close_rth\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker IN (SELECT ticker FROM events UNION ALL SELECT 'SPY')\n      AND window_start >= '2025-01-01 00:00:00' AND window_start < '2026-03-01 00:00:00'\n    GROUP BY ticker, d\n    HAVING close_rth > 0\n),\nseries AS (\n    SELECT ticker, arraySort(x -> x.1, groupArray((d, close_rth))) AS dc\n    FROM daily\n    GROUP BY ticker\n),\nspy AS (\n    SELECT dc AS spy_dc FROM series WHERE ticker = 'SPY'\n),\nper_event AS (\n    SELECT e.ticker AS tkr,\n           arrayFirstIndex(x -> x.1 >= e.execution_date, s.dc) AS idx,\n           arrayFirstIndex(x -> x.1 >= e.execution_date, spy_dc) AS sidx,\n           s.dc AS dc, spy_dc\n    FROM events e\n    JOIN series s ON s.ticker = e.ticker\n    CROSS JOIN spy\n),\nmeasured AS (\n    SELECT tkr,\n           (dc[idx + 5].2 / dc[idx].2 - 1) * 100 AS r5,\n           (dc[idx + 21].2 / dc[idx].2 - 1) * 100 AS r21,\n           (spy_dc[sidx + 21].2 / spy_dc[sidx].2 - 1) * 100 AS spy21\n    FROM per_event\n    WHERE idx > 0 AND length(dc) >= idx + 21\n      AND sidx > 0 AND length(spy_dc) >= sidx + 21\n      AND dc[idx].2 > 0\n)\nSELECT count() AS splits_measured,\n       round(quantileDeterministic(0.5)(r5, cityHash64(tkr)), 1) AS median_5_session_pct,\n       round(quantileDeterministic(0.5)(r21, cityHash64(tkr)), 1) AS median_21_session_pct,\n       round(100.0 * countIf(r21 > 0) / count(), 0) AS pct_up_after_21_sessions,\n       round(quantileDeterministic(0.5)(spy21, cityHash64(tkr)), 1) AS median_spy_21_session_pct\nFROM measured","computed_at":"2026-07-26T06:22:28.757440+00:00","elapsed":36.05995663}