STRASMORE/EXPLORE 2,214 QUERIES

forward_returns

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-12, from what-happens-after-a-reverse-stock-split.

as of ranking 3×4read in context →
forward_returns — 3 rows by 4 columns, computed from US exchange, SIP and OPRA data.
horizonnames_countmedian_return_pctshare_below_split_close_pct
20 sessions after586-12.769.5
60 sessions after557-2673.1
120 sessions after513-38.675.6
Rows × columns
3 × 4
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 forward_returns, derived from the stored result.
ColumnTypeRangeNotes
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.

the exact SQL behind every number
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)

Run your own version of this

The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.

More from this analysiswhat-happens-after-a-reverse-stock-split
ratio_buckets ranking 5×3 monthly_counts series 24×5 weekly_leaders ranking 25×4 Annualized volatility vs total return, 25 large caps, calmest to wildest (~2 years) ranking 25×3 SPY options median spread by expiration date, near-the-money strikes only ranking 25×4 When market headlines publish, by New York clock hour ranking 24×2 See all 2,214 queries →