import matplotlib.pyplot as plt
import pandas as pd
from fredapi import Fred
fred = Fred(api_key="your_api_key")

start = '1948-01'
end = '2022-01'

unr = fred.get_series('UNRATE',  observation_start=start)
unr.index.freq = unr.index.inferred_freq
unr.name = 'Unemployment'
recessions = fred.get_series('USREC',  observation_start=start, observation_end=end)
recessions.name='recessions'
df = pd.merge(unr, recessions, how='outer', left_index=True, right_index=True)
df = df.fillna(value=0)
df.index.freq = df.index.inferred_freq
dates = df.index._mpl_repr()


indpr = fred.get_series('INDPRO',  observation_start=start, observation_end=end)
indpr.index.freq = indpr.index.inferred_freq
indpr.name = 'Industrial production'
indpr = indpr.to_frame()

Regime-switching models

Motivation

  • empirically, economic contractions are steeper and more short-lived than expansions

fig, ax = plt.subplots(figsize=(12,6))

df[['Unemployment']].plot(ax=ax)
ylim = ax.get_ylim()
ax.fill_between(dates, ylim[0], ylim[1], df[['recessions']].values.flatten(), facecolor='k', alpha=0.1);
../../_images/01-MS_3_0.png
fig2, ax = plt.subplots(figsize=(12,6))

indpr.plot(ax=ax)
ylim = ax.get_ylim()
ax.fill_between(dates, ylim[0], ylim[1], df[['recessions']].values.flatten(), facecolor='k', alpha=0.1);
../../_images/01-MS_4_0.png
  • asymmetry between different phases of the business cycle

  • linear models rule out different dynamics of variables during contractions and expansions

  • contractions are much less common part of the sample

    • trend-cycle decompositions based on linear models are better at representing dynamics during expansions.

  • non-linear models may be better at capturing the business cycle asymmetry

  • asymmetry may be explained by different propagation mechanism in contractions vs expansions, or by asymmetry in the shocks

    • capacity constraints, monopoly power, downward vs upward price/wage stickiness, etc

Regime-switching AR§ model

α(L)(ztμt)=εt,εtN(0,σt2)μt=μ0+μ1I(St=1)σt2=σ02+σ12I(St=1)St=0,1(expansion, contraction)
  • if St is known (observed) this model can be estimated in the usual way by MLE or OLS using dummies

(θ|z,S)=t=1Tln(p(zt|Zt1,St,St1,...,Stp))if p = 1ln(p(zt|Zt1,St,St1))=12ln(2πσt2)12σt2((ztμt)α1(yt1μt1))
  • not very appealing as this assumes regime switches are deterministic - can be predicted

  • if St is unobserved, we cannot condition on St,St1,...,Stp, and have to work with

(θ|z)=t=1Tln(p(zt|Zt1))
  • integrate out St,St1 from the joint density p(zt,St,St1|Zt1) by summing over all possible values of St and St1

p(zt|Zt1)=St=01St1=01p(zt,St,St1|Zt1)

using

p(zt,St,St1|Zt1)=p(zt|St,St1,Zt1)Pr(St,St1|Zt1)

we have

p(zt|Zt1)=St=01St1=01p(zt|St,St1,Zt1)Pr(St,St1|Zt1)
  • p(zt|St,St1,Zt1) computed as before (for known St)

Hamilton filter (Hamilton (1989)):

  • assumes time-invariant Markov chain

Pr[St=i|St1=j,St2=k,...,Zt1]=Pr[St=i|St1=j]=pij
  • what if p1,1=1?

  • restrictions?

p0,j+p1,j=1
  • computes Pr(St=i,St1=j|Zt1) iteratively starting with the unconditional probabilities

Pr(S1=0)=1p112p11p00,Pr(S1=1)=1p002p11p00

Markov-switching models in Statsmodels

Two classes of models:

markov-switching dynamic regression models

zt=μt+xtγ+ytβt+εt,εtN(0,σt2)

where both xt and yt may include lags of zt

  • zt depends only on the current state (the intercept has 2 possible values for a model with 2 states)

markov-switching autoregression models

zt=μt+xtγ+ytβt+i=1pαi,t(ztiμt1+xtiγ+ytiβti),εtN(0,σt2)αt(L)(ztμtxtγytβt)=εt,εtN(0,σt2)
  • zt depends on the current and past states (the intercept has 4 possible values for a model with 2 states when p=1)