NBER Heterogeneous-Agent Macro Workshop
Matthew Rognlie
Spring 2023
Four steps, middle two the hardest:
All our code from lecture boiled down into sim_steady_state.py
, refined slightly in sim_steady_state_fast.py
, which doubles speed
import sim_steady_state_fast as sim
Other Python libraries:
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
# some useful plot defaults
plt.rcParams.update({'font.size' : 20, 'lines.linewidth' : 3.5, 'figure.figsize' : (13,7)})
Our methods compute steady state of standard incomplete markets model given parameters, e.g.
calib = sim.example_calibration()
calib.keys()
ss = sim.steady_state(**calib)
ss['A']
But an alternative is to choose some parameters (for instance, $\beta$) to hit some targets (for instance, total assets equal to 5.6, or 1.4 times annual income):
beta_calib = optimize.brentq(
lambda beta: sim.steady_state(**{**calib, 'beta': beta})['A'] - 5.6,
0.98, 0.995)
ss = sim.steady_state(**{**calib, 'beta': beta_calib})
beta_calib, ss['A']
Embed partial equilibrium standard incomplete markets in simple general equilibrium setting:
Calibrate to same asset target:
calib = sim.example_calibration()
B = 5.6
tau = calib['r']*B
calib['y'] *= (1-tau)
beta_ge = optimize.brentq(lambda beta: sim.steady_state(**{**calib, 'beta': beta})['A'] - B, 0.98, 0.995)
ss_ge = sim.steady_state(**{**calib, 'beta': beta_ge})
Asset and goods market clearing:
ss_ge['A'] - B, ss_ge['C'] - 1
Vary some parameter of model, then recalculate $r$ to satisfy asset market clearing.
Here, let's change standard deviation of income:
sigmas = np.linspace(0.5, 0.9, 6) # our benchmark was sigma=0.7
rs = []
for sigma in sigmas:
e, pi, Pi = sim.discretize_income(0.975, sigma, 7)
rs.append(optimize.brentq(
lambda r: sim.steady_state(**{**calib, 'y': (1-r*B)*e, 'r': r, 'beta': beta_ge, 'Pi': Pi})['A'] - B,
-0.02, 0.01))
plt.plot(sigmas, 4*np.array(rs))
plt.xlabel('Cross-sectional standard deviation of income')
plt.ylabel('Equilibrium real interest rate (annualized)');
(Minor side note: using a narrower range of $\sigma$ here, since the larger range in original lecture required more forward iterations than sim_steady_state
code allows by default.)
curlyE = sim.expectation_functions(ss['a'], ss['Pi'], ss['a_i'], ss['a_pi'], 100)
plt.plot(curlyE[:, -1, 0]);