SPY calendar-year price change vs the 12% assumption, 2006-2025
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-31, from The 8-4-3 Rule for Mutual Funds, Explained.
| year | annual_change_pct | distance_from_12_pct |
|---|---|---|
| 2006 | 13.59 | 1.59 |
| 2007 | 3.48 | 8.52 |
| 2008 | -38.35 | 50.35 |
| 2009 | 23.45 | 11.45 |
| 2010 | 12.88 | 0.88 |
| 2011 | -0.17 | 12.17 |
| 2012 | 13.43 | 1.43 |
| 2013 | 29.54 | 17.54 |
| 2014 | 11.36 | 0.64 |
| 2015 | -0.78 | 12.78 |
| 2016 | 9.62 | 2.38 |
| 2017 | 19.38 | 7.38 |
| 2018 | -6.28 | 18.28 |
| 2019 | 28.69 | 16.69 |
| 2020 | 16.14 | 4.14 |
| 2021 | 27.02 | 15.02 |
| 2022 | -19.47 | 31.47 |
| 2023 | 24.29 | 12.29 |
| 2024 | 23.27 | 11.27 |
| 2025 | 16.35 | 4.35 |
- Rows × columns
- 20 × 3
- 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 |
|---|---|---|---|
year |
number | 2,006 to 2,025 | |
annual_change_pct |
number | -38.35 to 29.54 | percent |
distance_from_12_pct |
number | 0.64 to 50.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 ye AS (
SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS year,
argMax(close, window_start) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND toDate(toTimeZone(window_start, 'America/New_York')) BETWEEN toDate('2004-12-01') AND toDate('2025-12-31')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY year
)
SELECT a.year AS year,
round((a.px / b.px - 1) * 100, 2) AS annual_change_pct,
round(abs((a.px / b.px - 1) * 100 - 12), 2) AS distance_from_12_pct
FROM ye AS a
INNER JOIN ye AS b ON a.year = b.year + 1
WHERE a.year >= 2006
ORDER BY year
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 analysisThe 8-4-3 Rule for Mutual Funds, Explained
An illustrative $10,000 SPY stake from year end 2005, marked at each year end
ranking 21×3
→
Annualized SPY price growth over rolling eight-year windows, by starting year end
ranking 14×3
→
How a two-decade streak compounds: Microsoft's annual dividend, year by year
ranking 22×2
→
Dividend growth champions: 20+ straight years of raises, ranked by how many times over the payout grew
ranking 20×3
→
The same monthly lots ranked by per share result at the December 2022 price
ranking 18×3
→
When Q1 2026 13F reports landed, by week after quarter end
ranking 13×2
→
See all 2,170 queries →