@@ -64,31 +64,17 @@ To keep lecture this lecture narrowly focused, we estimate one return at a time
64646565* we use only monthly nondurable consumption (`ND`).
666667-In addition to what comes with Anaconda, this lecture requires `pandas-datareader`
68-69-```{code-cell} ipython3
70-:tags: [hide-output]
71-72-!pip install pandas-datareader
73-```
74-7567```{code-cell} ipython3
76-import warnings
7768from itertools import combinations
78697970import matplotlib.pyplot as plt
8071import numpy as np
8172import pandas as pd
8273from IPython.display import Latex
83-from pandas_datareader import data as web
8474from scipy import stats
8575from scipy.linalg import LinAlgError, cholesky, solve_triangular
8676from scipy.optimize import minimize
8777from statsmodels.stats.stattools import durbin_watson
88-89-warnings.filterwarnings(
90- "ignore", message=".*date_parser.*", category=FutureWarning
91-)
9278```
93799480We also define a helper to display DataFrames as LaTeX arrays in the hidden cell below
@@ -1439,85 +1425,34 @@ While Hansen-Singleton use CRSP value-weighted NYSE returns, we use the Ken Fren
1439142514401426The consumption series is constructed from consumption of nondurables (`ND`) with the nondurables deflator.
144114271442-The hidden cell below pulls the relevant FRED series, constructs per capita real consumption, and joins with the Ken French returns
1428+The hidden cell below loads a vendored monthly dataset of returns and consumption series. The data are built from the [FRED](https://fred.stlouisfed.org/) and [Ken French](https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html) data libraries by the maintenance script at [`_static/lecture_specific/hansen_singleton_1983/make_data.py`](https://github.com/QuantEcon/lecture-python.myst/blob/main/lectures/_static/lecture_specific/hansen_singleton_1983/make_data.py) and read here directly from GitHub.
1443142914441430```{code-cell} ipython3
14451431:tags: [hide-cell]
144614321447-fred_codes = {
1448- "population_16plus": "CNP16OV",
1449- "cons_nd_real_index": "DNDGRA3M086SBEA",
1450- "cons_nd_price_index": "DNDGRG3M086SBEA",
1451-}
1433+DATA_URL = (
1434+ "https://github.com/QuantEcon/lecture-python.myst/raw/refs/heads/main/"
1435+ "lectures/_static/lecture_specific/hansen_singleton_1983/"
1436+ "hansen_singleton_1983_data.csv"
1437+)
145214381453-def to_month_end(index):
1454- """
1455- Convert a date index to month-end timestamps.
1456- """
1457- return pd.PeriodIndex(pd.DatetimeIndex(index), freq="M").to_timestamp("M")
1439+# Read the vendored snapshot once; load_hs_monthly_data just slices it.
1440+_data = pd.read_csv(DATA_URL, index_col=0, parse_dates=True)
14581441145914421460-def load_hs_monthly_data(
1461- start="1959-02-01",
1462- end="1978-12-01",
1463-):
1464- """
1465- Build monthly gross real return and gross consumption-growth series.
1443+def load_hs_monthly_data(start="1959-02-01", end="1978-12-01"):
14661444 """
1467- start_period = pd.Timestamp(start).to_period("M")
1468- end_period = pd.Timestamp(end).to_period("M")
1469-1470- # Pull one extra month to build the first in-sample growth rate
1471- fetch_start = (start_period - 1).to_timestamp(how="start")
1472- fetch_end = end_period.to_timestamp("M")
1473- sample_start = start_period.to_timestamp("M")
1474- sample_end = end_period.to_timestamp("M")
1475-1476- fred = web.DataReader(
1477- list(fred_codes.values()), "fred", fetch_start, fetch_end)
1478- fred = fred.rename(columns={v: k for k, v in fred_codes.items()})
1479- fred.index = to_month_end(fred.index)
1480- fred["cons_real_level"] = fred["cons_nd_real_index"]
1481- fred["cons_price_index"] = fred["cons_nd_price_index"]
1482- fred["consumption_per_capita"] = fred["cons_real_level"] \
1483- / fred["population_16plus"]
1484- fred["gross_cons_growth"] = (
1485- fred["consumption_per_capita"] / fred["consumption_per_capita"].shift(1)
1486- )
1487- fred["gross_inflation_cons"] = (
1488- fred["cons_price_index"] / fred["cons_price_index"].shift(1)
1489- )
1445+ Load the monthly series used in the lecture: gross real market return,
1446+ gross consumption growth, gross consumption inflation, per capita real
1447+ consumption, and gross real T-bill return.
149014481491- ff = web.DataReader(
1492- "F-F_Research_Data_Factors", "famafrench",
1493- fetch_start, fetch_end)[0].copy()
1494- ff.columns = [str(col).strip() for col in ff.columns]
1495- if ("Mkt-RF" not in ff.columns) or ("RF" not in ff.columns):
1496- raise KeyError(
1497- "Fama-French data missing required columns: 'Mkt-RF' and 'RF'.")
1498-1499- # Mkt-RF and RF are reported in percent per month
1500- ff["gross_nom_return"] = 1.0 + (ff["Mkt-RF"] + ff["RF"]) / 100.0
1501- ff["gross_nom_tbill"] = 1.0 + ff["RF"] / 100.0
1502- ff.index = ff.index.to_timestamp(how="end")
1503- ff.index = to_month_end(ff.index)
1504- market = ff[["gross_nom_return", "gross_nom_tbill"]]
1505-1506- out = fred.join(market, how="inner")
1507- out["gross_real_return"] = out["gross_nom_return"] \
1508- / out["gross_inflation_cons"]
1509- out["gross_real_tbill"] = out["gross_nom_tbill"] \
1510- / out["gross_inflation_cons"]
1511- out = out.loc[sample_start:sample_end].dropna()
1512-1513- required_cols = [
1514- "gross_real_return",
1515- "gross_cons_growth",
1516- "gross_inflation_cons",
1517- "consumption_per_capita",
1518- "gross_real_tbill",
1519- ]
1520- return out[required_cols].copy()
1449+ The data are a vendored snapshot built by the maintenance script at
1450+ ``_static/lecture_specific/hansen_singleton_1983/make_data.py``, which
1451+ constructs them from FRED and the Ken French data library.
1452+ """
1453+ start = pd.Timestamp(start).to_period("M").to_timestamp("M")
1454+ end = pd.Timestamp(end).to_period("M").to_timestamp("M")
1455+ return _data.loc[start:end].copy()
152114561522145715231458def get_estimation_data(