death_crosses
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-13, from can-a-death-cross-be-bullish.
| event | off_1y_high_pct | fwd_1m_pct | fwd_3m_pct | fwd_6m_pct | fwd_12m_pct |
|---|---|---|---|---|---|
| Aug 18, 2004 | 5.5 | 2.8 | 7.1 | 10.2 | 11.1 |
| Jul 19, 2006 | 5.2 | 3.5 | 8.5 | 13.6 | 22.1 |
| Dec 21, 2007 | 5.3 | -8.9 | -10.1 | -11.4 | -41.2 |
| Jul 6, 2010 | 15.6 | 9.8 | 10.6 | 23.5 | 30.1 |
| Aug 12, 2011 | 13.4 | -0.3 | 5.2 | 14.6 | 19.2 |
| Aug 28, 2015 | 6.7 | -5.6 | 5.2 | -0.6 | 9.6 |
| Jan 11, 2016 | 10 | -3.6 | 7.2 | 11.9 | 17.9 |
| Dec 7, 2018 | 10.2 | -2.1 | 6 | 9.6 | 19.1 |
| Mar 30, 2020 | 22.7 | 12.1 | 16.4 | 27.7 | 50.9 |
| Mar 14, 2022 | 12.7 | 5.1 | -10.1 | -5.7 | -6.6 |
| Apr 14, 2025 | 12 | 9 | 15.8 | 22.8 | 30.1 |
- Rows × columns
- 11 × 6
- 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 |
|---|---|---|---|
event |
text | 11 distinct values (Apr 14, 2025, Aug 12, 2011, Aug 18, 2004…) | |
off_1y_high_pct |
number | 5.2 to 22.7 | percent |
fwd_1m_pct |
number | -8.9 to 12.1 | percent |
fwd_3m_pct |
number | -10.1 to 16.4 | percent |
fwd_6m_pct |
number | -11.4 to 27.7 | percent |
fwd_12m_pct |
number | -41.2 to 50.9 | 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
bars AS
(
SELECT
date,
toFloat64(argMax(close, _ingest_time)) AS px
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
GROUP BY date
),
smas AS
(
SELECT
date,
px,
row_number() OVER (ORDER BY date) AS rn,
avg(px) OVER (ORDER BY date ROWS BETWEEN 49 PRECEDING AND CURRENT ROW) AS avg_50,
avg(px) OVER (ORDER BY date ROWS BETWEEN 199 PRECEDING AND CURRENT ROW) AS avg_200,
max(px) OVER (ORDER BY date ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) AS high_1y,
leadInFrame(px, 21) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS px_1m,
leadInFrame(px, 63) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS px_3m,
leadInFrame(px, 126) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS px_6m,
leadInFrame(px, 252) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS px_12m
FROM bars
),
states AS
(
SELECT
*,
(avg_50 < avg_200) AS below,
lagInFrame((avg_50 < avg_200), 1) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS prev_below
FROM smas
),
flags AS
(
SELECT
*,
(rn >= 201 AND below = 1 AND prev_below = 0) AS is_death,
(rn >= 201 AND below = 0 AND prev_below = 1) AS is_golden
FROM states
)
SELECT
concat(formatDateTime(date, '%b'), ' ', toString(toDayOfMonth(date)), ', ', toString(toYear(date))) AS event,
round((1 - px / high_1y) * 100, 1) AS off_1y_high_pct,
if(px_1m > 0, round((px_1m / px - 1) * 100, 1), NULL) AS fwd_1m_pct,
if(px_3m > 0, round((px_3m / px - 1) * 100, 1), NULL) AS fwd_3m_pct,
if(px_6m > 0, round((px_6m / px - 1) * 100, 1), NULL) AS fwd_6m_pct,
if(px_12m > 0, round((px_12m / px - 1) * 100, 1), NULL) AS fwd_12m_pct
FROM flags
WHERE is_death
ORDER BY date
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 analysiscan-a-death-cross-be-bullish
forward_record
table 4×9
→
trace_2020
series 126×4
→
whipsaw
ranking 11×4
→
window
scalar 1×11
→
covid_2020
scalar 1×16
→
The 2s10s spread, every print of the half
table 124×2
→
See all 2,225 queries →