{"slug":"what-is-a-reverse-stock-split","qid":"after_split","label":"What happened next: median move after a reverse split vs. SPY, splits executed 4-9 months ago","post_title":"What Is a Reverse Stock Split? Good or Bad?","post_url":"/blog/what-is-a-reverse-stock-split#q-after_split","columns":["horizon","splits_measured","median_stock_pct","median_stock_pct_abs","median_spy_pct","median_gap_pct","pct_below_split_day"],"rows":[{"horizon":"1 week after (5 sessions)","splits_measured":319,"median_stock_pct":-6.9,"median_stock_pct_abs":6.9,"median_spy_pct":0.2,"median_gap_pct":-7.1,"pct_below_split_day":64.3},{"horizon":"1 month after (21 sessions)","splits_measured":315,"median_stock_pct":-10,"median_stock_pct_abs":10,"median_spy_pct":0.7,"median_gap_pct":-10.6,"pct_below_split_day":66},{"horizon":"3 months after (63 sessions)","splits_measured":307,"median_stock_pct":-22.6,"median_stock_pct_abs":22.6,"median_spy_pct":6.8,"median_gap_pct":-29.4,"pct_below_split_day":69.4}],"shape":"series","sql":"WITH cohort AS (\n    SELECT ticker, min(execution_date) AS ex\n    FROM global_markets.stocks_splits\n    WHERE adjustment_type = 'reverse_split'\n      AND execution_date >= today() - INTERVAL 270 DAY\n      AND execution_date <= today() - INTERVAL 120 DAY\n      AND ticker != 'SPCX'\n    GROUP BY ticker\n),\nbars AS (\n    SELECT ticker,\n           toDate(toTimeZone(window_start, 'America/New_York')) AS d,\n           toFloat64(argMax(close, window_start)) AS px\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE (ticker IN (SELECT ticker FROM cohort) OR ticker = 'SPY')\n      AND window_start >= today() - INTERVAL 275 DAY\n      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60\n           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959\n    GROUP BY ticker, d\n),\nseries AS (\n    SELECT ticker,\n           arrayMap(x -> x.1, arraySort(x -> x.1, groupArray((d, px)))) AS days,\n           arrayMap(x -> x.2, arraySort(x -> x.1, groupArray((d, px)))) AS prices\n    FROM bars\n    GROUP BY ticker\n),\nspy AS (\n    SELECT days AS spy_days, prices AS spy_prices\n    FROM series\n    WHERE ticker = 'SPY'\n),\nhorizons AS (SELECT arrayJoin([5, 21, 63]) AS h),\nfwd AS (\n    SELECT c.ticker AS ticker,\n           h.h AS h,\n           indexOf(s.days, c.ex) AS i0,\n           indexOf(spy.spy_days, c.ex) AS j0,\n           (s.prices[i0 + h.h] / s.prices[i0] - 1) * 100 AS ret,\n           (spy.spy_prices[j0 + h.h] / spy.spy_prices[j0] - 1) * 100 AS spy_ret\n    FROM cohort AS c\n    INNER JOIN series AS s ON s.ticker = c.ticker\n    CROSS JOIN horizons AS h\n    CROSS JOIN spy AS spy\n    WHERE i0 > 0\n      AND j0 > 0\n      AND length(s.prices) >= i0 + h.h\n      AND s.prices[i0] > 0\n)\nSELECT multiIf(h = 5, '1 week after (5 sessions)',\n               h = 21, '1 month after (21 sessions)',\n               '3 months after (63 sessions)') AS horizon,\n       count() AS splits_measured,\n       round(quantileDeterministic(0.5)(ret, cityHash64(ticker)), 1) AS median_stock_pct,\n       round(abs(quantileDeterministic(0.5)(ret, cityHash64(ticker))), 1) AS median_stock_pct_abs,\n       round(quantileDeterministic(0.5)(spy_ret, cityHash64(ticker)), 1) AS median_spy_pct,\n       round(quantileDeterministic(0.5)(ret, cityHash64(ticker))\n             - quantileDeterministic(0.5)(spy_ret, cityHash64(ticker)), 1) AS median_gap_pct,\n       round(100.0 * countIf(ret < 0) / count(), 1) AS pct_below_split_day\nFROM fwd\nGROUP BY h\nORDER BY h","computed_at":"2026-08-22T04:33:37.307973+00:00","elapsed":27.658414017}