{"slug":"survivorship-bias-in-stock-data","qid":"cohort_outcomes","label":"The January 2019 universe, grouped by what happened to each name","post_title":"Survivorship Bias in Stock Data, Explained","post_url":"/blog/survivorship-bias-in-stock-data#q-cohort_outcomes","columns":["outcome_label","cohort_size","avg_return_pct","share_above_entry_pct"],"rows":[{"outcome_label":"Last bar in 2019","cohort_size":119,"avg_return_pct":12.2,"share_above_entry_pct":72.3},{"outcome_label":"Last bar in 2020","cohort_size":90,"avg_return_pct":20.9,"share_above_entry_pct":53.3},{"outcome_label":"Last bar in 2021","cohort_size":97,"avg_return_pct":62.1,"share_above_entry_pct":79.4},{"outcome_label":"Last bar in 2022","cohort_size":97,"avg_return_pct":56,"share_above_entry_pct":66},{"outcome_label":"Last bar in 2023","cohort_size":83,"avg_return_pct":33.2,"share_above_entry_pct":56.6},{"outcome_label":"Last bar in 2024","cohort_size":76,"avg_return_pct":19.7,"share_above_entry_pct":53.9},{"outcome_label":"Last bar in 2025","cohort_size":84,"avg_return_pct":70.3,"share_above_entry_pct":52.4},{"outcome_label":"Last bar in 2026","cohort_size":49,"avg_return_pct":75.5,"share_above_entry_pct":63.3},{"outcome_label":"Still trading","cohort_size":1951,"avg_return_pct":138.1,"share_above_entry_pct":72.4}],"shape":"ranking","sql":"WITH\n    entry AS\n    (\n        SELECT\n            ticker,\n            argMin(toFloat64(close), date) AS entry_close\n        FROM global_markets.stocks_daily_aggs\n        WHERE date BETWEEN '2019-01-01' AND '2019-01-31'\n          AND ticker NOT IN ('SPCX')\n        GROUP BY ticker\n        HAVING argMin(toFloat64(close), date) >= 5\n           AND avg(volume) >= 250000\n    ),\n    outcome AS\n    (\n        SELECT\n            ticker,\n            argMax(toFloat64(close), date) AS final_close,\n            max(date)                      AS last_bar\n        FROM global_markets.stocks_daily_aggs\n        WHERE date >= '2019-01-01'\n        GROUP BY ticker\n    )\nSELECT\n    if(o.last_bar >= today() - 45,\n       'Still trading',\n       concat('Last bar in ', toString(toYear(o.last_bar))))            AS outcome_label,\n    count()                                                             AS cohort_size,\n    round(100 * avg(o.final_close / e.entry_close - 1), 1)              AS avg_return_pct,\n    round(100 * countIf(o.final_close > e.entry_close) / count(), 1)    AS share_above_entry_pct\nFROM entry AS e\nINNER JOIN outcome AS o ON o.ticker = e.ticker\nGROUP BY outcome_label\nORDER BY outcome_label","computed_at":"2026-08-22T04:22:28.109704+00:00","elapsed":1.063293572}