STRASMORE/EXPLORE 2,170 QUERIES 22Y EQUITIES · 12Y OPTIONS

2,170 answered market questions

every one with its exact SQL, its result and the date it was computed · free, no signup

Survivorship Bias in Stock Data, Explained
Survivors-only average vs whole-cohort average, by starting yeartable · 2026-08-22 · 7×6 Symbols relisted under a new issuer after a long silenceranking · 2026-08-22 · 5×4Preview: 5 ranked values, smallest first. Symbols that printed a final daily bar, by yearranking · 2026-08-22 · 10×3Preview: 10 ranked values, smallest first. The January 2019 universe, grouped by what happened to each nameranking · 2026-08-22 · 9×4Preview: 9 ranked values, smallest first.
Look-Ahead Bias: The Backtest Killer
Survivorship in the universe: names trading each year, share still listed in July 2026, and median returntable · 2026-07-31 · 10×6 Same-bar decision vs a one-session lag: SPY, average session gain, 2016-2025table · 2026-07-31 · 10×5 The hindsight ceiling: SPY buy and hold, the same year without its biggest up days, and perfect one-day foresighttable · 2026-07-31 · 10×5
Survivors-only average vs whole-cohort average, by starting year

Survivors-only average vs whole-cohort average, by starting year

most recentas of table 7×6read in context →
Survivors-only average vs whole-cohort average, by starting year — 7 rows by 6 columns, computed from US exchange, SIP and OPRA data.
cohort_yearcohort_sizegone_countsurvivors_only_pctfull_universe_pctgap_pct
20162728969209.9148.261.8
20172522819160.8117.343.4
20182669824121.488.732.6
20192646695138.1112.725.5
202026696398773.113.9
2021341695764.448.416
2022337869434.224.99.2
the exact SQL behind every number
WITH
    entry AS
    (
        SELECT
            ticker,
            toYear(date)                   AS cohort_start,
            argMin(toFloat64(close), date) AS entry_close
        FROM global_markets.stocks_daily_aggs
        WHERE toMonth(date) = 1
          AND date BETWEEN '2016-01-01' AND '2022-01-31'
          AND ticker NOT IN ('SPCX')
        GROUP BY ticker, cohort_start
        HAVING argMin(toFloat64(close), date) >= 5
           AND avg(volume) >= 250000
    ),
    outcome AS
    (
        SELECT
            ticker,
            argMax(toFloat64(close), date) AS final_close,
            max(date)                      AS last_bar
        FROM global_markets.stocks_daily_aggs
        WHERE date >= '2016-01-01'
        GROUP BY ticker
    )
SELECT
    toString(e.cohort_start)                                                             AS cohort_year,
    count()                                                                              AS cohort_size,
    countIf(o.last_bar < today() - 45)                                                   AS gone_count,
    round(100 * avgIf(o.final_close / e.entry_close - 1, o.last_bar >= today() - 45), 1) AS survivors_only_pct,
    round(100 * avg(o.final_close / e.entry_close - 1), 1)                               AS full_universe_pct,
    round(100 * (avgIf(o.final_close / e.entry_close - 1, o.last_bar >= today() - 45)
                 - avg(o.final_close / e.entry_close - 1)), 1)                           AS gap_pct
FROM entry AS e
INNER JOIN outcome AS o ON o.ticker = e.ticker
GROUP BY e.cohort_start
HAVING countIf(o.last_bar >= today() - 45) > 0
ORDER BY e.cohort_start
$