Theory


GASX models extend GAS models by including exogenous factors X. For a conditional observation density p\left(y_{t}\mid{\theta_{t}}\right) with an observation y_{t} and a latent time-varying parameter \theta_{t}, we assume the parameter \theta_{t} follows the recursion:

\theta_{t} = \mu + \sum^{K}_{k=1}\beta_{k}X_{t,k} + \sum^{p}_{i=1}\phi_{i}\theta_{t-i} + \sum^{q}_{j=1}\alpha_{j}S\left(x_{j-1}\right)\frac{\partial\log p\left(y_{t-j}\mid{\theta_{t-j}}\right) }{\partial{\theta_{t-j}}}


For example, for a Poisson distribution density, where the default scaling is \exp\left(\theta_{j}\right), the time-varying parameter follows:

\theta_{t} = \mu + \sum^{K}_{k=1}\beta_{k}X_{t,k} + \sum^{p}_{i=1}\phi_{i}\theta_{t-i} + \sum^{q}_{j=1}\alpha_{j}\left(\frac{y_{t-j}}{\exp\left(\theta_{t-j}\right)} - 1\right)


This model can be viewed as an approximation to a non-linear ARIMAX model.

PyFlux

Types of GASX Model

PyFlux supports many types of distribution for GAS modelling, including

PyFlux Class
Poisson GAS GASPoisson()
t GAS GASt()
Skew t GAS GASSkewt()
Normal GAS GASNormal()
Laplace GAS GASLaplace()
Exponential GAS GASExponential()

Below we demonstrate usage for heavy-tailed data

GASX Model for Beta Calculation in Finance

Below we estimate the \beta for a stock – the systematic (market) component of returns – using a heavy tailed distribution and some short-term autoregressive effects. First let’s load some data:

from pandas_datareader.data import DataReader
from datetime import datetime

a = DataReader('AMZN',  'yahoo', datetime(2012,1,1), datetime(2016,6,1))
a_returns = pd.DataFrame(np.diff(np.log(a['Adj Close'].values)))
a_returns.index = a.index.values[1:a.index.values.shape[0]]
a_returns.columns = ["Amazon Returns"]

spy = DataReader('SPY',  'yahoo', datetime(2012,1,1), datetime(2016,6,1))
spy_returns = pd.DataFrame(np.diff(np.log(spy['Adj Close'].values)))
spy_returns.index = spy.index.values[1:spy.index.values.shape[0]]
spy_returns.columns = ['S&P500 Returns']

one_mon = DataReader('DGS1MO', 'fred',datetime(2012,1,1), datetime(2016,6,1))
one_day = np.log(1+one_mon)/365

returns = pd.concat([one_day,a_returns,spy_returns],axis=1).dropna()
excess_m = returns["Amazon Returns"].values - returns['DGS1MO'].values
excess_spy = returns["S&P500 Returns"].values - returns['DGS1MO'].values
final_returns = pd.DataFrame(np.transpose([excess_m,excess_spy, returns['DGS1MO'].values]))
final_returns.columns=["Amazon","SP500","Risk-free rate"]
final_returns.index = returns.index

plt.figure(figsize=(15,5))
plt.title("Excess Returns")
x = plt.plot(final_returns);
plt.legend(iter(x), final_returns.columns);
png

We will estimate a GASX model with a GASSkewt() family:

model2 = pf.GASX(formula="Amazon~SP500",data=final_returns,ar=1,sc=1,family=pf.GASSkewt())
x = model2.fit()
x.summary()
Skewt GASX(1,0,1)                                                                                         
======================================================= =================================================
Dependent Variable: Amazon                              Method: MLE                                       
Start Date: 2012-01-05 00:00:00                         Log Likelihood: 3165.9237                         
End Date: 2016-06-01 00:00:00                           AIC: -6317.8474                                   
Number of observations: 1100                            BIC: -6282.8259                                   
=========================================================================================================
Latent Variable                          Estimate   Std Error  z        P>|z|    95% C.I.                 
======================================== ========== ========== ======== ======== ========================
AR(1)                                    0.0807     0.0202     3.9956   0.0001   (0.0411 | 0.1203)        
SC(1)                                    -0.0       0.0187     -0.0001  0.9999   (-0.0367 | 0.0367)       
Beta 1                                   -0.0005    0.0249     -0.0184  0.9853   (-0.0493 | 0.0484)       
Beta SP500                               1.2683     0.0426     29.7473  0.0      (1.1848 | 1.3519)        
Skewness                                 1.017                                                            
Skewt Scale                              0.0093                                                           
v                                        2.7505                                                           
=========================================================================================================
WARNING: Skew t distribution is not well-suited for MLE or MAP inference
Workaround 1: Use a t-distribution instead for MLE/MAP
Workaround 2: Use M-H or BBVI inference for Skew t distribution

The results table warns us about using the Skew t distribution. This choice of family can sometimes be unstable, so we may want to opt for a t-distribution instead. But in this case, we seem to have obtained sensible results. We can plot the constant and the GAS latent variables by referencing their indices with plot_z:

model2.plot_z(indices=[0,1,2])
png
Similarly we can plot \beta_{AMZN}:

model2.plot_z(indices=[3])
png

Our \beta_{AMZN} estimate is above 1.0 (fairly strong systematic risk). Let us plot the model fit and the systematic component of returns:

model2.plot_fit(figsize=(15,10))
png