In [1]:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import linearsolve as ls
%matplotlib inline

Class 17: A Centralized Real Business Cycle Model without Labor

The Model

Setup

A representative household lives for an infinite number of periods. The expected present value of lifetime utility to the household from consuming $C_0, C_1, C_2, \ldots $ is denoted by $U_0$:

\begin{align} U_0 & = \log (C_0) + \beta E_0 \log (C_1) + \beta^2 E_0 \log (C_2) + \cdots\\ & = E_0\sum_{t = 0}^{\infty} \beta^t \log (C_t), \end{align}

where $0<\beta<1$ is the household's subjective discount factor. $E_0$ denotes the expectation with respect to all information available as of date 0.

The household enters period 0 with capital $K_0>0$. Production in period $t$:

\begin{align} F(A_t,K_t) & = A_t K_t^{\alpha} \end{align}

where TFP $A_t$ is stochastic:

\begin{align} \log A_{t+1} & = \rho \log A_t + \epsilon_{t+1} \end{align}

Capital depreciates at the constant rate $\delta$ per period and so the household's resource constraint in each period $t$ is:

\begin{align} C_t + K_{t+1} & = A_t K_{t}^{\alpha} + (1-\delta)K_t \end{align}

Optimization problem

In period 0, the household solves:

\begin{align} & \max_{C_0,K_1} \; E_0\sum_{t=0}^{\infty}\beta^t\log (C_t) \\ & \; \; \; \; \; \; \; \; \text{s.t.} \; \; \; \; C_t + K_{t+1} = A_t K_{t}^{\alpha} + (1-\delta)K_t \end{align}

which can be written as a choice of $K_1$ only:

\begin{align} \max_{K_1} \; E_0\sum_{t=0}^{\infty}\beta^t\log \left( A_t K_{t}^{\alpha} + (1-\delta)K_t - K_{t+1}\right) \end{align}

Equilibrium

So given $K_0>0$ and $A_0$, the equilibrium paths for consumption, capital, and TFP are described described by:

\begin{align} \frac{1}{C_t} & = \beta E_t \left[\frac{\alpha A_{t+1}K_{t+1}^{\alpha - 1} + 1 - \delta}{C_{t+1}}\right]\\ C_t + K_{t+1} & = A_{t} K_t^{\alpha} + (1-\delta) K_t\\ \log A_{t+1} & = \rho \log A_t + \epsilon_{t+1} \end{align}

Calibration

For computation purposes, assume the following values for the parameters of the model:

\begin{align} \beta & = 0.99\\ \rho & = .75\\ \sigma & = 0.006\\ \alpha & = 0.35\\ \delta & = 0.025 \end{align}

Steady State

The steady state:

\begin{align} A & = 1\\ K & = \left(\frac{\alpha A}{\beta^{-1} - 1 + \delta} \right)^{\frac{1}{1-\alpha}}\\ C & = AK^{\alpha} - \delta K \end{align}

In [2]:
# 1. Input model parameters and print
parameters = pd.Series()
parameters['rho'] = .75
parameters['sigma'] = 0.006
parameters['alpha'] = 0.35
parameters['delta'] = 0.025
parameters['beta'] = 0.99
print(parameters)


rho      0.750
sigma    0.006
alpha    0.350
delta    0.025
beta     0.990
dtype: float64

In [3]:
# 2. Compute the steady state of the model directly
A = 1
K = (parameters['alpha']*A/(parameters['beta']**-1+parameters['delta']-1))**(1/(1-parameters['alpha']))
C = A*K**parameters.alpha - parameters.delta*K

In [4]:
# 3. Define a function that evaluates the equilibrium conditions
def equilibrium_equations(variables_forward,variables_current,parameters):
    
    # Parameters 
    p = parameters
    
    # Variables
    fwd = variables_forward
    cur = variables_current
        
    # Resource constraint
    resource = cur.a*cur.k**p.alpha + (1-p.delta)* cur.k - fwd.k - cur.c
    
    # Exogenous tfp
    tfp_proc = p.rho*np.log(cur.a) - np.log(fwd.a)
    
    # Euler equation
    euler = p.beta*(p.alpha*fwd.a*fwd.k**(p.alpha-1) + 1 - p.delta)/fwd.c - 1/cur.c
    
    # Stack equilibrium conditions into a numpy array
    return np.array([
        resource,
        tfp_proc,
        euler
        ])

In [5]:
# 4. Initialize the model
model = ls.model(equations = equilibrium_equations,
                 nstates=2,
                 varNames=['a','k','c'],                   # Any order as long as the state variables are named first
                 shockNames=['eA','eK'],                 # Name a shock for each state variable *even if there is no corresponding shock in the model*
                 parameters = parameters)

In [6]:
# 5. Set the steady state of the model directly. 
model.set_ss([A,K,C])

In [7]:
# 6. Find the log-linear approximation around the non-stochastic steady state and solve
model.approximate_and_solve()

In [8]:
# 7. Print the approximated model in terms of log-deviations from the stady state
print(model.approximated())


Log-linear equilibrium conditions:

                            -34.3982·k[t+1] = -3.4497·a[t]-34.7457·k[t]+2.5898·c[t]

                                    -a[t+1] = -0.75·a[t]

0.0134·a[t+1]-0.0087·k[t+1]-0.3861·c[t+1|t] = -0.3861·c[t]

In [9]:
# 8(a) Compute impulse responses and print the computed impulse responses
model.impulse(T=41,t0=5,shock=None)
print(model.irs['eA'].head(10))


          a         c    eA         k
0  0.000000  0.000000  0.00  0.000000
1  0.000000  0.000000  0.00  0.000000
2  0.000000  0.000000  0.00  0.000000
3  0.000000  0.000000  0.00  0.000000
4  0.000000  0.000000  0.00  0.000000
5  0.010000  0.001253  0.01  0.000000
6  0.007500  0.001493  0.00  0.000909
7  0.005625  0.001654  0.00  0.001557
8  0.004219  0.001755  0.00  0.002013
9  0.003164  0.001812  0.00  0.002324

In [10]:
# 8(b) Plot the computed impulse responses to a TFP shock
fig = plt.figure(figsize=(12,4))

ax1 = fig.add_subplot(1,2,1)
model.irs['eA'][['a','k','c']].plot(lw=5,alpha=0.5,grid=True,ax = ax1).legend(loc='upper right',ncol=3)

ax2 = fig.add_subplot(1,2,2)
model.irs['eA'][['eA','a']].plot(lw=5,alpha=0.5,grid=True,ax = ax2).legend(loc='upper right',ncol=2)


Out[10]:
<matplotlib.legend.Legend at 0x111f387f0>

In [11]:
# 9() Compute stochastic simulation and print the simulated values
model.stoch_sim(seed=192,covMat= [[parameters['sigma']**2,0],[0,0]])
print(model.simulated.head(10))


          a         c        eA   eK         k
0  0.005779 -0.007326  0.000843  0.0 -0.013217
1  0.003489 -0.007005 -0.000845  0.0 -0.012219
2  0.000161 -0.006963 -0.002456  0.0 -0.011465
3 -0.003394 -0.007150 -0.003515  0.0 -0.011041
4 -0.006195 -0.007449 -0.003650  0.0 -0.010954
5 -0.007545 -0.007722 -0.002899  0.0 -0.011125
6 -0.006517 -0.007768 -0.000858  0.0 -0.011413
7  0.000981 -0.006941  0.005869  0.0 -0.011597
8  0.001545 -0.006563  0.000809  0.0 -0.011093
9 -0.006102 -0.007195 -0.007261  0.0 -0.010556

In [12]:
# 9(b) Plot the computed stochastic simulation
fig = plt.figure(figsize=(12,4))

ax1 = fig.add_subplot(1,2,1)
model.simulated[['a','c','k']].plot(lw=5,alpha=0.5,grid=True,ax = ax1).legend(loc='upper right',ncol=3)

ax2 = fig.add_subplot(1,2,2)
model.simulated[['eA','a']].plot(lw=5,alpha=0.5,grid=True,ax = ax2).legend(loc='upper right',ncol=2)


Out[12]:
<matplotlib.legend.Legend at 0x112498710>