US Production Data for RBC Modeling


In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from fredpy import series, window_equalize, toFredSeries
%matplotlib inline

In [2]:
# Download nominal GDP, nominal personal consumption expenditures, nominal
# gross private domestic investment, the GDP deflator, and an index of hours 
# worked in the nonfarm business sector produced by the BLS. All data are
# from FRED and are quarterly.

gdp = series('GDP')
cons = series('PCEC')
invest = series('GPDI')
hours = series('HOANBS')
defl = series('GDPDEF')

# Make sure that all of the downloaded series have the same data ranges
gdp,cons,invest,hours,defl = window_equalize([gdp,cons,invest,hours,defl])

# Compute real GDP, real consumption, real investment
gdp.data = gdp.data/defl.data*100
cons.data = cons.data/defl.data*100
invest.data = invest.data/defl.data*100

Next, compute the quarterly capital stock series for the US using the perpetual inventory method. The discrete-time Solow growth model is given by:

\begin{align} Y_t & = A_tK_t^{\alpha}L_t^{1-\alpha} \tag{1}\\ C_t & = (1-s)Y_t \tag{2}\\ Y_t & = C_t + I_t \tag{3}\\ K_{t+1} & = I_t + (1-\delta)K_t \tag{4}\\ A_{t+1} & = (1+g)A_t \tag{5}\\ L_{t+1} & = (1+n)L_t \tag{6}. \end{align}

Here the model is assumed to be quarterly so $n$ is the quarterly growth rate of labor hours, $g$ is the quarterly growth rate of TFP, and $\delta$ is the quarterly rate of depreciation of the capital stock. Given a value of the quarterly depreciation rate $\delta$, an investment series $I_t$, and an initial capital stock $K_0$, the law of motion for the capital stock, Equation (4), can be used to compute an implied capital series. But we don't know $K_0$ or $\delta$ so we'll have to calibrate these values using statistics computed from the data that we've already obtained.

Let lowercase letters denote a variable that's been divided by $A_t^{1/(1-\alpha)}L_t$. E.g.,

\begin{align} y_t = \frac{Y_t}{A_t^{1/(1-\alpha)}L_t}\tag{7} \end{align}

Then (after eliminating consumption from the model), the scaled version of the model can be written as:

\begin{align} y_t & = k_t^{\alpha} \tag{8}\\ i_t & = sy_t \tag{9}\\ k_{t+1} & = i_t + (1-\delta-n-g')k_t,\tag{10} \end{align}

where $g' = g/(1-\alpha)$ is the growth rate of $A_t^{1/(1-\alpha)}$. In the steady state:

\begin{align} k & = \left(\frac{s}{\delta+n+g'}\right)^{\frac{1}{1-\alpha}} \tag{11} \end{align}

which means that the ratio of capital to output is constant:

\begin{align} \frac{k}{y} & = \frac{s}{\delta+n+g'} \tag{12} \end{align}

Furthermore, in the steady state, the growth rate of output is constant:

\begin{align} \frac{\Delta Y}{Y} & = n + g' \tag{13} \end{align}

  1. Assume $\alpha = 0.35$.
  2. Calibrate $s$ as the average of ratio of investment to GDP.
  3. Calibrate $n$ as the average quarterly growth rate of labor hours.
  4. Calibrate $g'$ as the average quarterly growth rate of real GDP minus n.
  5. Calculate the average ratio of depreciation to GDP $\Delta K /Y$ and use the result to calibrate $\delta$. That is, find the average ratio of Current-Cost Depreciation of Fixed Assets (FRED series ID: M1TTOTL1ES000) to GDP (FRED series ID: GDPA). Then calibrate $\delta$ from the following steady state relationship: \begin{align} \delta & = \frac{\left( \frac{\Delta K}{Y} \right)\left(n + g' \right)}{s - \left( \frac{\Delta K}{Y} \right)} \tag{12} \end{align}
  6. Calibrate $K_0$ by asusming that the capital stock is initially equal to its steady state value: \begin{align} K_0 & = \left(\frac{s}{\delta + n + g'}\right) Y_0 \tag{13} \end{align}

Then, armed with calibrated values for $K_0$ and $\delta$, compute $K_1, K_2, \ldots$ recursively. See Timothy Kehoe's notes for more information on the perpetual inventory method:

http://users.econ.umn.edu/~tkehoe/classes/GrowthAccountingNotes.pdf


In [3]:
# Set the capital share of income
alpha = 0.35

# Average saving rate
s = np.mean(invest.data/gdp.data)

# Average quarterly labor hours growth rate
n = (hours.data[-1]/hours.data[0])**(1/(len(hours.data)-1)) - 1

# Average quarterly real GDP growth rate
g = ((gdp.data[-1]/gdp.data[0])**(1/(len(gdp.data)-1)) - 1) - n

# Compute annual depreciation rate
depA = series('M1TTOTL1ES000')
gdpA = series('gdpa')

gdpA = gdpA.window([gdp.dates[0],gdp.dates[-1]])
gdpA,depA = window_equalize([gdpA,depA])

deltaKY = np.mean(depA.data/gdpA.data)
delta = (n+g)*deltaKY/(s-deltaKY)

# print calibrated values:
print('Avg saving rate:        ',round(s,5))
print('Avg annual labor growth:',round(4*n,5))
print('Avg annual gdp growth:  ',round(4*g,5))
print('Avg annual dep rate:    ',round(4*delta,5))

# Construct the capital series. Note that the GPD and investment data are reported on an annualized basis
# so divide by 4 to get quarterly data.
capital = np.zeros(len(gdp.data))
capital[0] = gdp.data[0]/4*s/(n+g+delta)

for t in range(len(gdp.data)-1):
    capital[t+1] = invest.data[t]/4 + (1-delta)*capital[t]

# Save in a fredpy series
capital = toFredSeries(data = capital,dates =gdp.dates,units = gdp.units,title='Capital stock of the US',freq='Quarterly')

# plot the computed capital series
plt.plot_date(capital.dates,capital.data,'-',lw=3,alpha = 0.7)
plt.grid()
plt.ylabel(capital.units)
plt.title(capital.title)


Avg saving rate:         0.17169
Avg annual labor growth: 0.01218
Avg annual gdp growth:   0.01893
Avg annual dep rate:     0.12697
Out[3]:
<matplotlib.text.Text at 0x1184af0b8>

In [4]:
# Compute TFP
tfp = gdp.data/capital.data**alpha/hours.data**(1-alpha)
tfp = toFredSeries(data = tfp,dates =gdp.dates,units = gdp.units,title='TFP of the US',freq='Quarterly')

# Plot the computed capital series
plt.plot_date(tfp.dates,tfp.data,'-',lw=3,alpha = 0.7)
plt.grid()
plt.ylabel(tfp.units)
plt.title(tfp.title)


Out[4]:
<matplotlib.text.Text at 0x118697be0>

In [5]:
# Convert each series into per capita using civilian pop 16 and over
gdp = gdp.percapita(civ_pop=True)
cons = cons.percapita(civ_pop=True)
invest = invest.percapita(civ_pop=True)
hours = hours.percapita(civ_pop=True)
capital = capital.percapita(civ_pop=True)

# Put GDP, consumption, and investment in units of thousands of dollars per person
gdp.data = gdp.data*1000
cons.data = cons.data*1000
invest.data = invest.data*1000
capital.data = capital.data*1000

# Scale hours per person to equal 100 on October (Quarter III) of 2009 
hours.data = hours.data/hours.data[hours.dates.index('2009-10-01')]*100

# Make sure TFP series has same length as the rest (since the .percapita() function may affect the date range.
tfp,gdp = window_equalize([tfp,gdp])

# Compute and plot log real GDP, log consumption, log investment, log hours
gdp_log = gdp.log()
cons_log = cons.log()
invest_log = invest.log()
hours_log = hours.log()
capital_log = capital.log()
tfp_log = tfp.log()

# HP filter to isolate trend and cyclical components
gdp_log_cycle,gdp_log_trend = gdp_log.hpfilter()
cons_log_cycle,cons_log_trend = cons_log.hpfilter()
invest_log_cycle,invest_log_trend = invest_log.hpfilter()
hours_log_cycle,hours_log_trend = hours_log.hpfilter()
capital_log_cycle,capital_log_trend = capital_log.hpfilter()
tfp_log_cycle,tfp_log_trend = tfp_log.hpfilter()

In [6]:
# Create a DataFrame with actual and trend data
data = pd.DataFrame({
        'gdp':gdp.data,
        'gdp_trend':np.exp(gdp_log_trend.data),
        'consumption':cons.data,
        'consumption_trend':np.exp(cons_log_trend.data),
        'investment':invest.data,
        'investment_trend':np.exp(invest_log_trend.data),
        'hours':hours.data,
        'hours_trend':np.exp(hours_log_trend.data),
        'capital':capital.data,
        'capital_trend':np.exp(capital_log_trend.data),
        'tfp':tfp.data,
        'tfp_trend':np.exp(tfp_log_trend.data),
    },index = pd.DatetimeIndex(gdp.dates))

columns_ordered =[]
names = ['gdp','consumption','investment','hours','capital','tfp']
for name in names:
    columns_ordered.append(name)
    columns_ordered.append(name+'_trend')
    
data[columns_ordered].to_csv('Econ129_Rbc_Data.csv')