SPB Git forge

spb/wp18_uqo

Public
6commits 1branches 0releases
5.4 MBsize
maindefault branch
yesterdaylast push
TeX 53.2% Python 46.6%

WP18 phase 2 : modèle, propositions, preuves, benchmark 2-3 périodes

- research/model_specification.md : Partie A (benchmark 3 étapes / générations
  de 2 périodes, hypothèque nominale FRM/ARM, prêteur, marchés segmentés) et
  Partie B (OLG complet implémentable : états, grilles, timing, Bellman, ERC
  stationnaire, transition MIT, choix numériques)
- paper/appendix_proofs.tex (+ wrapper standalone compilé avec latexmk) :
  6 hypothèses, 2 lemmes, 9 propositions, 1 corollaire, lacunes étiquetées
- research/propositions.md (statuts), research/failed_hypotheses.md
- src/toy_model.py + tests/test_toy_model.py : 44 tests (identités budgétaires,
  dette nominale/réelle, Fisher, seuil fermé = optimisé, A4 vérifiée, signes,
  chaîne dynastique, apurement, comptabilité de l'inflation surprise, impact GE)
- requirements.txt épinglé ; research/progress.md (Phase 2)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed yesterday (Oct 20, 2026) parent fd424de

9 changed files +1,748 −0

added paper/appendix_proofs.tex +320 −0
@@ -0,0 +1,320 @@
1 +% ============================================================================
2 +% WP18 — Appendix: assumptions, propositions and proofs (Part A benchmark model)
3 +% Input from main.tex after \begin{appendices}. Theorem environments are defined
4 +% in the preamble of main.tex (see research/wp_style_audit.md, §6) and reproduced
5 +% in appendix_proofs_standalone.tex for stand-alone compilation.
6 +% ============================================================================
7 +\section{Assumptions, propositions and proofs}
8 +\label{app:proofs}
9 +
10 +This appendix states and proves the analytical results of the benchmark model of Section~\ref{sec:model} (three stages of life, two-period generations; full specification in \texttt{research/model\_specification.md}, Part~A). Throughout, $R = 1+r$, $d \equiv \theta + \kappa_b + m$ is the stage-1 cash outlay per unit of house price, and, in the stationary state with inflation $\bar\pi$,
11 +\begin{equation}
12 +\delta_2 \equiv (1-\theta)\Big[R - \frac{1-a}{1+\bar\pi}\Big], \qquad
13 +\delta_3 \equiv \frac{(1-a)(1-\theta)R}{1+\bar\pi}, \qquad
14 +e_3 \equiv (1-\kappa_s) - \delta_3,
15 +\label{eq:app_deltas}
16 +\end{equation}
17 +so that an owner who bought one unit at price $p$ pays $D_2 = \delta_2 p$ at stage~2 and $D_3 = \delta_3 p$ at stage~3, and sells at stage~3 for $(1-\kappa_s)p$ in a stationary state. The identity
18 +\begin{equation}
19 +\delta_2 + \frac{\delta_3}{R} = (1-\theta)R
20 +\label{eq:app_fisher}
21 +\end{equation}
22 +follows from $1+i = R(1+\bar\pi)$ and is the present-value (Fisher) neutrality of the nominal contract. Consumption of a hand-to-mouth household is written $c^O_1(b) = b + y_1 - dp$, $c^R_1(b) = b + y_1 - \rho$, $c^O_2 = y_2 - \delta_2 p - mp$, $c^R_2 = y_2 - \rho$, $W^O_3(y_3) = y_3 + e_3 p$, $W^R_3(y_3) = y_3$.
23 +
24 +\subsection{Assumptions}
25 +
26 +\begin{assumption}[Preferences, demography, housing need]
27 +\label{ass:pref}
28 +A household born at $t$ lives three stages and has utility $\ln c_1 + \chi\mathbf 1\{\text{owner}\} + \beta\,\mathbb E\ln c_2 + \beta^2\,\mathbb E[\ln c_3 + \nu \ln b']$ with $\beta\in(0,1)$, $\nu>0$, $\chi\ge 0$, where $b'$ is the inter-vivos transfer to its child, who enters the model at the parent's stage~3. Each household needs one unit of housing services at stages 1 and 2, obtained by owning one unit of the owner-occupied stock or renting one unit of the rental stock. Stage-3 households do not demand housing in the two markets. Incomes $y_1, y_2 > 0$ are common and deterministic; $y_3$ is drawn, independently across households and generations, from a distribution $G$ with a continuous density $g>0$ on $[\underline y_3, \bar y_3]$, $0 < \underline y_3 < \bar y_3 < \infty$.
29 +\end{assumption}
30 +
31 +\begin{assumption}[Prices, contracts, lender]
32 +\label{ass:prices}
33 +The real rate $r\ge 0$ is exogenous. The one-period nominal rate satisfies $1+i_t = R(1+\pi^e_{t+1})$. A mortgage of real principal $B \le (1-\theta)p_t$ is a nominal contract paying $(i_1 + a)B^{nom}$ at stage~2 and $(1+i_2)(1-a)B^{nom}$ at stage~3, with $a\in(0,1]$, $i_1$ fixed at origination and $i_2 = i_1$ (FRM) or $i_2$ reset at stage~2 to the then-current nominal rate (ARM). Deposits pay $i_t$ and cannot be negative. The lender is competitive and risk neutral, holds the mortgages and the deposits, and its realised real profit accrues to rentiers outside the dynasties. The rental stock is segmented from the owner-occupied stock; per cohort, owner-occupied supply is $S(p) = \bar H p^{\varepsilon}$, $\varepsilon\in[0,\infty)$, and rental supply is $S_r(\rho) = \bar H_r \rho^{\varepsilon_r}$, $\varepsilon_r\in(0,\infty]$.
34 +\end{assumption}
35 +
36 +\begin{assumption}[Feasibility and no default]
37 +\label{ass:feas}
38 +For all prices considered, $c^O_2 > 0$, $c^R_2 > 0$ and $\underline y_3 + \min\{e_3 p, 0\} > 0$. (Every stage-2 payment can be met out of income and every owner can repay the stage-3 balance out of income plus the sale proceeds; there is no default.)
39 +\end{assumption}
40 +
41 +\begin{assumption}[Liquidity-constrained at the margin: hand-to-mouth, HTM]
42 +\label{ass:htm}
43 +On the wealth interval $\mathcal B = (dp - y_1, \bar b]$ relevant for the tenure decision, the following strict Euler inequalities hold for both tenures at the corner allocation $n_1 = n_2 = 0$ (and $B = (1-\theta)p$ for owners):
44 +\begin{equation}
45 +\frac{1}{c^o_1(b)} > \beta R\,\frac{1}{c^o_2}, \qquad
46 +\frac{1}{c^o_2} > \beta R (1+\nu)\,\mathbb E\Big[\frac{1}{W^o_3(y_3)}\Big], \qquad o\in\{O,R\},\ b\in\mathcal B .
47 +\label{eq:app_euler}
48 +\end{equation}
49 +\end{assumption}
50 +
51 +\begin{assumption}[Interior tenure margin]
52 +\label{ass:interior}
53 +$\Delta > 0$ and $dp > \rho$, where
54 +\begin{equation}
55 +\Delta \equiv \chi + \beta\big[\ln c^O_2 - \ln c^R_2\big] + \beta^2(1+\nu)\,\mathbb E\big[\ln W^O_3(y_3) - \ln W^R_3(y_3)\big], \qquad \Lambda \equiv e^{-\Delta} \in (0,1).
56 +\label{eq:app_Delta}
57 +\end{equation}
58 +\end{assumption}
59 +
60 +\begin{assumption}[Static expectations on impact]
61 +\label{ass:static}
62 +In the period of an unanticipated inflation surprise, stage-1 households evaluate their stage-2 rent and stage-3 resale price at the pre-shock stationary values $(\rho^*, p^*)$, while buying, borrowing and renting at the current prices $(p_{t+1}, \rho_{t+1})$.
63 +\end{assumption}
64 +
65 +Assumption~\ref{ass:htm} is verified, not imposed, in the numerical benchmark (\texttt{tests/test\_toy\_model.py}): the Euler slacks are computed on the support of the stationary transfer distribution and the general optimiser returns the corner. Assumption~\ref{ass:static} is only used in Proposition~\ref{prop:impact}; the perfect-foresight transition is computed numerically in Phase~3.
66 +
67 +\subsection{Preliminary lemmas}
68 +
69 +\begin{lemma}[Stage-3 split]
70 +\label{lem:split}
71 +A stage-3 household with resources $W_3$ chooses $c_3 = W_3/(1+\nu)$ and $b' = \nu W_3/(1+\nu)$.
72 +\end{lemma}
73 +\begin{proof}
74 +Maximise $\ln c_3 + \nu\ln b'$ subject to $c_3 + b' = W_3$: the first-order condition $1/c_3 = \nu/b'$ with the constraint gives the result; the objective is strictly concave.
75 +\end{proof}
76 +
77 +\begin{lemma}[Hand-to-mouth values]
78 +\label{lem:htm}
79 +Under Assumptions~\ref{ass:pref}--\ref{ass:htm}, for $b\in\mathcal B$ the optimal plan of a renter is $n_1 = n_2 = 0$ and that of an owner is $B = (1-\theta)p$, $n_1 = n_2 = 0$. The value functions are
80 +\begin{align}
81 +V^O(b) &= \ln c^O_1(b) + \chi + \beta\ln c^O_2 + \beta^2(1+\nu)\,\mathbb E\ln W^O_3(y_3) + K, \label{eq:app_VO}\\
82 +V^R(b) &= \ln c^R_1(b) + \beta\ln c^R_2 + \beta^2(1+\nu)\,\mathbb E\ln W^R_3(y_3) + K, \label{eq:app_VR}
83 +\end{align}
84 +with $K = \beta^2[\nu\ln\nu - (1+\nu)\ln(1+\nu)]$, and $V^O(b) - V^R(b) = \ln c^O_1(b) - \ln c^R_1(b) + \Delta$.
85 +\end{lemma}
86 +\begin{proof}
87 +Using Lemma~\ref{lem:split}, the stage-3 continuation is $(1+\nu)\ln W_3 + K$. For a renter the problem is to maximise $\ln(b+y_1-\rho-n_1) + \beta\ln(y_2-\rho+n_1R-n_2) + \beta^2(1+\nu)\mathbb E\ln(y_3+n_2R)$ over $n_1,n_2\ge 0$ (the stage-2 choice is made before $y_3$ is known; $n_1$ is chosen at stage 1 and $n_2$ at stage 2, but since $c_2$ is deterministic given $n_1$ the two-stage problem equals this static problem). The objective is strictly concave in $(n_1,n_2)$ and the constraint set is convex, so the Karush--Kuhn--Tucker conditions are necessary and sufficient. At $n_1 = n_2 = 0$ they read $1/c^R_1 \ge \beta R/c^R_2$ and $1/c^R_2 \ge \beta R(1+\nu)\mathbb E[1/W^R_3]$, which hold strictly by~\eqref{eq:app_euler}. For an owner, the choice variables are $(B, n_1, n_2)$ with $0\le B\le (1-\theta)p$; lowering $B$ by $\epsilon$ lowers $c_1$ by $\epsilon$ and raises $c_2$ by $\epsilon\,\delta_2/(1-\theta)$ and $W_3$ by $\epsilon\,\delta_3/(1-\theta)$. The KKT condition for $B = (1-\theta)p$ is
88 +\[
89 +\frac{1}{c^O_1} \;\ge\; \beta\frac{\delta_2}{1-\theta}\frac{1}{c^O_2} + \beta^2(1+\nu)\frac{\delta_3}{1-\theta}\,\mathbb E\Big[\frac{1}{W^O_3}\Big].
90 +\]
91 +By~\eqref{eq:app_euler}, $\beta/c^O_2 < 1/(Rc^O_1)$ and $\beta^2(1+\nu)\mathbb E[1/W^O_3] = \beta\cdot\beta(1+\nu)\mathbb E[1/W^O_3] < \beta/(Rc^O_2) < 1/(R^2 c^O_1)$, so the right-hand side is strictly below $\frac{1}{c^O_1}\cdot\frac{\delta_2/R + \delta_3/R^2}{1-\theta} = \frac{1}{c^O_1}$ by~\eqref{eq:app_fisher}. The conditions for $n_1 = n_2 = 0$ are as for the renter. Substituting the corner allocations gives \eqref{eq:app_VO}--\eqref{eq:app_VR}, and the difference follows from \eqref{eq:app_Delta}.
92 +\end{proof}
93 +
94 +\subsection{Ownership-entry threshold}
95 +
96 +\begin{proposition}[Ownership threshold]
97 +\label{prop:threshold}
98 +Under Assumptions~\ref{ass:pref}--\ref{ass:interior}, there is a unique $\hat b\in\mathcal B$ such that a household with transfer $b\in\mathcal B$ owns if and only if $b\ge\hat b$, where
99 +\begin{equation}
100 +\hat b \;=\; \frac{d\,p - \Lambda\,\rho}{1-\Lambda} - y_1, \qquad
101 +\hat b - (dp - y_1) = \frac{\Lambda\,(dp-\rho)}{1-\Lambda} > 0, \qquad c^O_1(\hat b) = \frac{\Lambda(dp-\rho)}{1-\Lambda}.
102 +\label{eq:app_bhat}
103 +\end{equation}
104 +If instead $dp \le \rho$ (owning costs no more cash than renting), every household with $b > dp - y_1$ owns and the threshold is the feasibility bound $dp - y_1$.
105 +\end{proposition}
106 +\begin{proof}
107 +Let $D(b) \equiv V^O(b) - V^R(b) = \ln c^O_1(b) - \ln c^R_1(b) + \Delta$ on $\mathcal B$ (Lemma~\ref{lem:htm}). $D$ is continuous, $D(b)\to-\infty$ as $b\downarrow dp - y_1$ (since $c^O_1\to 0$ while $c^R_1 \to dp - \rho > 0$), and $D'(b) = 1/c^O_1(b) - 1/c^R_1(b) > 0$ because $c^O_1(b) = c^R_1(b) - (dp-\rho) < c^R_1(b)$ by Assumption~\ref{ass:interior}. As $b\to\infty$, $\ln(c^O_1/c^R_1)\to 0$ so $D(b)\to\Delta>0$. Hence $D$ has exactly one zero $\hat b$, at which $c^O_1/c^R_1 = \Lambda$, i.e. $b + y_1 - dp = \Lambda(b+y_1-\rho)$, which gives~\eqref{eq:app_bhat}; the two identities follow by substitution. If $dp\le\rho$, $c^O_1\ge c^R_1$ so $D(b)\ge\Delta>0$ for all feasible $b$.
108 +\end{proof}
109 +
110 +\begin{remark}[Proof gap: single crossing outside the HTM region]
111 +\label{rem:gap_single}
112 +Proposition~\ref{prop:threshold} characterises the tenure decision on $\mathcal B$, where Assumption~\ref{ass:htm} holds. For $b>\bar b$ the household saves and the values are not the closed forms \eqref{eq:app_VO}--\eqref{eq:app_VR}; the envelope derivative is still $1/c^o_1(b)$ for each tenure, so $V^O-V^R$ is increasing wherever $c^O_1(b) < c^R_1(b)$, but we have not proved that this holds at every crossing point. The numerical benchmark finds a single crossing on $[dp-y_1, 3]$ with the general optimiser; a general proof is left open.
113 +\end{remark}
114 +
115 +\begin{proposition}[Comparative statics of the threshold]
116 +\label{prop:cs}
117 +Under Assumptions~\ref{ass:pref}--\ref{ass:interior}, with the rent $\rho$ held fixed and the resale price moving with $p$ (stationary comparative statics),
118 +\[
119 +\frac{\partial\hat b}{\partial p}>0,\quad
120 +\frac{\partial\hat b}{\partial\rho}<0,\quad
121 +\frac{\partial\hat b}{\partial\theta}>0,\quad
122 +\frac{\partial\hat b}{\partial\kappa_b}>0,\quad
123 +\frac{\partial\hat b}{\partial\kappa_s}>0,\quad
124 +\frac{\partial\hat b}{\partial m}>0,\quad
125 +\frac{\partial\hat b}{\partial\chi}<0,\quad
126 +\frac{\partial\hat b}{\partial y_1}=-1,\quad
127 +\frac{\partial\hat b}{\partial\bar\pi}>0 .
128 +\]
129 +\end{proposition}
130 +\begin{proof}
131 +$\hat b$ is defined by $D(\hat b;\xi) = 0$ for a parameter $\xi$, with $\partial D/\partial b = 1/c^O_1 - 1/c^R_1 > 0$ at $\hat b$ (proof of Proposition~\ref{prop:threshold}). Because the Euler inequalities are strict, a small change in $\xi$ leaves the corner allocation optimal, so the derivative of each value function with respect to $\xi$ is the partial derivative of \eqref{eq:app_VO}--\eqref{eq:app_VR} at the fixed allocation. By the implicit function theorem $\operatorname{sign}(\partial\hat b/\partial\xi) = -\operatorname{sign}(\partial D/\partial\xi)$. We compute $\partial D/\partial\xi = \partial V^O/\partial\xi - \partial V^R/\partial\xi$ for each parameter, using the shorthand $E_3 \equiv \mathbb E[1/W^O_3(y_3)]$ and the bounds implied by~\eqref{eq:app_euler}:
132 +\begin{equation}
133 +\frac{\beta}{c^O_2} < \frac{1}{R\,c^O_1}, \qquad
134 +\beta^2(1+\nu)E_3 < \frac{\beta}{R\,c^O_2} < \frac{1}{R^2 c^O_1}.
135 +\label{eq:app_bounds}
136 +\end{equation}
137 +
138 +\emph{Rent.} $\partial V^R/\partial\rho = -1/c^R_1 - \beta/c^R_2 < 0$ and $V^O$ does not depend on $\rho$, so $\partial D/\partial\rho > 0$.
139 +
140 +\emph{Premium and stage-1 income.} $\partial D/\partial\chi = 1$. $\partial D/\partial y_1 = 1/c^O_1 - 1/c^R_1 = \partial D/\partial b$, hence $\partial\hat b/\partial y_1 = -1$.
141 +
142 +\emph{Costs.} $\partial V^O/\partial\kappa_b = -p/c^O_1 < 0$; $\partial V^O/\partial m = -p/c^O_1 - \beta p/c^O_2 < 0$; $\partial V^O/\partial\kappa_s = -\beta^2(1+\nu)\,p\,E_3 < 0$; $V^R$ is unaffected.
143 +
144 +\emph{Price.} $\partial V^O/\partial p = -d/c^O_1 - \beta(\delta_2+m)/c^O_2 + \beta^2(1+\nu)e_3E_3$. If $e_3\le 0$ all three terms are non-positive and the first is strictly negative. If $e_3>0$, use the second Euler inequality in the form $\beta/c^O_2 > \beta^2 R(1+\nu)E_3$ on the middle term:
145 +\[
146 +\frac{\partial V^O}{\partial p} < -\frac{d}{c^O_1} + \beta^2(1+\nu)E_3\,\big[e_3 - R(\delta_2+m)\big], \qquad e_3 - R(\delta_2+m) = (1-\kappa_s) - (1-\theta)R^2 - Rm,
147 +\]
148 +where the last equality uses $\delta_3 + R\delta_2 = (1-\theta)R^2$ from~\eqref{eq:app_fisher}. If the bracket is non-positive we are done. Otherwise apply~\eqref{eq:app_bounds}:
149 +\[
150 +\frac{\partial V^O}{\partial p} < -\frac{1}{c^O_1}\Big[d - \frac{(1-\kappa_s) - (1-\theta)R^2 - Rm}{R^2}\Big]
151 += -\frac{1}{c^O_1}\Big[1 + \kappa_b + m + \frac{m}{R} - \frac{1-\kappa_s}{R^2}\Big] < 0,
152 +\]
153 +because $R\ge 1$ implies $(1-\kappa_s)/R^2 < 1$. Hence $\partial D/\partial p < 0$.
154 +
155 +\emph{Down payment.} With $\tilde\delta_2 \equiv -\partial\delta_2/\partial\theta = R - (1-a)/(1+\bar\pi) > 0$ and $\tilde\delta_3 \equiv -\partial\delta_3/\partial\theta = (1-a)R/(1+\bar\pi)$, note $\tilde\delta_2 + \tilde\delta_3/R = R$. Then
156 +\[
157 +\frac{\partial V^O}{\partial\theta} = p\Big[-\frac{1}{c^O_1} + \frac{\beta\tilde\delta_2}{c^O_2} + \beta^2(1+\nu)\tilde\delta_3 E_3\Big]
158 +< \frac{p}{c^O_1}\Big[-1 + \frac{\tilde\delta_2}{R} + \frac{\tilde\delta_3}{R^2}\Big] = 0 ,
159 +\]
160 +by~\eqref{eq:app_bounds}. A higher down payment is present-value neutral and hurts only through liquidity.
161 +
162 +\emph{Anticipated inflation.} $\partial\delta_2/\partial\bar\pi = (1-\theta)(1-a)/(1+\bar\pi)^2 \equiv x > 0$ and $\partial\delta_3/\partial\bar\pi = -Rx$. Hence
163 +\[
164 +\frac{\partial V^O}{\partial\bar\pi} = xp\Big[-\frac{\beta}{c^O_2} + \beta^2 R(1+\nu)E_3\Big] < 0
165 +\]
166 +by the second inequality in~\eqref{eq:app_euler}; $V^R$ does not depend on $\bar\pi$.
167 +\end{proof}
168 +
169 +\begin{proposition}[Anticipated inflation and the down payment: tilt versus neutrality]
170 +\label{prop:tilt}
171 +(i) Under Assumptions~\ref{ass:pref}--\ref{ass:interior}, an increase in anticipated inflation $\bar\pi$ raises the real stage-2 payment and lowers the real stage-3 payment of a nominal mortgage, leaves their present value unchanged, and raises the ownership threshold $\hat b$. (ii) For a household whose optimal plan has $n_1>0$ and $n_2>0$ (slack liquidity constraints), a small change in $\bar\pi$ or in $\theta$ leaves its value, consumption and transfer unchanged.
172 +\end{proposition}
173 +\begin{proof}
174 +(i) The signs of $\partial\delta_2/\partial\bar\pi$, $\partial\delta_3/\partial\bar\pi$ and the present-value identity are in the proof of Proposition~\ref{prop:cs}; the threshold result is the last item of that proposition. (ii) Let the stage-2 real payment rise by $x$ and the stage-3 payment fall by $Rx$ (a change in $\bar\pi$). Replace $n_2$ by $n_2 - x$, feasible for $x < n_2$: $c_2$ is unchanged, and $W_3 = y_3 + (1-\kappa_s)p - D_3 + n_2R$ changes by $+Rx - Rx = 0$. The original allocation of $(c_1,c_2,c_3,b')$ is therefore still feasible; conversely any allocation feasible after the change is feasible before it with $n_2 + x$, so the feasible sets of consumption plans coincide and the optimum is unchanged. For $\theta$: an increase by $x$ raises the down payment by $px$ and lowers the stage-2 and stage-3 payments by $\tilde\delta_2 px$ and $\tilde\delta_3 px$. Replace $n_1$ by $n_1 - px$ and $n_2$ by $n_2 - \tilde\delta_3 px/R$ (feasible for small $x$): $c_1$ is unchanged; $c_2$ changes by $+\tilde\delta_2 px - Rpx + \tilde\delta_3 px/R = 0$ by $\tilde\delta_2+\tilde\delta_3/R = R$; $W_3$ changes by $+\tilde\delta_3 px - \tilde\delta_3 px = 0$. The same argument in reverse shows the feasible sets coincide.
175 +\end{proof}
176 +
177 +\subsection{Leverage amplification with transaction costs}
178 +
179 +\begin{proposition}[Leverage multiplier, break-even growth, underwater threshold]
180 +\label{prop:leverage}
181 +Let an owner buy at $p$, hold a mortgage $(1-\theta)p$ and resell at $(1+g)p$ at stage~3. Under Assumption~\ref{ass:prices}:
182 +\begin{enumerate}
183 +\item End-of-life wealth responds to the resale price with $\partial W^O_3/\partial(\text{resale price}) = 1-\kappa_s$ per unit of price, i.e. $(1-\kappa_s)/d$ per unit of cash invested at purchase; this multiplier is decreasing in $\theta$, $\kappa_b$, $\kappa_s$ and $m$.
184 +\item Compared with a renter who follows the same consumption path and invests the cash-flow differences at $R$, the owner has higher stage-3 wealth if and only if $g\ge g^*$ with
185 +\begin{equation}
186 +1+g^* = \frac{R^2(1+\kappa_b+m) + mR - (\rho/p)(R+R^2)}{1-\kappa_s},
187 +\label{eq:app_gstar}
188 +\end{equation}
189 +which is increasing in $\kappa_b$, $\kappa_s$ and $m$, decreasing in $\rho/p$, and independent of $\theta$.
190 +\item A price decline of $x$ (resale at $(1-x)p$) leaves the owner with no housing equity if and only if $x\ge x^* \equiv 1 - \delta_3/(1-\kappa_s)$; a renter's wealth is unaffected.
191 +\end{enumerate}
192 +\end{proposition}
193 +\begin{proof}
194 +(1) $W^O_3 = y_3 + (1-\kappa_s)(1+g)p - \delta_3 p$, so $\partial W^O_3/\partial[(1+g)p] = 1-\kappa_s$; dividing by the stage-1 cash outlay $dp$ gives the multiplier, whose monotonicity is immediate. (2) The owner's housing-related stage-3 wealth is $(1-\kappa_s)(1+g)p - \delta_3 p$. The renter-investor pays $\rho$ at stages 1 and 2 instead of $dp$ and $(\delta_2+m)p$, so saves $dp-\rho$ at stage 1 and $(\delta_2+m)p-\rho$ at stage 2, worth $(dp-\rho)R^2 + ((\delta_2+m)p-\rho)R$ at stage 3. The owner does at least as well iff
195 +\[
196 +(1-\kappa_s)(1+g) \ge dR^2 + (\delta_2+m)R + \delta_3 - \frac{\rho}{p}(R^2+R) = R^2(1+\kappa_b+m) + mR - \frac{\rho}{p}(R^2+R),
197 +\]
198 +using $dR^2 + \delta_2 R + \delta_3 = (\theta+\kappa_b+m)R^2 + (1-\theta)R^2$ from~\eqref{eq:app_fisher}; $\theta$ cancels. (3) Housing equity at resale is $(1-\kappa_s)(1-x)p - \delta_3 p \le 0$ iff $x\ge x^*$.
199 +\end{proof}
200 +
201 +\subsection{Dynasties and persistence}
202 +
203 +\begin{proposition}[Tenure transitions, persistence and the equal-income wealth gap]
204 +\label{prop:persist}
205 +Under Assumptions~\ref{ass:pref}--\ref{ass:interior}, with stationary prices and the stationary transfer support contained in $\mathcal B$, let $\hat y_R \equiv (1+\nu)\hat b/\nu$ and $\hat y_O \equiv \hat y_R - e_3 p$. Then:
206 +\begin{enumerate}
207 +\item The child of a renter owns iff $y_3\ge\hat y_R$ and the child of an owner owns iff $y_3\ge\hat y_O$; the tenure of a dynasty is a Markov chain with $q_{RO} = 1-G(\hat y_R)$ and $q_{OO} = 1 - G(\hat y_O)$.
208 +\item The second eigenvalue of the chain is $\lambda = q_{OO} - q_{RO} = G(\hat y_R) - G(\hat y_R - e_3 p)$; it equals the parent--child correlation of the ownership indicator in the stationary distribution and the per-generation persistence of any difference in ownership rates between groups of dynasties. $\lambda>0$ iff $e_3>0$ and $g>0$ somewhere on $(\hat y_O, \hat y_R)$; for fixed $\hat b$, $\lambda$ is non-decreasing in $e_3 p$.
209 +\item For $\lambda<1$ the chain has the unique stationary owner share $\mu^* = q_{RO}/(1-\lambda)$ and converges to it geometrically at rate $\lambda$ from any initial distribution.
210 +\item Among dynasties with identical income processes, the expected transfer received by an owner's child exceeds that of a renter's child by $\nu e_3 p/(1+\nu)$, and the end-of-life wealth gap between an owner and a renter with the same $y_3$ is $e_3 p$.
211 +\end{enumerate}
212 +\end{proposition}
213 +\begin{proof}
214 +(1) By Lemma~\ref{lem:split} and Lemma~\ref{lem:htm}, $b' = \nu W_3/(1+\nu)$ with $W^R_3 = y_3$ and $W^O_3 = y_3 + e_3p$; the child owns iff $b'\ge\hat b$ (Proposition~\ref{prop:threshold}), which gives the two cutoffs. Independence of $y_3$ across generations makes the tenure sequence Markov. (2) The transition matrix $\big(\begin{smallmatrix}1-q_{RO} & q_{RO}\\ 1-q_{OO} & q_{OO}\end{smallmatrix}\big)$ has trace $1-q_{RO}+q_{OO}$ and determinant $q_{OO}-q_{RO}$, hence eigenvalues $1$ and $\lambda$. For a two-state chain in its stationary distribution, $\mathbb E[O'\mid O=1]-\mathbb E[O'\mid O=0] = q_{OO}-q_{RO} = \lambda$, and $\operatorname{Corr}(O,O') = \lambda$ (direct computation with $\Pr(O=1)=\mu^*$). If $\mu_t$ is the owner share of a group, $\mu_{t+1} - \mu^* = \lambda(\mu_t-\mu^*)$. The sign and monotonicity statements follow from $\lambda = G(\hat y_R) - G(\hat y_R - e_3 p)$ with $G$ non-decreasing and strictly increasing where $g>0$. (3) Standard for an irreducible aperiodic two-state chain ($0<q_{RO}$, $q_{OO}<1$ or $\lambda<1$): $\mu^*$ solves $\mu^* = \mu^* q_{OO} + (1-\mu^*)q_{RO}$. (4) Immediate from $W^O_3 - W^R_3 = e_3 p$ and Lemma~\ref{lem:split}.
215 +\end{proof}
216 +
217 +\begin{remark}[No income risk: absorbing classes and history dependence]
218 +\label{rem:norisk}
219 +If $G$ is degenerate at $\bar y_3$, then $\lambda\in\{0,1\}$: when $\nu\bar y_3/(1+\nu) < \hat b \le \nu(\bar y_3+e_3p)/(1+\nu)$ the two tenure classes are absorbing, every initial owner share $\mu_0$ compatible with that inequality at $p = S^{-1}(\mu_0)$ is a stationary equilibrium, and the long-run ownership rate is determined by the initial distribution of transfers. This continuum of history-dependent steady states is a knife-edge of the no-risk case: any $G$ with positive density on $(\hat y_O,\hat y_R)$ gives $\lambda<1$ and a unique stationary distribution given prices (part~3). We therefore state persistence as a half-life, $\ln 2/(-\ln\lambda)$, not as multiplicity (see \texttt{research/failed\_hypotheses.md}).
220 +\end{remark}
221 +
222 +\subsection{Stationary equilibrium}
223 +
224 +\begin{definition}[Stationary equilibrium of the benchmark]
225 +\label{def:se}
226 +A stationary equilibrium is $(p^*,\rho^*,\mu^*)$ with $\hat b^* = \hat b(p^*,\rho^*)$ such that $\mu^* = q_{RO}/(1-\lambda)$ evaluated at $(p^*,\rho^*)$, $S(p^*) = \mu^*$ and $S_r(\rho^*) = 1-\mu^*$ (per cohort), the lender earns zero expected real profit, and the distribution of transfers is the stationary distribution of the dynasty chain.
227 +\end{definition}
228 +
229 +Write $f(\mu) \equiv \mu^*\big(S^{-1}(\mu), S_r^{-1}(1-\mu)\big)$ for the owner share generated by the dynasty chain when prices clear both markets at a cohort owner share $\mu$, with the convention $\mu^* = 0$ when $\Delta\le 0$ (nobody owns) and $\mu^*=1$ when $\hat b < 0$.
230 +
231 +\begin{proposition}[Existence; uniqueness under a dominance condition]
232 +\label{prop:exist}
233 +Let Assumptions~\ref{ass:pref}--\ref{ass:feas} hold for all $(p,\rho)$ with $p\in[0,S^{-1}(1)]$ and $\rho\in[0,S_r^{-1}(1)]$, with $\varepsilon>0$ and $\varepsilon_r<\infty$. Then a stationary equilibrium exists. If, in addition, Assumptions~\ref{ass:htm}--\ref{ass:interior} hold along the clearing curve and
234 +\begin{equation}
235 +\text{(C)}\qquad \frac{1+\nu}{\nu}\,\frac{\partial\hat b}{\partial p}\;\ge\; e_3 \qquad\text{for all } \mu\in(0,1),
236 +\label{eq:app_C}
237 +\end{equation}
238 +then $f$ is non-increasing, strictly decreasing wherever $g(\hat y_R)>0$, and the stationary equilibrium is unique.
239 +\end{proposition}
240 +\begin{proof}
241 +\emph{Existence.} $S^{-1}$ and $S_r^{-1}$ are continuous on $[0,1]$; $\Delta$, $\Lambda$ and $\hat b$ are continuous in $(p,\rho)$ where Assumption~\ref{ass:feas} holds (compositions of continuous functions and of the expectation of a continuous function over a compact support), with $\hat b\to+\infty$ as $\Delta\downarrow 0$ when $dp>\rho$, so the convention $\mu^*=0$ at $\Delta\le 0$ makes $\mu^*$ continuous; $G$ is continuous. Hence $f:[0,1]\to[0,1]$ is continuous. At $\mu = 0$, $p = 0$, so $dp = 0\le\rho$ and every feasible household owns ($\hat b = -y_1 < 0$): $f(0) = 1\ge 0$. At $\mu=1$, $f(1)\le 1$. By the intermediate value theorem $f(\mu)-\mu$ has a zero on $[0,1]$, which is a stationary equilibrium with $p^* = S^{-1}(\mu)$, $\rho^* = S_r^{-1}(1-\mu)$.
242 +
243 +\emph{Uniqueness.} $\mu^* = q_{RO}/(1-q_{OO}+q_{RO})$ is increasing in $q_{RO}$ and in $q_{OO}$; $q_{RO} = 1-G(\hat y_R)$ is non-increasing in $\hat y_R = (1+\nu)\hat b/\nu$ and $q_{OO} = 1-G(\hat y_O)$ is non-increasing in $\hat y_O = \hat y_R - e_3p$. Along the clearing curve, $dp/d\mu>0$ and $d\rho/d\mu<0$, so by Proposition~\ref{prop:cs}
244 +\[
245 +\frac{d\hat b}{d\mu} = \frac{\partial\hat b}{\partial p}\frac{dp}{d\mu} + \frac{\partial\hat b}{\partial\rho}\frac{d\rho}{d\mu} \;\ge\; \frac{\partial\hat b}{\partial p}\frac{dp}{d\mu} > 0,
246 +\qquad
247 +\frac{d\hat y_O}{d\mu} = \frac{1+\nu}{\nu}\frac{d\hat b}{d\mu} - e_3\frac{dp}{d\mu} \;\ge\; \Big[\frac{1+\nu}{\nu}\frac{\partial\hat b}{\partial p} - e_3\Big]\frac{dp}{d\mu} \ge 0
248 +\]
249 +under (C). Thus both cutoffs are non-decreasing in $\mu$, $f$ is non-increasing, and strictly decreasing where $g(\hat y_R)>0$ (then $q_{RO}$ strictly falls). Since $f$ is non-increasing and $\mu\mapsto\mu$ is strictly increasing, $f(\mu)-\mu$ is strictly decreasing on $[0,1]$ and has at most one zero; existence gives exactly one.
250 +\end{proof}
251 +
252 +\begin{corollary}[Fixed owner-occupied stock]
253 +\label{cor:fixed}
254 +If $\varepsilon = 0$ (so $S(p)=\bar H$), every stationary equilibrium has $\mu^* = \bar H$, and under (C) the price $p^*$ is the unique solution of $\mu^*(p,S_r^{-1}(1-\bar H)) = \bar H$. A change in any parameter that raises $\mu^*$ at given prices (a lower $\theta$, lower transaction costs, a higher $\chi$ or $y_1$) raises $p^*$ and leaves the ownership rate unchanged; it changes the composition of owners and, through $e_3p^*$ and $\hat b^*$, the persistence $\lambda$.
255 +\end{corollary}
256 +\begin{proof}
257 +Market clearing forces $\mu^* = \bar H$. Under (C), $\mu^*(p,\rho)$ is strictly decreasing in $p$ at fixed $\rho$ (proof of Proposition~\ref{prop:exist} with $d\rho = 0$), so the clearing price is unique and, by the implicit function theorem, moves in the direction of the demand shift.
258 +\end{proof}
259 +
260 +\begin{proposition}[Price neutrality without segmentation]
261 +\label{prop:noseg}
262 +Suppose instead of Assumption~\ref{ass:prices} that owner-occupied and rental units are the same stock, converted costlessly by competitive risk-neutral landlords with maintenance $m$ and operating wedge $\phi\ge 0$. Then in any stationary equilibrium $p^*$ solves $S(p^*) = 1$ (per cohort) and $\rho^* = p^*(1+m+\phi-1/R)$: the price and the rent are independent of $\theta$, $\kappa_b$, $\kappa_s$, $\chi$, $\nu$, $G$, the distribution of transfers, and of inflation surprises; tenure shares, $\hat b^*$ and $\lambda$ adjust to these prices without feeding back on them.
263 +\end{proposition}
264 +\begin{proof}
265 +With unit demand, every stage-1 and stage-2 household occupies exactly one unit whatever its tenure, so the total demand for units per cohort is $1$ and $S(p^*)=1$ pins $p^*$. Landlord arbitrage (buy at $p$, pay $(m+\phi)p$, collect $\rho$, sell at $p$ next period, discount at $R$) gives $\rho^* = p^*(1+m+\phi) - p^*/R$. Nothing else enters either equation.
266 +\end{proof}
267 +
268 +\subsection{Surprise inflation}
269 +
270 +\begin{proposition}[Direct revaluation and its incidence]
271 +\label{prop:accounting}
272 +Let the economy be in the stationary equilibrium up to $t$ and let a surprise $\pi^u$ occur at $t+1$: $1+\pi_{t+1} = (1+\bar\pi)(1+\pi^u)$. Consider (E1) a level surprise, with $\pi_{t+2} = \pi^e_{t+2} = \bar\pi$, and (E2) a persistent surprise, with $\pi_{t+2} = \pi^e_{t+2|t+1} = \pi_{t+1}$ and real rate $r' = r+\phi_r\pi^u$ for $(t+1,t+2)$. Holding real prices fixed:
273 +\begin{enumerate}
274 +\item For the cohort aged~2 at $t+1$, the real stage-2 payment is $\delta_2 p/(1+\pi^u)$ for every contract. The real stage-3 payment is $\delta_3 p/(1+\pi^u)$ for every contract under (E1); under (E2) it is $\delta_3 p/(1+\pi^u)^2$ for an FRM and $\delta_3 p\,(R'/R)/(1+\pi^u)$ for an ARM, $R' = 1+r'$. Hence the FRM borrower gains at least as much as the ARM borrower, strictly under (E2), and the ARM stage-3 payment rises in real terms iff $\phi_r > R$.
275 +\item For the cohort aged~3 at $t+1$, the real stage-3 payment is $\delta_3 p/(1+\pi^u)$ for every contract.
276 +\item A household holding nominal deposits $n$ at $t$ loses $nR\pi^u/(1+\pi^u)$ in real terms; a household whose nominal wage is indexed with elasticity $\eta_w$ loses $y[1-(1+\pi^u)^{-(1-\eta_w)}]$ of real income in the surprise period; a sitting tenant whose rent is indexed with elasticity $\eta_\rho$ gains $\rho[1-(1+\pi^u)^{-(1-\eta_\rho)}]$ at the landlord's expense.
277 +\item The sum over households of real gains on nominal positions (mortgages minus deposits) equals the lender's real loss: the revaluation is zero-sum. Let $\Gamma_3$ denote the real stage-3 gain of the cohort aged~2: $\Gamma_3 = \delta_3p\,\pi^u/(1+\pi^u)$ under (E1) for both contracts, $\Gamma_3 = \delta_3p\,[1-(1+\pi^u)^{-2}]$ for an FRM under (E2), and $\Gamma_3 = \delta_3p\,[1-(R'/R)/(1+\pi^u)]$ for an ARM under (E2). An owner of that cohort with deposits $n$ gains on net over its remaining life iff
278 +\begin{equation}
279 +\delta_2 p\,\frac{\pi^u}{1+\pi^u} + \Gamma_3 \;>\; y_2\Big[1-(1+\pi^u)^{-(1-\eta_w)}\Big] + nR\,\frac{\pi^u}{1+\pi^u} .
280 +\label{eq:app_gaincond}
281 +\end{equation}
282 +With full wage indexation and no deposits the left-hand side is positive for an FRM and for an ARM with $\phi_r \le R$; with $\eta_w<1$ the owner loses whenever the real-income loss exceeds the debt erosion, which happens for any $\pi^u>0$ if $y_2(1-\eta_w)$ is large relative to $\delta_2p+\delta_3p$.
283 +\end{enumerate}
284 +\end{proposition}
285 +\begin{proof}
286 +(1)--(2) Substitute the inflation paths into $D_2 = (i_1+a)(1-\theta)p/(1+\pi_{t+1})$ and $D_3 = (1+i_2)(1-a)(1-\theta)p/((1+\pi_{t+1})(1+\pi_{t+2}))$ with $1+i_1 = R(1+\bar\pi)$ and, for the ARM under (E2), $1+i_2 = R'(1+\pi_{t+2})$: the $(1+\pi_{t+2})$ factors cancel and leave $\delta_3p\,(R'/R)/(1+\pi^u)$; the FRM keeps $1+i_2 = R(1+\bar\pi)$ and the extra $(1+\pi^u)$ in the denominator remains. The real stage-3 payment of the ARM exceeds $\delta_3 p$ iff $R' > R(1+\pi^u)$, i.e. $1+r+\phi_r\pi^u > (1+r)(1+\pi^u)$, i.e. $\phi_r > 1+r = R$. The cohort aged~3 has a nominal stage-3 payment fixed before the shock, deflated by the realised price level. (3) Real deposit return $R/(1+\pi^u)$ against $R$; the wage and rent factors are definitions. (4) The lender's nominal claims are the mortgages net of deposits, so its real revaluation is minus the households' aggregate real revaluation. Condition \eqref{eq:app_gaincond} is the household's net real gain written out, the stage-3 term being the contract-specific erosion of items 1--2; the sign statements follow because $\Gamma_3\ge 0$ when $\phi_r\le R$ and the right-hand side is $O(\pi^u)$ with coefficient $y_2(1-\eta_w)$ versus $\delta_2p+\delta_3p$ on the left.
287 +\end{proof}
288 +
289 +\begin{proposition}[General-equilibrium impact of a level surprise]
290 +\label{prop:impact}
291 +Let the economy be in a stationary equilibrium satisfying Assumptions~\ref{ass:pref}--\ref{ass:interior} with $g(\hat y_O)>0$, and let a level surprise $\pi^u>0$ occur at $t+1$ (any contract). Under Assumption~\ref{ass:static}, with stage-2 owners not transacting, owner-market clearing $2S(p_{t+1}) = \mu^* + \mu_{t+1}$, rental clearing $2S_r(\rho_{t+1}) = 2-\mu^*-\mu_{t+1}$, and the static-expectations dominance condition
292 +\begin{equation}
293 +\text{(C$'$)}\qquad \frac{1+\nu}{\nu}\,\frac{\partial\hat b}{\partial p}\Big|_{p''=p^*} \;\ge\; 1-\kappa_s ,
294 +\label{eq:app_Cprime}
295 +\end{equation}
296 +the impact responses satisfy:
297 +\begin{enumerate}
298 +\item $dp_{t+1}/d\pi^u \ge 0$ and $d\rho_{t+1}/d\pi^u\le 0$, both strict if $\varepsilon<\infty$ (respectively $\varepsilon_r<\infty$); if $\varepsilon=0$ the price response is strictly positive and $\mu_{t+1} = \mu^*$.
299 +\item $d\mu_{t+1}/d\pi^u\ge 0$, strictly if $\varepsilon>0$.
300 +\item $d\hat b_{t+1}/d\pi^u\ge 0$; the renter-to-owner transition probability $q_{RO}$ falls, the owner-to-owner probability $q_{OO}$ rises, and the persistence $\lambda$ rises.
301 +\item Stage-3 owner-sellers gain $\delta_3p^*\pi^u/(1+\pi^u) + (1-\kappa_s)\,dp_{t+1} \ge 0$; the lender loses the nominal erosion; the stage-1 cash of an inframarginal owner-dynasty child changes by $\frac{\nu}{1+\nu}\big[\delta_3p^*\frac{\pi^u}{1+\pi^u} + (1-\kappa_s)dp_{t+1}\big] - d\,dp_{t+1}$, which is negative whenever $dp_{t+1}$ is large relative to the erosion (inelastic supply) and $\nu/(1+\nu) < d/(1-\kappa_s)$; renter-dynasty children who rent in both situations gain iff $\rho_{t+1}<\rho^*$.
302 +\item Without segmentation (Proposition~\ref{prop:noseg}) items 1--3 are zero and only Proposition~\ref{prop:accounting} applies.
303 +\end{enumerate}
304 +\end{proposition}
305 +\begin{proof}
306 +Stage-3 owner-parents at $t+1$ bought at $p^*$ and sell at $p_{t+1}$, with nominal stage-3 payment fixed before the shock, so their end-of-life wealth is $W_3 = y_3 + E$ with $E(p_{t+1},\pi^u) \equiv (1-\kappa_s)p_{t+1} - \delta_3p^*/(1+\pi^u)$; renter-parents have $W_3 = y_3$. Under Assumption~\ref{ass:static} the children's threshold is $\hat b(p_{t+1},\rho_{t+1})$ computed with $p''=p^*$, $\rho'=\rho^*$; its partial derivative in $p$ is $-\big[d/c^O_1 + \beta(\delta_2+m)/c^O_2\big]\big/\big[1/c^O_1 - 1/c^R_1\big] > 0$ (no resale term) and in $\rho$ it is negative as in Proposition~\ref{prop:cs}. With $\hat y_R = (1+\nu)\hat b/\nu$ and $\hat y_O = \hat y_R - E$, the stage-1 owner share is
307 +\[
308 +\mu^d(p,\rho,\pi^u) = \mu^*\big[1-G(\hat y_O)\big] + (1-\mu^*)\big[1-G(\hat y_R)\big].
309 +\]
310 +Let $Q\equiv(\mu^*+\mu_{t+1})/2$, $p = S^{-1}(Q)$, $\rho = S_r^{-1}(1-Q)$ and $\Psi(Q,\pi^u)\equiv \mu^d(S^{-1}(Q),S_r^{-1}(1-Q),\pi^u) - (2Q-\mu^*)$; an impact equilibrium is a zero of $\Psi$. Then $\partial\Psi/\partial\pi^u = \mu^* g(\hat y_O)\,\delta_3p^*/(1+\pi^u)^2 > 0$, and
311 +\[
312 +\frac{\partial\mu^d}{\partial p} = -\Big[\mu^*g(\hat y_O) + (1-\mu^*)g(\hat y_R)\Big]\frac{1+\nu}{\nu}\frac{\partial\hat b}{\partial p} + \mu^* g(\hat y_O)(1-\kappa_s) \le 0
313 +\]
314 +under (C$'$), while $\partial\mu^d/\partial\rho = -[\cdots]\frac{1+\nu}{\nu}\partial\hat b/\partial\rho \ge 0$ multiplies $d\rho/dQ<0$. Hence $\partial\Psi/\partial Q \le -2 < 0$ and, by the implicit function theorem, $dQ/d\pi^u = -(\partial\Psi/\partial\pi^u)/(\partial\Psi/\partial Q) > 0$. Items 1--2 follow from $dp/dQ = p/(\varepsilon Q) > 0$ for $\varepsilon\in(0,\infty)$, $d\rho/dQ<0$ for $\varepsilon_r<\infty$, and $\mu_{t+1} = 2Q-\mu^*$. If $\varepsilon = 0$ the owner stock is fixed, $\mu_{t+1}=\mu^*$, and $p_{t+1}$ solves $\mu^d(p,\rho^*,\pi^u)=\mu^*$ with $\partial\mu^d/\partial p<0$ (strict because $g(\hat y_O)>0$ and (C$'$) with the $(1-\mu^*)g(\hat y_R)$ term), so $dp/d\pi^u = -(\partial\mu^d/\partial\pi^u)/(\partial\mu^d/\partial p) > 0$. Item 3: $d\hat b = (\partial\hat b/\partial p)dp + (\partial\hat b/\partial\rho)d\rho \ge 0$ since both products are non-negative; hence $\hat y_R$ rises and $q_{RO}$ falls. Since $\mu_{t+1}-\mu^* = \mu^*(q_{OO}-q^*_{OO}) + (1-\mu^*)(q_{RO}-q^*_{RO}) \ge 0$ with the second term non-positive, $q_{OO}\ge q^*_{OO}$, and $\lambda = q_{OO}-q_{RO}$ rises. Item 4 is the change in $W_3$ of stage-3 owners (both terms non-negative), the lender's side of Proposition~\ref{prop:accounting}, Lemma~\ref{lem:split} applied to the parents' gain minus the higher outlay $d\,dp_{t+1}$ of the child, and the stage-1 budget of a renter. Item 5: with one stock, $p_{t+1}$ solves $S(p)=1$ and does not depend on $\pi^u$.
315 +\end{proof}
316 +
317 +\begin{remark}[Scope of Proposition~\ref{prop:impact}]
318 +\label{rem:impact_scope}
319 +The proposition covers the first period after the shock under per-period supply and static expectations. Contracts do not matter on impact because the stage-3 parents' nominal payment was fixed before the shock under every contract; they matter for the cohort aged~2 (Proposition~\ref{prop:accounting}), whose children buy at $t+2$. With units held for two periods, the stage-2 cohort's holdings crowd the next cohort ($\mu_{t+1}+\mu_t \approx 2S(p)$), which generates an alternating adjustment in the myopic simulation of \texttt{src/toy\_model.py}; the perfect-foresight transition with a durable stock, the second-round effects, and the owner--renter welfare comparison for marginal households are left to the numerical model and are not claimed here.
320 +\end{remark}
added paper/appendix_proofs_standalone.tex +46 −0
@@ -0,0 +1,46 @@
1 +% Stand-alone wrapper to compile appendix_proofs.tex on its own:
2 +% cd paper && latexmk -pdf appendix_proofs_standalone.tex
3 +% The preamble mirrors main.tex (template) plus the WP18 theorem environments
4 +% proposed in research/wp_style_audit.md, §6.
5 +\documentclass[12pt,letterpaper]{article}
6 +\usepackage[utf8]{inputenc}
7 +\usepackage[T1]{fontenc}
8 +\usepackage[english]{babel}
9 +\usepackage[letterpaper,top=1in,bottom=1in,left=1in,right=1in]{geometry}
10 +\usepackage{mathptmx}
11 +\usepackage{microtype}
12 +\usepackage{setspace}
13 +\onehalfspacing
14 +\usepackage{amsmath,amssymb,amsthm}
15 +\usepackage{booktabs}
16 +\usepackage[dvipsnames]{xcolor}
17 +\usepackage[colorlinks=true,linkcolor=NavyBlue,citecolor=NavyBlue,urlcolor=NavyBlue]{hyperref}
18 +\usepackage{enumitem}
19 +\setlist{nosep,leftmargin=*}
20 +\usepackage[toc,page]{appendix}
21 +
22 +% --- Theorem Environments (WP18) ---
23 +\theoremstyle{plain}
24 +\newtheorem{proposition}{Proposition}
25 +\newtheorem{lemma}{Lemma}
26 +\newtheorem{corollary}{Corollary}
27 +\newtheorem{theorem}{Theorem}
28 +\theoremstyle{definition}
29 +\newtheorem{assumption}{Assumption}
30 +\newtheorem{definition}{Definition}
31 +\theoremstyle{remark}
32 +\newtheorem{remark}{Remark}
33 +
34 +\title{WP18 --- Appendix: assumptions, propositions and proofs\\ \large (stand-alone compilation of \texttt{appendix\_proofs.tex})}
35 +\author{Simon-Pierre Boucher}
36 +\date{Phase 2 draft, October 2026}
37 +
38 +\begin{document}
39 +\maketitle
40 +\section{Model (placeholder for the main text)}
41 +\label{sec:model}
42 +This section stands in for the model section of the main text; the benchmark model is specified in \texttt{research/model\_specification.md}, Part~A.
43 +\begin{appendices}
44 +\input{appendix_proofs}
45 +\end{appendices}
46 +\end{document}
added requirements.txt +4 −0
@@ -0,0 +1,4 @@
1 +# WP18 — pinned Python dependencies (Phase 2 benchmark; Phase 3 will add pandas, matplotlib, pyyaml)
2 +numpy==2.5.4
3 +pytest==9.1.1
4 +scipy==1.18.1
added research/failed_hypotheses.md +37 −0
@@ -0,0 +1,37 @@
1 +# WP18 — Failed, weakened or abandoned hypotheses (Phase 2)
2 +
3 +Recorded 2026-10-20. Each entry gives the hypothesis as it appeared in the brief or in the Phase 1 novelty matrix, what the analysis found, and what replaced it.
4 +
5 +## 1. "Persistence through multiple equilibria / path dependence" — not established; knife-edge
6 +*Hypothesis (contribution ii).* Inherited wealth and the down-payment constraint generate path-dependent, possibly multiple, long-run ownership distributions among equal-income dynasties.
7 +*Finding.* With no income risk, the benchmark has absorbing tenure classes and a continuum of history-dependent stationary owner shares (Remark after Proposition 5). This disappears for any income distribution with positive density between the two cutoffs: the dynasty chain is then ergodic with a unique stationary distribution given prices. Multiplicity of *equilibrium prices* can only come from the ladder channel (bequeathed equity rising with the price) dominating the threshold channel, i.e. failure of condition (C); in the benchmark (C) holds by a factor of 50.
8 +*Replacement.* Persistence is stated as the intergenerational tenure correlation $\lambda = G(\hat y_R) - G(\hat y_R - e_3p)$ and its half-life (Proposition 5). Multiplicity is kept as an open conjecture to be searched numerically under near-fixed supply.
9 +
10 +## 2. "Surprise inflation raises real house prices" — not a theorem
11 +*Finding.* Without segmentation the price does not move at all (Proposition 7). With segmentation the impact sign is positive only through a specific channel — owner-parents with eroded debt whose children are at the margin ($\mu^* g(\hat y_O) > 0$) — and the magnitude is small in the benchmark (0.03 % for a 10 % surprise). Nothing in the model links the surprise to real prices directly; a monetary tightening ($\phi_r > 0$) lowers demand through $\Delta$ and could reverse the sign (not analysed formally).
12 +*Replacement.* Proposition 9 states conditions and signs; the quantitative claim is left to Phase 3.
13 +
14 +## 3. "Inflation enriches owners" — false in general
15 +*Finding.* Four classes of owners lose: ARM borrowers when the real rate rises by more than $R$ per unit of surprise (Proposition 8.1); owners with imperfectly indexed wages when $y_2(1-\eta_w)$ exceeds the eroded payments; owners holding nominal deposits larger than their mortgage; and new buyers in inelastic markets, whose transfer rises by less than the price-induced outlay (Proposition 9.4). Stage-3 sellers always gain.
16 +*Replacement.* Condition (8.4) and the list of losers.
17 +
18 +## 4. "Leverage raises the return hurdle / lowers it" — leverage is neutral for the break-even
19 +*Finding.* With borrowing at the deposit rate, the break-even real price growth $g^*$ at which owning beats renting-and-investing is independent of the LTV (Proposition 4.2); leverage only scales gains and losses. The brief's "leverage amplification with costs" is therefore a statement about the multiplier $(1-\kappa_s)/d$ and the underwater threshold, not about the mean return.
20 +
21 +## 5. "Ownership threshold is a feasibility (down-payment) threshold" — only partly
22 +*Finding.* The down payment gives the feasibility bound $dp - y_1$; the actual threshold is higher by the marginal buyer's stage-1 consumption $\Lambda(dp-\rho)/(1-\Lambda)$, a preference/liquidity component that depends on rent, costs, the amortisation schedule, expected inflation and the bequest motive. When owning costs less cash than renting ($dp \le \rho$) the preference component vanishes.
23 +
24 +## 6. Single crossing of the tenure decision for savers — proof gap
25 +*Finding.* Proposition 1 is proved on the hand-to-mouth region. For households that save, the envelope derivative argument shows $V^O - V^R$ increases where the would-be owner consumes less than the would-be renter, but we could not show this at every crossing. Numerically the crossing is unique on the tested grid. Left open (Remark in the appendix); Phase 3 must report the ownership policy as a function of $a_1$ and flag non-monotonicity.
26 +
27 +## 7. Static expectations in the impact proposition — strong assumption
28 +*Finding.* Proposition 9 needs the stage-1 cohort to expect pre-shock future prices; with forward-looking prices the threshold depends on $p_{t+3}$ and the dominance condition changes to (C). The myopic simulation also shows a cohort-crowding oscillation (units held two periods) that a durable-stock, forward-looking model may not have. Labelled **P-strong**; the transition is a numerical object.
29 +
30 +## 8. Comparative statics that are ambiguous in theory (not failures, but not signed)
31 +* $\partial\lambda/\partial\theta$: a higher down payment raises $e_3$ (more persistence) and $\hat b$ (moves both cutoffs); sign depends on $g$.
32 +* $\partial\mu^*/\partial\theta$ in GE with fixed stock: zero by construction; with elastic supply negative under (C).
33 +* Welfare of renter-dynasty children priced out on impact: they lose the option to own at the old price but rent at a lower rent; unsigned.
34 +* $\partial\hat b/\partial p$ with an intensive housing margin (Part B): not covered by the unit-demand proof.
35 +
36 +## 9. Two-period version — abandoned in favour of three stages
37 +A two-period lifecycle (buy, then sell) makes the whole mortgage a balloon repaid with compound interest at the end of life, so the house is net wealth only if $\theta > 1 - (1-\kappa_s)/R$, which fails for generation-length periods; persistence through housing equity then has the wrong sign. The three-stage structure with amortisation at stage 2 restores $e_3 > 0$ for reasonable parameters and is what the propositions use.
added research/model_specification.md +354 −0
@@ -0,0 +1,354 @@
1 +# WP18 — Model specification (Phase 2)
2 +
3 +Status: written incrementally on 2026-10-20 by the theory team. Part A is the tractable benchmark (three-period lifecycle, two-period generations) that delivers the analytical propositions proved in `paper/appendix_proofs.tex`; Part B is the full dynamic OLG model to be implemented in Phase 3. Notation is chosen to be consistent across the two parts and, where possible, with Kaplan–Mitman–Violante (2020) for the household block, Garriga–Kydland–Šustek (2017) for nominal mortgages and Sommer–Sullivan–Verbrugge (2013) for the rental block. Results of the simulations are never called theorems; every analytical claim below has a label (Proposition/Lemma) matching the appendix.
4 +
5 +---
6 +
7 +## 0. Conventions, units and notation
8 +
9 +* Time is discrete, $t = 0, 1, 2, \dots$. One model period is a block of years (Part A: a "stage of life", roughly 10–15 years; Part B: 5 years, see §B.9).
10 +* **Numéraire.** All quantities marked "real" are in units of the consumption good of the period. The consumer price index is $P_t$ (nominal price of one unit of consumption); gross CPI inflation is $1+\pi_t = P_t/P_{t-1}$.
11 +* **Expected and unexpected inflation.** $\pi^e_{t}$ is the inflation rate over $(t-1,t)$ expected at $t-1$; the surprise is defined multiplicatively, $1+\pi^u_t \equiv (1+\pi_t)/(1+\pi^e_t)$. In the stationary equilibrium $\pi_t = \pi^e_t = \bar\pi$ and $\pi^u_t = 0$.
12 +* **House price vs CPI.** $p_t$ is the *real* price of one unit of owner-occupied housing (units of consumption per unit of housing). The nominal house price is $P_t p_t$; the house-price index is therefore $P_t p_t$ and is distinct from the CPI $P_t$. "Real house-price growth" means $p_{t+1}/p_t - 1$.
13 +* **Rent.** $\rho_t$ is the real rent per unit of rental housing services for one period, paid at the start of the period.
14 +* **Nominal debt.** A mortgage originated at $t$ has nominal principal $B^{nom}_t$ (dollars). Its real value is $B^{nom}_t/P_t$. We write $B_t \equiv B^{nom}_t/P_t$ for the real principal at origination and track the real balance $b^m_{t+k} \equiv B^{nom}_{t+k}/P_{t+k}$ in later periods; the nominal balance is what the contract fixes, the real balance is what matters for consumption.
15 +* **Interest rates.** $r$ is the real one-period rate (gross $R \equiv 1+r$). The nominal rate on contracts written at $t$ for the period $(t,t+1)$ satisfies the Fisher relation $1+i_t = R\,(1+\pi^e_{t+1})$ (competitive risk-neutral lender, Assumption A2). An FRM keeps $i_t$ for the life of the loan; an ARM resets to the current $i$ every period; a term-$k$ contract (the Canadian five-year term) resets every $k$ periods.
16 +* **Households and dynasties.** Each household belongs to a dynasty; a dynasty is an infinite sequence of parent–child pairs. Labour income processes are identical across dynasties (the "equal income" design); dynasties differ only through the transfers they receive.
17 +* Indices: $j$ age, $z$ idiosyncratic income state, $o \in \{O, R\}$ tenure (owner, renter). Hats denote thresholds ($\hat b$), stars stationary-equilibrium values ($p^*$).
18 +
19 +Table of symbols (both parts):
20 +
21 +| Symbol | Meaning | Units |
22 +|---|---|---|
23 +| $c$ | non-housing consumption | goods |
24 +| $s$ | housing services consumed | housing units |
25 +| $h$ | owner-occupied house size held | housing units |
26 +| $a$, $n$ | liquid asset (nominal deposit) real balance; $n<0$ = net mortgage position in Part A | goods |
27 +| $b$ | transfer/bequest received at entry (real) | goods |
28 +| $b'$ | transfer given to the child | goods |
29 +| $y_j$ | real labour income (or pension) at age $j$ | goods |
30 +| $p$, $\rho$ | real house price, real rent | goods per housing unit |
31 +| $P$, $\pi$, $\pi^e$, $\pi^u$ | CPI level, inflation, expected, surprise | — |
32 +| $r$, $R$, $i$ | real rate, gross real rate, nominal rate | — |
33 +| $\theta$ | minimum down-payment share (max LTV $=1-\theta$) | — |
34 +| $\psi$ | maximum payment-to-income ratio at origination (Part B) | — |
35 +| $\kappa_b$, $\kappa_s$ | buying and selling transaction cost, share of price | — |
36 +| $m$ | maintenance cost per period, share of price | — |
37 +| $a$ (Part A) | amortisation share of principal repaid at age 2 | — |
38 +| $\omega$ | share of the nominal payment stream not repriced after a surprise (contract-type summary) | — |
39 +| $\chi$ | ownership utility premium (per period of owner-occupancy, utils) | — |
40 +| $\beta$, $\nu$ | discount factor, warm-glow weight on the transfer | — |
41 +| $\varepsilon$, $\varepsilon_r$ | price elasticity of owner-occupied and rental supply | — |
42 +| $\bar H$, $\bar H_r$ | scale of the two supply curves | housing units |
43 +| $\mu$ | share of a cohort that owns | — |
44 +| $G$, $g$ | cdf and density of the age-3 income $y_3$ (Part A) | — |
45 +| $\eta_w$, $\eta_\rho$ | indexation of nominal wages and rents to a surprise (1 = full) | — |
46 +
47 +---
48 +
49 +# Part A — Tractable benchmark: three-stage lifecycle, two-period generations
50 +
51 +## A.1 Demographics and timing
52 +
53 +A household lives three stages, $j = 1, 2, 3$: **buyer** (young adult; chooses tenure, buys or rents, borrows), **payer** (prime age; pays rent or mortgage interest and amortisation; under an ARM/term contract the mortgage rate is reset at the start of this stage), **seller/donor** (sells the house, repays the remaining balance, consumes and gives an inter-vivos transfer to the child). The child is born into the model (stage 1) at the date at which the parent enters stage 3, so a generation lasts two periods and the transfer is received exactly when the child makes its tenure decision — the empirical "gift at first purchase" channel (Engelhardt–Mayer 1998; Blickle–Brown 2019). Each period a unit mass of stage-1 households is born; the cross-section at any date has one unit mass of each stage.
54 +
55 +Stage-3 households do not demand housing in the two housing markets of the model (their retirement housing is outside the model and its cost is netted out of $y_3$). This is the only demographic simplification of Part A; Part B has housing at all ages.
56 +
57 +**Within-period timing (date $t$).** (1) The price level $P_t$ is realised (possibly with a surprise $\pi^u_t$) and the income shock $y_{3}$ of stage-3 households is realised. (2) Real prices $p_t$ and $\rho_t$ are determined. (3) Stage-3 households sell, repay, consume and transfer $b'$ to their stage-1 child. (4) Stage-1 households receive $b'$, choose tenure, housing and the mortgage; stage-2 households make payments and consume. (5) The owner-occupied and rental markets clear.
58 +
59 +## A.2 Preferences and the housing need
60 +
61 +Lifetime utility of a household born at $t$ with tenure $o \in \{O,R\}$:
62 +$$
63 +U^o = \ln c_1 + \chi\,\mathbf 1\{o = O\} + \beta\,\mathbb E\big[\ln c_2\big] + \beta^2\,\mathbb E\big[\ln c_3 + \nu \ln b'\big], \qquad \beta \in (0,1),\ \nu > 0,\ \chi \ge 0 .
64 +$$
65 +Each household needs exactly **one unit of housing services** in stages 1 and 2 (unit demand): an owner holds one unit of the owner-occupied stock, a renter rents one unit of the rental stock. Housing therefore enters utility only through the constant $\chi$ (an ownership premium, Henderson–Ioannides 1983; $\chi = 0$ is allowed). The warm-glow term $\nu \ln b'$ is the De Nardi (2004) specification with the luxury shift set to zero so that the transfer rule is linear (Lemma 1). Income $y_1, y_2$ are deterministic and common; $y_3$ is drawn from a continuous distribution $G$ with density $g > 0$ on $[\underline y_3, \bar y_3]$, i.i.d. across households and generations. The income process is the same for every dynasty.
66 +
67 +## A.3 Markets, contracts and the lender
68 +
69 +**Mortgage.** A stage-1 owner buys one unit at $p_t$, pays the buying cost $\kappa_b p_t$ and maintenance $m p_t$, makes the down payment $\theta p_t$ and borrows the nominal principal $B^{nom}_t = P_t (1-\theta) p_t$ (the LTV constraint binds under Assumption A4; in general $B^{nom}_t \le P_t(1-\theta)p_t$). The contract specifies the nominal payments
70 +
71 +* stage 2 (date $t+1$): interest $i_{1} B^{nom}_t$ plus amortisation $a B^{nom}_t$, $a \in (0,1]$;
72 +* stage 3 (date $t+2$): $(1+i_{2})(1-a) B^{nom}_t$,
73 +
74 +with $i_1 = R(1+\pi^e_{t+1}) - 1$ fixed at origination for every contract, and $i_2 = i_1$ (FRM) or $i_2 = R(1+\pi^e_{t+2|t+1}) - 1$ (ARM / term contract renewed at $t+1$). Real payments are
75 +$$
76 +D_2 = \frac{(i_1 + a)(1-\theta)p_t}{1+\pi_{t+1}}, \qquad
77 +D_3 = \frac{(1+i_2)(1-a)(1-\theta)p_t}{(1+\pi_{t+1})(1+\pi_{t+2})}.
78 +$$
79 +In the stationary state ($\pi = \pi^e = \bar\pi$) write $D_2 = \delta_2 p$, $D_3 = \delta_3 p$ with
80 +$$
81 +\delta_2 = (1-\theta)\Big[R - \frac{1-a}{1+\bar\pi}\Big], \qquad \delta_3 = \frac{(1-a)(1-\theta)R}{1+\bar\pi}, \qquad \delta_2 + \frac{\delta_3}{R} = (1-\theta)R .
82 +$$
83 +The last identity is Fisher neutrality in present value: anticipated inflation front-loads real payments (the "tilt", $\partial\delta_2/\partial\bar\pi > 0$, $\partial\delta_3/\partial\bar\pi < 0$) without changing their present value.
84 +
85 +**Liquid asset.** A one-period nominal deposit paying $i_t$; real balance $n \ge 0$ (no unsecured borrowing). Its real gross return is $R/(1+\pi^u_{t+1})$: a surprise erodes nominal savings exactly as it erodes nominal debt.
86 +
87 +**Lender.** A competitive, risk-neutral intermediary funds mortgages and takes deposits at the same nominal rate, earning zero expected real profit; its equity is held by rentiers outside the dynasties (equivalently, a small open economy facing the world real rate $r$). Its realised real profit in a surprise period is the mirror image of the households' revaluation gains (Proposition 8). The alternative closure (mortgages funded by domestic deposits, endogenous $r$) is a Part B extension.
88 +
89 +**Rental sector.** Landlords are competitive and risk neutral; the rental stock is segmented from the owner-occupied stock (different units; no costless conversion). Rental supply per cohort is $S_r(\rho) = \bar H_r \rho^{\varepsilon_r}$, $\varepsilon_r \in [0,\infty]$ ($\varepsilon_r = \infty$: rent fixed at $\bar\rho$). This reduced form stands for landlords who hold a stock $H^r$ priced at $p^r$ with the arbitrage rent $\rho = p^r(1+m+\phi) - \mathbb E p^{r\prime}/R$, so that $S_r$ is the supply of rental units expressed in rent space. Real wage and rent indexation to a surprise are $\eta_w, \eta_\rho \in [0,1]$ (baseline 1).
90 +
91 +**Owner-occupied supply.** $S(p) = \bar H p^{\varepsilon}$ units per cohort, $\varepsilon \in [0,\infty)$; $\varepsilon = 0$ is a fixed stock. In Part A, $S$ is used as a per-period supply curve (the stock is re-supplied each period along $S$, equivalently a reversible land-conversion technology). The durable stock-flow version $H_{t} = (1-\delta)H_{t-1} + \iota p_t^{\varepsilon}$ with stationary curve $S(p) = \iota p^\varepsilon/\delta$ and impact elasticity $\varepsilon\delta$ is the Part B specification; the Part A propositions on impact effects are stated under the per-period curve and the Phase 3 code will report both.
92 +
93 +**No segmentation (benchmark).** If instead owner and rental units are the same stock and landlords convert costlessly, the total demand for units is fixed by unit demand (two per cohort) and $p$ is pinned by $S(p) = 1$ (per cohort), the rent follows $\rho = p(1+m+\phi) - p'/R$, and tenure has no effect on the price (Proposition 7). This is the Kaplan–Mitman–Violante/Greenwald–Guren neutrality; price feedback in Part A requires segmentation.
94 +
95 +## A.4 Household budgets
96 +
97 +Owner (born at $t$; stationary prices unless noted):
98 +$$
99 +\begin{aligned}
100 +\text{stage 1:}\quad & c_1 + (\theta + \kappa_b + m)\,p_t + n_1 = b + y_1 + \underbrace{\big[(1-\theta)p_t - B_t\big]}_{\ge 0 \text{ if the LTV constraint is slack}}, \\
101 +\text{stage 2:}\quad & c_2 + D_2 + m\,p_t + n_2 = y_2 + n_1 \tfrac{R}{1+\pi^u_{t+1}}, \\
102 +\text{stage 3:}\quad & c_3 + b' = W_3^O \equiv y_3 + (1-\kappa_s)\,p_{t+2} - D_3 + n_2 \tfrac{R}{1+\pi^u_{t+2}} .
103 +\end{aligned}
104 +$$
105 +(Maintenance in stage 2 is $m p_t$: it is a share of the purchase price, i.e. a physical cost; the distinction is immaterial in the stationary state.) We write $d \equiv \theta + \kappa_b + m$ for the stage-1 cash outlay per unit of price. Define the **net equity share at sale** $e_3 \equiv (1-\kappa_s) - \delta_3$ (stationary), so that $W_3^O = y_3 + e_3 p$ for an owner with $n_2 = 0$; $e_3 > 0$ requires $(1-\kappa_s)(1+\bar\pi) > (1-a)(1-\theta)R$, i.e. enough amortisation and down payment for the house to be net wealth at the end of life.
106 +
107 +Renter (born at $t$):
108 +$$
109 +c_1 + \rho_t + n_1 = b + y_1, \qquad c_2 + \rho_{t+1} + n_2 = y_2 + n_1\tfrac{R}{1+\pi^u_{t+1}}, \qquad c_3 + b' = W_3^R \equiv y_3 + n_2\tfrac{R}{1+\pi^u_{t+2}} .
110 +$$
111 +Constraints: $c_j > 0$, $n_1, n_2 \ge 0$ for renters; $n_1 \ge -(1-\theta)p_t$ for owners (a negative $n_1$ is the mortgage; the payment schedule above applies to the mortgage part), $n_2 \ge 0$ (no refinancing in Part A; Part B allows it). No default: Assumption A3 guarantees $c_2, W_3 > 0$ on the support of $y_3$.
112 +
113 +**Stage-3 split (Lemma 1).** Maximising $\ln c_3 + \nu \ln b'$ subject to $c_3 + b' = W_3$ gives $c_3 = W_3/(1+\nu)$, $b' = \nu W_3/(1+\nu)$: the transfer is a fixed share of end-of-life wealth, so the dynasty map is linear in $W_3$.
114 +
115 +## A.5 The hand-to-mouth (HTM) regime and closed-form values
116 +
117 +Assumption A4 (liquidity-constrained at the margin) requires that at the wealth level at which the tenure choice is marginal, both the would-be owner and the would-be renter would like to borrow against future income but cannot: $1/c_1 > \beta R\,\mathbb E[1/c_2]$ and $1/c_2 > \beta R (1+\nu)\, \mathbb E[1/W_3 \mid y_2]$ at $n_1 = n_2 = 0$ (renter) and at $B = (1-\theta)p$, $n_2 = 0$ (owner). Under A4, the closed-form values are
118 +$$
119 +V^O(b) = \ln(b + y_1 - d p) + \chi + \beta\,\mathbb E\ln(y_2 - D_2 - m p) + \beta^2(1+\nu)\,\mathbb E\ln\big(y_3 + (1-\kappa_s)p'' - D_3\big) + K,
120 +$$
121 +$$
122 +V^R(b) = \ln(b + y_1 - \rho) + \beta\,\mathbb E\ln(y_2 - \rho') + \beta^2(1+\nu)\,\mathbb E\ln y_3 + K,
123 +$$
124 +with $K = \beta^2[\nu\ln\nu - (1+\nu)\ln(1+\nu)]$ common. Define the **ownership premium in utility units**
125 +$$
126 +\Delta \equiv \chi + \beta\,\mathbb E\big[\ln(y_2 - D_2 - mp) - \ln(y_2 - \rho')\big] + \beta^2(1+\nu)\,\mathbb E\big[\ln(y_3 + (1-\kappa_s)p'' - D_3) - \ln y_3\big], \qquad \Lambda \equiv e^{-\Delta}.
127 +$$
128 +$\Delta$ collects everything that happens after the purchase: the stage-2 cash-flow comparison (mortgage payment plus maintenance versus rent) and the stage-3 housing equity. The tenure decision compares the stage-1 cash sacrifice $d p - \rho$ with $\Delta$.
129 +
130 +## A.6 Ownership-entry threshold (Proposition 1) and comparative statics (Proposition 2)
131 +
132 +Under A1–A5 (A5: $\Delta > 0$ and $dp > \rho$, i.e. owning costs more cash up front and pays off later), the household owns iff $b \ge \hat b$ with
133 +$$
134 +\boxed{\;\hat b(p,\rho) = \frac{d\,p - \Lambda\,\rho}{1-\Lambda} - y_1\;}, \qquad \hat b > b_{\min} \equiv d p - y_1,
135 +$$
136 +and the stage-1 consumption of the marginal owner is $c_1^O(\hat b) = \Lambda(dp-\rho)/(1-\Lambda)$. If $dp \le \rho$ (owning is cheaper even in cash), $\hat b = b_{\min}$: only feasibility (the down payment plus costs) binds. The threshold is the sum of a *feasibility* component (down payment, costs) and a *preference* component (the sacrifice of stage-1 consumption is worth it only if the household is rich enough that the marginal utility of stage-1 consumption is low).
137 +
138 +Comparative statics (Proposition 2; all under strict A4 and $r \ge 0$): $\partial\hat b/\partial p > 0$, $\partial\hat b/\partial\rho < 0$, $\partial\hat b/\partial\theta > 0$, $\partial\hat b/\partial\kappa_b > 0$, $\partial\hat b/\partial\kappa_s > 0$, $\partial\hat b/\partial m > 0$, $\partial\hat b/\partial\chi < 0$, $\partial\hat b/\partial y_1 = -1$ (direct), and $\partial \hat b/\partial\bar\pi > 0$ (anticipated inflation raises the threshold through the tilt of real mortgage payments, Proposition 3). The sign of $\partial\hat b/\partial\theta$ is *not* a present-value effect — a higher down payment is PV-neutral under Fisher pricing — it is a liquidity effect, which is why A4 is needed; for an unconstrained household $\theta$ and $\bar\pi$ are neutral (Proposition 3).
139 +
140 +Interpretation of $\partial\hat b/\partial p > 0$: a higher price raises the cash outlay $dp$ and the stage-2 payments, and raises the equity carried into stage 3 ($e_3 p$); for a liquidity-constrained household the first effect dominates whenever $r \ge 0$ (the proof bounds the stage-3 term by the Euler inequalities). The opposite sign would require a household that values forced saving more than current consumption, which contradicts A4.
141 +
142 +## A.7 Leverage amplification with costs (Proposition 4)
143 +
144 +For an owner, end-of-life wealth is $W_3^O = y_3 + (1-\kappa_s)p'' - D_3$. Its response to the resale price is $(1-\kappa_s)$ per unit of price, i.e. $(1-\kappa_s)/d$ per unit of cash invested at purchase: the **leverage multiplier net of costs**, decreasing in $\theta$, $\kappa_b$, $\kappa_s$, $m$. Compared with a renter who follows the same consumption path and invests the cash-flow differences at $R$, the owner ends with more wealth iff
145 +$$
146 +(1-\kappa_s)(1+g) \;\ge\; R^2(1+\kappa_b+m) + mR - \frac{\rho}{p}\,(R+R^2), \qquad g \equiv p''/p - 1,
147 +$$
148 +i.e. iff real price growth exceeds a break-even rate $g^*$ that is increasing in $\kappa_b, \kappa_s, m$ and decreasing in the rent–price ratio, and **independent of $\theta$**: leverage scales gains and losses but does not change the break-even. A negative price shock $x$ (resale at $(1-x)p$) wipes out the owner's housing equity iff $x \ge x^* \equiv 1 - \delta_3/(1-\kappa_s)$; the renter is unaffected. In the stationary state ($g = 0$) with $\rho/p$ at the segmented-market level, the owner–renter end-of-life wealth gap among HTM households with the same income is exactly $e_3 p$ and the transfer gap is $\nu e_3 p/(1+\nu)$.
149 +
150 +## A.8 Dynasties: transitions, persistence and the intergenerational tenure correlation (Proposition 5)
151 +
152 +With HTM households, $b' = \nu W_3/(1+\nu)$ with $W_3^R = y_3$ and $W_3^O = y_3 + e_3 p$ (stationary). The child owns iff $b' \ge \hat b$. Hence, with $\hat y_R \equiv (1+\nu)\hat b/\nu$ and $\hat y_O \equiv \hat y_R - e_3 p$,
153 +$$
154 +q_{RO} = \Pr(\text{child owns}\mid\text{parent rents}) = 1 - G(\hat y_R), \qquad q_{OO} = \Pr(\text{child owns}\mid\text{parent owns}) = 1 - G(\hat y_O).
155 +$$
156 +The tenure of a dynasty is a two-state Markov chain; its second eigenvalue
157 +$$
158 +\lambda \equiv q_{OO} - q_{RO} = G(\hat y_R) - G(\hat y_R - e_3 p)
159 +$$
160 +is the parent–child correlation of the ownership indicator and the per-generation persistence of any tenure gap (half-life $\ln 2/(-\ln\lambda)$). $\lambda > 0$ iff $e_3 > 0$ (the house is net wealth at the end of life) and the density $g$ is positive between $\hat y_O$ and $\hat y_R$; $\lambda$ is increasing in $e_3 p$ for fixed $\hat b$. Given prices, the unique stationary owner share is $\mu^* = q_{RO}/(1-\lambda)$ and the dynasty distribution converges to it geometrically at rate $\lambda$. In the no-risk limit ($G$ degenerate) $\lambda \in \{0, 1\}$: tenure classes become absorbing when $b'_R < \hat b \le b'_O$, and any $\mu$ consistent with that inequality is stationary — a continuum of history-dependent steady states that disappears as soon as income risk mixes dynasties across the threshold (Remark in the appendix; see also `failed_hypotheses.md`).
161 +
162 +## A.9 Stationary equilibrium (Proposition 6), fixed supply (Corollary) and neutrality without segmentation (Proposition 7)
163 +
164 +**Definition (stationary equilibrium, Part A).** Given $(\bar\pi, r, G)$ and parameters, a stationary equilibrium is $(p^*, \rho^*, \mu^*, \hat b^*)$ such that (i) $\hat b^* = \hat b(p^*, \rho^*)$ from A.6 with $p'' = p^*$, $\rho' = \rho^*$; (ii) $\mu^* = q_{RO}/(1-\lambda)$ evaluated at $(p^*,\rho^*)$; (iii) owner-occupied market clearing $S(p^*) = \mu^*$ (per cohort; two cohorts hold units, two cohorts are supplied); (iv) rental market clearing $S_r(\rho^*) = 1 - \mu^*$; (v) the lender earns zero real profit; (vi) the distribution of transfers is the stationary distribution of the dynasty chain: a mass $\mu^*$ of stage-1 households draw $b' = \nu(y_3 + e_3 p^*)/(1+\nu)$ and a mass $1-\mu^*$ draw $b' = \nu y_3/(1+\nu)$, $y_3 \sim G$.
165 +
166 +Existence follows from the intermediate value theorem applied to $f(\mu) = \mu^*(S^{-1}(\mu), S_r^{-1}(1-\mu)) - \mu$ on $[0,1]$ (continuity under A3). Uniqueness holds when the entry-threshold channel dominates the *ladder channel*: a higher $p$ raises $\hat b$ (fewer renter children qualify) but also raises the equity $e_3 p$ bequeathed by owners (more owner children qualify); condition (C): $\tfrac{1+\nu}{\nu}\,\tfrac{d\hat b}{dp} \ge e_3$ along the clearing curve makes $f$ decreasing. If (C) fails, multiple stationary equilibria are *possible* (a Stein-type property-ladder multiplicity); we do not establish them and leave the search to Phase 3.
167 +
168 +**Fixed supply (Corollary).** With $\varepsilon = 0$ the owner share is $\mu^* = \bar H$ in every stationary equilibrium: any change in $\theta$, transfers, $y$ or $\chi$ is absorbed by $p^*$ and the composition of owners, not by the ownership rate; $\lambda$ can still change through $e_3 p^*$.
169 +
170 +**No segmentation (Proposition 7).** With one stock and costless conversion, $p^*$ solves $S(p) = 1$ (per cohort) and is independent of $\theta$, $G$, the transfer distribution and of inflation surprises; tenure, $\hat b$ and $\lambda$ are determined given that price, and there is no price feedback from credit, inheritance or inflation. Price feedback in this model is therefore a statement about segmentation and supply, not about credit per se.
171 +
172 +## A.10 Surprise inflation: accounting (Proposition 8) and general equilibrium impact (Proposition 9)
173 +
174 +**Experiments.** The economy is in the stationary equilibrium up to $t$. At $t+1$: (E1) *level surprise*: $1+\pi_{t+1} = (1+\bar\pi)(1+\pi^u)$, expectations for $t+2$ onward unchanged at $\bar\pi$; (E2) *persistent surprise*: $\pi_{t+1} = \pi_{t+2} = (1+\bar\pi)(1+\pi^u)-1$, learned at $t+1$ (so ARMs reset to the higher nominal rate at $t+1$, FRMs do not). Optional monetary response: the real rate for $(t+1,t+2)$ becomes $r' = r + \phi_r\pi^u$.
175 +
176 +**Direct revaluation (partial equilibrium, prices fixed).** Real payment changes relative to the no-surprise path, for the cohort aged 2 at $t+1$ (bought at $t$):
177 +* $D_2$: multiplied by $1/(1+\pi^u)$ for every contract (the stage-2 nominal payment was fixed before the shock);
178 +* $D_3$: (E1) multiplied by $1/(1+\pi^u)$ for every contract; (E2) multiplied by $1/(1+\pi^u)^2$ under an FRM and by $1/(1+\pi^u)$ under an ARM (the reset recovers one factor for the lender); with a real-rate response, the ARM payment is further multiplied by $R'/R$.
179 +
180 +For the cohort aged 3 at $t+1$ (bought at $t-1$): $D_3$ multiplied by $1/(1+\pi^u)$ for every contract. Nominal savers lose $n R\,\pi^u/(1+\pi^u)$. Real wages change by the factor $(1+\pi^u)^{-(1-\eta_w)}$, real rents paid by sitting tenants by $(1+\pi^u)^{-(1-\eta_\rho)}$. Summing over households, the real revaluation of nominal claims is zero-sum: the lender's realised real loss equals the households' net real gain on nominal positions, and landlords bear the rent-rigidity transfer. An owner with a mortgage *loses* from the surprise iff the real-income loss from imperfect wage indexation plus the loss on nominal savings exceeds the debt erosion: with full ARM repricing and a real-rate response $\phi_r > 0$ in (E2), the stage-3 payment can rise in real terms, so the net sign depends on $(1-a)R\phi_r$ versus the erosion of the stage-2 payment (explicit condition in the appendix).
181 +
182 +**General-equilibrium impact at $t+1$ (Proposition 9; under per-period supply and static expectations of post-$t+1$ prices, Assumption A6).** The stage-3 owner-parents at $t+1$ have $W_3 = y_3 + (1-\kappa_s)p_{t+1} - D_3/(1+\pi^u)$, so the mass of their children who qualify rises: $\partial\mu_{t+1}/\partial\pi^u|_{p,\rho} = \mu^* g(\hat y_O) D_3/(1+\pi^u)^2 > 0$. With stage-2 owners not transacting, owner-market clearing is $S(p_{t+1}) = (\mu^* + \mu_{t+1})/2$ and rental clearing $S_r(\rho_{t+1}) = 1 - (\mu^* + \mu_{t+1})/2$. Under condition (C):
183 +1. $dp_{t+1}/d\pi^u \ge 0$ and $d\rho_{t+1}/d\pi^u \le 0$ (strict iff $g(\hat y_O) > 0$ and the respective elasticity is finite); the rent–price ratio falls.
184 +2. $d\mu_{t+1}/d\pi^u \ge 0$, strict iff $\varepsilon > 0$; with a fixed owner stock the ownership rate does not move and the entire effect is a *composition* shift: owner-dynasty children replace renter-dynasty children at the margin.
185 +3. $d\hat b_{t+1}/d\pi^u \ge 0$: the renter-to-owner transition probability $q_{RO}$ falls on impact — surprise inflation lowers upward tenure mobility of dynasties without nominal debt, and raises $\lambda$.
186 +4. Winners: stage-3 FRM/ARM owner-sellers (debt erosion plus a higher sale price), stage-2 owners (erosion of $D_2$, and of $D_3$ under an FRM in E2). Losers: the lender (full nominal erosion), renter-dynasty children at the margin (priced out), nominal savers, and — a case that shows inflation does not enrich every owner — inframarginal owner-dynasty children who buy at $t+1$: their cash position changes by $\tfrac{\nu}{1+\nu}\big[D_3\tfrac{\pi^u}{1+\pi^u} + (1-\kappa_s)dp_{t+1}\big] - d\,dp_{t+1}$, negative when supply is inelastic and the transfer share $\nu/(1+\nu)$ is small. Renter-dynasty children who remain renters gain from the lower rent if $\varepsilon_r < \infty$.
187 +5. Under no segmentation (Proposition 7) items 1–3 vanish and only the direct revaluation remains.
188 +
189 +The full perfect-foresight transition (durable stock, forward-looking prices, two affected parent cohorts, propagation through the dynasty composition) is computed numerically in Phase 3 and is *not* covered by Proposition 9; the toy script `src/toy_model.py` simulates it under the Part A structure as a check on the sign results.
190 +
191 +## A.11 What the propositions do and do not deliver
192 +
193 +Delivered analytically: threshold with feasibility and preference components; signs of its comparative statics incl. LTV, costs, rent and anticipated inflation; leverage multiplier and break-even growth with costs; closed-form tenure persistence and half-life; existence of a stationary GE and a uniqueness condition; price-neutrality without segmentation; the complete accounting of a surprise under FRM/ARM, level/persistent, with wage and rent indexation and lender wealth; signed impact effects of a surprise on price, rent, ownership, threshold and mobility under segmentation. Not delivered (honest gaps): single crossing of the tenure decision outside the HTM regime; multiplicity of stationary equilibria (possible, not established); the full transition path; anything about the *intensive* margin of housing (unit demand).
194 +
195 +
196 +---
197 +
198 +# Part B — Full dynamic model: lifecycle OLG with nominal mortgages, bequests, rental and construction sectors
199 +
200 +Part B generalises Part A along the dimensions that Part A freezes: many ages, housing at all ages and on an intensive margin, persistent income risk, long-term amortising nominal mortgages with refinancing and three contract types, a payment-to-income constraint, bequests at two dates, a durable housing stock, and a lender with an explicit balance sheet. The equilibrium concept is a stationary recursive competitive equilibrium with constant inflation $\bar\pi$, and a perfect-foresight transition after an unanticipated inflation shock. Everything is written so that `src/model.py`, `household_solver.py`, `equilibrium.py`, `distributions.py` and `simulation.py` can be coded from this section alone.
201 +
202 +## B.1 Demographics and the dynasty link
203 +
204 +* Ages $j = 1, \dots, J$ (baseline $J = 12$ periods of 5 years, model age 1 = 25–29, death after age $J$ = 80–84; retirement at $j_R = 9$, 65 years). No survival risk in the baseline (a survival profile $\{s_j\}$ is a switch; accidental bequests then go to the child).
205 +* Each household has one child who enters the model (age 1) when the parent is aged $j_g = 1 + \Delta_g$ with $\Delta_g = 6$ (30-year generation gap). The child receives an **inter-vivos transfer** $b^g$ at its age 1, chosen by the parent at age $j_g$, and the parent's **estate** $b^e$ at the parent's death, i.e. at the child's age $j_e = J - j_g + 2 = 7$. Both transfers are chosen with warm-glow utility (B.2). Baseline experiments switch on both; "bequests off" sets $\nu = 0$ for both.
206 +* Population is constant: a unit mass per age. A dynasty is indexed by its phase; the cross-section at any date contains all phases, so the stationary distribution is over $(j, \text{state})$ with equal mass at each $j$.
207 +
208 +## B.2 Preferences
209 +
210 +Period utility over non-housing consumption $c$ and housing services $s$:
211 +$$
212 +u(c, s) = \frac{\big(c^{1-\alpha}\,s^{\alpha}\big)^{1-\gamma}}{1-\gamma}, \qquad \alpha \in (0,1),\ \gamma > 1,
213 +$$
214 +with $s = h$ for an owner of a house of size $h$ scaled by the ownership premium $s = (1+\chi) h$ if desired ($\chi \ge 0$; $\chi = 0$ baseline, so that any owner premium comes from the rent–user-cost wedge), and $s$ = rented size for a renter. Warm glow for a transfer $x \in \{b^g, b^e\}$ (De Nardi 2004):
215 +$$
216 +\phi(x) = \nu\,\frac{(x + \underline x)^{1-\gamma}}{1-\gamma}, \qquad \nu \ge 0,\ \underline x > 0,
217 +$$
218 +so that transfers are a luxury ($\underline x > 0$) — Part A's linear rule is the limit $\underline x \to 0$, $\gamma \to 1$. Discount factor $\beta$. Preferences are identical across dynasties.
219 +
220 +## B.3 Endowments and income
221 +
222 +Real labour income at age $j < j_R$: $y_{j} = \bar y_j\,z$, with $\bar y_j$ a deterministic age profile (hump-shaped) and $z$ a first-order Markov chain on $\{z_1,\dots,z_{n_z}\}$ with transition $\Pi_z$ (Rouwenhorst discretisation of $\log z' = \rho_z \log z + \sigma_z\epsilon$). Pension at $j \ge j_R$: $y_j = \varrho\,\bar y_{j_R-1}\,\bar z$ (flat, with $\bar z$ the last working-age state in the baseline). The child's initial state $z_1$ is drawn from the stationary distribution of $\Pi_z$ independently of the parent in the **baseline** (equal-income design: dynasties differ only through transfers); an intergenerational earnings correlation $\rho_g \in [0,1)$ is a robustness switch (experiment 8). Nominal income is $P_t y_j$; a surprise with wage indexation $\eta_w$ changes real income by $(1+\pi^u)^{-(1-\eta_w)}$ in the surprise period.
223 +
224 +## B.4 Housing, tenure and transaction technology
225 +
226 +* Owner-occupied houses come in sizes $h \in \mathcal H = \{h_1 < \dots < h_{n_h}\}$ with $h_1 = \underline h > 0$ the minimum owner-occupied size (the indivisibility that creates an entry threshold). Rented sizes $s \in \mathcal S = [\underline s, \bar s]$ (continuous or a fine grid), $\underline s < \underline h$.
227 +* Maintenance $m\,p_t h$ per period keeps the unit intact (owners); landlords pay the same $m$ plus an operating wedge $\phi$ (B.6).
228 +* Buying costs $\kappa_b p_t h$, selling costs $\kappa_s p_t h$ (shares of value). Moving between owned sizes = sell + buy. Renters move costlessly.
229 +* Discrete tenure/adjustment choice each period: for an owner with $(h, b^m)$: *stay* (keep $h$, keep mortgage, possibly refinance), *move* (sell, buy $h'$, new mortgage), *sell and rent*; for a renter: *rent* ($s$ chosen) or *buy* ($h$, mortgage). All households must consume housing every period ($s \ge \underline s$).
230 +
231 +## B.5 Mortgage contracts (nominal), amortisation, refinancing, constraints
232 +
233 +A mortgage originated at $t$ with real principal $B$ ($B^{nom} = P_t B$), nominal contract rate $i_0$ and amortisation length $N$ periods (baseline $N = 5$, 25 years) has the **constant nominal payment**
234 +$$
235 +\text{pay}^{nom} = B^{nom}\,\frac{i_0}{1 - (1+i_0)^{-N}} .
236 +$$
237 +Let $n \in \{N, N-1, \dots, 1\}$ be the remaining number of payments. The real balance $b^m \equiv B^{nom}_{\text{outstanding}}/P_t$ evolves as
238 +$$
239 +b^{m\prime} = \frac{b^m(1+i_{c}) - \text{pay}_t}{1+\pi_{t+1}}, \qquad \text{pay}_t = \frac{\text{pay}^{nom}_t}{P_t},
240 +$$
241 +where $i_c$ is the rate currently applying to the contract: $i_c = i_0$ for an FRM; $i_c = i_t$ (the current nominal rate, Fisher) for an ARM, with the nominal payment recomputed each period on the remaining balance and term; for a term-$k$ contract $i_c$ resets every $k$ periods (the Canadian five-year term with $k = 1$ in a 5-year-period calibration is an ARM at the period frequency with an annual-within-period fixed rate; the US 30-year FRM is $k = N$). The real payment of an FRM falls with realised inflation (nominal payment fixed), that of an ARM is re-priced each period: this is the only difference between contracts and it is exactly what Part A's $\omega$ summarises.
242 +
243 +**Origination constraints** (at purchase or refinancing; $y$ = current real income):
244 +* LTV: $B \le (1-\theta)\,p_t h$;
245 +* payment-to-income (DSTI) at the qualifying rate $i_q = i_t + \Delta_q$ (stress test, $\Delta_q \ge 0$): $\text{pay}^{nom}(i_q)/(P_t y) \le \psi$. Because the qualifying payment is nominal and income is current, expected inflation raises $i_t$ and tightens this constraint: the tilt effect of Part A reappears here as a constraint on leverage.
246 +* No unsecured borrowing: liquid asset $a' \ge 0$.
247 +
248 +**Refinancing.** An owner may at any period replace the outstanding balance by a new loan at the current rate and remaining term reset to $N$, paying $\kappa_f p_t h$, subject to the origination constraints (cash-out allowed up to LTV). Prepayment without a new loan is the case $B' < b^m$.
249 +
250 +**Default.** None in the baseline: the solver enforces $c \ge \underline c > 0$ and reports any state where the payment cannot be met (a "forced sale" rule — sell, repay, rent — is applied in those states and their mass is reported as a diagnostic; if it exceeds 0.1 % of households the calibration is rejected).
251 +
252 +## B.6 Rental sector, landlords and segmentation
253 +
254 +Rental units are a separate stock $H^r$ (units) owned by competitive risk-neutral landlords who buy rental units at price $p^r_t$, pay maintenance $m p^r_t$ and an operating wedge $\phi p^r_t$ (management, vacancy, tax treatment — the Henderson–Ioannides source of an owner premium), and rent at $\rho_t$:
255 +$$
256 +\rho_t = p^r_t\,(1 + m + \phi) - \frac{\mathbb E_t\,p^r_{t+1}}{R} \qquad (\text{zero expected profit}).
257 +$$
258 +Segmentation parameter $\sigma \in [0,1]$: a share $\sigma$ of rental units is structurally distinct (supplied by its own construction curve), a share $1-\sigma$ can be converted one-for-one and costlessly from the owner-occupied stock so that $p^r_t = p_t$ on that margin. Baseline $\sigma = 1$ (full segmentation, as in Part A); $\sigma = 0$ is the no-segmentation benchmark (Proposition 7). Implementation: $p^r_t = \sigma\,\tilde p^r_t + (1-\sigma)\,p_t$ with $\tilde p^r_t$ clearing the structurally rental stock. Rent rigidity $\eta_\rho$: in a surprise period sitting tenants pay $\rho_t (1+\pi^u)^{-(1-\eta_\rho)}$; new tenants pay $\rho_t$; the difference is a transfer from landlords.
259 +
260 +## B.7 Construction and the housing stocks
261 +
262 +Owner-occupied stock $H_t$ and rental stock $H^r_t$ (units) evolve as
263 +$$
264 +H_{t+1} = (1-\delta_H)H_t + I_t, \qquad I_t = \iota\,p_t^{\varepsilon}, \qquad H^r_{t+1} = (1-\delta_H)H^r_t + I^r_t, \qquad I^r_t = \iota_r\,(p^r_t)^{\varepsilon_r},
265 +$$
266 +with $\delta_H$ physical depreciation of the stock (units retired), $\varepsilon$, $\varepsilon_r$ long-run supply elasticities, $\iota,\iota_r$ scales. Stationary: $H = \iota p^\varepsilon/\delta_H \equiv S(p)$ and the impact (one-period) elasticity is $\varepsilon\delta_H$. Construction profits are rebated lump-sum to a construction-owner class outside the dynasties (equivalently, the construction sector uses land owned by rentiers) so that household budgets are unaffected; this is recorded in the aggregate resource constraint. Near-fixed supply (experiment 7) is $\varepsilon \to 0$.
267 +
268 +## B.8 The lender and the government
269 +
270 +The lender is a competitive intermediary with nominal assets (mortgage balances) and nominal liabilities (household deposits $a$ and rentier funding at the world real rate $r$). The nominal rate is $1+i_t = R(1+\pi^e_{t+1})$ (plus a constant spread $\varsigma \ge 0$ on mortgages, baseline 0). Its real net worth $A^L_t$ obeys
271 +$$
272 +A^L_{t+1} = \frac{(1+i_t)\,\big(\text{Mortgages}_t - \text{Deposits}_t\big)}{1+\pi_{t+1}} + \text{Rentier flow},
273 +$$
274 +and a surprise $\pi^u_{t+1}$ generates the real revaluation $-(\text{Mortgages}_t - \text{Deposits}_t)(1+i_t)\pi^u_{t+1}/((1+\pi^e_{t+1})(1+\pi^u_{t+1}))$ for the lender, the mirror image of the households' aggregate real gain on nominal positions (Proposition 8 holds state by state). Baseline closure: rentiers absorb the lender's gains and losses (exogenous $r$); extension: a closed economy where deposits must fund mortgages and $r$ clears the credit market (recorded as experiment 8c).
275 +
276 +Government: none in the baseline. Experiment 6 adds a transfer tax $\tau_b$ on $b^g$ and $b^e$ with lump-sum rebate to age-1 households.
277 +
278 +## B.9 State variables, timing and the household problem
279 +
280 +**Individual state at age $j$:** $x = (j, z, o, h, b^m, n_m, \iota_c, a, \beta^{rec})$ where $o \in \{R, O\}$; $h \in \mathcal H$ (0 for renters); $b^m \ge 0$ real mortgage balance; $n_m$ remaining payments; $\iota_c$ contract-rate state (FRM only; in a stationary equilibrium a single value, during a transition "pre-shock rate" vs "post-shock rate": two values); $a \ge 0$ liquid real asset; $\beta^{rec} \in \{0, 1\}$ whether the estate has already been received (only needed at $j_e$). The aggregate state in the stationary equilibrium is the distribution $\Phi$ over $x$.
281 +
282 +**Timing within period $t$ for a household of age $j$:**
283 +1. Income shock $z$ realised; aggregate surprise $\pi^u_t$ (if any) realised; real prices $(p_t, p^r_t, \rho_t)$ and $i_t$ announced.
284 +2. Transfers: an age-$j_g$ household chooses $b^g$ (paid now to its age-1 child); an age-$J$ household's estate $b^e$ (chosen at $J$ out of terminal wealth after selling the house, net of $\kappa_s$ and the mortgage balance) is paid to its age-$j_e$ child. Age-1 households start with $a_1 = b^g$; age-$j_e$ households add $b^e$ to $a$.
285 +3. Mortgage payment due: pay$_t$ (FRM: fixed nominal; ARM: repriced at $i_t$). Real wages and rents indexed per $\eta_w, \eta_\rho$ in a surprise period.
286 +4. Discrete choice (stay / move / sell-and-rent / rent / buy / refinance), then $c$, $a'$.
287 +5. Markets clear; stocks evolve.
288 +
289 +**Bellman equations** (stationary prices; $V_j(x)$):
290 +$$
291 +V_j(x) = \max_{\text{discrete } \ell \in \mathcal L(x)} V^{\ell}_j(x), \qquad
292 +V^{\ell}_j(x) = \max_{c, a', (h', B', s)} \Big\{ u(c, s) + \mathbf 1_{j=j_g}\phi(b^g) + \beta\,\mathbb E\big[V_{j+1}(x') \mid z\big] \Big\},
293 +$$
294 +subject to the budget of branch $\ell$ (all real):
295 +* *Renter stays renter* ($\ell = RR$): $c + \rho s + a' = y_j + a\,R_a - \mathbf 1_{j=j_g} b^g$, with $R_a \equiv (1+i_{t-1})/(1+\pi_t)$ the realised real deposit return; $x' = (j+1, z', R, 0, 0, 0, \cdot, a')$.
296 +* *Renter buys* ($\ell = RO$): $c + (1 + \kappa_b + m)\,p\,h' - B' + a' = y_j + a R_a - \mathbf 1_{j=j_g} b^g$, with $B' \le (1-\theta)p h'$, DSTI, $a' \ge 0$; $s = (1+\chi)h'$; $x' = (j+1, z', O, h', b^{m\prime}(B'), N, i_t, a')$.
297 +* *Owner stays* ($\ell = OO$): $c + \text{pay}(b^m, n_m, i_c) + m p h + a' = y_j + a R_a - \mathbf 1_{j=j_g} b^g$; $s = (1+\chi)h$; $x' = (j+1, z', O, h, b^{m\prime}, n_m - 1, i_c, a')$. Refinancing ($\ell = OF$): replace pay by the new schedule with $B'$, pay $\kappa_f p h$, constraints at origination; cash-out $B' - b^m(1+i_c)$ enters the budget.
298 +* *Owner moves* ($\ell = OM$): sell at $(1-\kappa_s)p h$, repay $b^m(1+i_c)$, then as $RO$ with $h'$.
299 +* *Owner sells and rents* ($\ell = OR$): $c + \rho s + a' = y_j + a R_a + (1-\kappa_s)p h - b^m(1+i_c) - \mathbf 1_{j=j_g} b^g$.
300 +* Terminal condition at $j = J$: the house is sold, the balance repaid, and $V_{J+1} \equiv \phi(b^e)$ with $b^e = a' $ (terminal wealth not consumed); with survival risk, the same applies at death at any age.
301 +* Feasibility: $c \ge \underline c$, $s \ge \underline s$, $a' \ge 0$; if no feasible branch exists the forced-sale rule applies.
302 +
303 +The transfer $b^g$ at age $j_g$ is a continuous choice with first-order condition $u_c = \phi'(b^g)$ (interior) and corner $b^g = 0$; the estate $b^e$ at $J$ is a continuous choice between $c_J$ and $b^e$.
304 +
305 +**Nominal vs real in the solver.** The solver works in real variables; $B^{nom}$ never appears explicitly, only $b^m$ and the real payment. Inflation enters through (i) $R_a$ and the real payment of FRMs (both divided by $1+\pi_t$), (ii) the nominal rate in the DSTI constraint and in ARM repricing, (iii) wage and rent indexation parameters. Reporting must always give both $B^{nom}/P$ (real debt) and the house-price index $P p$ separately from the CPI.
306 +
307 +## B.10 Equilibrium definitions
308 +
309 +**Stationary recursive competitive equilibrium (SRCE)** with constant inflation $\bar\pi$ and exogenous $r$: value functions $\{V_j\}$, policies, prices $(p^*, p^{r*}, \rho^*)$, nominal rate $i^* = R(1+\bar\pi) - 1$, stocks $(H^*, H^{r*})$, lender net worth $A^{L*}$ and a distribution $\Phi^*$ such that
310 +1. policies solve the household problems given prices;
311 +2. owner-occupied market clears: $\int h\,\mathbf 1\{o = O\}\,d\Phi^* = H^* = \iota (p^*)^{\varepsilon}/\delta_H$;
312 +3. rental market clears: $\int s\,\mathbf 1\{o = R\}\,d\Phi^* = H^{r*}$, with $\rho^* = p^{r*}(1+m+\phi - 1/R)$ and $H^{r*} = \iota_r (p^{r*})^{\varepsilon_r}/\delta_H$ on the segmented margin ($p^{r*} = p^*$ on the converted margin);
313 +4. dynasty consistency: the distribution of $a_1 = b^g$ across age-1 households equals the distribution of $b^g$ chosen by age-$j_g$ households, and likewise for $b^e$ at $j_e$ (the child's $z_1$ is drawn independently in the baseline);
314 +5. $\Phi^*$ is invariant under the policies, the Markov chain and the dynasty link;
315 +6. the lender earns zero expected real profit; construction profits and the lender's flows go to the outside classes;
316 +7. aggregate resource constraint: $C + m p^* H^* + (m+\phi)p^{r*}H^{r*} + \text{transaction costs} + p^* I + p^{r*} I^r = Y + r\,\text{(net foreign position)}$, reported as a residual.
317 +
318 +**Transition after an unanticipated inflation shock (MIT shock).** Start from the SRCE. At $t = 0$ the inflation path $\{\pi_t\}_{t \ge 0}$ is revealed (E1: $\pi_0 = (1+\bar\pi)(1+\pi^u)-1$, then $\bar\pi$; E2: elevated for $k$ periods), with $\pi^e_t = \pi_t$ for $t \ge 1$ (perfect foresight after the surprise), $\pi^e_0 = \bar\pi$ (the surprise). A transition equilibrium is a path $\{p_t, p^r_t, \rho_t, i_t, H_t, H^r_t, \Phi_t\}_{t=0}^{T}$ with $T$ large such that households optimise with perfect foresight, markets clear every period, and the economy is within tolerance of the SRCE at $T$. Pre-shock FRM cohorts carry $\iota_c$ = old rate; new originations use the new $i_t$. Partial-equilibrium versions (prices fixed at $p^*,\rho^*$) are reported separately and are **never** labelled GE.
319 +
320 +## B.11 Aggregation and accounting identities to be tested
321 +
322 +* Budget identity per household and period (sum of uses = sum of sources), state by state, in the simulation (`tests/`).
323 +* Debt law of motion: $b^{m\prime}(1+\pi') = b^m(1+i_c) - \text{pay}$; after $N$ payments $b^m = 0$ to machine precision.
324 +* Zero-sum revaluation: $\sum_{\text{households}} \Delta(\text{real nominal position}) + \Delta A^L = 0$ in the surprise period.
325 +* Market clearing residuals $|{\int h\,d\Phi - H}|/H$, $|{\int s\,d\Phi - H^r}|/H^r$ below tolerance; Bellman residuals on off-grid points; transfer consistency (item 4).
326 +* Wealth decomposition: net worth $= a + \mathbf 1_O\,[(1-\kappa_s)p h - b^m]$; owner–renter gap by age, by transfer quantile, holding $z$ history fixed (equal-income comparison, experiment 2).
327 +
328 +## B.12 Recommended numerical choices (for Phase 3)
329 +
330 +| Object | Recommendation |
331 +|---|---|
332 +| Period | 5 years; $J = 12$; $j_R = 9$; $j_g = 7$; $j_e = 7$; $N = 5$ (25-year amortisation) |
333 +| Income | $n_z = 5$ (Rouwenhorst), $\rho_z^{5y}$ and $\sigma_z^{5y}$ from annual values $\rho = 0.95$, $\sigma = 0.15$ converted to 5-year ($\rho^5$, variance of the 5-year sum) — illustrative, to be documented in `calibration.py` |
334 +| Grids | $a$: 60 points, double-exponential spacing on $[0, a_{\max}]$ with $a_{\max}$ ≈ 20× median annual income; $b^m$: 25 points on $[0, (1-\theta)p\,h_{n_h}]$; $\mathcal H$: 4 sizes $\{\underline h, 1.5, 2.25, 3.4\}\underline h$; $s$: 30 points; $n_m \in \{1..N\}$; $\iota_c$: 1 (SRCE) or 2 (transition) |
335 +| Solver | Backward induction over $j$; for each discrete branch, EGM on $a'$ with the discrete-choice upper envelope (Fella 2014 / Iskhakov et al. 2017 taste-shock smoothing with scale $\sigma_\epsilon \to$ small, reported); mortgage $B'$ on a grid at origination (LTV and DSTI corners included); refinancing as a branch |
336 +| Distribution | Non-stochastic simulation (Young 2010 histogram) on the state grid, with the dynasty link implemented as a transfer kernel from age-$j_g$ (and $J$) states to age-1 (and $j_e$) states; fallback: Monte-Carlo panel of 200 000 dynasties with fixed seeds for the mobility statistics |
337 +| Prices | Outer loop on $(p, p^r)$ with damped Broyden on the two excess-demand functions; inner loop solves households and the distribution; tolerance $10^{-5}$ on relative excess demand; report both residuals |
338 +| Transition | $T = 40$ periods; sequence-space shooting on $\{p_t, p^r_t\}$ (Newton/Broyden on the stacked excess demands, Jacobian by finite differences from the SRCE), backward household solution with time-varying prices, forward distribution |
339 +| Statistics | Ownership threshold: smallest $a_1$ at which the age-1 policy is "buy", by $z_1$; mobility: $\Pr(\text{child owns at } j = 3 \mid \text{parent tenure at } j_g)$, rank–rank slope of net worth at age $j_g$; inequality: Gini and owner/renter median net-worth ratio by age; welfare: consumption-equivalent variation $\lambda^{CE}$ defined by $V^{\text{alt}}_1(x) = V^{\text{base}}_1(x;\ c \cdot (1+\lambda^{CE}))$ at age 1, by transfer quantile |
340 +| Diagnostics | Bellman residuals, Euler errors in constrained/unconstrained states, mass at forced sale, grid sensitivity (double grids), tolerance sensitivity, seed sensitivity |
341 +
342 +## B.13 Mapping between Part A and Part B
343 +
344 +| Part A object | Part B counterpart |
345 +|---|---|
346 +| stages 1–3 | ages 1–$J$ with the purchase typically at $j \in \{1,2,3\}$, amortisation over $N$, sale at $J$ |
347 +| $a$ (amortisation share) | constant-payment schedule; $\omega$ (share not repriced) | FRM / ARM / term-$k$ |
348 +| HTM assumption A4 | binding $a' = 0$ at the purchase age (to be verified in the solved model, not assumed) |
349 +| $\hat b$ | smallest $a_1$ such that the age-1 (or age-2) policy is "buy", given $z_1$ |
350 +| $\lambda$ | parent–child correlation of the ownership indicator at age $j_g$ |
351 +| $e_3 p$ | net housing equity at $J$ |
352 +| $S$, $S_r$ per cohort | stock-flow construction with $\delta_H$ |
353 +| Proposition 9 (impact) | first period of the MIT transition |
354 +
modified research/progress.md +9 −0
@@ -14,3 +14,12 @@
14 14 - Verdicts de nouveauté : (i) seuil d'accession — **incrémental** (Ortalo-Magné & Rady 2006, KMV 2020, FLVN 2017 ; nouveau = héritage + secteur locatif + caractérisation analytique conditionnelle à la segmentation/offre) ; (ii) persistance — **nouveau en théorie, établi empiriquement** (Daysal et al. 2023, Charles & Hurst 2002 ; multiplicité à ne pas promettre) ; (iii) inflation surprise — **incrémental** sur la revalorisation directe (Doepke-Schneider, GKS 2017, Meh et al. 2010), **potentiellement nouveau** sur la marge d'entrée et le terme de 5 ans canadien ; (iv) offre × contrat → mobilité — **incrémental** (KMN 2011, Grossmann et al. 2021, Chambers et al. 2009), nouveau seulement comme statique comparative d'une mesure de mobilité.
15 15 - Blocages : aucune source vérifiée d'élasticité de l'offre canadienne (paramètre illustratif à prévoir) ; « Uzeda » et « Alexander & Bazel » à préciser par l'auteur ; Muellbauer et al. 2015 (BoC) à revérifier pour la calibration.
16 16 - Prochaines étapes : Phase 2 (spécification du modèle, agent parallèle) doit (1) rendre explicite le paramètre de segmentation propriétaire/locatif et l'élasticité de l'offre, (2) tenir le processus de revenus fixe entre quantiles d'héritage dans la base, (3) prévoir trois contrats (FRM long, FRM renouvelable 5 ans, ARM) et deux régimes d'indexation des loyers pour toute expérience d'inflation, (4) formuler (ii) comme distribution stationnaire à deux classes de tenure avec demi-vie, sans promettre la multiplicité.
17 +
18 +## 2026-10-20 — Phase 2 (modèle, propositions, preuves, benchmark 2-3 périodes) : FAIT
19 +- **Modèle** : `research/model_specification.md` (≈7 300 mots). Partie A = benchmark à trois étapes de vie (acheteur / payeur / vendeur-donateur) et générations de deux périodes, transfert inter vivos reçu au moment de l'achat, demande unitaire de logement, hypothèque nominale (principal `B_nom = P(1-θ)p`, amortissement `a` à l'étape 2, FRM vs ARM/terme renouvelé), dépôts nominaux, prêteur risque-neutre (résidu des réévaluations), marchés propriétaire et locatif segmentés avec élasticités `ε`, `ε_r`, indexation salaires/loyers `η_w`, `η_ρ`. Partie B = modèle OLG complet directement implémentable (J = 12 périodes de 5 ans, revenu de Markov Rouwenhorst, tailles de logement avec minimum, hypothèques nominales à paiement constant sur N périodes, FRM/ARM/terme-k, refinancement, LTV + DSTI nominal, don à j_g = 7 et succession à J, bailleurs avec arbitrage et paramètre de segmentation σ, construction stock-flux, prêteur avec bilan, ERC stationnaire + transition MIT, états/grilles/EGM/Young/Broyden, statistiques de mobilité et bien-être).
20 +- **Propositions et preuves** : `paper/appendix_proofs.tex` (amsthm : 6 hypothèses, 2 lemmes, 9 propositions, 1 corollaire, 3 remarques de lacunes ; compilable seul via `cd paper && latexmk -pdf appendix_proofs_standalone.tex`, 12 p., 0 référence non définie ; artefacts nettoyés, PDF non commité conformément à HARMONISATION §2). Résumé des statuts : `research/propositions.md`. Hypothèses abandonnées/affaiblies : `research/failed_hypotheses.md`.
21 +- **Résultats analytiques** : (1) seuil d'accession fermé `b̂ = (dp − Λρ)/(1−Λ) − y_1` = borne de faisabilité + composante de préférence (consommation du marginal) ; (2) signes : ↑ en p, θ, κ_b, κ_s, m, π̄ anticipée (effet de « tilt »), ↓ en ρ, χ, y_1 — tous des effets de liquidité (neutres pour un ménage non contraint, Prop. 3) ; (4) multiplicateur de levier `(1−κ_s)/d`, seuil de croissance d'équilibre `g*` **indépendant du LTV**, seuil de dette négative `x*` ; (5) persistance intergénérationnelle fermée `λ = G(ŷ_R) − G(ŷ_R − e_3 p)` = corrélation de tenure parent-enfant, demi-vie, nulle si la maison n'est pas une richesse nette en fin de vie ; (6) existence de l'équilibre stationnaire (TVI) et unicité sous la condition de dominance (C) ; corollaire offre fixe (taux de propriété figé, prix et composition absorbent tout) ; (7) neutralité des prix sans segmentation ; (8) comptabilité de l'inflation surprise : FRM = ARM pour une surprise de niveau, FRM > ARM pour une surprise persistante, l'ARM perd à l'étape 3 ssi φ_r > R, identité à somme nulle avec le prêteur, condition exacte de gain ; (9) impact GE d'une surprise : dp ≥ 0, dρ ≤ 0, dμ ≥ 0 (= 0 à stock fixe : effet de composition pur), seuil ↑, mobilité ascendante q_RO ↓, persistance λ ↑, vendeurs gagnants, nouveaux acheteurs perdants possibles.
22 +- **Benchmark numérique** : `src/toy_model.py` (formules fermées HTM, optimiseur général pour *vérifier* A4 et non la supposer, chaîne dynastique, équilibre stationnaire, comptabilité, impact GE, simulation myope diagnostique) ; `tests/test_toy_model.py` : **44 tests passent** (`.venv/bin/python -m pytest tests/` ; venv `.venv` avec numpy 2.5.4, scipy 1.18.1, pytest 9.1.1 épinglés dans `requirements.txt`) : identités budgétaires état par état (2 tenures × 2 contrats × 3 surprises × 2 expériences), trajectoire dette nominale/réelle, identité de Fisher, seuil fermé = seuil optimisé (1e-14), inégalités d'Euler strictes sur le support des transferts, croisement unique, signes des 9 statiques comparatives, chaîne de Markov (valeur propre, distribution stationnaire), apurement des deux marchés, condition (C), offre fixe, non-segmentation, somme nulle, ordre FRM/ARM, signes d'impact, impact croissant quand l'offre est moins élastique, transition myope = impact puis retour.
23 +- **Résultats surprenants ou négatifs** : le seuil de croissance d'équilibre ne dépend pas du levier ; la persistance par classes absorbantes est un cas limite sans risque (remplacée par une demi-vie) ; sans segmentation, ni crédit, ni héritage, ni inflation ne bougent les prix ; les effets GE d'une surprise de 10 % sont minuscules dans le benchmark (dp = +0,03 %) parce que le prix absorbe le déplacement de demande ; une version à deux périodes a été abandonnée (hypothèque-ballon ⇒ richesse immobilière nette négative) ; la simulation myope montre une oscillation d'éviction entre cohortes (unités détenues deux périodes, valeur propre ≈ −1) à surveiller en Phase 3.
24 +- **Hypothèses fortes** : A4 (ménages contraints à la marge, vérifiée numériquement dans le benchmark mais à vérifier dans le modèle complet), A6 (anticipations statiques pour l'impact), demande unitaire de logement, prêteur extérieur au système dynastique, offre « par période » en Partie A.
25 +- **Prochaines étapes (Phase 3)** : implémenter la Partie B selon §B.9–B.12 ; vérifier A4 au seuil, le croisement unique pour les épargnants, la condition (C) le long de la courbe d'apurement et chercher des équilibres multiples sous offre quasi fixe ; transition à anticipations parfaites avec stock durable ; expériences 1–10 du CLAUDE.md ; ne jamais étiqueter GE un résultat à prix fixes.
added research/propositions.md +71 −0
@@ -0,0 +1,71 @@
1 +# WP18 — Propositions: statements, status, intuition, and what the simulations must check
2 +
3 +Phase 2 deliverable (2026-10-20). Formal statements and proofs: `paper/appendix_proofs.tex` (compiles stand-alone via `paper/appendix_proofs_standalone.tex`, 12 pp., no undefined references). Model: `research/model_specification.md`. Numerical verification of every identity and sign: `src/toy_model.py` + `tests/test_toy_model.py` (44 tests, all passing). Illustrative benchmark numbers below come from `Params()` in `src/toy_model.py` and carry no calibration claim.
4 +
5 +Status codes: **P** = proved under the stated assumptions; **P-strong** = proved but under a strong/knife-edge assumption that the numerical model must relax; **C** = conjecture or partial result with an explicit proof gap; **N** = negative result (hypothesis from the brief that does *not* hold in general).
6 +
7 +| # | Result | Status | Key assumptions |
8 +|---|---|---|---|
9 +| L1 | Stage-3 split: $c_3 = W_3/(1+\nu)$, $b' = \nu W_3/(1+\nu)$ | P | log warm glow |
10 +| L2 | HTM corner (max LTV, no deposits) is optimal; closed-form values | P | A4 strict Euler inequalities (verified numerically, not assumed, in the benchmark) |
11 +| 1 | Ownership threshold $\hat b = (dp-\Lambda\rho)/(1-\Lambda) - y_1$, unique, above feasibility bound | P on the HTM region; **C** outside it (single crossing not proved for savers) | A1–A5 |
12 +| 2 | Signs: $\hat b$ ↑ in $p,\theta,\kappa_b,\kappa_s,m,\bar\pi$; ↓ in $\rho,\chi,y_1$ | P | A4, $r \ge 0$ |
13 +| 3 | Anticipated inflation: PV-neutral tilt; raises $\hat b$ for constrained households; neutral (with $\theta$) for unconstrained | P | A4 for (i); slack constraints for (ii) |
14 +| 4 | Leverage multiplier $(1-\kappa_s)/d$; break-even growth $g^*$ independent of $\theta$, increasing in costs; underwater threshold $x^*$ | P | accounting only |
15 +| 5 | Dynasty chain: $q_{RO}, q_{OO}$ closed form; persistence $\lambda = G(\hat y_R) - G(\hat y_R - e_3p)$ = parent–child tenure correlation; half-life; $\lambda > 0$ iff $e_3 > 0$; equal-income transfer gap $\nu e_3 p/(1+\nu)$ | P | HTM on the transfer support; i.i.d. $y_3$ |
16 +| 6 | Stationary GE exists; unique under dominance condition (C) | P (existence); P under (C) (uniqueness) | A1–A5 along the clearing curve |
17 +| 6c | Fixed stock: ownership rate pinned by supply; LTV/transfers only move price and composition | P | (C) |
18 +| 7 | No segmentation ⇒ price and rent independent of credit, transfers, inflation (KMV neutrality) | P | unit demand, costless conversion |
19 +| 8 | Surprise accounting: erosion factors by contract (FRM = ARM for a level surprise; FRM > ARM for a persistent one; ARM loses at stage 3 iff $\phi_r > R$); zero-sum with lender; owner gains iff explicit condition (wage indexation, deposits) | P | fixed real prices |
20 +| 9 | GE impact of a level surprise: $dp \ge 0$, $d\rho \le 0$, $d\mu \ge 0$ (= 0 if fixed stock: pure composition), $d\hat b \ge 0$, $q_{RO}$ ↓, $q_{OO}$ ↑, $\lambda$ ↑; sellers gain; new buyers in inelastic markets can lose | **P-strong** | A6 static expectations; per-period supply; condition (C′) |
21 +| — | Multiple stationary equilibria (Stein-type ladder multiplicity) | **C** — not established; possible only if (C) fails | — |
22 +| — | Full perfect-foresight transition after a surprise | **C** — numerical only | — |
23 +| — | "Inflation raises real house prices" | **N** in general: sign tied to $g(\hat y_O)$, segmentation, contract and supply; zero without segmentation | — |
24 +| — | "Inflation enriches every owner" | **N**: ARM with $\phi_r > R$, unindexed wages, nominal savers, and new buyers in inelastic markets lose | — |
25 +| — | Persistence via absorbing tenure classes / path dependence | **N** as a generic result: knife-edge of no income risk (Remark in appendix); replaced by half-life | — |
26 +
27 +## Proposition-by-proposition notes
28 +
29 +### Proposition 1 — Ownership-entry threshold
30 +*Statement.* Own iff $b \ge \hat b = (dp - \Lambda\rho)/(1-\Lambda) - y_1$, with $\Lambda = e^{-\Delta}$ and $\Delta$ the utility premium of ownership after the purchase (stage-2 cash-flow comparison plus stage-3 housing equity). The threshold exceeds the feasibility bound $dp - y_1$ by $\Lambda(dp-\rho)/(1-\Lambda)$ = the stage-1 consumption of the marginal buyer.
31 +*Intuition.* A liquidity-constrained household compares the certain cut in current consumption needed for the down payment and costs with the discounted future advantage of owning; only households rich enough that the marginal utility of current consumption is low accept the cut. Bequests enter one-for-one; price enters through the outlay and through the equity carried forward.
32 +*Benchmark.* $\hat b = 0.999$ (units of stage-1 income $y_1 = 1$) at $p = 1.203$, $\rho = 0.348$; feasibility bound $0.456 - 1 < 0$; $\Delta = 0.069$. The closed form equals the threshold obtained by brute-force optimisation to $10^{-14}$.
33 +*Simulation must check.* In the full model the threshold is the smallest $a_1$ at which the age-1 policy is "buy" for each $z_1$; verify it is increasing in $p$, $\theta$, costs and decreasing in $\rho$ at *equilibrium* prices (Proposition 2 is partial equilibrium in $\rho$), and whether the ordering survives when the household can save first and buy at age 2–3 (Remark: proof gap outside HTM).
34 +
35 +### Proposition 2 — Comparative statics
36 +*Intuition.* All signs are liquidity effects: a higher down payment or more front-loaded real payments (higher $\bar\pi$) are present-value neutral but shift resources from the constrained young to the unconstrained old. The proof bounds the stage-3 equity term by the Euler inequalities; $r \ge 0$ guarantees that the price effect on the outlay dominates the price effect on future equity.
37 +*Simulation must check.* Magnitudes (benchmark: $\partial\hat b/\partial\theta = 9.8$, $\partial\hat b/\partial p = 7.3$, $\partial \hat b/\partial\bar\pi = 1.2$ per unit); whether $\partial\hat b/\partial p$ stays positive with an intensive housing margin (bigger houses at higher $p$ could change the ladder term).
38 +
39 +### Proposition 3 — Tilt vs neutrality
40 +*Intuition.* Nominal contracts front-load real payments when expected inflation is higher; this is irrelevant to a household that can re-time consumption with deposits, and costly to one that cannot. The same holds for the down payment.
41 +*Simulation must check.* In Part B the tilt operates through the payment-to-income constraint and the constant-nominal-payment schedule; verify that raising $\bar\pi$ lowers ownership at ages 1–3 in partial equilibrium, and trace the GE offset through $p$ and $\rho$.
42 +
43 +### Proposition 4 — Leverage with costs
44 +*Intuition.* Leverage multiplies the exposure of terminal wealth to the resale price (multiplier $(1-\kappa_s)/d = 2.5$ in the benchmark) but does not change the break-even growth rate, which depends on costs and the rent–price ratio only. In the benchmark $g^* = -0.27$ (rent is high relative to user cost) and the underwater threshold is a 63 % price fall. The owner–renter wealth gap among equal-income HTM households is $e_3 p = 0.72$ and the transfer gap $0.17$.
45 +*Simulation must check.* Experiment 5 (negative price shocks, LTV sweeps): the dispersion of terminal wealth across inheritance quantiles should scale with the multiplier; the sign of the mean owner–renter gap should flip at $g^*$ when the renter is allowed to invest the down payment (experiment 2, "renter investment return").
46 +
47 +### Proposition 5 — Persistence
48 +*Intuition.* Owner-parents bequeath $e_3 p$ more; their children clear the threshold for a wider range of income draws. Persistence is the probability mass of income draws for which the parental housing equity is pivotal. It is zero if the house is not net wealth at the end of life (no amortisation, high selling costs, low down payment).
49 +*Benchmark.* $q_{RO} = 0.56$, $q_{OO} = 0.78$, $\lambda = 0.23$, half-life 0.47 generations, $\mu^* = 0.72$.
50 +*Simulation must check.* Parent–child tenure correlation and rank–rank slope of net worth with and without bequests (experiment 6); monotonicity of $\lambda$ in amortisation $a$, $\theta$ (ambiguous in theory: $\theta$ raises both $e_3$ and $\hat b$), and $p$; whether persistence is much higher when income shocks are persistent across generations ($\rho_g > 0$, experiment 8).
51 +
52 +### Proposition 6 and Corollary — Stationary equilibrium
53 +*Intuition.* Higher ownership raises the price and lowers the rent, both of which raise the threshold and reduce the next generation's ownership (the stabilising channel); but a higher price also raises the equity incumbents bequeath (the ladder channel). Uniqueness holds if the first dominates (condition (C), satisfied by a wide margin in the benchmark: 31 vs 0). With a fixed stock, credit relaxation only raises the price and reshuffles who owns.
54 +*Simulation must check.* Experiment 3 and 7: search for multiple equilibria by starting the price iteration from several initial prices under near-fixed supply and high $e_3$; report the sign of $d\mu^*/dp$ along the clearing curve.
55 +
56 +### Proposition 7 — No segmentation
57 +*Intuition.* With a single stock and costless conversion, tenure is a pure portfolio choice that does not change the number of units demanded, so credit, bequests and inflation cannot move the price. This is the Kaplan–Mitman–Violante / Greenwald–Guren lesson restated; the feedback results of WP18 are statements about segmentation and supply.
58 +*Simulation must check.* Run the baseline at $\sigma = 0$ and $\sigma = 1$ (B.6); with an intensive margin the neutrality is only approximate — quantify.
59 +
60 +### Proposition 8 — Revaluation accounting
61 +*Intuition.* A surprise erodes every nominal payment fixed before it. A level surprise erodes all remaining FRM and ARM payments equally (the ARM reset rate is unchanged); a persistent surprise is recovered by the lender on ARM payments after the reset; a real-rate response can make ARM borrowers lose. Deposits lose symmetrically; unindexed wages lose; rent rigidity transfers from landlords to sitting tenants. The lender bears the mirror image.
62 +*Benchmark (10 % surprise).* Age-2 owner gains 0.049 (stage 2) + 0.038 (stage 3, level) or 0.073 (FRM, persistent) in units of $y_1$; lender loses 0.126 (level) / 0.161 (FRM persistent); ARM with $\phi_r = 2 > R = 1.1$ loses 0.031 at stage 3; with $\eta_w = 0$ the owner's net is $-0.185$.
63 +*Simulation must check.* Experiment 4 with the three contracts (long FRM, five-year term, ARM) and two rent regimes; the zero-sum identity state by state; the distribution of gains by age and tenure (compare with Meh–Terajima).
64 +
65 +### Proposition 9 — GE impact
66 +*Intuition.* Eroded debt of stage-3 owners becomes larger transfers, more owner-dynasty children qualify, the price rises and the rent falls, the threshold rises, and renter-dynasty children at the margin are displaced: inflation lowers upward tenure mobility and raises persistence, with no change in the ownership rate if the stock is fixed. Sellers gain twice; new buyers can lose.
67 +*Benchmark (10 % surprise, $\varepsilon = \varepsilon_r = 1$).* $dp = +0.03$ %, $d\rho = -0.06$ %, $d\mu = +0.03$ pp, $d\hat b = +0.6$ %, $q_{RO}$ 0.559 → 0.550, $\lambda$ 0.226 → 0.238; with $\varepsilon = 0$: $d\mu = 0$, $dp = +0.05$ %. The effects are small because the eroded payment is small relative to $W_3$ and the price absorbs most of the shift (demand is very price-elastic under static expectations).
68 +*Simulation must check.* The full perfect-foresight transition with a durable stock (A6 removed); second-round effects through the cohort aged 2 (contract-dependent); the alternating cohort-crowding dynamics found in the myopic simulation; welfare of marginal households (not signed in theory); whether the mobility effect survives when prices are forward-looking.
69 +
70 +## Numbers that the numerical phase must *not* take from here
71 +All numbers above are from illustrative parameters (stage lengths unequal in spirit, $R = 1.1$ per stage, Beta-distributed $y_3$). They verify signs and identities only.
added src/toy_model.py +630 −0
@@ -0,0 +1,630 @@
1 +"""WP18 — Part A benchmark model (three-stage lifecycle, two-period generations).
2 +
3 +Implements the closed-form hand-to-mouth (HTM) solution of `research/model_specification.md`
4 +(Part A) and the objects used by the propositions of `paper/appendix_proofs.tex`:
5 +
6 +* mortgage schedule (FRM / ARM, level or persistent surprise), real payments D2, D3;
7 +* ownership premium Delta, Lambda = exp(-Delta), entry threshold b_hat (Proposition 1);
8 +* HTM value functions and a general numerical household problem used to *verify*
9 + that the HTM corner is optimal (Assumption A4) rather than to assume it;
10 +* dynasty transition probabilities, persistence lambda, stationary owner share (Prop. 5);
11 +* stationary general equilibrium with segmented owner / rental markets (Prop. 6);
12 +* leverage statistics (Prop. 4);
13 +* surprise-inflation accounting, FRM vs ARM, level vs persistent (Prop. 8);
14 +* impact general-equilibrium response to a surprise (Prop. 9) and a myopic-expectations
15 + transition simulation (diagnostic only — not covered by a proposition).
16 +
17 +Units: one model period = one stage of life; all flows real (consumption units); the house
18 +price p and rent rho are per unit of housing; nominal principal B_nom = P * (1-theta) * p.
19 +Parameters are illustrative (no calibration claim).
20 +"""
21 +from __future__ import annotations
22 +
23 +from dataclasses import dataclass, replace
24 +from typing import Literal
25 +
26 +import numpy as np
27 +from scipy import optimize, stats
28 +
29 +Contract = Literal["FRM", "ARM"]
30 +Experiment = Literal["level", "persistent"]
31 +
32 +
33 +# --------------------------------------------------------------------------------------
34 +# Parameters
35 +# --------------------------------------------------------------------------------------
36 +@dataclass(frozen=True)
37 +class Params:
38 + # preferences
39 + beta: float = 0.80 # discount factor per stage
40 + nu: float = 0.30 # warm-glow weight: transfer share nu/(1+nu) of end-of-life wealth
41 + chi: float = 0.02 # ownership utility premium (utils, stage 1 + 2 combined)
42 + # incomes (real, per stage); y3 ~ y_lo + (y_hi - y_lo) * Beta(a_y, b_y)
43 + y1: float = 1.0
44 + y2: float = 3.0
45 + y3_lo: float = 2.0
46 + y3_hi: float = 7.0
47 + y3_a: float = 2.5
48 + y3_b: float = 2.5
49 + # housing finance and costs
50 + theta: float = 0.30 # minimum down-payment share (max LTV = 0.70)
51 + kappa_b: float = 0.03 # buying cost (share of price)
52 + kappa_s: float = 0.05 # selling cost (share of price)
53 + m: float = 0.05 # maintenance per stage (share of price)
54 + amort: float = 0.50 # share of principal amortised at stage 2
55 + # rates and inflation
56 + r: float = 0.10 # real rate per stage
57 + pibar: float = 0.10 # steady-state inflation per stage
58 + # supply curves (per cohort): S(p) = Hbar p^eps ; S_r(rho) = Hbar_r rho^eps_r
59 + Hbar: float = 0.60
60 + eps: float = 1.0
61 + Hbar_r: float = 0.80
62 + eps_r: float = 1.0
63 + # indexation of nominal wages / rents to a surprise (1 = full)
64 + eta_w: float = 1.0
65 + eta_rho: float = 1.0
66 + # quadrature nodes for expectations over y3
67 + n_quad: int = 64
68 +
69 + @property
70 + def R(self) -> float:
71 + return 1.0 + self.r
72 +
73 + @property
74 + def d(self) -> float:
75 + """Stage-1 cash outlay per unit of price: down payment + buying cost + maintenance."""
76 + return self.theta + self.kappa_b + self.m
77 +
78 +
79 +# --------------------------------------------------------------------------------------
80 +# Income distribution G (stage-3 income) — bounded support, smooth density
81 +# --------------------------------------------------------------------------------------
82 +def y3_dist(par: Params):
83 + return stats.beta(par.y3_a, par.y3_b, loc=par.y3_lo, scale=par.y3_hi - par.y3_lo)
84 +
85 +
86 +def y3_quad(par: Params):
87 + """Gauss–Legendre nodes/weights for E[f(y3)] with y3 ~ G on [y_lo, y_hi]."""
88 + x, w = np.polynomial.legendre.leggauss(par.n_quad)
89 + lo, hi = par.y3_lo, par.y3_hi
90 + y = lo + (hi - lo) * (x + 1) / 2
91 + pdf = y3_dist(par).pdf(y)
92 + wts = w * (hi - lo) / 2 * pdf
93 + wts = wts / wts.sum() # renormalise (quadrature error of the density integral)
94 + return y, wts
95 +
96 +
97 +def E_y3(par: Params, f) -> float:
98 + y, w = y3_quad(par)
99 + return float(np.sum(w * f(y)))
100 +
101 +
102 +def G(par: Params, y) -> np.ndarray | float:
103 + return y3_dist(par).cdf(y)
104 +
105 +
106 +def g(par: Params, y) -> np.ndarray | float:
107 + return y3_dist(par).pdf(y)
108 +
109 +
110 +# --------------------------------------------------------------------------------------
111 +# Mortgage schedule
112 +# --------------------------------------------------------------------------------------
113 +def nominal_rate(par: Params, pi_e: float, r: float | None = None) -> float:
114 + """Fisher: 1 + i = R (1 + pi_e)."""
115 + R = par.R if r is None else 1.0 + r
116 + return R * (1.0 + pi_e) - 1.0
117 +
118 +
119 +def real_payments(par: Params, p: float, *, pi1: float, pi2: float, pi_e1: float, pi_e2: float,
120 + contract: Contract = "FRM", r2: float | None = None,
121 + principal_share: float | None = None) -> tuple[float, float]:
122 + """Real stage-2 and stage-3 payments of a mortgage originated at price p.
123 +
124 + pi1, pi2 : realised inflation over (t, t+1) and (t+1, t+2)
125 + pi_e1 : inflation expected at origination for (t, t+1) -> fixes i_1 for all contracts
126 + pi_e2 : inflation expected at t+1 for (t+1, t+2) -> ARM reset rate
127 + r2 : real rate used at the ARM reset (None = par.r)
128 + """
129 + B = ((1.0 - par.theta) if principal_share is None else principal_share) * p
130 + i1 = nominal_rate(par, pi_e1)
131 + if contract == "FRM":
132 + i2 = i1
133 + elif contract == "ARM":
134 + i2 = nominal_rate(par, pi_e2, r2)
135 + else:
136 + raise ValueError(contract)
137 + D2 = (i1 + par.amort) * B / (1.0 + pi1)
138 + D3 = (1.0 + i2) * (1.0 - par.amort) * B / ((1.0 + pi1) * (1.0 + pi2))
139 + return D2, D3
140 +
141 +
142 +def stationary_schedule(par: Params) -> tuple[float, float, float]:
143 + """(delta2, delta3, e3): payments per unit of price and net equity share at sale."""
144 + D2, D3 = real_payments(par, 1.0, pi1=par.pibar, pi2=par.pibar, pi_e1=par.pibar, pi_e2=par.pibar)
145 + e3 = (1.0 - par.kappa_s) - D3
146 + return D2, D3, e3
147 +
148 +
149 +# --------------------------------------------------------------------------------------
150 +# HTM closed forms (Part A, §A.5–A.6)
151 +# --------------------------------------------------------------------------------------
152 +def ownership_premium(par: Params, p: float, rho: float, *, p_sale: float | None = None,
153 + rho2: float | None = None, D2: float | None = None, D3: float | None = None) -> float:
154 + """Delta = chi + beta E[ln c2^O - ln c2^R] + beta^2 (1+nu) E[ln W3^O - ln W3^R] under HTM."""
155 + p_sale = p if p_sale is None else p_sale
156 + rho2 = rho if rho2 is None else rho2
157 + if D2 is None or D3 is None:
158 + d2, d3, _ = stationary_schedule(par)
159 + D2 = d2 * p if D2 is None else D2
160 + D3 = d3 * p if D3 is None else D3
161 + c2O = par.y2 - D2 - par.m * p
162 + c2R = par.y2 - rho2
163 + if c2O <= 0 or c2R <= 0:
164 + raise ValueError("Assumption A3 violated: non-positive stage-2 consumption")
165 + eq3 = (1.0 - par.kappa_s) * p_sale - D3
166 + if par.y3_lo + eq3 <= 0:
167 + raise ValueError("Assumption A3 violated: owner end-of-life wealth can be negative")
168 + term3 = E_y3(par, lambda y: np.log(y + eq3) - np.log(y))
169 + return par.chi + par.beta * (np.log(c2O) - np.log(c2R)) + par.beta**2 * (1 + par.nu) * term3
170 +
171 +
172 +def threshold(par: Params, p: float, rho: float, **kw) -> float:
173 + """Ownership-entry threshold b_hat (Proposition 1). Returns -inf-like value if nobody is excluded."""
174 + Delta = ownership_premium(par, p, rho, **kw)
175 + d = par.d
176 + b_min = d * p - par.y1
177 + if Delta <= 0:
178 + return np.inf # nobody owns (A5 fails): owning is dominated at every wealth level
179 + Lam = np.exp(-Delta)
180 + if d * p <= rho:
181 + return b_min
182 + return (d * p - Lam * rho) / (1.0 - Lam) - par.y1
183 +
184 +
185 +def value_htm(par: Params, b: float, p: float, rho: float, tenure: Literal["O", "R"], **kw) -> float:
186 + """Lifetime value of a hand-to-mouth household (n1 = n2 = 0, max mortgage if owner)."""
187 + K = par.beta**2 * (par.nu * np.log(par.nu) - (1 + par.nu) * np.log(1 + par.nu))
188 + d2, d3, _ = stationary_schedule(par)
189 + D2 = kw.get("D2", d2 * p)
190 + D3 = kw.get("D3", d3 * p)
191 + p_sale = kw.get("p_sale", p)
192 + rho2 = kw.get("rho2", rho)
193 + if tenure == "O":
194 + c1 = b + par.y1 - par.d * p
195 + if c1 <= 0:
196 + return -np.inf
197 + c2 = par.y2 - D2 - par.m * p
198 + eq3 = (1 - par.kappa_s) * p_sale - D3
199 + return (np.log(c1) + par.chi + par.beta * np.log(c2)
200 + + par.beta**2 * (1 + par.nu) * E_y3(par, lambda y: np.log(y + eq3)) + K)
201 + c1 = b + par.y1 - rho
202 + if c1 <= 0:
203 + return -np.inf
204 + c2 = par.y2 - rho2
205 + return (np.log(c1) + par.beta * np.log(c2)
206 + + par.beta**2 * (1 + par.nu) * E_y3(par, lambda y: np.log(y)) + K)
207 +
208 +
209 +def htm_slack(par: Params, b: float, p: float, rho: float, tenure: Literal["O", "R"]) -> tuple[float, float]:
210 + """Euler-inequality slacks (Assumption A4): positive values mean the household would like
211 + to borrow more at stage 1 and at stage 2 (so n1 = n2 = 0 is the optimum)."""
212 + d2, d3, e3 = stationary_schedule(par)
213 + R = par.R
214 + if tenure == "O":
215 + c1 = b + par.y1 - par.d * p
216 + c2 = par.y2 - d2 * p - par.m * p
217 + EW3inv = E_y3(par, lambda y: 1.0 / (y + e3 * p))
218 + else:
219 + c1 = b + par.y1 - rho
220 + c2 = par.y2 - rho
221 + EW3inv = E_y3(par, lambda y: 1.0 / y)
222 + s1 = 1.0 / c1 - par.beta * R * (1.0 / c2) # stage 1 vs 2 (c2 deterministic)
223 + s2 = 1.0 / c2 - par.beta * R * (1 + par.nu) * EW3inv # stage 2 vs 3
224 + return s1, s2
225 +
226 +
227 +# --------------------------------------------------------------------------------------
228 +# General (non-HTM) household problem — numerical, used to verify the corner solution
229 +# --------------------------------------------------------------------------------------
230 +def value_general(par: Params, b: float, p: float, rho: float, tenure: Literal["O", "R"],
231 + return_policy: bool = False):
232 + """Owner chooses mortgage share phi in [0, 1-theta], savings n1 >= 0, n2 >= 0.
233 + Renter chooses n1 >= 0, n2 >= 0. Stage-3 split by Lemma 1. Returns the max value."""
234 + y, w = y3_quad(par)
235 + K = par.beta**2 * (par.nu * np.log(par.nu) - (1 + par.nu) * np.log(1 + par.nu))
236 + R = par.R
237 +
238 + def obj_owner(x):
239 + phi, n1, n2 = x
240 + D2, D3 = real_payments(par, p, pi1=par.pibar, pi2=par.pibar, pi_e1=par.pibar, pi_e2=par.pibar,
241 + principal_share=phi)
242 + c1 = b + par.y1 - (par.theta + par.kappa_b + par.m) * p - ((1 - par.theta) - phi) * p - n1
243 + c2 = par.y2 - D2 - par.m * p + n1 * R - n2
244 + W3 = y + (1 - par.kappa_s) * p - D3 + n2 * R
245 + if c1 <= 1e-9 or c2 <= 1e-9 or np.any(W3 <= 1e-9):
246 + return 1e6
247 + return -(np.log(c1) + par.chi + par.beta * np.log(c2)
248 + + par.beta**2 * (1 + par.nu) * np.sum(w * np.log(W3)) + K)
249 +
250 + def obj_renter(x):
251 + n1, n2 = x
252 + c1 = b + par.y1 - rho - n1
253 + c2 = par.y2 - rho + n1 * R - n2
254 + W3 = y + n2 * R
255 + if c1 <= 1e-9 or c2 <= 1e-9 or np.any(W3 <= 1e-9):
256 + return 1e6
257 + return -(np.log(c1) + par.beta * np.log(c2)
258 + + par.beta**2 * (1 + par.nu) * np.sum(w * np.log(W3)) + K)
259 +
260 + best = None
261 + if tenure == "O":
262 + bounds = [(0.0, 1 - par.theta), (0.0, 5.0), (0.0, 5.0)]
263 + starts = [(1 - par.theta, 0.0, 0.0), (0.5 * (1 - par.theta), 0.1, 0.1), (0.0, 0.0, 0.5)]
264 + f = obj_owner
265 + else:
266 + bounds = [(0.0, 5.0), (0.0, 5.0)]
267 + starts = [(0.0, 0.0), (0.2, 0.2), (0.0, 1.0)]
268 + f = obj_renter
269 + for x0 in starts:
270 + res = optimize.minimize(f, np.array(x0), bounds=bounds, method="L-BFGS-B")
271 + if res.fun < 1e5 and (best is None or res.fun < best.fun):
272 + best = res
273 + if best is None:
274 + return (-np.inf, None) if return_policy else -np.inf
275 + return (-best.fun, best.x) if return_policy else -best.fun
276 +
277 +
278 +def threshold_general(par: Params, p: float, rho: float) -> float:
279 + """Threshold from the general (numerically optimised) values; verifies Proposition 1."""
280 + lo = par.d * p - par.y1 + 1e-6
281 + hi = lo + 10.0
282 + f = lambda b: value_general(par, b, p, rho, "O") - value_general(par, b, p, rho, "R")
283 + if f(hi) < 0:
284 + return np.inf
285 + if f(lo) > 0:
286 + return lo
287 + return optimize.brentq(f, lo, hi, xtol=1e-8)
288 +
289 +
290 +# --------------------------------------------------------------------------------------
291 +# Dynasties and persistence (Proposition 5)
292 +# --------------------------------------------------------------------------------------
293 +def transitions(par: Params, p: float, rho: float, b_hat: float | None = None, *,
294 + eq3: float | None = None) -> dict:
295 + """q_RO, q_OO, lambda, stationary owner share mu* for given prices.
296 + eq3 = owner's net housing equity at sale (default e3 p)."""
297 + if b_hat is None:
298 + b_hat = threshold(par, p, rho)
299 + _, _, e3 = stationary_schedule(par)
300 + eq3 = e3 * p if eq3 is None else eq3
301 + yR = (1 + par.nu) / par.nu * b_hat
302 + yO = yR - eq3
303 + qRO = 1.0 - float(G(par, yR)) if np.isfinite(b_hat) else 0.0
304 + qOO = 1.0 - float(G(par, yO)) if np.isfinite(b_hat) else 0.0
305 + lam = qOO - qRO
306 + mu_star = qRO / (1.0 - lam) if (1.0 - lam) > 0 else 1.0
307 + half_life = np.log(2) / (-np.log(lam)) if 0 < lam < 1 else (np.inf if lam >= 1 else 0.0)
308 + return dict(b_hat=b_hat, yR=yR, yO=yO, qRO=qRO, qOO=qOO, lam=lam, mu_star=mu_star,
309 + half_life=half_life, transfer_gap=par.nu / (1 + par.nu) * eq3)
310 +
311 +
312 +# --------------------------------------------------------------------------------------
313 +# Supply and stationary equilibrium (Proposition 6)
314 +# --------------------------------------------------------------------------------------
315 +def S(par: Params, p: float) -> float:
316 + return par.Hbar * p ** par.eps
317 +
318 +
319 +def S_inv(par: Params, mu: float) -> float:
320 + return (mu / par.Hbar) ** (1.0 / par.eps)
321 +
322 +
323 +def Sr(par: Params, rho: float) -> float:
324 + return par.Hbar_r * rho ** par.eps_r
325 +
326 +
327 +def Sr_inv(par: Params, share: float) -> float:
328 + return (share / par.Hbar_r) ** (1.0 / par.eps_r)
329 +
330 +
331 +def p_upper(par: Params) -> float:
332 + """Largest price compatible with Assumption A3 (positive stage-2 owner consumption)."""
333 + d2, _, _ = stationary_schedule(par)
334 + return 0.999 * par.y2 / (d2 + par.m)
335 +
336 +
337 +def excess_map(par: Params, mu: float) -> float:
338 + """f(mu) = mu*(S^-1(mu), S_r^-1(1-mu)) - mu."""
339 + p = S_inv(par, mu)
340 + rho = Sr_inv(par, 1.0 - mu)
341 + return transitions(par, p, rho)["mu_star"] - mu
342 +
343 +
344 +def stationary_equilibrium(par: Params, mu_lo: float = 1e-4, mu_hi: float = 1 - 1e-4) -> dict:
345 + """Solve f(mu) = 0 on [mu_lo, mu_hi] (IVT); returns prices, shares, thresholds, diagnostics.
346 + With a fixed owner stock (eps = 0) the owner share is mu = Hbar and the price solves
347 + mu*(p, rho) = Hbar (Corollary to Proposition 6)."""
348 + if par.eps == 0:
349 + mu = par.Hbar
350 + rho = Sr_inv(par, 1.0 - mu)
351 + h = lambda p: transitions(par, p, rho)["mu_star"] - mu
352 + p = optimize.brentq(h, 1e-3, p_upper(par), xtol=1e-12)
353 + else:
354 + mu_hi = min(mu_hi, S(par, p_upper(par)) * (1 - 1e-9)) # keep A3 along the bracket
355 + f_lo, f_hi = excess_map(par, mu_lo), excess_map(par, mu_hi)
356 + if f_lo <= 0:
357 + mu = mu_lo
358 + elif f_hi >= 0:
359 + mu = mu_hi
360 + else:
361 + mu = optimize.brentq(lambda x: excess_map(par, x), mu_lo, mu_hi, xtol=1e-12)
362 + p = S_inv(par, mu)
363 + rho = Sr_inv(par, 1.0 - mu)
364 + tr = transitions(par, p, rho)
365 + out = dict(mu=mu, p=p, rho=rho, **tr)
366 + out["Delta"] = ownership_premium(par, p, rho)
367 + out["Lambda"] = np.exp(-out["Delta"])
368 + out["owner_clearing"] = S(par, p) - mu
369 + out["rental_clearing"] = Sr(par, rho) - (1 - mu)
370 + out["A5_cash"] = par.d * p - rho # > 0 : owning costs more cash up front
371 + return out
372 +
373 +
374 +def uniqueness_condition(par: Params, p: float, rho: float, h: float = 1e-5) -> float:
375 + """Condition (C): (1+nu)/nu * d b_hat/dp - e3 >= 0 (b_hat channel dominates ladder channel)."""
376 + _, _, e3 = stationary_schedule(par)
377 + db = (threshold(par, p + h, rho) - threshold(par, p - h, rho)) / (2 * h)
378 + return (1 + par.nu) / par.nu * db - e3
379 +
380 +
381 +def no_segmentation_equilibrium(par: Params, phi: float = 0.0) -> dict:
382 + """Proposition 7 benchmark: a single stock with costless conversion and unit demand.
383 + Total demand per cohort is 1, so p solves S(p) = 1 and does not depend on theta, G, transfers
384 + or surprises; the rent follows landlord arbitrage rho = p (1 + m + phi - 1/R)."""
385 + p = S_inv(par, 1.0)
386 + rho = p * (1.0 + par.m + phi - 1.0 / par.R)
387 + bh = threshold(par, p, rho)
388 + tr = transitions(par, p, rho, bh)
389 + return dict(p=p, rho=rho, b_hat=bh, **{k: v for k, v in tr.items() if k != "b_hat"})
390 +
391 +
392 +# --------------------------------------------------------------------------------------
393 +# Leverage amplification with costs (Proposition 4)
394 +# --------------------------------------------------------------------------------------
395 +def leverage_stats(par: Params, p: float, rho: float) -> dict:
396 + d2, d3, e3 = stationary_schedule(par)
397 + R = par.R
398 + multiplier = (1 - par.kappa_s) / par.d # dW3 per unit of initial cash, per unit price growth
399 + rhs = R**2 * (1 + par.kappa_b + par.m) + par.m * R - (rho / p) * (R + R**2)
400 + g_star = rhs / (1 - par.kappa_s) - 1.0 # break-even real price growth
401 + x_star = 1.0 - d3 / (1 - par.kappa_s) # underwater threshold (price drop)
402 + return dict(multiplier=multiplier, g_star=g_star, x_star=x_star, e3=e3,
403 + wealth_gap=e3 * p, transfer_gap=par.nu / (1 + par.nu) * e3 * p)
404 +
405 +
406 +def owner_vs_renter_investor(par: Params, p: float, rho: float, growth: float) -> float:
407 + """Terminal wealth of an owner minus that of a renter who invests the cash-flow differences
408 + at R (same consumption path). Sign flips at g_star (Proposition 4)."""
409 + d2, d3, _ = stationary_schedule(par)
410 + R = par.R
411 + owner = (1 - par.kappa_s) * p * (1 + growth) - d3 * p
412 + renter = (par.d * p - rho) * R**2 + (d2 * p + par.m * p - rho) * R
413 + return owner - renter
414 +
415 +
416 +# --------------------------------------------------------------------------------------
417 +# Surprise inflation accounting (Proposition 8)
418 +# --------------------------------------------------------------------------------------
419 +def surprise_accounting(par: Params, p: float, rho: float, pi_u: float, *, contract: Contract = "FRM",
420 + experiment: Experiment = "level", phi_r: float = 0.0,
421 + n_savings_age2: float = 0.0, n_savings_age3: float = 0.0) -> dict:
422 + """Real gains (+) / losses (-) relative to the no-surprise path at fixed real prices,
423 + for the cohorts aged 2 and 3 when the surprise hits, the lender, landlords and wages.
424 +
425 + n_savings_age2 / age3: nominal deposits held by (non-HTM) households of those ages, to show
426 + that nominal savers lose. Returns a dict with a zero-sum check on nominal claims."""
427 + pb = par.pibar
428 + pi1 = (1 + pb) * (1 + pi_u) - 1
429 + if experiment == "level":
430 + pi2 = pb
431 + pi_e2 = pb
432 + elif experiment == "persistent":
433 + pi2 = pi1
434 + pi_e2 = pi1
435 + else:
436 + raise ValueError(experiment)
437 + r2 = par.r + phi_r * pi_u
438 + # baseline (no surprise)
439 + D2_0, D3_0 = real_payments(par, p, pi1=pb, pi2=pb, pi_e1=pb, pi_e2=pb, contract=contract)
440 + # cohort aged 2 at the shock (bought at t)
441 + D2_s, D3_s = real_payments(par, p, pi1=pi1, pi2=pi2, pi_e1=pb, pi_e2=pi_e2, contract=contract, r2=r2)
442 + gain_age2_D2 = D2_0 - D2_s
443 + gain_age2_D3 = D3_0 - D3_s
444 + # cohort aged 3 at the shock (bought at t-1): stage-3 nominal payment fixed before the shock
445 + gain_age3_D3 = D3_0 - D3_0 / (1 + pi_u)
446 + # nominal savers
447 + R = par.R
448 + loss_savers = (n_savings_age2 + n_savings_age3) * R * (1 - 1 / (1 + pi_u))
449 + # wages (imperfect indexation) — cohort aged 2 and 3 real income at the shock date
450 + wage_factor = (1 + pi_u) ** (-(1 - par.eta_w))
451 + wage_loss_age2 = par.y2 * (1 - wage_factor)
452 + # rents (rigidity): sitting tenants aged 2 pay less; landlords absorb
453 + rent_factor = (1 + pi_u) ** (-(1 - par.eta_rho))
454 + renter_gain_age2 = rho * (1 - rent_factor)
455 + # lender: mirror image of all nominal revaluations on the shock date and (for the age-2 cohort)
456 + # on the continuation, both contracts
457 + lender_loss = (gain_age2_D2 + gain_age2_D3 + gain_age3_D3) - loss_savers
458 + zero_sum = (gain_age2_D2 + gain_age2_D3 + gain_age3_D3 - loss_savers) - lender_loss
459 + net_owner_age2 = gain_age2_D2 + gain_age2_D3 - wage_loss_age2 - n_savings_age2 * R * (1 - 1 / (1 + pi_u))
460 + return dict(D2_base=D2_0, D3_base=D3_0, D2_shock=D2_s, D3_shock=D3_s,
461 + gain_age2_D2=gain_age2_D2, gain_age2_D3=gain_age2_D3, gain_age3_D3=gain_age3_D3,
462 + loss_savers=loss_savers, wage_loss_age2=wage_loss_age2,
463 + renter_gain_age2=renter_gain_age2, landlord_loss=renter_gain_age2,
464 + lender_loss=lender_loss, zero_sum_residual=zero_sum, net_owner_age2=net_owner_age2)
465 +
466 +
467 +# --------------------------------------------------------------------------------------
468 +# Impact general-equilibrium response (Proposition 9) under static expectations (A6)
469 +# --------------------------------------------------------------------------------------
470 +def impact_response(par: Params, eq: dict, pi_u: float, *, contract: Contract = "FRM") -> dict:
471 + """Date t+1 equilibrium after a level surprise pi_u, with (i) stage-2 owners not transacting,
472 + (ii) stage-3 owner-parents' D3 eroded by 1/(1+pi_u), (iii) the stage-1 cohort's threshold
473 + evaluated at current (p, rho) and stationary future prices (A6).
474 +
475 + Owner market: S(p) = (mu* + mu_{t+1})/2 ; rental: S_r(rho) = 1 - (mu* + mu_{t+1})/2.
476 + Solved by a root search on mu_{t+1}."""
477 + mu_s, p_s, rho_s = eq["mu"], eq["p"], eq["rho"]
478 + d2, d3, _ = stationary_schedule(par)
479 + D3_parent = d3 * p_s / (1 + pi_u) # stage-3 parents bought at p_s; payment eroded
480 +
481 + def mu_next_given(mu1, p_fixed=None):
482 + avg = (mu_s + mu1) / 2
483 + p = S_inv(par, avg) if p_fixed is None else p_fixed
484 + rho = Sr_inv(par, 1 - avg)
485 + # child's threshold: buys at p now, pays D2, D3 on (1-theta) p, sells at p_s (static exp.), rents at rho now, rho_s later
486 + bh = threshold(par, p, rho, p_sale=p_s, rho2=rho_s, D2=d2 * p, D3=d3 * p)
487 + eq3_parent = (1 - par.kappa_s) * p - D3_parent # parent's equity at sale (sells at p)
488 + tr = transitions(par, p, rho, bh, eq3=eq3_parent)
489 + mu_new = mu_s * tr["qOO"] + (1 - mu_s) * tr["qRO"]
490 + return mu_new, p, rho, bh, tr
491 +
492 + if par.eps == 0:
493 + # fixed owner stock: mu_{t+1} = mu* and the price clears the owner market
494 + mu1 = mu_s
495 + hfun = lambda p: mu_next_given(mu1, p_fixed=p)[0] - mu1
496 + p_sol = optimize.brentq(hfun, 1e-3, p_upper(par), xtol=1e-12)
497 + mu_new, p, rho, bh, tr = mu_next_given(mu1, p_fixed=p_sol)
498 + else:
499 + f = lambda mu1: mu_next_given(mu1)[0] - mu1
500 + lo, hi = 1e-6, min(1 - 1e-6, 2 * S(par, p_upper(par)) * (1 - 1e-9) - mu_s)
501 + if f(lo) <= 0:
502 + mu1 = lo
503 + elif f(hi) >= 0:
504 + mu1 = hi
505 + else:
506 + mu1 = optimize.brentq(f, lo, hi, xtol=1e-12)
507 + mu_new, p, rho, bh, tr = mu_next_given(mu1)
508 + return dict(mu_next=mu1, p=p, rho=rho, b_hat=bh, qRO=tr["qRO"], qOO=tr["qOO"], lam=tr["lam"],
509 + dp=p - p_s, drho=rho - rho_s, dmu=mu1 - mu_s, db_hat=bh - eq["b_hat"],
510 + rent_price=rho / p, rent_price_base=rho_s / p_s,
511 + seller_gain=d3 * p_s * (1 - 1 / (1 + pi_u)) + (1 - par.kappa_s) * (p - p_s),
512 + new_owner_cash_change=par.nu / (1 + par.nu) * (d3 * p_s * (1 - 1 / (1 + pi_u))
513 + + (1 - par.kappa_s) * (p - p_s))
514 + - par.d * (p - p_s))
515 +
516 +
517 +def simulate_myopic_transition(par: Params, eq: dict, pi_u: float, T: int = 12,
518 + experiment: Experiment = "level", contract: Contract = "FRM") -> dict:
519 + """Diagnostic simulation of the dynasty composition after a surprise at date 1 under the
520 + Part A structure with per-period supply and static expectations. Tracks, for each cohort,
521 + the tenure share and the purchase price, so that parents' equity at sale uses the right
522 + purchase price and payment erosion. Not a proposition: a check that the economy returns to
523 + the stationary state and that the impact signs match `impact_response`."""
524 + d2, d3, _ = stationary_schedule(par)
525 + pb = par.pibar
526 + # histories are indexed by cohort c = -1, 0, 1, ... at position c + 1
527 + mu_hist = [eq["mu"], eq["mu"]] # cohorts born at t=-1, 0
528 + p_hist = [eq["p"], eq["p"]]
529 + rho_hist = [eq["rho"], eq["rho"]]
530 + rows = []
531 + for t in range(1, T + 1):
532 + # parents of this cohort: born at t-2 (stage 3 now), position t-1; previous cohort: position t
533 + p_buy = p_hist[t - 1]
534 + mu_parents = mu_hist[t - 1]
535 + # erosion of the parents' D3 and of D2/D3 of the cohort born at t-1 (not needed for mu)
536 + if t == 1:
537 + pi1, pi2, pi_e2 = (1 + pb) * (1 + pi_u) - 1, pb, pb
538 + _, D3_par = real_payments(par, p_buy, pi1=pb, pi2=pi1, pi_e1=pb, pi_e2=pb, contract=contract)
539 + elif t == 2 and experiment == "persistent":
540 + pi1 = (1 + pb) * (1 + pi_u) - 1
541 + _, D3_par = real_payments(par, p_buy, pi1=pi1, pi2=pi1, pi_e1=pb, pi_e2=pi1, contract=contract)
542 + elif t == 2:
543 + pi1 = (1 + pb) * (1 + pi_u) - 1
544 + _, D3_par = real_payments(par, p_buy, pi1=pi1, pi2=pb, pi_e1=pb, pi_e2=pb, contract=contract)
545 + else:
546 + D3_par = d3 * p_buy
547 + mu_prev = mu_hist[t]
548 +
549 + def mu_given(mu1):
550 + avg = (mu_prev + mu1) / 2
551 + p = S_inv(par, avg)
552 + rho = Sr_inv(par, 1 - avg)
553 + bh = threshold(par, p, rho, p_sale=eq["p"], rho2=eq["rho"], D2=d2 * p, D3=d3 * p)
554 + eq3_par = (1 - par.kappa_s) * p - D3_par
555 + tr = transitions(par, p, rho, bh, eq3=eq3_par)
556 + return mu_parents * tr["qOO"] + (1 - mu_parents) * tr["qRO"], p, rho, bh
557 +
558 + f = lambda x: mu_given(x)[0] - x
559 + hi = min(1 - 1e-6, 2 * S(par, p_upper(par)) * (1 - 1e-9) - mu_prev)
560 + mu1 = optimize.brentq(f, 1e-6, hi, xtol=1e-12) if f(1e-6) > 0 > f(hi) else (1e-6 if f(1e-6) <= 0 else hi)
561 + _, p, rho, bh = mu_given(mu1)
562 + mu_hist.append(mu1); p_hist.append(p); rho_hist.append(rho)
563 + rows.append(dict(t=t, mu=mu1, p=p, rho=rho, b_hat=bh))
564 + return dict(rows=rows, mu=np.array(mu_hist[2:]), p=np.array(p_hist[2:]), rho=np.array(rho_hist[2:]))
565 +
566 +
567 +# --------------------------------------------------------------------------------------
568 +# Budget identities (used by the tests)
569 +# --------------------------------------------------------------------------------------
570 +def htm_allocation(par: Params, b: float, p: float, rho: float, tenure: Literal["O", "R"], y3: float,
571 + *, pi_u1: float = 0.0, pi_u2: float = 0.0, contract: Contract = "FRM",
572 + experiment: Experiment = "level", p_sale: float | None = None) -> dict:
573 + """Full real flows of an HTM household for a given y3 draw; used to check budget identities
574 + state by state. Returns sources and uses at each stage, the nominal principal path and the
575 + real debt path (B_nom / P)."""
576 + pb = par.pibar
577 + P0 = 1.0
578 + pi1 = (1 + pb) * (1 + pi_u1) - 1
579 + if experiment == "persistent" and pi_u1 != 0:
580 + pi2, pi_e2 = pi1, pi1
581 + else:
582 + pi2 = (1 + pb) * (1 + pi_u2) - 1
583 + pi_e2 = pb
584 + P1, P2 = P0 * (1 + pi1), P0 * (1 + pi1) * (1 + pi2)
585 + p_sale = p if p_sale is None else p_sale
586 + out = dict(P=(P0, P1, P2))
587 + if tenure == "O":
588 + B_nom0 = P0 * (1 - par.theta) * p
589 + i1 = nominal_rate(par, pb)
590 + i2 = i1 if contract == "FRM" else nominal_rate(par, pi_e2)
591 + pay2_nom = (i1 + par.amort) * B_nom0
592 + B_nom1 = B_nom0 * (1 + i1) - pay2_nom # balance after stage-2 payment = (1-a) B_nom0
593 + pay3_nom = (1 + i2) * B_nom1
594 + D2, D3 = pay2_nom / P1, pay3_nom / P2
595 + c1 = b + par.y1 - par.d * p
596 + c2 = par.y2 - D2 - par.m * p
597 + W3 = y3 + (1 - par.kappa_s) * p_sale - D3
598 + out.update(B_nom=(B_nom0, B_nom1, 0.0), real_debt=(B_nom0 / P0, B_nom1 / P1, 0.0),
599 + D2=D2, D3=D3, c1=c1, c2=c2,
600 + sources=(b + par.y1 + B_nom0 / P0, par.y2, y3 + (1 - par.kappa_s) * p_sale),
601 + uses=(c1 + (1 + par.kappa_b + par.m) * p, c2 + D2 + par.m * p, None))
602 + # check D2, D3 against real_payments
603 + D2c, D3c = real_payments(par, p, pi1=pi1, pi2=pi2, pi_e1=pb, pi_e2=pi_e2, contract=contract)
604 + out["schedule_check"] = (D2 - D2c, D3 - D3c)
605 + else:
606 + c1 = b + par.y1 - rho
607 + c2 = par.y2 - rho
608 + W3 = y3
609 + out.update(c1=c1, c2=c2, sources=(b + par.y1, par.y2, y3), uses=(c1 + rho, c2 + rho, None))
610 + c3 = W3 / (1 + par.nu)
611 + bq = par.nu * W3 / (1 + par.nu)
612 + out.update(W3=W3, c3=c3, bequest=bq)
613 + out["uses"] = (out["uses"][0], out["uses"][1], c3 + bq + (D3 if tenure == "O" else 0.0))
614 + return out
615 +
616 +
617 +if __name__ == "__main__": # quick report
618 + par = Params()
619 + eq = stationary_equilibrium(par)
620 + print("Stationary equilibrium:")
621 + for k, v in eq.items():
622 + print(f" {k:>18s} = {v:.6f}" if isinstance(v, float) else f" {k:>18s} = {v}")
623 + print("Uniqueness condition (C) at eq:", uniqueness_condition(par, eq["p"], eq["rho"]))
624 + print("Leverage:", leverage_stats(par, eq["p"], eq["rho"]))
625 + for contract in ("FRM", "ARM"):
626 + for exp_ in ("level", "persistent"):
627 + acc = surprise_accounting(par, eq["p"], eq["rho"], 0.10, contract=contract, experiment=exp_)
628 + print(contract, exp_, {k: round(v, 5) for k, v in acc.items() if k.startswith(("gain", "lender"))})
629 + imp = impact_response(par, eq, 0.10)
630 + print("Impact:", {k: round(v, 5) for k, v in imp.items()})
added tests/test_toy_model.py +277 −0
@@ -0,0 +1,277 @@
1 +"""Tests of the Part A benchmark (`src/toy_model.py`).
2 +
3 +Each test is tied to an object of `research/model_specification.md` / `paper/appendix_proofs.tex`:
4 +budget identities and debt evolution (B.11 / A.4), Fisher present-value identity, Proposition 1
5 +(threshold = numerically optimised threshold), Assumption A4 verified on the support of the
6 +stationary transfer distribution, Proposition 2 (signs), Proposition 3 (tilt / neutrality),
7 +Proposition 4 (leverage), Proposition 5 (persistence, chain), Proposition 6 (clearing, condition C),
8 +Corollary (fixed supply), Proposition 7 (no segmentation), Proposition 8 (accounting, FRM vs ARM),
9 +Proposition 9 (impact signs). Parameters are illustrative.
10 +"""
11 +import os
12 +import sys
13 +
14 +import numpy as np
15 +import pytest
16 +
17 +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
18 +
19 +import toy_model as tm # noqa: E402
20 +from toy_model import Params, replace # noqa: E402
21 +
22 +PAR = Params()
23 +EQ = tm.stationary_equilibrium(PAR)
24 +H = 1e-5
25 +
26 +
27 +def num_deriv(fun, x, h=H):
28 + return (fun(x + h) - fun(x - h)) / (2 * h)
29 +
30 +
31 +# ------------------------------------------------------------------ identities
32 +@pytest.mark.parametrize("tenure", ["O", "R"])
33 +@pytest.mark.parametrize("contract", ["FRM", "ARM"])
34 +@pytest.mark.parametrize("pi_u", [0.0, 0.1, -0.05])
35 +@pytest.mark.parametrize("experiment", ["level", "persistent"])
36 +def test_budget_identities_state_by_state(tenure, contract, pi_u, experiment):
37 + y3_nodes, _ = tm.y3_quad(PAR)
38 + for y3 in y3_nodes[::8]:
39 + for b in [EQ["b_hat"] + 0.05, 1.5]:
40 + a = tm.htm_allocation(PAR, b, EQ["p"], EQ["rho"], tenure, float(y3), pi_u1=pi_u,
41 + contract=contract, experiment=experiment)
42 + src, use = a["sources"], a["uses"]
43 + for j in range(3):
44 + assert src[j] == pytest.approx(use[j], abs=1e-12), (tenure, j)
45 + assert a["c1"] > 0 and a["c2"] > 0 and a["W3"] > 0 # Assumption A3
46 + if tenure == "O":
47 + assert a["schedule_check"] == pytest.approx((0.0, 0.0), abs=1e-12)
48 +
49 +
50 +def test_debt_evolution_nominal_vs_real():
51 + a = tm.htm_allocation(PAR, 1.2, EQ["p"], EQ["rho"], "O", 4.0, pi_u1=0.2)
52 + B0, B1, B2 = a["B_nom"]
53 + P0, P1, P2 = a["P"]
54 + # nominal: balance after stage-2 payment = (1 - amort) * B0 (interest paid in full at stage 2)
55 + assert B1 == pytest.approx((1 - PAR.amort) * B0, abs=1e-12)
56 + assert B2 == 0.0
57 + # real debt = B_nom / CPI; the surprise lowers real debt by 1/(1+pi_u) relative to the no-surprise path
58 + a0 = tm.htm_allocation(PAR, 1.2, EQ["p"], EQ["rho"], "O", 4.0, pi_u1=0.0)
59 + assert a["real_debt"][1] == pytest.approx(a0["real_debt"][1] / 1.2, rel=1e-12)
60 + # nominal house-price index (P p) differs from the CPI path
61 + assert P1 * EQ["p"] != pytest.approx(P1)
62 +
63 +
64 +def test_fisher_present_value_identity():
65 + d2, d3, _ = tm.stationary_schedule(PAR)
66 + assert d2 + d3 / PAR.R == pytest.approx((1 - PAR.theta) * PAR.R, rel=1e-12)
67 + for pibar in [0.0, 0.1, 0.5]:
68 + d2, d3, _ = tm.stationary_schedule(replace(PAR, pibar=pibar))
69 + assert d2 + d3 / PAR.R == pytest.approx((1 - PAR.theta) * PAR.R, rel=1e-12)
70 +
71 +
72 +def test_stage3_split_lemma1():
73 + a = tm.htm_allocation(PAR, 1.0, EQ["p"], EQ["rho"], "R", 4.0)
74 + assert a["c3"] == pytest.approx(a["W3"] / (1 + PAR.nu))
75 + assert a["bequest"] == pytest.approx(PAR.nu * a["W3"] / (1 + PAR.nu))
76 +
77 +
78 +# ------------------------------------------------------------------ Proposition 1 & A4
79 +def test_threshold_equals_numerically_optimised_threshold():
80 + b_num = tm.threshold_general(PAR, EQ["p"], EQ["rho"])
81 + assert b_num == pytest.approx(EQ["b_hat"], abs=1e-6)
82 + assert EQ["b_hat"] > PAR.d * EQ["p"] - PAR.y1 # strictly above the feasibility bound
83 + assert EQ["A5_cash"] > 0 and EQ["Delta"] > 0 # Assumption A5 holds at the equilibrium
84 +
85 +
86 +@pytest.mark.parametrize("tenure", ["O", "R"])
87 +def test_htm_corner_is_optimal_on_transfer_support(tenure):
88 + """Assumption A4 verified (not assumed): Euler slacks positive at the threshold and at the
89 + largest transfer of the stationary distribution, and the general optimiser returns the corner."""
90 + _, _, e3 = tm.stationary_schedule(PAR)
91 + b_max = PAR.nu / (1 + PAR.nu) * (PAR.y3_hi + e3 * EQ["p"])
92 + for b in [EQ["b_hat"], 0.5 * (EQ["b_hat"] + b_max), b_max]:
93 + s1, s2 = tm.htm_slack(PAR, b, EQ["p"], EQ["rho"], tenure)
94 + assert s1 > 0 and s2 > 0
95 + v_gen, pol = tm.value_general(PAR, b, EQ["p"], EQ["rho"], tenure, return_policy=True)
96 + v_htm = tm.value_htm(PAR, b, EQ["p"], EQ["rho"], tenure)
97 + assert v_gen == pytest.approx(v_htm, abs=1e-6)
98 + if tenure == "O":
99 + assert pol[0] == pytest.approx(1 - PAR.theta, abs=1e-6) # max LTV
100 + assert pol[1] == pytest.approx(0.0, abs=1e-6) and pol[2] == pytest.approx(0.0, abs=1e-6)
101 + else:
102 + assert np.allclose(pol, 0.0, atol=1e-6)
103 +
104 +
105 +def test_single_crossing_general_values():
106 + """V^O - V^R crosses zero once on a grid (checked with the general optimiser)."""
107 + grid = np.linspace(PAR.d * EQ["p"] - PAR.y1 + 0.02, 3.0, 25)
108 + diff = np.array([tm.value_general(PAR, b, EQ["p"], EQ["rho"], "O") - tm.value_general(PAR, b, EQ["p"], EQ["rho"], "R")
109 + for b in grid])
110 + signs = np.sign(diff)
111 + assert np.sum(signs[1:] != signs[:-1]) == 1
112 + assert diff[0] < 0 < diff[-1]
113 +
114 +
115 +# ------------------------------------------------------------------ Proposition 2 & 3
116 +def test_threshold_comparative_statics_signs():
117 + p, rho = EQ["p"], EQ["rho"]
118 + assert num_deriv(lambda x: tm.threshold(PAR, x, rho), p) > 0
119 + assert num_deriv(lambda x: tm.threshold(PAR, p, x), rho) < 0
120 + for name, sign in [("theta", +1), ("kappa_b", +1), ("kappa_s", +1), ("m", +1), ("chi", -1), ("pibar", +1)]:
121 + v = getattr(PAR, name)
122 + der = num_deriv(lambda x: tm.threshold(replace(PAR, **{name: x}), p, rho), v)
123 + assert np.sign(der) == sign, name
124 + assert num_deriv(lambda x: tm.threshold(replace(PAR, y1=x), p, rho), PAR.y1) == pytest.approx(-1.0, abs=1e-6)
125 +
126 +
127 +def test_anticipated_inflation_neutral_in_pv_but_tilts_payments():
128 + d2a, d3a, _ = tm.stationary_schedule(replace(PAR, pibar=0.0))
129 + d2b, d3b, _ = tm.stationary_schedule(replace(PAR, pibar=0.3))
130 + assert d2b > d2a and d3b < d3a # tilt
131 + assert d2a + d3a / PAR.R == pytest.approx(d2b + d3b / PAR.R) # PV neutrality (Fisher)
132 +
133 +
134 +# ------------------------------------------------------------------ Proposition 4
135 +def test_leverage_multiplier_and_break_even():
136 + ls = tm.leverage_stats(PAR, EQ["p"], EQ["rho"])
137 + assert ls["multiplier"] == pytest.approx((1 - PAR.kappa_s) / PAR.d)
138 + # multiplier falls with the down payment and with costs
139 + assert tm.leverage_stats(replace(PAR, theta=0.4), EQ["p"], EQ["rho"])["multiplier"] < ls["multiplier"]
140 + assert tm.leverage_stats(replace(PAR, kappa_b=0.06), EQ["p"], EQ["rho"])["multiplier"] < ls["multiplier"]
141 + # owner vs renter-investor terminal wealth changes sign exactly at g*
142 + g = ls["g_star"]
143 + assert tm.owner_vs_renter_investor(PAR, EQ["p"], EQ["rho"], g) == pytest.approx(0.0, abs=1e-10)
144 + assert tm.owner_vs_renter_investor(PAR, EQ["p"], EQ["rho"], g + 0.1) > 0
145 + assert tm.owner_vs_renter_investor(PAR, EQ["p"], EQ["rho"], g - 0.1) < 0
146 + # break-even growth is independent of theta, increasing in costs, decreasing in rent
147 + assert tm.leverage_stats(replace(PAR, theta=0.5), EQ["p"], EQ["rho"])["g_star"] == pytest.approx(g)
148 + assert tm.leverage_stats(replace(PAR, kappa_s=0.10), EQ["p"], EQ["rho"])["g_star"] > g
149 + assert tm.leverage_stats(PAR, EQ["p"], EQ["rho"] * 1.2)["g_star"] < g
150 + # underwater threshold: resale at (1 - x*) p leaves zero housing equity
151 + d2, d3, _ = tm.stationary_schedule(PAR)
152 + assert (1 - PAR.kappa_s) * (1 - ls["x_star"]) - d3 == pytest.approx(0.0, abs=1e-12)
153 +
154 +
155 +# ------------------------------------------------------------------ Proposition 5
156 +def test_dynasty_chain_persistence():
157 + tr = tm.transitions(PAR, EQ["p"], EQ["rho"])
158 + assert 0 < tr["qRO"] < tr["qOO"] < 1
159 + assert tr["lam"] == pytest.approx(tr["qOO"] - tr["qRO"])
160 + assert tr["lam"] == pytest.approx(float(tm.G(PAR, tr["yR"]) - tm.G(PAR, tr["yO"])))
161 + # stationary distribution of the two-state chain by power iteration
162 + Pm = np.array([[1 - tr["qRO"], tr["qRO"]], [1 - tr["qOO"], tr["qOO"]]])
163 + pi = np.array([0.5, 0.5])
164 + for _ in range(500):
165 + pi = pi @ Pm
166 + assert pi[1] == pytest.approx(tr["mu_star"], abs=1e-10)
167 + assert np.sort(np.abs(np.linalg.eigvals(Pm)))[0] == pytest.approx(tr["lam"], abs=1e-10)
168 + # persistence vanishes when the house is not net wealth at the end of life (e3 <= 0)
169 + tr0 = tm.transitions(PAR, EQ["p"], EQ["rho"], eq3=0.0)
170 + assert tr0["lam"] == pytest.approx(0.0, abs=1e-12)
171 + # and increases with the equity carried into stage 3 (threshold fixed)
172 + assert tm.transitions(PAR, EQ["p"], EQ["rho"], eq3=0.9)["lam"] > tr["lam"]
173 + assert tr["transfer_gap"] == pytest.approx(PAR.nu / (1 + PAR.nu) * tm.stationary_schedule(PAR)[2] * EQ["p"])
174 +
175 +
176 +# ------------------------------------------------------------------ Proposition 6 + Corollary + 7
177 +def test_stationary_equilibrium_clears_and_is_unique_under_C():
178 + assert abs(EQ["owner_clearing"]) < 1e-10 and abs(EQ["rental_clearing"]) < 1e-10
179 + assert EQ["mu"] == pytest.approx(EQ["mu_star"], abs=1e-10)
180 + assert tm.uniqueness_condition(PAR, EQ["p"], EQ["rho"]) > 0
181 + # f(mu) is decreasing on a grid -> single root
182 + grid = np.linspace(0.05, 0.95, 19)
183 + f = np.array([tm.excess_map(PAR, m) for m in grid])
184 + assert np.all(np.diff(f) < 0)
185 + assert np.sum(np.sign(f[1:]) != np.sign(f[:-1])) == 1
186 +
187 +
188 +def test_fixed_supply_corollary():
189 + par0 = replace(PAR, eps=0.0, Hbar=0.72)
190 + e0 = tm.stationary_equilibrium(par0)
191 + assert e0["mu"] == pytest.approx(0.72)
192 + # relaxing the down-payment constraint does not change the ownership rate, only the price
193 + e1 = tm.stationary_equilibrium(replace(par0, theta=0.25))
194 + assert e1["mu"] == pytest.approx(0.72)
195 + assert e1["p"] > e0["p"]
196 +
197 +
198 +def test_no_segmentation_neutrality():
199 + base = tm.no_segmentation_equilibrium(PAR, phi=0.3)
200 + for par_alt in [replace(PAR, theta=0.5), replace(PAR, nu=0.6), replace(PAR, y3_hi=9.0)]:
201 + alt = tm.no_segmentation_equilibrium(par_alt, phi=0.3)
202 + assert alt["p"] == pytest.approx(base["p"])
203 + assert alt["rho"] == pytest.approx(base["rho"])
204 + assert tm.no_segmentation_equilibrium(replace(PAR, theta=0.5), phi=0.3)["b_hat"] != pytest.approx(base["b_hat"])
205 +
206 +
207 +# ------------------------------------------------------------------ Proposition 8
208 +def test_surprise_accounting_zero_sum_and_contract_ordering():
209 + p, rho = EQ["p"], EQ["rho"]
210 + for contract in ["FRM", "ARM"]:
211 + for exp_ in ["level", "persistent"]:
212 + acc = tm.surprise_accounting(PAR, p, rho, 0.1, contract=contract, experiment=exp_,
213 + n_savings_age2=0.2, n_savings_age3=0.3)
214 + assert acc["zero_sum_residual"] == pytest.approx(0.0, abs=1e-12)
215 + assert acc["gain_age2_D2"] > 0 and acc["gain_age3_D3"] > 0
216 + assert acc["loss_savers"] > 0
217 + frm_l = tm.surprise_accounting(PAR, p, rho, 0.1, contract="FRM", experiment="level")
218 + arm_l = tm.surprise_accounting(PAR, p, rho, 0.1, contract="ARM", experiment="level")
219 + frm_p = tm.surprise_accounting(PAR, p, rho, 0.1, contract="FRM", experiment="persistent")
220 + arm_p = tm.surprise_accounting(PAR, p, rho, 0.1, contract="ARM", experiment="persistent")
221 + assert frm_l["gain_age2_D3"] == pytest.approx(arm_l["gain_age2_D3"]) # level: identical
222 + assert frm_p["gain_age2_D3"] > arm_p["gain_age2_D3"] # persistent: FRM gains more
223 + assert arm_p["gain_age2_D3"] == pytest.approx(arm_l["gain_age2_D3"]) # ARM reset recovers one factor
224 + # erosion factors exactly
225 + d2, d3, _ = tm.stationary_schedule(PAR)
226 + assert frm_l["D2_shock"] == pytest.approx(d2 * p / 1.1) and frm_l["D3_shock"] == pytest.approx(d3 * p / 1.1)
227 + assert frm_p["D3_shock"] == pytest.approx(d3 * p / 1.1**2)
228 + assert frm_l["lender_loss"] == pytest.approx(frm_l["gain_age2_D2"] + frm_l["gain_age2_D3"] + frm_l["gain_age3_D3"])
229 +
230 +
231 +def test_owner_can_lose_arm_with_real_rate_response_and_unindexed_wages():
232 + p, rho = EQ["p"], EQ["rho"]
233 + arm = tm.surprise_accounting(PAR, p, rho, 0.1, contract="ARM", experiment="persistent", phi_r=2.0)
234 + assert arm["gain_age2_D3"] < 0 # stage-3 real payment rises
235 + nowage = tm.surprise_accounting(replace(PAR, eta_w=0.0), p, rho, 0.1, contract="FRM", experiment="level")
236 + assert nowage["net_owner_age2"] < 0 # debt erosion < real income loss
237 + full = tm.surprise_accounting(PAR, p, rho, 0.1, contract="FRM", experiment="level")
238 + assert full["net_owner_age2"] > 0
239 +
240 +
241 +# ------------------------------------------------------------------ Proposition 9
242 +def test_impact_signs_segmented_elastic():
243 + imp = tm.impact_response(PAR, EQ, 0.1)
244 + assert imp["dp"] > 0 and imp["drho"] < 0 and imp["dmu"] > 0 and imp["db_hat"] > 0
245 + assert imp["qRO"] < EQ["qRO"] and imp["lam"] > EQ["lam"]
246 + assert imp["rent_price"] < imp["rent_price_base"]
247 + assert imp["seller_gain"] > 0
248 + zero = tm.impact_response(PAR, EQ, 0.0)
249 + assert abs(zero["dp"]) < 1e-9 and abs(zero["dmu"]) < 1e-9
250 +
251 +
252 +def test_impact_fixed_supply_is_pure_composition():
253 + par0 = replace(PAR, eps=0.0, Hbar=0.72)
254 + e0 = tm.stationary_equilibrium(par0)
255 + imp = tm.impact_response(par0, e0, 0.1)
256 + assert imp["dmu"] == pytest.approx(0.0, abs=1e-12)
257 + assert imp["dp"] > 0 and imp["db_hat"] > 0 and imp["qRO"] < e0["qRO"] and imp["qOO"] > e0["qOO"]
258 +
259 +
260 +def test_impact_larger_price_response_when_supply_less_elastic():
261 + outs = []
262 + for eps in [2.0, 1.0, 0.3]:
263 + par = replace(PAR, eps=eps, Hbar=EQ["mu"] / EQ["p"] ** eps) # same stationary point
264 + e = tm.stationary_equilibrium(par)
265 + assert e["p"] == pytest.approx(EQ["p"], rel=1e-6)
266 + outs.append(tm.impact_response(par, e, 0.1)["dp"])
267 + assert outs[0] < outs[1] < outs[2]
268 +
269 +
270 +def test_myopic_transition_matches_impact_and_returns_to_steady_state():
271 + sim = tm.simulate_myopic_transition(PAR, EQ, 0.1, T=12)
272 + imp = tm.impact_response(PAR, EQ, 0.1)
273 + assert sim["mu"][0] == pytest.approx(imp["mu_next"], abs=1e-10)
274 + assert sim["p"][0] == pytest.approx(imp["p"], abs=1e-10)
275 + assert abs(sim["mu"][-1] - EQ["mu"]) < 0.1 * abs(sim["mu"][0] - EQ["mu"])
276 + flat = tm.simulate_myopic_transition(PAR, EQ, 0.0, T=6)
277 + assert np.allclose(flat["mu"], EQ["mu"], atol=1e-10)
278