Median move after the split, same cohort, at 20, 60 and 120 sessions
Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-09-20, from What Happens After a Reverse Stock Split?.
| horizon | names_count | median_return_pct | share_below_split_close_pct |
|---|---|---|---|
| 20 sessions after | 586 | -12.7 | 69.5 |
| 60 sessions after | 557 | -26 | 73.1 |
| 120 sessions after | 513 | -38.6 | 75.6 |
- Rows × columns
- 3 × 4
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
horizon |
text | 3 distinct values | |
names_count |
number | 513 to 586 | count |
median_return_pct |
number | -38.6 to -12.7 | percent |
share_below_split_close_pct |
number | 69.5 to 75.6 | percent |
Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.
Run it yourself
This is the exact query behind the result above. Change a ticker, a date or a column and run it against the warehouse — no account, no key. The no-signup tier is smaller than the one this page was computed on; a query that reaches past it comes back saying which plan runs it.
WITH
reverse_splits AS
(
SELECT ticker, toDate(execution_date) AS execution_date
FROM global_markets.stocks_splits
WHERE split_to < split_from
AND toDate(execution_date) >= '2025-03-01'
AND toDate(execution_date) < '2026-03-01'
AND ticker NOT IN ('SPCX')
GROUP BY ticker, execution_date
),
post_split_closes AS
(
SELECT
d.ticker AS ticker,
r.execution_date AS execution_date,
arrayMap(x -> tupleElement(x, 2), arraySort(groupArray((d.date, toFloat64(d.close))))) AS closes
FROM global_markets.stocks_daily_aggs AS d
INNER JOIN reverse_splits AS r ON r.ticker = d.ticker
WHERE d.ticker IN (SELECT ticker FROM reverse_splits)
AND d.date >= '2025-03-01'
AND d.date < '2026-10-01'
AND d.date >= r.execution_date
AND d.date < r.execution_date + 200
AND d.close > 0
GROUP BY d.ticker, r.execution_date
)
SELECT
horizon,
count() AS names_count,
round(quantileDeterministic(0.5)(return_pct, cityHash64(ticker)), 1) AS median_return_pct,
round(100 * countIf(return_pct < 0) / count(), 1) AS share_below_split_close_pct
FROM
(
SELECT
ticker,
sessions_after,
concat(toString(sessions_after), ' sessions after') AS horizon,
100 * (closes[sessions_after + 1] / closes[1] - 1) AS return_pct
FROM post_split_closes
ARRAY JOIN [20, 60, 120] AS sessions_after
WHERE length(closes) > sessions_after
)
GROUP BY horizon
ORDER BY min(sessions_after)