@@ -76,7 +76,7 @@ from scipy.optimize import minimize
7676import 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
510510We now compute the HJ bound from annual US stock and bond returns
511511(1891--1985).
@@ -585,7 +585,7 @@ squares enter the admissible region.
585585The cross marks the reciprocal of the
586586stock return, $1/r_ {\text{stock}}$, as a simple benchmark.
587587
588- ## The Duality Theorem
588+ ## The duality theorem
589589
590590The preceding figure illustrates the duality between the two frontiers --
591591the SDF frontier and the asset return mean-variance frontier -- that Hansen
@@ -730,7 +730,7 @@ plt.tight_layout()
730730plt.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
904904extremes of $E(m)$, where the linear frontier $m^v$ would need to take
905905negative values with high probability.
906906
907- ## The Equity Premium Puzzle Revisited
907+ ## The equity premium puzzle revisited
908908
909909The 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
940940This is far higher than the values of 1--5 that are typically considered
941941plausible.
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
944944and 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):
962962pd.DataFrame(rows).set_index('γ')
963963```
964964
965- ## Time-Nonseparable Preferences
965+ ## Time-nonseparable preferences
966966
967967Section V of the paper examines whether relaxing time separability can help
968968close the gap to the HJ bound.
@@ -1014,9 +1014,9 @@ v_m_nopositivity, σ_m_nopositivity = hj_bound_no_positivity(
10141014
10151015def 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))
10511058ax.fill_between(v_m_nopositivity, σ_m_nopositivity, 0.4, alpha=0.15)
10521059ax.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
11041111the admissible region at moderate $|\gamma|$.
11051112```
11061113
1107- ## Treasury Bill Data and Monetary Models
1114+ ## Treasury bill data and monetary models
11081115
11091116Figure 6 in the paper uses monthly prices on 3-, 6-, 9-, and 12-month
11101117discount bonds to construct real quarterly holding-period returns.
0 commit comments