# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] id="view-in-github" colab_type="text"
# <a href="https://colab.research.google.com/github/abhiruchi97/Econometrics-in-Python/blob/master/Trend_component__time_series.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>

# + id="GiddzBsIyu5S" colab_type="code" colab={}
## Authors: <NAME> & <NAME>
## 31st May 2020

# + id="YWX_KAgoJnnE" colab_type="code" colab={}
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pandas_datareader as pdr
import seaborn as sns
# #!pip install statsmodels --upgrade
import statsmodels.api as sm
from statsmodels.tsa.ar_model import AutoReg, ar_select_order
from statsmodels.tsa.api import acf, pacf, graphics
from datetime import datetime

# + [markdown] id="rznz9Xjd3Kmu" colab_type="text"
# ## The objective of this exercise is to extract the trend component of a time-series
# #### Example: In macroeconomics, the moving natural rate theory suggests that the unemployment rate is a stationary series around its moving target and its steady state- the natural rate of unemployment. Hence, the trend component of the unemployment series is equal to the natural rate. We will estimate the natural rate using data on monthly unemployment rate, using the following methodologies:
#
#
# *   Hodrick-Prescott filter
# *   Baxter-King filter
# *   Christiano-Fitzgerald filter
# *   Beveridge-Nelson decomposition
#
#
#
#
#

# + id="BlvxSj4FL855" colab_type="code" outputId="16e63121-e350-42c2-832a-896618d953d4" colab={"base_uri": "https://localhost:8080/", "height": 235}
unemp_m = pd.read_csv("unemp_monthly.csv", parse_dates=True, index_col = 'DATE')
unemp_m.dropna(inplace = True)
unemp_m.head()

# + [markdown] id="MXvr9M1c5m32" colab_type="text"
# ### Hodrick-Prescott (HP) filter

# + id="sZ90JCph5mbR" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 320} outputId="bbc5cf5a-1c04-4f56-e395-7146cef0eec9"
hp_cycle, hp_trend = sm.tsa.filters.hpfilter(unemp_m['UNRATE'])
#unemp_m['hp_cycle'] = hp_cycle
unemp_m['hp_trend'] = hp_trend

unemp_m.plot(subplots = True, figsize = (10,4))

# + [markdown] id="IvacZHPImTno" colab_type="text"
# ### Baxter-King approximate band-pass filter

# + id="G7m6z0crmx0O" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 337} outputId="fdab6c94-220d-4edc-d195-4d2fb0e5ef31"
bk_cycles = sm.tsa.filters.bkfilter(unemp_m['UNRATE'])
unemp_m['bk_trend'] = unemp_m['UNRATE'] - pd.Series(bk_cycles)
unemp_m.plot(subplots = True, figsize = (10,4))

# + [markdown] id="SaC5B7dl-Jp7" colab_type="text"
# ## Christiano-Fitzgerald approximate band-pass filter

# + id="8K8hpnB9-Pp0" colab_type="code" outputId="8d99cf04-0a62-4469-afd7-4f5f340f301c" colab={"base_uri": "https://localhost:8080/", "height": 452}
cf_cycles, cf_trend = sm.tsa.filters.cffilter(unemp_m['UNRATE'])
#unemp_m['cf_cycle'] = cf_cycles
unemp_m['cf_trend'] = cf_trend
unemp_m.plot(subplots = True, figsize = (10,6))

# + [markdown] id="3UZs8Nj9a0UE" colab_type="text"
# ### Beveridge-Nelson decomposition

# + id="uQcGACtxAMsP" colab_type="code" outputId="31302e65-d617-4227-adb4-495ae7503bdf" colab={"base_uri": "https://localhost:8080/", "height": 235}
bn_dec = pd.read_csv("unemp_monthly.csv", parse_dates=True, index_col = 'DATE')
bn_dec.head()

# + id="xd738-gIANG1" colab_type="code" outputId="24169134-88eb-4177-fe95-883d956083d1" colab={"base_uri": "https://localhost:8080/", "height": 235}
bn_dec["diff"] = bn_dec["UNRATE"] - bn_dec["UNRATE"].shift(1)
bn_dec["diff_mean"] = bn_dec["diff"] - bn_dec['diff'].mean()
bn_dec.dropna(inplace=True)
bn_dec.head()

# + id="Ts6jFvInAMnX" colab_type="code" outputId="50417615-698a-4663-d4c1-21ff6a58c0a4" colab={"base_uri": "https://localhost:8080/", "height": 513}
# Taking 8 lags and auto-selecting the best orders of autoregression on the differenced series of unemployment rate

select = ar_select_order(bn_dec["diff_mean"], 8, trend= 'n', glob=True)
select.ar_lags
res = select.model.fit()
print(res.summary())

# + id="opx7ALIJRle6" colab_type="code" outputId="19405ac0-ab25-4169-98ed-82bbb89fa1e5" colab={"base_uri": "https://localhost:8080/", "height": 235}
'''The formula for BN trend component = y_t + (phi/1-phi) * delta(differenced(1)-mean)_t
From the results above, all our 3 selected AR lags have p-values=0; we choose diff_mean.L4 i.e. the 4th lag = 0.1791 = phi and put in the above formula
RHS gives the BN trend = natural rate estimates'''

bn_dec['natural_rate'] = bn_dec['UNRATE'] + (0.1791/(1-0.1791)) * bn_dec['diff_mean']
bn_dec.head()

# + id="TmldH766TAFD" colab_type="code" outputId="8d26d1cd-7689-4c09-bac3-e37a79d4f624" colab={"base_uri": "https://localhost:8080/", "height": 297}
# Plotting the natural rate derived from BN decomposition alongside the actual unemployment rate series

plt.figure(figsize=(10, 4))
plt.plot(bn_dec.index, bn_dec['UNRATE'], label="Unemployment rate", c="dodgerblue", linewidth=1.5)
plt.plot(bn_dec.index, bn_dec['natural_rate'], linestyle = '--', c="crimson", label="BN decomposition", linewidth=1.25)
plt.xlabel("Year")
plt.ylabel("Unemployment (%)")
plt.legend()
plt.tight_layout()

# + [markdown] id="CiJ79wDpqwLD" colab_type="text"
# ### Plotting all versions of the trend component

# + id="ylLDkgbZqpf_" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 235} outputId="094555e8-e1ea-44a3-fc4c-e34612f3341c"
unemp_m = pd.concat([unemp_m, bn_dec['natural_rate']], axis=1)
unemp_m.iloc[0,4] = 6.10
unemp_m.head()

# + id="MKjFciturN9t" colab_type="code" colab={}
unemp_m.dropna(inplace = True)


# + id="wqxkNc4ms8sj" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 420} outputId="0d54c530-f57c-4c2f-89f2-02940c851d83"
unemp_m.plot(subplots = True, figsize = (10,5))

# + id="oY2no37WtDZN" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="1ebcd15d-251a-4af4-8feb-8c54c6bd6b1f"
lst = [i+"_error" for i in unemp_m.columns[1:]]
lst

# + id="rGpyVWNZt7Lk" colab_type="code" colab={}
unemp_m[lst[0]] = unemp_m['UNRATE'] - unemp_m['hp_trend']
unemp_m[lst[1]] = unemp_m['UNRATE'] - unemp_m['bk_trend']
unemp_m[lst[2]] = unemp_m['UNRATE'] - unemp_m['cf_trend']
unemp_m[lst[3]] = unemp_m['UNRATE'] - unemp_m['natural_rate']

# + id="1wROhwX-uojO" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 235} outputId="11ba7c14-87ad-48a4-8f2e-b3c064c72593"
unemp_m.head()

# + id="jCUBwXQvurG0" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 235} outputId="5fad4d1e-43fb-4210-c1b8-48759cd38b54"
unemp_m[lst] = unemp_m[lst].apply(lambda x: x**2)
unemp_m.head()

# + id="qWBkxhM6vXoc" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 85} outputId="0cdca02b-6b6b-4ce2-b04a-c9158d915ccf"
for i in lst:
  k = np.sqrt(unemp_m[i].sum())/len(unemp_m)
  print('RMSE for {} is {}'.format(i,k))

# + [markdown] id="eaqrhrYgx2Kq" colab_type="text"
# In conclusion, the Root Mean Squared Error (RMSE) i.e. the standard deviation of residuals is lowest for BN decomposition as compared to the other filters used for deriving trend components. However, this does not imply that the BN trend is the best representation of the natural rate, since we do not actually observe the natural rate.

StarcoderdataJupyterScriptsDedupFiltered