We will consider a bivariate model with returns of W&T Offshore, Inc. and the S&P 500 index.
#install.packages("quantmod")
#install.packages("stochvol")
#install.packages("factorstochvol")
#install.packages("MTS")
library("quantmod")
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library("stochvol")
library("factorstochvol")
library("MTS")
##
## Attaching package: 'MTS'
## The following object is masked from 'package:TTR':
##
## VMA
tickers = c("WTI","^GSPC")
getSymbols(tickers,from='2014-04-05',to='2023-04-04',warnings=FALSE,auto.assign=TRUE)
## [1] "WTI" "^GSPC"
names = c("W&T Offshore, Inc.","S&P 500")
price = cbind(WTI[,6],GSPC[,6])
price = as.matrix(price)
n = nrow(price)
p = ncol(price)
par(mfrow=c(1,2))
ts.plot(price[,1],ylab="Price",main=names[1])
ts.plot(price[,2],ylab="Price",main=names[2])
par(mfrow=c(1,2))
return = NULL
for (i in 1:p){
ts.plot(100*(price[2:n,i]/price[1:(n-1),i]-1),ylab="Returns (%)",main=names[i])
return = cbind(return,100*(price[2:n,i]/price[1:(n-1),i]-1))
}
ind = !is.na(return[,1])
return = return[ind==TRUE,]
n = nrow(return)
sigmas.sv = matrix(0,n,p)
for (i in 1:p){
y = as.double(return[,i])
fit.sv = svtlsample(y)
sigmas.sv[,i] = apply(exp(fit.sv$latent[[1]]/2),2,mean)
}
## Argument 'y' (data vector) contains values very close to zero. I am applying an offset constant of size 0.000490249617855 to do the auxiliary mixture sampling. If you want to avoid this, you might consider de-meaning the returns before calling this function.
## Done!
## Summarizing posterior draws...
## Argument 'y' (data vector) contains values very close to zero. I am applying an offset constant of size 0.000115179072042785 to do the auxiliary mixture sampling. If you want to avoid this, you might consider de-meaning the returns before calling this function.
## Done!
## Summarizing posterior draws...
par(mfrow=c(1,1))
ts.plot(sigmas.sv,col=1:p,ylab="Standard deviation",main="SVLT-AR(1)")
legend("topright",legend=names,col=1:p,lty=1)
fsv = fsvsample(return,factors=1,runningstore=6)
##
## Calling 1-factor MCMC sampler for 2 series of length 2263.
##
##
********* Iteration 1 of 2000 ( 0%) *********
********* Iteration 443 of 2000 ( 22%) *********
********* Iteration 885 of 2000 ( 44%) *********
********* Iteration 1327 of 2000 ( 66%) *********
********* Iteration 1769 of 2000 ( 88%) *********
********* Iteration 2000 of 2000 (100%) *********
##
## Reorganizing runningstores... Done!
## Ex-post sign-identification... Done!
par(mfrow=c(1,1))
plot(density(fsv$facload[1,1,]),xlim=c(0.4,2.0),ylim=c(0,10),main="Loadings",xlab="")
lines(density(fsv$facload[2,1,]),col=2)
legend("topright",legend=c(expression(beta[11]),expression(beta[21])),col=1:2,bty="n",lty=1)
sd1 = sqrt(fsv$runningstore$cov[,1,1])
sd2 = sqrt(fsv$runningstore$cov[,3,1])
corr = fsv$runningstore$cov[,2,1]/(sd1*sd2)
par(mfrow=c(1,2))
ts.plot(sd1,ylab="Standard deviation",main=names[1],ylim=c(0,20))
lines(sigmas.sv[,1],col=2)
lines(0.1*abs(return[,1]),type="h",col=grey(0.7))
ts.plot(sd2,ylab="Standard deviation",main=names[2],ylim=c(0,7))
lines(sigmas.sv[,2],col=2)
lines(0.1*abs(return[,2]),type="h",col=grey(0.7))
par(mfrow=c(1,1))
ts.plot(corr,ylim=c(0,1),ylab="Correlation")
abline(h=0.2,lty=2)
abline(h=0.5,lty=2)
abline(h=0.8,lty=2)
pre = dccPre(return, include.mean = T, p = 0, cond.dist = "std")
## Sample mean of the returns: 0.06922153 0.04221578
## Component: 1
## Estimates: 1.298495 0.106114 0.843234 5.464443
## se.coef : 0.356701 0.019165 0.026749 0.620598
## t-value : 3.640288 5.536999 31.5245 8.805131
## Component: 2
## Estimates: 0.020261 0.196425 0.806509 5.600777
## se.coef : 0.005211 0.025366 0.021183 0.657168
## t-value : 3.888033 7.743504 38.07419 8.522596
pre$est
## omega alpha1 beta1 shape
## [1,] 1.29849458 0.1061140 0.8432337 5.464443
## [2,] 0.02026142 0.1964253 0.8065090 5.600777
return1 = pre$sresi
Vol = pre$marVol
fit = dccFit(return1)
## Estimates: 0.7017527 0.049999 6.110255
## st.errors: 0.1838962 0.02334849 0.4161715
## t-values: 3.816026 2.141423 14.68206
S2.t = fit$rho.t
fit1 = dccFit(return1,type="Engle")
## Estimates: 0.8703852 0.03813264 6.137094
## st.errors: 0.05133039 0.01414681 0.4192691
## t-values: 16.95653 2.695495 14.6376
S3.t = fit1$rho.t
MCHdiag(return1,S2.t)
## Test results:
## Q(m) of et:
## Test and p-value: 12.96677 0.2255356
## Rank-based test:
## Test and p-value: 27.4336 0.002222899
## Qk(m) of epsilon_t:
## Test and p-value: 37.47703 0.5844202
## Robust Qk(m):
## Test and p-value: 49.37191 0.1471156
MCHdiag(return1,S3.t)
## Test results:
## Q(m) of et:
## Test and p-value: 12.31411 0.2645841
## Rank-based test:
## Test and p-value: 28.04948 0.001772611
## Qk(m) of epsilon_t:
## Test and p-value: 37.27335 0.5936759
## Robust Qk(m):
## Test and p-value: 57.95281 0.03293376
par(mfrow=c(2,1))
range = range(pre$marVol[,1],sd1)
ts.plot(pre$marVol[,1],xlab="",ylab="",main=names[1],ylim=range)
lines(sigmas.sv[,1],col=2)
legend("topright",legend=c("GARCH(1,1)","SV-AR(1)"),col=1:2,lty=1,bty="n")
range = range(pre$marVol[,2],sd2)
ts.plot(pre$marVol[,2],xlab="",ylab="",main=names[2],ylim=range)
lines(sigmas.sv[,2],col=2)
legend("topright",legend=c("GARCH(1,1)","SV-AR(1)"),col=1:2,lty=1,bty="n")
par(mfrow=c(1,1))
plot(fit1$rho.t[,2],type="l",ylab="Correlation",ylim=c(0,1),xlab="Time")
lines(corr,col=2)
legend("topleft",legend=c("DCC","FSV(1)"),col=1:2,lty=1,bty="n")
title(paste(names[1]," x ",names[2],sep=""),cex=0.75)
abline(h=0.2,lty=2)
abline(h=0.5,lty=2)
abline(h=0.8,lty=2)