Skip to content

Commit 247f487

Browse files
committed
updates
1 parent 3292e64 commit 247f487

1 file changed

Lines changed: 28 additions & 21 deletions

File tree

lectures/hansen_jagannathan_1991.md

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ from scipy.optimize import minimize
7676
import json
7777
```
7878

79-
## The Asset Pricing Framework
79+
## The asset pricing framework
8080

8181
### General model
8282

@@ -254,7 +254,7 @@ def load_annual_paper_data():
254254
)
255255
```
256256

257-
## The Linear Volatility Bound (Without Positivity)
257+
## The linear volatility bound (without positivity)
258258

259259
### Constructing $m^*$
260260

@@ -505,7 +505,7 @@ def max_sharpe_ratio(μ_x, μ_q, Σ, rf=None):
505505
return float(sr_max)
506506
```
507507

508-
## Computing the Annual Frontier
508+
## Computing the annual frontier
509509

510510
We now compute the HJ bound from annual US stock and bond returns
511511
(1891--1985).
@@ -585,7 +585,7 @@ squares enter the admissible region.
585585
The cross marks the reciprocal of the
586586
stock return, $1/r_{\text{stock}}$, as a simple benchmark.
587587

588-
## The Duality Theorem
588+
## The duality theorem
589589

590590
The preceding figure illustrates the duality between the two frontiers --
591591
the SDF frontier and the asset return mean-variance frontier -- that Hansen
@@ -730,7 +730,7 @@ plt.tight_layout()
730730
plt.show()
731731
```
732732

733-
## Tightening the Bound: Imposing Positivity of $m$
733+
## Tightening the bound: imposing positivity of $m$
734734

735735
### Option-based construction
736736

@@ -904,7 +904,7 @@ Requiring positivity eliminates a portion of the admissible region near the
904904
extremes of $E(m)$, where the linear frontier $m^v$ would need to take
905905
negative values with high probability.
906906

907-
## The Equity Premium Puzzle Revisited
907+
## The equity premium puzzle revisited
908908

909909
The HJ bound provides a nonparametric restatement of the equity premium puzzle.
910910

@@ -940,7 +940,7 @@ With U.S. annual data, $\text{SR}_{\max} \approx 0.37$ and $\sigma_c \approx
940940
This is far higher than the values of 1--5 that are typically considered
941941
plausible.
942942

943-
The table below reports $E(m)$ and $\sigma(m)$ for selected values of $\gamma$
943+
The table reports $E(m)$ and $\sigma(m)$ for selected values of $\gamma$ for **positivity-restricted** frontier
944944
and indicates whether the implied IMRS lies inside the admissible region.
945945

946946
```{code-cell} ipython3
@@ -962,7 +962,7 @@ for g, E_m, s_m in zip(annual_γ_grid, annual_crra_mean, annual_crra_std):
962962
pd.DataFrame(rows).set_index('γ')
963963
```
964964

965-
## Time-Nonseparable Preferences
965+
## Time-nonseparable preferences
966966

967967
Section V of the paper examines whether relaxing time separability can help
968968
close the gap to the HJ bound.
@@ -1014,9 +1014,9 @@ v_m_nopositivity, σ_m_nopositivity = hj_bound_no_positivity(
10141014
10151015
def simulate_nonseparable_imrs(
10161016
T=20_000,
1017-
gamma=-5,
1018-
theta=0.0,
1019-
delta=1.0,
1017+
γ=-5,
1018+
θ=0.0,
1019+
δ=1.0,
10201020
μ_c=0.0045,
10211021
σ_c=0.0055,
10221022
seed=1,
@@ -1028,14 +1028,21 @@ def simulate_nonseparable_imrs(
10281028
for t in range(T + 1):
10291029
c[t + 1] = c[t] * growth[t + 1]
10301030
1031-
s = c[1:] + theta * c[:-1]
1032-
s = np.maximum(s, 1e-30) # avoid 0**gamma when gamma < 0
1033-
s_gamma = s ** gamma
1034-
num = s_gamma[1:T + 1] + theta * delta * np.append(s_gamma[2:T + 1], s_gamma[-1])
1035-
denom = s_gamma[:T] + theta * delta * s_gamma[1:T + 1]
1031+
s = c[1:] + θ * c[:-1]
1032+
s = np.maximum(s, 1e-30) # avoid 0**γ when γ < 0
1033+
s_γ = s ** γ
1034+
1035+
# Precompute κ via Monte Carlo.
1036+
g_mc = np.exp(μ_c + σ_c * rng.standard_normal(500_000))
1037+
κ = np.mean(np.maximum(g_mc + θ, 1e-30) ** γ)
1038+
1039+
c_γ = np.maximum(c, 1e-30) ** γ
1040+
1041+
num = s_γ[1:T+1] + θ * δ * c_γ[2:T+2] * κ
1042+
denom = s_γ[0:T] + θ * δ * c_γ[1:T+1] * κ
10361043
10371044
with np.errstate(divide='ignore', invalid='ignore'):
1038-
m = delta * num / denom
1045+
m = δ * num / denom
10391046
return m[np.isfinite(m) & (np.abs(m) < 1e6)]
10401047
```
10411048

@@ -1051,14 +1058,14 @@ fig, ax = plt.subplots(figsize=(8, 5))
10511058
ax.fill_between(v_m_nopositivity, σ_m_nopositivity, 0.4, alpha=0.15)
10521059
ax.plot(v_m_nopositivity, σ_m_nopositivity, lw=2)
10531060
1054-
for theta, marker, label in [
1061+
for θ, marker, label in [
10551062
(0.0, "s", r"$\theta = 0$"),
10561063
(0.5, "o", r"$\theta = 0.5$"),
10571064
(-0.5, "^", r"$\theta = -0.5$"),
10581065
]:
10591066
pts = []
1060-
for gamma in range(0, -15, -1):
1061-
m_sim = simulate_nonseparable_imrs(gamma=gamma, theta=theta, seed=abs(gamma) + 5)
1067+
for γ in range(0, -15, -1):
1068+
m_sim = simulate_nonseparable_imrs(γ=γ, θ=θ, seed=abs(γ) + 5)
10621069
pts.append((m_sim.mean(), m_sim.std()))
10631070
pts = np.asarray(pts)
10641071
ax.scatter(
@@ -1104,7 +1111,7 @@ The qualitative pattern matches: habit persistence ($\theta < 0$) helps enter
11041111
the admissible region at moderate $|\gamma|$.
11051112
```
11061113

1107-
## Treasury Bill Data and Monetary Models
1114+
## Treasury bill data and monetary models
11081115

11091116
Figure 6 in the paper uses monthly prices on 3-, 6-, 9-, and 12-month
11101117
discount bonds to construct real quarterly holding-period returns.

0 commit comments

Comments
 (0)