STRASMORE/EXPLORE 3,256 QUERIES

Every liquid forward split, 2016-2025: median 3-month return after the split vs the S&P 500, by period

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-07-15, from Does a Stock Go Up After a Split?.

as of table 3×7read in context →
Every liquid forward split, 2016-2025: median 3-month return after the split vs the S&P 500, by period — 3 rows by 7 columns, computed from US exchange, SIP and OPRA data.
periodsplitsmedian_runup_before_pctmedian_after_3mo_pctmedian_spy_3mo_pctmedian_gap_vs_spy_pctpct_beat_spy
2016-201913910.61.83.8-2.140
2020-202317717.114.9-2.837
2024-20259810.803.3-1.941
Rows × columns
3 × 7
Computed
Completeness
No missing values
Source
US exchange, SIP and OPRA market data
Licence
Strasmore terms · free, no signup
Formats
JSON · CSV · the SQL below

What each column holds

Column definitions for Every liquid forward split, 2016-2025: median 3-month return after the split vs the S&P 500, by period, derived from the stored result.
ColumnTypeRangeNotes
period text 3 distinct values (2016-2019, 2020-2023, 2024-2025)
splits number 98 to 177
median_runup_before_pct number 10.6 to 17.1 percent
median_after_3mo_pct number 0 to 1.8 percent
median_spy_3mo_pct number 3.3 to 4.9 percent
median_gap_vs_spy_pct number -2.8 to -1.9 percent
pct_beat_spy number 37 to 41 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
cohort AS (
    SELECT ticker, min(execution_date) AS ex
    FROM global_markets.stocks_splits
    WHERE adjustment_type IN ('forward_split', 'stock_dividend') AND split_to >= 2 * split_from
      AND execution_date >= '2016-01-01' AND execution_date <= '2025-12-31' AND ticker != 'SPCX'
    GROUP BY ticker, execution_date
),
bars AS (
    SELECT ticker, toDate(toTimeZone(window_start, 'America/New_York')) AS d,
           toFloat64(argMax(close, window_start)) AS px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE (ticker IN (SELECT ticker FROM cohort) OR ticker = 'SPY')
      AND window_start >= '2015-06-01 00:00:00' AND window_start < '2026-02-01 00:00:00'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, d
),
series AS (
    SELECT ticker,
           arrayMap(x -> x.1, arraySort(x -> x.1, groupArray((d, px)))) AS days,
           arrayMap(x -> x.2, arraySort(x -> x.1, groupArray((d, px)))) AS prices
    FROM bars GROUP BY ticker
),
spy AS (SELECT days AS sd, prices AS sp FROM series WHERE ticker = 'SPY'),
fwd AS (
    SELECT ex,
        (prices[i0 - 1] / prices[i0 - 1 - 126] - 1) * 100 AS run_up,
        (prices[i0 + 63] / prices[i0] - 1) * 100 AS ret,
        (sp[j0 + 63] / sp[j0] - 1) * 100 AS spy_ret
    FROM (
        SELECT c.ex AS ex, indexOf(s.days, c.ex) AS i0, indexOf(spy.sd, c.ex) AS j0,
               s.prices AS prices, spy.sp AS sp
        FROM cohort c INNER JOIN series s ON s.ticker = c.ticker CROSS JOIN spy
    )
    WHERE i0 > 130 AND length(prices) >= i0 + 63 AND prices[i0] > 0 AND prices[i0 - 1] >= 30
)
SELECT multiIf(toYear(ex) <= 2019, '2016-2019', toYear(ex) <= 2023, '2020-2023', '2024-2025') AS period,
    count() AS splits,
    round(median(run_up), 1) AS median_runup_before_pct,
    round(median(ret), 1) AS median_after_3mo_pct,
    round(median(spy_ret), 1) AS median_spy_3mo_pct,
    round(median(ret - spy_ret), 1) AS median_gap_vs_spy_pct,
    round(100.0 * countIf(ret > spy_ret) / count(), 0) AS pct_beat_spy
FROM fwd GROUP BY period ORDER BY period
⌘/Ctrl + Enter

Work with this data in your AI assistant

Opens ready to query, with this page's data. Free, no account.

More from this analysisDoes a Stock Go Up After a Split?
The best-known recent stock splits: the six months before vs the three months after series 7×6 → Upcoming US stock splits: announced, with a future effective date table 27×5 → Recent reverse stock splits (shares consolidated), last 30 days ranking 15×4 → Recent forward stock splits (shares multiplied), last 60 days, ETFs excluded ranking 15×4 → Announced stock splits by effective month: forward vs reverse series 3×4 → Announced upcoming splits by direction ranking 2×2 → See all 3,256 queries →