# 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? Commented Jul 28, 2016 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. Commented Jul 28, 2016 at 12:50
• So is it solved now? Commented Jul 28, 2016 at 12:55
• yeah... thx and sorry for this kind of not-question ;) Commented Jul 28, 2016 at 12:55
• You could write a short answer yourself and accept it to show the problem is solved. Commented Jul 28, 2016 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. Commented Jul 30, 2016 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. Commented Jul 30, 2016 at 18:36