Original link: http://tecdat.cn/?p=3385
Recently I was asked to write a survey on copulas for financial time series
A description of the various models is obtained from the read data, including some graphical and statistical output.
copy> oil = read.xlsx(temp,sheetName ="DATA",dec =",")
We can then plot the three time series
copy1 1997-01-10 2.73672 2.25465 3.3673 1.5400 2 1997-01-17 -3.40326 -6.01433 -3.8249 -4.1076 3 1997-01-24 -4.09531 -1.43076 -6.6375 -4.6166 4 1997-01-31 -0.65789 0.34873 0.7326 -1.5122 5 1997-02-07 -3.14293 -1.97765 -0.7326 -1.8798 6 1997-02-14 -5.60321 -7.84534 -7.6372 -11.0549
The idea is to use some multivariate ARMA-GARCH process here. The heuristic here is that the first part is used to model the dynamics of the time series mean and the second part is used to model the dynamics of the time series variance.
This paper considers two models
- Multivariate GARCH process on ARMA model residuals (or variance matrix dynamics model)
- Multivariate model (copula-based) on ARMA-GARCH process residuals
Therefore, different series will be considered here, obtained as residuals of different models. We can also normalize these residuals.
ARMA model
copy> fit1 = arima(x = dat [,1],order = c(2,0,1)) > fit2 = arima(x = dat [,2],order = c(1,0,1)) > fit3 = arima(x = dat [,3],order = c(1,0,1)) > m < - apply(dat_arma,2,mean) > v < - apply(dat_arma,2,var) > dat_arma_std < - t((t(dat_arma)-m)/ sqrt(v))
ARMA-GARCH model
copy> fit1 = garchFit(formula = ~arma(2,1)+ garch(1,1),data = dat [,1],cond.dist ="std") > fit2 = garchFit(formula = ~arma(1,1)+ garch(1,1),data = dat [,2],cond.dist ="std") > fit3 = garchFit(formula = ~arma(1,1)+ garch(1,1),data = dat [,3],cond.dist ="std") > m_res < - apply(dat_res,2,mean) > v_res < - apply(dat_res,2,var) > dat_res_std = cbind((dat_res [,1] -m_res [1])/ sqrt(v_res [1]),(dat_res [,2] -m_res [2])/ sqrt(v_res [2]),(dat_res [ ,3] -m_res [3])/ SQRT(v_res [3]))
Multivariate GARCH model
The first model that can be considered is the multivariate EWMA of the covariance matrix,
copy> ewma = EWMAvol(dat_res_std,lambda = 0.96)
volatility
copy> emwa_series_vol = function(i = 1){ + lines(Time,dat_arma [,i] + 40,col ="gray") + j = 1 + if(i == 2)j = 5 + if(i == 3)j = 9
implicit correlation
copy> emwa_series_cor = function(i = 1,j = 2){ + if((min(i,j)== 1)&(max(i,j)== 2)){ + a = 1; B = 9; AB = 3} + r = ewma $ Sigma.t [,ab] / sqrt(ewma $ Sigma.t [,a] * + ewma $ Sigma.t [,b]) + plot(Time,r,type ="l",ylim = c(0,1)) +}
A multivariate GARCH, i.e. BEKK(1,1) model, for example using:
copy> bekk = BEKK11(dat_arma) > bekk_series_vol function(i = 1){ + plot(Time, $ Sigma.t [,1],type ="l", + ylab = (dat)[i],col ="white",ylim = c(0,80)) + lines(Time,dat_arma [,i] + 40,col ="gray") + j = 1 + if(i == 2)j = 5 + if(i == 3)j = 9 > bekk_series_cor = function(i = 1,j = 2){ + a = 1; B = 5; AB = 2} + a = 1; B = 9; AB = 3} + a = 5; B = 9; AB = 6} + r = bk $ Sigma.t [,ab] / sqrt(bk $ Sigma.t [,a] * + bk $ Sigma.t [,b])
Simulate residuals from univariate GARCH model
A first step might be to consider some static (joint) distribution of the residuals. The univariate marginal distribution is
Profile of edge density (obtained using bivariate kernel estimator)
It is also possible to visualize the copula density (some nonparametric estimates above, parametric copula below)
copy> copula_NP = function(i = 1,j = 2){ + n = nrow(uv) + s = 0.3 + norm.cop < - normalCopula(0.5) + norm.cop < - normalCopula(fitCopula(norm.cop,uv)@estimate) + dc = function(x,y)dCopula(cbind(x,y),norm.cop) + ylab = names(dat)[j],zlab ="copule Gaussienne",ticktype ="detailed",zlim = zl) + + t.cop < - tCopula(0.5,df = 3) + t.cop < - tCopula(t.fit [1],df = t.fit [2]) + ylab = names(dat)[j],zlab ="copule de Student",ticktype ="detailed",zlim = zl) +}
can consider this
function,
Compute empirical versions of the three sequences and compare them to some parametric versions,
copy> > lambda = function(C){ + l = function(u)pcopula(C,cbind(u,u))/ u + v = Vectorize(l)(u) + return(c(v,rev(v))) +} > > graph_lambda = function(i,j){ + X = dat_res + U = rank(X [,i])/(nrow(X)+1) + V = rank(X [,j])/(nrow(X)+1) + normal.cop < - normalCopula(.5,dim = 2) + t.cop < - tCopula(.5,dim = 2,df = 3) + fit1 = fitCopula(normal.cop,cbind(U,V),method ="ml") d(U,V),method ="ml") + C1 = normalCopula(fit1 @ copula @ parameters,dim = 2) + C2 = tCopula(fit2 @ copula @ parameters [1],dim = 2,df = trunc(fit2 @ copula @ parameters [2])) +
But one might wonder whether the correlation is stable over time.
copy> time_varying_correl_2 = function(i = 1,j = 2, + nom_arg ="Pearson"){ + uv = dat_arma [,c(i,j)] nom_arg))[1,2] +} > time_varying_correl_2(1,2) > time_varying_correl_2(1,2,"spearman") > time_varying_correl_2(1,2,"kendall")
Spearman and time-varying rank correlation coefficient
or Kendall correlation coefficient
For model relevance, consider the DCC model(S)
copy> m2 = dccFit(dat_res_std) > m3 = dccFit(dat_res_std,type ="Engle") > R2 = m2 $ rho.t > R3 = m3 $ rho.t
To get some predictions, use e.g.
copy> garch11.spec = ugarchspec(mean.model = list(armaOrder = c(2,1)),variance.model = list(garchOrder = c(1,1),model ="GARCH")) > dcc.garch11.spec = dccspec(uspec = multispec(replicate(3,garch11.spec)),dccOrder = c(1,1), distribution ="mvnorm") > dcc.fit = dccfit(dcc.garch11.spec,data = dat) > fcst = dccforecast(dcc.fit,n.ahead = 200)
This article is an excerpt from "R Language ARMA-GARCH-COPULA Model and Financial Time Series Cases"