Skip to content

Commit 144e55c

Browse files
committed
Add GARCH11 model
1 parent da477bd commit 144e55c

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

pymc3/distributions/timeseries.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import theano.tensor as T
2+
from theano import scan
23

34
from .continuous import Normal, Flat
45
from .distribution import Continuous
56

6-
__all__ = ['AR1', 'GaussianRandomWalk']
7+
__all__ = ['AR1', 'GaussianRandomWalk', 'GARCH11']
78

89

910
class AR1(Continuous):
@@ -71,3 +72,52 @@ def logp(self, x):
7172

7273
innov_like = Normal.dist(mu=x_im1 + mu, tau=tau, sd=sd).logp(x_i)
7374
return init.logp(x[0]) + T.sum(innov_like)
75+
76+
77+
class GARCH11(Continuous):
78+
"""
79+
GARCH(1,1) with Normal innovations. The model is specified by
80+
81+
y_t = sigma_t * z_t
82+
sigma_t^2 = omega + alpha_1 * y_{t-1}^2 + beta_1 * sigma_{t-1}^2
83+
84+
with z_t iid and Normal with mean zero and unit standard deviation.
85+
86+
Parameters
87+
----------
88+
omega : distribution
89+
omega > 0, distribution for mean variance
90+
alpha_1 : distribution
91+
alpha_1 >= 0, distribution for autoregressive term
92+
beta_1 : distribution
93+
beta_1 >= 0, alpha_1 + beta_1 < 1, distribution for moving
94+
average term
95+
initial_vol : distribution
96+
initial_vol >= 0, distribution for initial volatility, sigma_0
97+
"""
98+
def __init__(self, omega=None, alpha_1=None, beta_1=None,
99+
initial_vol=None, *args, **kwargs):
100+
super(GARCH11, self).__init__(*args, **kwargs)
101+
102+
self.omega = omega
103+
self.alpha_1 = alpha_1
104+
self.beta_1 = beta_1
105+
self.initial_vol = initial_vol
106+
self.mean = 0
107+
108+
def _get_volatility(self, x):
109+
110+
def volatility_update(x, vol, w, a, b):
111+
return T.sqrt(w + a * T.square(x) + b * T.square(vol))
112+
113+
vol, _ = scan(fn=volatility_update,
114+
sequences=[x],
115+
outputs_info=[self.initial_vol],
116+
non_sequences=[self.omega, self.alpha_1,
117+
self.beta_1])
118+
return vol
119+
120+
def logp(self, x):
121+
vol = self._get_volatility(x[:-1])
122+
return (Normal.dist(0., sd=self.initial_vol).logp(x[0]) +
123+
T.sum(Normal.dist(0, sd=vol).logp(x[1:])))

0 commit comments

Comments
 (0)