STRASMORE/EXPLORE 2,170 QUERIES

Average S&P 500 forward return after fearful, greedy, and ordinary days (2024-2026)

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-16, from Buy When Others Are Fearful: The Data.

as of table 3×5read in context →
Average S&P 500 forward return after fearful, greedy, and ordinary days (2024-2026) — 3 rows by 5 columns, computed from US exchange, SIP and OPRA data.
market_mooddaysfwd_5d_pctfwd_20d_pctfwd_60d_pct
Extreme fear (least upbeat)450.081.476.35
In between3590.381.244.03
Extreme greed (most upbeat)450.131.532.85
Rows × columns
3 × 5
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 Average S&P 500 forward return after fearful, greedy, and ordinary days (2024-2026), derived from the stored result.
ColumnTypeRangeNotes
market_mood text 3 distinct values
days number 45 to 359
fwd_5d_pct number 0.08 to 0.38 percent
fwd_20d_pct number 1.24 to 1.53 percent
fwd_60d_pct number 2.85 to 6.35 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 sent AS (
    SELECT toDate(published_utc) AS d,
           (countIf(s='positive') - countIf(s='negative')) / (countIf(s='positive') + countIf(s='negative')) AS net
    FROM (SELECT published_utc, JSONExtractString(ins,'sentiment') AS s
          FROM global_markets.stocks_news ARRAY JOIN insights AS ins
          WHERE JSONExtractString(ins,'sentiment') != '')
    GROUP BY d HAVING countIf(s='positive') + countIf(s='negative') >= 20
),
spyd AS (
    SELECT toDate(toTimeZone(window_start,'America/New_York')) AS d,
           argMax(toFloat64(close), toTimeZone(window_start,'America/New_York')) AS c
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker='SPY' AND window_start >= '2024-01-01'
      AND (toHour(toTimeZone(window_start,'America/New_York'))*60 + toMinute(toTimeZone(window_start,'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY d
),
spy AS (
    SELECT d, c, leadInFrame(c,5) OVER w AS c5, leadInFrame(c,20) OVER w AS c20, leadInFrame(c,60) OVER w AS c60
    FROM spyd WINDOW w AS (ORDER BY d ASC ROWS BETWEEN CURRENT ROW AND 60 FOLLOWING)
),
j AS (
    SELECT s.net AS net, (spy.c5/spy.c-1)*100 AS f5, (spy.c20/spy.c-1)*100 AS f20, (spy.c60/spy.c-1)*100 AS f60
    FROM sent s INNER JOIN spy ON s.d = spy.d WHERE spy.c60 > 0
),
qt AS (SELECT quantile(0.1)(net) AS p10, quantile(0.9)(net) AS p90 FROM j)
SELECT multiIf(net <= (SELECT p10 FROM qt), 'Extreme fear (least upbeat)',
               net >= (SELECT p90 FROM qt), 'Extreme greed (most upbeat)',
               'In between') AS market_mood,
       count() AS days,
       round(avg(f5),2)  AS fwd_5d_pct,
       round(avg(f20),2) AS fwd_20d_pct,
       round(avg(f60),2) AS fwd_60d_pct
FROM j GROUP BY market_mood
ORDER BY multiIf(market_mood='Extreme fear (least upbeat)',0, market_mood='In between',1, 2)

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 analysisBuy When Others Are Fearful: The Data
News sentiment coverage by year: how many tagged insights, and the share downbeat ranking 3×3 The S&P 500's underwater curve: worst drawdown from a prior high, by month series 127×2 SPY's 20 best and 20 worst days since 2016, counted by year ranking 11×3 S&P 500 worst intra-year drawdown vs the year's price return, since 2016 ranking 11×3 The ten biggest single-day gains for SPY since 2016 ranking 10×2 SPY total return since 2016, after removing the best single days ranking 5×2 See all 2,170 queries →