Yale (Robert J. Shiller)
Shiller long-run data — Stock prices, dividends, earnings, CPI and long rates since 1871 — the CAPE's home
When the question is valuation over decades rather than years — the cyclically adjusted price–earnings ratio, real prices and real dividends, the long rate — and you need the one series that goes back before the Fed existed.
Reach for it when…
When the question is valuation over decades rather than years — the cyclically adjusted price–earnings ratio, real prices and real dividends, the long rate — and you need the one series that goes back before the Fed existed.
Not for: Anything current-month (the file updates irregularly), daily data, non-US markets, earnings by company.
Units, revisions, traps
Units. Monthly averages of daily closes for prices; earnings and dividends are trailing twelve months, interpolated; CAPE is price over the 10-year average of real earnings.
Revisions. Recent months change as earnings finalise; the history is stable.
- The Data sheet has eight header rows; the date column is a decimal (1871.01 = January).
- Prices are monthly averages, not month-end closes.
- CAPE uses reported (GAAP) earnings; the 'total return CAPE' is a separate column.
Classic mistake: Selling because CAPE is 'above average' — it has been above its long-run mean for most of the last 30 years.
Three recipes
- Recipe 1 · CAPE since 1881
- Recipe 2 · Real total return, a century
- Recipe 3 · The long rate since 1871
Each recipe: Python · Excel · Sheets, with how to read the result. Python recipes run under pandas; recipe 1 is re-run by the weekly check where the source allows it.
How to use it in your own work
Copy the snippet, change the series id, read the result the way the footer says. Replace YOUR_…_KEY with your own key where one is needed.
Recipe 1CAPE since 1881
# pip install xlrd (needed for .xls)
import pandas as pd
u = "http://www.econ.yale.edu/~shiller/data/ie_data.xls"
df = pd.read_excel(u, sheet_name="Data", skiprows=7)
df = df.rename(columns={df.columns[0]: "date", df.columns[12]: "CAPE"})
df = df[pd.to_numeric(df.date, errors="coerce").notna()]
df["year"] = df.date.astype(float)
print(df[["year", "CAPE"]].dropna().tail())- Open ie_data.xls; the Data sheet's column M is CAPE.
- Import the xls; CAPE is column M of the Data sheet.
Recipe 2Real total return, a century
import pandas as pd
df = pd.read_excel("http://www.econ.yale.edu/~shiller/data/ie_data.xls", sheet_name="Data", skiprows=7)
df = df.rename(columns={df.columns[0]: "date", df.columns[1]: "P", df.columns[2]: "D", df.columns[4]: "CPI"})
df = df[pd.to_numeric(df.date, errors="coerce").notna()].astype({"P": float, "D": float, "CPI": float})
real_p = df.P / df.CPI * df.CPI.iloc[-1]
print(real_p.iloc[[0, -1]])- Deflate column B by column E in a helper column.
- Same helper column after import.
Recipe 3The long rate since 1871
import pandas as pd
df = pd.read_excel("http://www.econ.yale.edu/~shiller/data/ie_data.xls", sheet_name="Data", skiprows=7)
df = df.rename(columns={df.columns[0]: "date", df.columns[5]: "GS10"})
df = df[pd.to_numeric(df.date, errors="coerce").notna()]
print(df[["date", "GS10"]].tail())- Column F of the Data sheet.
- Column F after import.
Series → question map
The ids we use from Shiller long-run data, each with the question it answers. The catalog's compare view reads the concept tags behind these rows.
| Series | Answers | Region | Concept |
|---|---|---|---|
| ie_data · CAPE | Is the market expensive by long-run standards? | United States | long_run_valuation |
| ie_data · P, D, E | Real prices, dividends and earnings since 1871 | United States | long_run_valuation |
| ie_data · GS10 | The long rate since 1871 | United States | yield_10y |
| ie_data · CPI | US CPI since 1871 | United States | cpi |
Compare with
Same question, different source: Kenneth French Data Library, FRED, Stooq. The compare view lines up coverage, frequency, history and access side by side and lists what the combination makes possible.
Open compare: Shiller long-run data · Kenneth French Data Library · FRED →
Questions readers ask
Is the Shiller data free?
Yes for personal and academic use; do not redistribute the file.
How often is it updated?
Irregularly, roughly monthly; check the file's last row.
Why xls and not csv?
It has been an Excel file since the 1990s. pandas needs the xlrd package to read .xls.
Educational only — we explain, we never advise · snippet licence: public domain · corrections to [email protected], fixed within a day and logged in the changelog.