#!/usr/bin/env python # coding: utf-8 # # Insurance and Incentives # # *By Sebastian Graves and Thomas Sargent* # # This notebook computes optimal contracts for the three examples that lead off chapter 21 of # **Recursive Macroeconomic Theory, Fourth edition** by Lars Ljungqvist and Thomas Sargent. # # The examples illustrate different sorts of tradeoffs between insurance and incentives that emerge under different # limits on enforcement and information. # # In each of the three economies, a planner or money-lender designs an efficient contract to supply insurance to a risk-averse consumer who receives an exogenous random stream of a non-storable endowment. # # The only way that the consumer to smooth consumption across states and time is to interact with the planner. # # The three models differ in the constraints that they impose on the planner. # # These constraints express the planner's limited ability either to enforce a contract or to observe the consumer's endowment # # Each of the examples uses a version of what we have nicknamed **dynamic programming squared** # # In a dynamic programming squared problem, a value function from one Bellman equation is an argument of another Bellman equation. # # In the examples below, a planner or money lender's value function will have as an argument the value of a villager # that satisfies a Bellman equation # # # ### Three models of a villager and a money lender # # Imagine a village with a large number of ex ante # identical households. Each household has preferences over # consumption streams that are ordered by # $$ E_{-1}\sum_{t=0}^\infty \beta^t u(c_t), $$ # where $u(c)$ is an increasing, strictly concave, and twice # continuously differentiable function, # $\beta \in (0,1)$ is a discount factor, and $E_{-1}$ is the mathematical expectation # not conditioning on any information available at time $0$ or later. # # Each household # receives a stochastic endowment stream $\{y_t\}_{t=0}^\infty$, # where for each $t \geq 0$, $y_t$ is independently and # identically distributed according to the discrete # probability distribution ${\rm Prob} (y_t = \overline y_s) = \Pi_s,$ # where $s \in \{1, 2, \ldots ,S\}\equiv {\bf S}$ and # $\overline y_{s+1}>\overline y_s$. # # The consumption # good is not storable. # # At time $t \geq 1$, the # household has received a history of endowments # $h_t = (y_t, y_{t-1}, \ldots, y_0).$ # # Endowment processes are distributed independently and identically # both across time and # across households. # # # ##### Competitive equilibrium # # In this setting, if there were a competitive equilibrium with # complete markets, at date # $0$ households would trade history- and date-contingent claims. # # Since households are ex ante # identical, each household would consume the per capita # endowment in every period, and its lifetime utility would be # # $$ v_{\rm pool} = \sum_{t=0}^\infty # \beta^t \, u\!\left(\sum_{s=1}^S \Pi_s \overline y_s\right) = # {1 \over 1-\beta}\, u\!\left(\sum_{s=1}^S \Pi_s \overline y_s\right) . # $$ # # Households would thus insure away all # risks from their individual endowment processes. # # But the # incentive constraints that we are about to specify make # this allocation unattainable. # # For each specification of incentive # constraints, we shall solve a planning problem for an efficient # allocation that respects those constraints. # # # Following a tradition started by # Edward Green (1987) [*Lending and the Smoothing of Uninsurable # Income*, in Edward C. Prescott and Neil Wallace, editors, **Contractual Arrangements for # Intertemporal Trade**, Minnesota Studies in Macroeconomics series, Vol. # 1, Minneapolis: University of Minnesota Press, pp. 3--25], we assume that a *moneylender* or *planner* is # the only person in the village who has access to # a risk-free loan market outside the village. # # The moneylender can borrow or lend at a constant one-period # risk-free gross interest rate $R=\beta^{-1}$. # # Households cannot borrow or lend with each other, # and can trade only with the moneylender. # # Furthermore, # we assume that the moneylender is committed to honor his # promises. # # We will study three distinct environments in which there are three alternative types of incentive constraints. # # # **Enviroment a.** Both the money lender and the household observe the household's history of endowments at each time $t$. # Although the moneylender can commit to honor a # contract, households cannot commit and at any time are # free to walk away from an arrangement # with the moneylender # and live in perpetual autarky thereafter. They must be induced not to do so # by the structure of # the contract. # This is a model of *one-sided commitment* in which the # contract must be *self-enforcing*. That is, it must be structured to induce the household to prefer to # conform to it. # # **Environment b.** Households *can* make commitments and enter # into enduring and binding contracts with the moneylender, # but they have private # information about their own incomes. The moneylender # can see neither their income nor their consumption. Instead, # exchanges between the moneylender and a household must # be based on the household's own reports about income # realizations. An incentive-compatible contract induces # a household to report its income truthfully. # # **Environment c.** The environment is the same as b except that now households have access to a storage technology that # cannot be observed by the moneylender. # Households can store nonnegative amounts of goods at a risk-free # gross return of $R$ equal to the interest rate that # the moneylender faces in the outside credit market. # Since the moneylender can both borrow and lend at the interest # rate $R$ outside of the village, # the private storage technology does not change the economy's # aggregate resource constraint, but it does affect the set of # incentive-compatible contracts between the moneylender and the # households. # # # #### Preview # # # When we compute efficient allocations for each of these three # environments, we find that the dynamics of the implied # consumption allocations differ dramatically. # # # We shall see that the dynamics # of consumption outcomes evidently differ substantially across the # three environments, increasing monotonically and then flattening out in environment a, # stochastically heading south in environment b, and stochastically heading north in # environment c. # These sample path properties will reflect how the optimal contracts cope with the three different frictions that we have put into the environment. # # Chapter 21 of RMT4 explains why sample paths of consumption differ # so much across these three settings. # ### Three computed contracts # # # For all three environments discussed, consumers have a utility function: # # $$u(c) = - \gamma^{-1} \exp(-\gamma c)$$ # # We set $\gamma = 0.7$, and the discount factor, $\beta$ to 0.8. # # The consumers receive an iid endowment that can take any integer in the range $[\bar y_1,...,\bar y_{5}] = [6,...,10]$. # # The probability of each realisation is $\Pi_s = \frac{1-\lambda}{1-\lambda^{5}}\lambda^{s-1}$ with $\lambda = 0.4$. # # As mentioned above, an interesting benchmark case is a complete markets environment. # # Because all households are *ex ante* identical, in a complete markets economy each household would consume the per capita endowment in every period, and its lifetime utility would be: # # $$ v_{pool} = \frac{1}{1-\beta} u \left( \sum_{s=1}^S \Pi_s \bar y_s \right) = \frac{u(c_{pool})}{1-\beta} $$ # # Later we will compare the consumption paths for each environment to that which would occur in the complete markets environment. # # In each environment, we compute allocations for the situation in which the planner or money lender just breaks even. # # ## Environment a # # The first environment is one in which the planner is able to commit, but households are not. # # At any time households are free to walk away from an arrangement with the planner, and live in perpetual autarky thereafter. # # RMT4 shows how this problem can be written in a recursive form. # # Equations 21.3.4 to 21.3.8 in RMT4 express the planners's problem as: # # \begin{align} # &P(v) = \max_{c_s,w_s} \sum_{s=1}^S \Pi_s \left[ (\bar y_s - c_s) + \beta P(w_s) \right] \\ # &\text{subject to} \\ # &\sum_{s=1}^S \Pi_s \left[ u(c_s) + \beta w_s \right] \geq v \\ # &u(c_s) + \beta w_s \geq u(\bar y_s) + \beta v_{aut} \text{ , s = 1,...,S} \\ # &c_s \in [c_{min},c_{max}] \\ # &w_s \in [v_{aut},\bar v] # \end{align} # # where $w_s$ is the promised value with which the consumer will enter the next period, given that $y = \bar y_s$ this period. # # The first constraint is a promise keeping constraint, while the second set of constraints are participation constraints. $[c_{min},c_{max}]$ is a bounded set, while $\bar v$ just needs to be a very large number. # # # The value of autarky to the households is: # # $$ v_{aut} = \frac{1}{1-\beta} \sum_{s=1}^S \Pi_s u(\bar y_s) $$ # # Below we solve the moneylender's problem in this environment by approximating $P(v)$ using Chebyshev polynomials. # In[1]: import numpy as np from scipy.optimize import minimize, fsolve from scipy.interpolate import UnivariateSpline import matplotlib.pyplot as plt import numpy.polynomial.chebyshev as cheb get_ipython().run_line_magic('matplotlib', 'inline') # In[2]: # Parameter values gamma = 0.7 beta = 0.8 lamb = 0.4 S = 5 y_grid = np.linspace(6,5+S,S) prob_grid = np.zeros(S) for i in range(S): prob_grid[i] = (1 - lamb)/(1-lamb**S)*lamb**(i) # Utility function u = lambda c: -gamma**(-1)*np.exp(-gamma*c) u_inv = lambda u: np.log(-gamma*u)/(-gamma) # Calculate complete markets consumption c_pool = np.dot(prob_grid,y_grid) # Calculate value of autarky v_aut = 1/(1-beta)*np.dot(prob_grid, u(y_grid)) # In[3]: # Functions used in each environment # Nodes and basis matrix for Chebyshev approximation def Cheb_basis(order,lb,ub): # Calculate roots of Chebyshev polynomial k = np.linspace(order, 1, order) roots = np.cos((2*k - 1)*np.pi/(2*order)) # Scale to approximation space s = lb + (roots - -1)/2*(ub-lb) # Create basis matrix Phi = cheb.chebvander(roots, order-1) return s, Phi # Value Function Iteration def Bellman_Iterations(s, Phi, P_fun, x_store, coeff, tolc=1e-6, bnds=None, cons=(), max_iters=100): global x, c c = coeff order = Phi.shape[1] iters = 0 diff = 1 while diff > tolc: # 1. Maximization, given value function guess P_iter = np.zeros(order) for i in range(order): x = s[i] res = minimize(P_fun, x_store[i], method = 'SLSQP', bounds = bnds, constraints=cons, tol=1e-15) x_store[i] = res.x P_iter[i] = -P_fun(res.x) # 2. Bellman updating of Value Function coefficients c1 = np.linalg.solve(Phi, P_iter) # 3. Compute distance and update diff = max(abs(c1 - c)) print(diff) c = np.copy(c1) iters = iters + 1 if iters >= max_iters: print('Convergence failed after {} iterations'.format(iters)) break if diff < tolc: print('Convergence achieved after {} iterations'.format(iters)) return c # In[4]: # Value Function Approximation # Set bounds and approximation order v_min = v_aut v_max = -0.065 c_min = 0 c_max = 50 order = 70 # Calculate nodes and basis matrix s, Phi = Cheb_basis(order, v_min, v_max) # Bounds for Maximisation lb = np.concatenate([np.ones(S)*c_min, np.ones(S)*v_min], axis=0) ub = np.concatenate([np.ones(S)*c_max, np.ones(S)*v_max], axis=0) # Initialize Value Function coefficients and goess for c,w y = (c_pool - u_inv(s*(1-beta)))/(1-beta) c = np.linalg.solve(Phi, y) x_init = np.concatenate([np.ones(S)*c_min, np.ones(S)*v_min], axis=0) # Function to minimize and constraints def P_fun(x): scale = -1 + 2*(x[S:2*S] - v_min)/(v_max - v_min) P = np.dot(cheb.chebvander(scale,order-1),c) P_fun = - prob_grid.dot((y_grid - x[0:S]) + beta*P) return P_fun def cons12(y): global x return prob_grid.dot(u(y[0:S]) + beta*y[S:2*S]) - x cons1 = ({'type': 'ineq', 'fun': lambda y: u(y[0:S]) + beta*y[S:2*S] - u(y_grid) - beta*v_aut}, {'type': 'ineq', 'fun': cons12}) bnds1 = np.concatenate([lb.reshape(2*S, 1), ub.reshape(2*S, 1)], axis = 1) # Bellman Iterations NBell = 5 tolc = 1e-6 diff = 1 iters = 1 x_store = {} for i in range(order): x_store[i] = x_init c = Bellman_Iterations(s, Phi, P_fun, x_store, c, bnds=bnds1, cons=cons1) # In[ ]: # Time Series Simulation T = 100 np.random.seed(2) y_series = np.random.choice(y_grid,size = T,p = prob_grid) c_series = np.zeros(T) w_series = np.zeros(T) resid_series = np.zeros(T) pval_series = np.zeros(T) # Initialize v such that P(v) = 0 v_find = lambda v: cheb.chebvander(-1 + 2*(v - v_min)/(v_max - v_min),order-1).dot(c) x = fsolve(v_find,v_max) res = minimize(P_fun,x_init,method = 'SLSQP',bounds = bnds1,constraints = cons1,tol=1e-15) c_series[0] = res.x[np.where(y_grid == y_series[0])[0][0]] w_series[0] = res.x[S + np.where(y_grid == y_series[0])[0][0]] # Simulate for t in range(1,T): x = w_series[t-1] res = minimize(P_fun, x_init,method = 'SLSQP',bounds = bnds1, constraints = cons1, tol=1e-15) c_series[t] = res.x[np.where(y_grid == y_series[t])[0][0]] w_series[t] = res.x[S + np.where(y_grid == y_series[t])[0][0]] plt.plot(c_series, label = 'Environment (a)') plt.plot(np.ones(T)*c_pool, label = 'Complete Markets') plt.ylabel('Consumption') plt.xlabel('Time') plt.legend(loc = 'best'); plt.title('Environment (a)'); # The above simulation is equivalent to Figure 21.2.1.a in RMT. # # The discussion in RMT4 confirms that the household's consumption ratchets upwards over time. # # The consumption level is constant after the first time that the household receives the highest possible endowment. # # ## Environment b # # The second environment is one in which households *can* make commitments to enter into binding contracts with the planner, but they have private information about their incomes. # # Consequently, incentive compatability constraints are required to ensure that households truthfully report their incomes. # # Equations 21.5.1 to 21.5.5 in RMT4 express the planners's problem. # # \begin{align} # &P(v) = \max_{b_s,w_s} \sum_{s=1}^S \Pi_s \left[ -b_s + \beta P(w_s) \right] \\ # &\text{s.t.} \\ # &\sum_{s=1}^S \Pi_s \left[ u(\bar y_s + b_s) + \beta w_s \right] = v \\ # & C_{s,k} \equiv u(\bar y_s + b_s) + \beta w_s - [ u(\bar y_s + b_k) + \beta w_k ] \geq 0 \hspace{2mm} \forall \hspace{2mm} s,k \in S \times S\\ # &b_s \in [a - \bar y_s,\infty ] \\ # &w_s \in [- \infty, v_{max}] # \end{align} # # Here $b_s$ is the transfer that the moneylender gives to a household who reports income $y_s$ if their promised value was $v$. # # The promise keeping constraint remains, while the participation constraint has been replaced by a large set of incentive compatibility constraints. # # RMT4 shows that we can discard many of the incentive compatibility constraints. # # In solving the model below, we keep only the local upward and downward incentive compatibility constraints. # In[ ]: # Set bounds and approximation order b_min = -20 b_max = 20 w_min = -150; w_max = -0.04; v_min = -150; v_max = -0.04; v_pool = u(c_pool)/(1-beta) order = 70 # Calculate nodes and basis matrix s, Phi = Cheb_basis(order,v_min,v_max) # Bounds for Maximisation lb = np.concatenate([np.ones(S)*b_min,np.ones(S)*w_min], axis=0) ub = np.concatenate([np.ones(S)*b_max,np.ones(S)*w_max], axis=0) # For initial guess, use upper bound given in RMT: cbar = np.zeros(order) upper = np.zeros(order) for i in range(order): cbar[i] = u_inv((1-beta)*s[i]) upper[i] = np.dot(prob_grid,(y_grid - cbar[i])/(1-beta)) c = np.linalg.solve(Phi,upper) # Function to minimize and constraints def P_fun2(x): scale = -1 + 2*(x[S:2*S] - v_min)/(v_max - v_min) P = np.dot(cheb.chebvander(scale,order-1),c) P_fun = - prob_grid.dot(-x[0:S] + beta*P) return P_fun def cons23(y): global x return prob_grid.dot(u(y_grid + y[0:S]) + beta*y[S:2*S]) - x cons2 = ({'type': 'ineq', 'fun': lambda x: u(y_grid[1:S] + x[1:S]) + beta*x[S+1:2*S] - u(y_grid[1:S] + x[0:S-1]) - beta*x[S:2*S-1]}, {'type': 'ineq', 'fun': lambda x: u(y_grid[0:S-1] + x[0:S-1]) + beta*x[S:2*S-1] - u(y_grid[0:S-1] + x[1:S]) - beta*x[S+1:2*S]}, {'type': 'eq', 'fun': cons23}) bnds2 = np.concatenate([lb.reshape(2*S,1),ub.reshape(2*S,1)], axis = 1) x_store = {} for i in range(order): x_store[i] = np.concatenate([np.zeros(S),np.ones(S)*s[i]], axis=0) c = Bellman_Iterations(s, Phi, P_fun2, x_store, c, tolc, bnds=bnds2, cons=cons2) # In[ ]: # Time Series Simulation T = 800 np.random.seed(2) y_series = np.random.choice(y_grid,size = T+1, p = prob_grid) c_series = np.zeros(T) w_series = np.zeros(T) # Initialize v such that P(v) = 0 v_find = lambda v: cheb.chebvander(-1 + 2*(v - v_min)/(v_max - v_min),order-1).dot(c) x = fsolve(v_find,v_aut) x_init = np.concatenate([np.zeros(S),np.ones(S)*x],axis=0) res = minimize(P_fun2,x_init,method = 'SLSQP',bounds = bnds2, constraints = cons2,tol=1e-10) c_series[0] = y_series[0] + res.x[np.where(y_grid == y_series[0])[0][0]] w_series[0] = res.x[S + np.where(y_grid == y_series[0])[0][0]] x_init = res.x # Simulate for t in range(1,T): x = w_series[t-1] res = minimize(P_fun2,x_init,method = 'SLSQP',bounds = bnds2,constraints = cons2,tol=1e-10) c_series[t] = y_series[t] + res.x[np.where(y_grid == y_series[t])[0][0]] w_series[t] = res.x[S + np.where(y_grid == y_series[t])[0][0]] x_init = res.x # Plot plt.plot(c_series, label = 'Environment (b)') plt.plot(np.ones(T)*c_pool, label = 'Complete Markets') plt.ylabel('Consumption') plt.xlabel('Time') plt.title('Environment (b)') plt.legend(loc = 'best'); # This simulation reported in the graph above confirms that in environment **b** the incentive compatibility constraints induce the planner to introduce a downward tilt into consumption paths. # # ## Environment c # # The third environment is the same as in (b), except for the additional assumption that households have access to a storage technology. # # A household can store nonnegative amounts that cannot be observed by the planner. # # The text of RMT4 chaper 21 shows that the solution to this problem is the same as in an economy in which each household can lend *or borrow* at the risk-free gross interest rate R, subject to the natural debt limit. # # Thus, the planner enables the household to relax the no-borrowing constraint implied by the restriction that it can store only nonnegative amounts # # We can find the natural debt limit by iterating forward on the households budget constraint: # # \begin{equation} # c + k' = y + Rk # \end{equation} # This iteration gives: # \begin{equation} # k = \frac{1}{R} \sum_{j=0}^\infty \frac{c - y}{R^j} # \end{equation} # # Imposing non-negativity on consumption: # # \begin{equation} # k \geq - \frac{1}{R} \sum_{j=0}^\infty \frac{y}{R^j} # \end{equation} # # Finally, the natural debt limit is found by choosing the lowest possible value of the endowment, so that for any possible endowment stream the household can always pay back its debts: # # \begin{equation} # k \geq - \frac{1}{R} \sum_{j=0}^\infty \frac{\bar y_{min}}{R^j} = - \frac{\bar y_{min}}{R-1} \equiv \phi # \end{equation} # # A recursive presentation of the household's problem is then: # \begin{align} # &V(k,y) = \max_{c,k'} u(c) + \beta E [V(k',y')] \\ # &\text{s.t.} \\ # &c + k' = y + Rk \\ # & k' \geq \phi # \end{align} # # As income is iid, we can re-write the household's problem with only one state. # # Define a = k + y. # # Then # \begin{align} # &V(a) = \max_{c,k'} u(c) + \beta E [V(Rk' + y')] \\ # &\text{subject to} \\ # &c + k' = a \\ # & k' \geq \phi # \end{align} # # Below we solve this latter problem using Value Function Iteration, again with Chebyshev polynomials. # In[ ]: # Update parameter values # Set bounds and approximation order R = 1/beta k_min = - y_grid[0]/(R - 1) k_max = 100 a_min = R*k_min + min(y_grid) a_max = R*k_max + max(y_grid) order = 150 # Calculate nodes and basis matrix s, Phi = Cheb_basis(order,a_min,a_max) # Create bounds bnds3 = np.array([[k_min,k_max]]) # Value function def P_fun3(kprime): global x,c # Function to minimize scale = -1 + 2*(R*kprime + y_grid - a_min)/(a_max - a_min) P_fun = -(u(x - kprime) + beta * prob_grid.dot(cheb.chebval(scale, c))) return P_fun # Initialize guess and VF coefficients c = np.zeros(order) x_store = {} for i in range(order): x_store[i] = k_min c = Bellman_Iterations(s, Phi, P_fun3, x_store, c, bnds=bnds3) # In[ ]: # Time Series Simulation T = 800 np.random.seed(2) y_series = np.random.choice(y_grid, size = T+1, p = prob_grid) a_series = np.zeros(T+1) c_series = np.zeros(T) # Initialise at v_aut def k_find(k): scale = -1 + 2 * (R * k + y_grid - a_min)/(a_max - a_min) return prob_grid.dot(cheb.chebval(scale,c)) - v_aut k0 = fsolve(k_find,0) a_series[0] = k0 + y_series[0] # Simulate for t in range(T): x = a_series[t] res = minimize(P_fun3, k_min,method='SLSQP', bounds=bnds3,tol=1e-15) c_series[t] = a_series[t] - res.x a_series[t+1] = R * res.x + y_series[t+1] # Plot plt.plot(c_series, label = 'Environment (c)') plt.plot(np.ones(T)*c_pool, label = 'Complete Markets') plt.ylabel('Consumption') plt.xlabel('Time') plt.title('Environment (c)') plt.legend(loc = 'best') # Notice that the introduction of a storage technology for the household means that the consumption path now has an upward trend. # # This occurs because our parameter values satisfy $\beta R = 1$.