I'm estimating a time-varying correlation matrix for the normal copula using the rmgarch
package from R. I've found this code in the rmgarch.tests folder. I use the semiparametric distribution with generalized pareto distribution, which is specified in cgarchspec
and controlled for in cgarchfit
(with thresholds at 0.05 and 0.95).
#required package
install.packages("rmgarch")
library(rmgarch)
#load data
data(dji30retw)
Dat = dji30retw[, 1:3, drop = FALSE]
#specification for univariate ARMA-GARCH, normal copula with SPD and fitting
uspec17 = ugarchspec(mean.model = list(armaOrder = c(2,1)),
variance.model = list(garchOrder = c(1,1), model = "sGARCH", variance.targeting=FALSE),
distribution.model = "norm")
spec17 = cgarchspec(uspec = multispec( replicate(3, uspec17) ), asymmetric = FALSE,
distribution.model = list(copula = "mvnorm", method = "Kendall",
time.varying = TRUE, transformation = "spd"))
fit17 <- cgarchfit(spec17, Dat, out.sample=100, spd.control=list(upper=0.95, lower=0.05, type="mle", kernel="normal"),
cluster=NULL, fit.control=list(eval.se=FALSE))
T = dim(Dat)[1]-100
simMu = simS = filtMu = filtS = matrix(NA, ncol = 3, nrow = 100)
simCor = simC = filtC = filtCor = array(NA, dim = c(3,3,100))
colSd = function(x) apply(x, 2, "sd")
specx17 = spec17
for(i in 1:3) specx17@umodel$fixed.pars[[i]] = as.list(fit17@model$mpars[fit17@model$midx[,i]==1,i])
setfixed(specx17)<-as.list(fit17@model$mpars[fit17@model$midx[,4]==1,4])
#simulation
{for(i in 1:100){
if(i==1){
presigma = matrix(tail(sigma(fit17), 2), ncol = 3)
prereturns = matrix(unlist(Dat[(T-1):T, ]), ncol = 3, nrow = 2)
preresiduals = matrix(tail(residuals(fit17),2), ncol = 3, nrow = 2)
preR = last(rcor(fit17))[,,1]
diag(preR) = 1
preQ = fit17@mfit$Qt[[length(fit17@mfit$Qt)]]
preZ = tail(fit17@mfit$Z, 1)
tmp = cgarchfilter(specx17, Dat[1:(T+1), ], filter.control = list(n.old = T), varcoef = fit17@model$varcoef)
filtMu[i,] = tail(fitted(tmp), 1)
filtS[i,] = tail(sigma(tmp), 1)
filtC[,,i] = last(rcov(tmp))[,,1]
filtCor[,,i] = last(rcor(tmp))[,,1]
} else{
presigma = matrix(tail(sigma(tmp), 2), ncol = 3)
prereturns = matrix(unlist(Dat[(T+i-2):(T+i-1), ]), ncol = 3, nrow = 2)
preresiduals = matrix(tail(residuals(tmp),2), ncol = 3, nrow = 2)
preR = last(rcor(tmp))[,,1]
diag(preR) = 1
preQ = tmp@mfilter$Qt[[length(tmp@mfilter$Qt)]]
preZ = tail(tmp@mfilter$Z, 1)
tmp = cgarchfilter(specx17, Dat[1:(T+i), ], filter.control = list(n.old = T), varcoef = fit17@model$varcoef)
filtMu[i,] = tail(fitted(tmp), 1)
filtS[i,] = tail(sigma(tmp), 1)
filtC[,,i] = last(rcov(tmp))[,,1]
filtCor[,,i] = last(rcor(tmp))[,,1]
}
sim17 = cgarchsim(fit17, n.sim = 1, m.sim = 2000, startMethod = "sample", preR = preR, preQ = preQ, preZ = preZ,
prereturns = prereturns, presigma = presigma, preresiduals = preresiduals, cluster = NULL)
simx = t(sapply(sim17@msim$simX, FUN = function(x) x[1,]))
simMu[i,] = colMeans(simx)
# Note: There is no uncertainty for the 1-ahead simulation of cov adn cor
simC[,,i] = sim17@msim$simH[[1]][,,1]
simCor[,,i] = sim17@msim$simR[[1]][,,1]
simS[i,] = sqrt(diag(simC[,,i]))
}}
After running this, simx
is a matrix containing all conditional returns. Do you know whether they take into account the copula and SPD marginals, i.e. does this procedure follow the steps: i) given data at $t$, construct correlation matrix $t+1$; ii) given correlation at $t+1$, generate 2000 correlated copula realizations; iii) using the inverse of the SPD obtain standardized residuals; iv) insert these back in the ARMA-GARCH specification and compute return? Intuitively I would say yes (why are GARCH, spd and normal copula specified earlier otherwise?) but I've found no "official" confirmation.