You are on page 1of 3

#

#
#
#
#
#
#
#
#
#
#

econ589backtestingRiskModels.r
R examples for lectures on backtesting risk models
Eric Zivot
April 23rd, 2012
update history
May 14, 2013
Changed "compound" to "log" in CalculateReturns()
April 29th, 2013
updated examples for spring 2013

# load libraries
library(PerformanceAnalytics)
library(quantmod)
library(rugarch)
library(car)
library(FinTS)
options(digits=4)
# download data
symbol.vec = c("MSFT", "^GSPC")
getSymbols(symbol.vec, from ="2000-01-03", to = "2012-04-03")
colnames(MSFT)
start(MSFT)
end(MSFT)
# extract adjusted closing prices
MSFT = MSFT[, "MSFT.Adjusted", drop=F]
GSPC = GSPC[, "GSPC.Adjusted", drop=F]
# plot prices
plot(MSFT)
plot(GSPC)
# calculate log-returns for GARCH analysis
MSFT.ret = CalculateReturns(MSFT, method="log")
GSPC.ret = CalculateReturns(GSPC, method="log")
# remove first NA observation
MSFT.ret = MSFT.ret[-1,]
GSPC.ret = GSPC.ret[-1,]
colnames(MSFT.ret) ="MSFT"
colnames(GSPC.ret) = "GSPC"
# create combined data series
MSFT.GSPC.ret = merge(MSFT.ret,GSPC.ret)
# plot returns
plot(MSFT.ret)
plot(GSPC.ret)
#
# backtesting unconditional VaR models
# normal VaR, HS and modified HS
#
# set up estimation window and testing window

n.obs
w.e =
w.t =
alpha

= nrow(MSFT.ret)
1000
n.obs - w.e
= 0.99

# loop over testing sample, compute VaR and record hit rates
backTestVaR <- function(x, p = 0.95) {
normal.VaR = as.numeric(VaR(x, p=p, method="gaussian"))
historical.VaR = as.numeric(VaR(x, p=p, method="historical"))
modified.VaR = as.numeric(VaR(x, p=p, method="modified"))
ans = c(normal.VaR, historical.VaR, modified.VaR)
names(ans) = c("Normal", "HS", "Modified")
return(ans)
}
# rolling 1-step ahead estimates of VaR
VaR.results = rollapply(as.zoo(MSFT.ret), width=w.e,
FUN = backTestVaR, p=0.99, by.column = FALSE,
align = "right")
VaR.results = lag(VaR.results, k=-1)
chart.TimeSeries(merge(MSFT.ret, VaR.results), legend.loc="topright")
violations.mat = matrix(0, 3, 5)
rownames(violations.mat) = c("Normal", "HS", "Modified")
colnames(violations.mat) = c("En1", "n1", "1-alpha", "Percent", "VR")
violations.mat[, "En1"] = (1-alpha)*w.t
violations.mat[, "1-alpha"] = 1 - alpha
# Show Normal VaR violations
normalVaR.violations = as.zoo(MSFT.ret[index(VaR.results), ]) < VaR.results[, "N
ormal"]
violation.dates = index(normalVaR.violations[which(normalVaR.violations)])
# plot violations
plot(as.zoo(MSFT.ret[index(VaR.results),]), col="blue", ylab="Return")
abline(h=0)
lines(VaR.results[, "Normal"], col="black", lwd=2)
lines(as.zoo(MSFT.ret[violation.dates,]), type="p", pch=16, col="red", lwd=2)
for(i in colnames(VaR.results)) {
VaR.violations = as.zoo(MSFT.ret[index(VaR.results), ]) < VaR.results[, i]
violations.mat[i, "n1"] = sum(VaR.violations)
violations.mat[i, "Percent"] = sum(VaR.violations)/w.t
violations.mat[i, "VR"] = violations.mat[i, "n1"]/violations.mat[i, "En1"]
}
violations.mat

?VaRTest
VaR.test = VaRTest(1-alpha,
actual=coredata(MSFT.ret[index(VaR.results),]),
VaR=coredata(VaR.results[,"Normal"]))
names(VaR.test)
# LR test for correct number of exceedances
VaR.test[1:7]
# LR tests for independence of exceedances
VaR.test[8:12]

# backtest VaR but re-fit every 20 obvs (e.g. every month)


VaR.results.20 = rollapply(as.zoo(MSFT.ret), width=w.e, by = 20,
FUN = backTestVaR, p=0.99, by.column = FALSE,
align = "right")
chart.TimeSeries(merge(MSFT.ret, VaR.results, fill=na.locf), legend.loc="toprigh
t")
# expand series to match MSFT.ret and use trick to fill NA values with last valu
es carried forward
VaR.results.20 = merge(xts(, order.by=index(MSFT.ret)), VaR.results.20, fill=na.
locf)
chart.TimeSeries(merge(MSFT.ret, VaR.results.20), legend.loc="topright")
#
# rolling GARCH(1,1) with VaR violations
MSFT.garch11.roll = ugarchroll(garch11.spec, MSFT.ret, n.ahead=1,
forecast.length = w.t,
refit.every=20, refit.window="moving",
calculate.VaR=TRUE, VaR.alpha=0.01)
class(MSFT.garch11.roll)
plot(MSFT.garch11.roll)
# VaR plot
plot(MSFT.garch11.roll, which=4)
# Coef plot`
plot(MSFT.garch11.roll, which=5)
# show backtesting report
?report
report.msft = report(MSFT.garch11.roll, type="VaR")
report(MSFT.garch11.roll, type="fpm")
xx = VaRTest(alpha=0.01, actual=MSFT.garch11.roll@forecast$VaR[,2],
VaR=MSFT.garch11.roll@forecast$VaR[,1])

You might also like