# Outlier detection in GARCH(1,1) in R by Doornik & Ooms (2002)

I try to find additive and innovative outliers in the German Stock Index (DAX) using the method Doornik & Ooms explained in 2002:

1. Estimate the baseline GARCH model to obtain log-likelihood ($lb$) and residuals.
2. Find the largest (in absolute value) standardized residual at $t=s$.
Estimate the extended GARCH model with dummy $d_t=1$ if $t=s$ in the mean, and $d_{t−1}$ in the variance.
This gives estimates for the added parameters and log-likelihood ($lm$).
3. If $2(lm-lb) < C$ then terminate: no further outliers are present with.
Here $C=5.66+1.88\log(T)$ and $T$ is the number of observations.

The data is the DAX (Deutscher Aktienindex) from 2014-06-02 till 2016-01-01 and I got it via Datastream cause pdfetch did not work proper at that time.

My question is, how do I distinguish between the $d_t$ dummy in the mean model and the $d_{t-1}$ dummy in the variance model within the extended GARCH model?

My code so far:

    # Preparation:
library("rugarch")
library("tseries")
library("xts")

dax_xts<-xts(dax, order.by=as.Date.character(dax$Date, format="%Y-%m-%d")) #Convert into xts-format dax_xts$Date=NULL #Remove "Date"-Column
storage.mode(dax_xts)<- "numeric"
colnames(dax_xts)<-c("Dax") #Rename Column-Names

dax.logs.prep<-diff(log(dax$Index), lag=1) dax.date<-dax$Date[-1]
dax.logs<-data.frame(dax.date,dax.logs.prep)
dax_ret<-xts(dax.logs, order.by=as.Date.character(dax.logs$Date, format="%Y-%m-%d")) #Convert into xts-format dax_ret$Date=NULL #Remove "Date"-Column
storage.mode(dax_ret)<- "numeric"
colnames(dax_ret)<-c("Index Returns") #Rename Column-Names

# Step 1: Estimate baseline GARCH model to obtain log-likelihood and residuals
dax_mod<-garch(dax_ret, order = c(1,1))
l.b<-dax_mod$n.likeli dax_mod.res<-data.frame(dax.date, dax_mod$residuals)

# Step 2: Find largest absolute standardized residual
max(abs(dax_mod.res$dax_mod.residuals/sd(dax_mod.res$dax_mod.residuals,    na.rm = TRUE)), na.rm = TRUE)
specgarch <- ugarchspec(variance.model=list(model="sGARCH", external.regressors=dummy), mean.model=list(external.regressor=dummy), distribution="norm")
garchfit <- ugarchfit(data=dax_ret, spec=specgarch)

• What is your question? Note that proof-reading code and questions on software implementation are off topic here. Still, it looks like you have everything under control. So what is the problem? – Richard Hardy Jul 28 '16 at 12:19
• Thx for the advice. My question was how I distinguish between the dt dummy in the mean model and the dt-1 dummy in the variance model within the extended GARCH model. However I just got it. It was my lack of understanding R ;-) First I have to find the observation with the largest absolut standardized residual. Put this into a new dummy variable and then the dummy variable into the extended model... Sorry, just did'nt get that quick. – Mo Bro Jul 28 '16 at 12:50
• So is it solved now? – Richard Hardy Jul 28 '16 at 12:55
• yeah... thx and sorry for this kind of not-question ;) – Mo Bro Jul 28 '16 at 12:55
• You could write a short answer yourself and accept it to show the problem is solved. – Richard Hardy Jul 28 '16 at 12:57

In order to perform the test I coded the following:

# Preparation:
library("rugarch")
library("tseries")
library("xts")

dax_xts<-xts(dax, order.by=as.Date.character(dax$Date, format="%Y-%m-%d")) #Convert into xts-format dax_xts$Date=NULL #Remove "Date"-Column
storage.mode(dax_xts)<- "numeric"
colnames(dax_xts)<-c("Dax") #Rename Column-Names
dax.logs.prep<-diff(log(dax$Index), lag=1) dax.date<-dax$Date[-1]
dax.logs<-data.frame(dax.date,dax.logs.prep)
dax_ret<-xts(dax.logs, order.by=as.Date.character(dax.logs$Date, format="%Y-%m-%d")) #Convert into xts-format dax_ret$Date=NULL #Remove "Date"-Column
storage.mode(dax_ret)<- "numeric"
colnames(dax_ret)<-c("Index Returns") #Rename Column-Names

#Preparation
T<- 414 #length(dax_ret)
Ct<- 5.66+1.88*log10(T)
specgarch0 <- ugarchspec()
mod0<- ugarchfit()
lb<-c()
mod0.resSt<-c()
mod0.res.abs<-c()
a<-c()
dt<-matrix()
dt1<-matrix()
specgarch<-ugarchspec()
mod<-ugarchfit()
lm<-c()
C<-c()
mod.resSt<-c()
mod.res.abs<-c()
loc<-matrix()
outliers<-matrix()
critval<-c("FALSE")
no<-c()
k<-c()
outliers<-c()

### Outlier Detection in GARCH(1,1) by Doornik & Ooms 2002
## Step 1
# Estimate baseline GARCH model to obtain log-likelihood and residuals
specgarch0 <- ugarchspec(variance.model=list(model="sGARCH", garchOrder=c(1,1)), mean.model=list(armaOrder=c(0,0)), distribution="norm")
mod0<- ugarchfit(data=dax_ret, spec=specgarch0)
lb<-likelihood(mod0)

## Step 2
# Find largest absolute standardized residual
mod0.resSt<-residuals(mod0, standardize=TRUE)
mod0.res.abs<-abs(mod0.resSt)
a<-which.max(mod0.res.abs)

# Estimate the extended GARCH model with dummy dt in mean and dt-1 in variance
# Dummies
dt<-matrix(0,T)
dt[a]<-1
dt1<-matrix(0,T)
dt1[a-1]<-1
# Extended GARCH model
# If C < Ct then terminate: no further outliers are present!
while (critval == "FALSE") {
specgarch <- ugarchspec(variance.model=list(model="sGARCH", garchOrder=c(1,1), external.regressors= dt1), mean.model=list(armaOrder=c(0,0), external.regressors= dt), distribution="norm")
mod<- ugarchfit(data=dax_ret, spec=specgarch)
lm<-likelihood(mod)
C<- 2*(lm-lb)
mod.resSt<-residuals(mod, standardize=TRUE)
mod.res.abs<-abs(mod.resSt)
a<-which.max(mod.res.abs)
dt[a]<-1
dt1[a-1]<-1
critval<- C < Ct}

outliers<-cbind(dax.date[which(dt==1)])
print(outliers)


Results: two outliers were found at 2015-06-22 and 2015-12-03 within data of the Dax (2014-06-03 till 2016-01-01) by using this outlier detection method.

• You can accept it, too, to indicate this has been solved. Some explanation extra to the code could be helpful, too. – Richard Hardy Jul 30 '16 at 16:34
• Yes. I think I will edit the answer soon cause I try to build a loop around it for detecting more outliers which appears to be quite difficult at the moment. – Mo Bro Jul 30 '16 at 18:36