The bull market turns 4 on Monday, up 118%. Every bull market since 1950 that made it to 4 years kept going. The shortest lasted 7 more weeks
The bull market turns four on Monday. The S&P 500 closed at 3,577 on October 12, 2022, and it closed Friday at 7,812, up 118%. Barron's ran it this weekend as "Four Years In, $40 Trillion Up," and with the 10-year yield above 5%, everyone's asking how much is left...
So I went back to 1950 and pulled every bull market that made it to four years. A bull market starts at the low after a 20% drop, on closing prices.
- Six made it to four years before this one, and all six kept going.
- The shortest ran 7 more weeks, ending in December 1961. The longest ran another 8 years, to March 2000.
- After year four, they gained anywhere from 7% to 302% more.
- Only two were up more than this one at four years: 1982 (+138%) and 2009 (+130%).
How much higher do you think this one goes?
Info pulled through the FMP MCP server:
import asyncio, json
from fastmcp import Client # pip install fastmcp
KEY = "YOUR_API_KEY"
DROP = 0.20 # a bear market = a 20% fall from the high, on closing prices
async def main():
async with Client(f"https://financialmodelingprep.com/mcp?apikey={KEY}") as fmp:
days = []
for year in range(1950, 2027, 15): # 15 years per call, each call returns up to 5,000 days
r = await fmp.call_tool("indexes", {"endpoint": "index-historical-price-eod-light", "symbol": "^GSPC",
"from_date": f"{year}-01-01", "to_date": f"{year + 14}-12-31"})
days += json.loads(r.content[0].text)
days.sort(key=lambda d: d["date"])
bulls, low, high, in_bull = [], days[0], days[0], True
for d in days:
if in_bull:
if d["price"] > high["price"]: high = d
if d["price"] <= high["price"] * (1 - DROP):
bulls.append((low, high)); in_bull, low = False, d
else:
if d["price"] < low["price"]: low = d
if d["price"] >= low["price"] * (1 + DROP):
in_bull, high = True, d
for start, peak in bulls[1:] + [(low, days[-1])]: # skip the one already running in 1950
birthday = f"{int(start['date'][:4]) + 4}{start['date'][4:]}"
four = next((d for d in days if d["date"] >= birthday), days[-1])
if four["date"] <= peak["date"]: # made it to four years
after = "still going" if peak is days[-1] else f"{peak['price'] / four['price'] - 1:+.0%} more"
print(f"{start['date']} to {peak['date']} {four['price'] / start['price'] - 1:+.0%} at 4 years, {after}")
asyncio.run(main())
Output:
1957-10-22 to 1961-12-12 +75% at 4 years, +7% more
1974-10-03 to 1980-11-28 +65% at 4 years, +37% more
1982-08-12 to 1987-08-25 +138% at 4 years, +38% more
1987-12-04 to 2000-03-24 +70% at 4 years, +302% more
2002-07-23 to 2007-10-09 +58% at 4 years, +24% more
2009-03-09 to 2020-02-19 +130% at 4 years, +118% more
2022-10-12 to 2026-10-09 +118% at 4 years, still going