import pandas as pd from pandas_datareader.data import DataReader import matplotlib.pyplot as plt from datetime import date from statsmodels.tsa.stattools import acf from statsmodels.graphics.tsaplots import plot_acf series = 'DGS10' datasource = 'fred' start = date(1984, 1, 1) end = date(2017, 1, 1) data = DataReader(series, datasource, start) data['dailydiff'] = data.diff() autocorrelation_daily = data['dailydiff'].autocorr() print("The autocorrelation of daily " + str(series) + " changes is %4.2f" % (autocorrelation_daily)) weekly_data = data[series].resample('W').last() weekly_data['weeklydiff'] = weekly_data.diff() autocorrelation_weekly = weekly_data['weeklydiff'].autocorr() print("The autocorrelation of weekly " + str(series) + " changes is %4.2f" % (autocorrelation_weekly)) monthly_data = data[series].resample('M').last() monthly_data['monthlydiff'] = monthly_data.diff() autocorrelation_monthly = monthly_data['monthlydiff'].autocorr() print("The autocorrelation of monthly " + str(series) + " changes is %4.2f" % (autocorrelation_monthly)) annual_data = data[series].resample('A').last() annual_data['annualdiff'] = annual_data.diff()
# # As described above, the goal of this model was to create an # interpretable series which could be used to understand the current status # of the macroeconomy. This is what the coincident index is designed to do. # It is constructed below. For readers interested in an explanation of the # construction, see Kim and Nelson (1999) or Stock and Watson (1991). # # In essense, what is done is to reconstruct the mean of the (differenced) # factor. We will compare it to the coincident index on published by the # Federal Reserve Bank of Philadelphia (USPHCI on FRED). usphci = DataReader( 'USPHCI', 'fred', start='1979-01-01', end='2014-12-01')['USPHCI'] usphci.plot(figsize=(13, 3)) dusphci = usphci.diff()[1:].values def compute_coincident_index(mod, res): # Estimate W(1) spec = res.specification design = mod.ssm['design'] transition = mod.ssm['transition'] ss_kalman_gain = res.filter_results.kalman_gain[:, :, -1] k_states = ss_kalman_gain.shape[0] W1 = np.linalg.inv( np.eye(k_states) - np.dot(np.eye(k_states) - np.dot(ss_kalman_gain, design), transition) ).dot(ss_kalman_gain)[0]
# # As described above, the goal of this model was to create an # interpretable series which could be used to understand the current status # of the macroeconomy. This is what the coincident index is designed to do. # It is constructed below. For readers interested in an explanation of the # construction, see Kim and Nelson (1999) or Stock and Watson (1991). # # In essense, what is done is to reconstruct the mean of the (differenced) # factor. We will compare it to the coincident index on published by the # Federal Reserve Bank of Philadelphia (USPHCI on FRED). usphci = DataReader('USPHCI', 'fred', start='1979-01-01', end='2014-12-01')['USPHCI'] usphci.plot(figsize=(13, 3)) dusphci = usphci.diff()[1:].values def compute_coincident_index(mod, res): # Estimate W(1) spec = res.specification design = mod.ssm['design'] transition = mod.ssm['transition'] ss_kalman_gain = res.filter_results.kalman_gain[:, :, -1] k_states = ss_kalman_gain.shape[0] W1 = np.linalg.inv( np.eye(k_states) - np.dot(np.eye(k_states) - np.dot(ss_kalman_gain, design), transition) ).dot(ss_kalman_gain)[0]
def dynamic_factor_model_example(): np.set_printoptions(precision=4, suppress=True, linewidth=120) # Get the datasets from FRED. start = '1979-01-01' end = '2014-12-01' indprod = DataReader('IPMAN', 'fred', start=start, end=end) income = DataReader('W875RX1', 'fred', start=start, end=end) sales = DataReader('CMRMTSPL', 'fred', start=start, end=end) emp = DataReader('PAYEMS', 'fred', start=start, end=end) #dta = pd.concat((indprod, income, sales, emp), axis=1) #dta.columns = ['indprod', 'income', 'sales', 'emp'] #HMRMT = DataReader('HMRMT', 'fred', start='1967-01-01', end=end) #CMRMT = DataReader('CMRMT', 'fred', start='1997-01-01', end=end) #HMRMT_growth = HMRMT.diff() / HMRMT.shift() #sales = pd.Series(np.zeros(emp.shape[0]), index=emp.index) # Fill in the recent entries (1997 onwards). #sales[CMRMT.index] = CMRMT # Backfill the previous entries (pre 1997). #idx = sales.loc[:'1997-01-01'].index #for t in range(len(idx)-1, 0, -1): # month = idx[t] # prev_month = idx[t-1] # sales.loc[prev_month] = sales.loc[month] / (1 + HMRMT_growth.loc[prev_month].values) dta = pd.concat((indprod, income, sales, emp), axis=1) dta.columns = ['indprod', 'income', 'sales', 'emp'] dta.loc[:, 'indprod':'emp'].plot(subplots=True, layout=(2, 2), figsize=(15, 6)); # Create log-differenced series. dta['dln_indprod'] = (np.log(dta.indprod)).diff() * 100 dta['dln_income'] = (np.log(dta.income)).diff() * 100 dta['dln_sales'] = (np.log(dta.sales)).diff() * 100 dta['dln_emp'] = (np.log(dta.emp)).diff() * 100 # De-mean and standardize. dta['std_indprod'] = (dta['dln_indprod'] - dta['dln_indprod'].mean()) / dta['dln_indprod'].std() dta['std_income'] = (dta['dln_income'] - dta['dln_income'].mean()) / dta['dln_income'].std() dta['std_sales'] = (dta['dln_sales'] - dta['dln_sales'].mean()) / dta['dln_sales'].std() dta['std_emp'] = (dta['dln_emp'] - dta['dln_emp'].mean()) / dta['dln_emp'].std() # Get the endogenous data. endog = dta.loc['1979-02-01':, 'std_indprod':'std_emp'] # Create the model. mod = sm.tsa.DynamicFactor(endog, k_factors=1, factor_order=2, error_order=2) initial_res = mod.fit(method='powell', disp=False) res = mod.fit(initial_res.params, disp=False) print(res.summary(separate_params=False)) # Estimated factors. fig, ax = plt.subplots(figsize=(13, 3)) # Plot the factor. dates = endog.index._mpl_repr() ax.plot(dates, res.factors.filtered[0], label='Factor') ax.legend() # Retrieve and also plot the NBER recession indicators. rec = DataReader('USREC', 'fred', start=start, end=end) ylim = ax.get_ylim() ax.fill_between(dates[:-3], ylim[0], ylim[1], rec.values[:-4,0], facecolor='k', alpha=0.1) # Post-estimation. res.plot_coefficients_of_determination(figsize=(8, 2)) # Coincident index. usphci = DataReader('USPHCI', 'fred', start='1979-01-01', end='2014-12-01')['USPHCI'] usphci.plot(figsize=(13, 3)) dusphci = usphci.diff()[1:].values fig, ax = plt.subplots(figsize=(13, 3)) # Compute the index. coincident_index = compute_coincident_index(mod, res, dta, usphci, dusphci) # Plot the factor. dates = endog.index._mpl_repr() ax.plot(dates, coincident_index, label='Coincident index') ax.plot(usphci.index._mpl_repr(), usphci, label='USPHCI') ax.legend(loc='lower right') # Retrieve and also plot the NBER recession indicators. ylim = ax.get_ylim() ax.fill_between(dates[:-3], ylim[0], ylim[1], rec.values[:-4,0], facecolor='k', alpha=0.1) # Extended dynamic factor model. # Create the model. extended_mod = ExtendedDFM(endog) initial_extended_res = extended_mod.fit(maxiter=1000, disp=False) extended_res = extended_mod.fit(initial_extended_res.params, method='nm', maxiter=1000) print(extended_res.summary(separate_params=False)) extended_res.plot_coefficients_of_determination(figsize=(8, 2)) fig, ax = plt.subplots(figsize=(13,3)) # Compute the index. extended_coincident_index = compute_coincident_index(extended_mod, extended_res, dta, usphci, dusphci) # Plot the factor. dates = endog.index._mpl_repr() ax.plot(dates, coincident_index, '-', linewidth=1, label='Basic model') ax.plot(dates, extended_coincident_index, '--', linewidth=3, label='Extended model') ax.plot(usphci.index._mpl_repr(), usphci, label='USPHCI') ax.legend(loc='lower right') ax.set(title='Coincident indices, comparison') # Retrieve and also plot the NBER recession indicators. ylim = ax.get_ylim() ax.fill_between(dates[:-3], ylim[0], ylim[1], rec.values[:-4,0], facecolor='k', alpha=0.1)