source("~/OneDrive - INSEAD/SkewEllipt/Code_Update/Final_function.R")
path = "~/OneDrive - INSEAD/SkewEllipt/Code_Update/CoVaR/"
k = 1
#### Read in Data
data = fread(paste(path,"ALL.csv",sep=""))
DJ = fread(paste(path,"Don.csv",sep=""))
DJ[,date := as.numeric(format(strptime(date,"%m/%d/%Y"),"%Y%m%d"))]
data = rbind(data, DJ)
# data <- data[ date>=20040101]
data <- data[!is.na(PRC)]
Ldata <- data.table(dcast(data,formula=date ~ PERMNO, value.var="PRC", drop = FALSE))
Ldata <- Ldata[!(rowSums(is.na(Ldata[,2:(ncol(Ldata)-1)])) == (ncol(Ldata)-2))]
Ldata[, date:=as.Date(as.character(date), "%Y%m%d")]
Dat = as.timeSeries(Ldata)
R_com=Return.calculate(Dat, method = "log")[-1,] * 100
num = ncol(R_com)
ndays = length(unique(Ldata$date)) - 1
nstock = length(unique(data$TICKER)) - 1
days = unique(Ldata$date)[-1]
days = as.numeric(days)
#### There are in total 99 financial institutions. The starting date of sample is 2002-01-02, and the end date is 2016-12-31. The longest sample has 3776 return data.
### ARMA-Garch Filter -- individual stock ###
INDEX_id = ncol(R_com)
loss_stock = -R_com[,k]
na.pos = which(is.na(loss_stock))
if(length(na.pos) == 0){
na.pos = 10^6
}
spec = ugarchspec(mean.model=list(armaOrder=c(1,0),include.mean=T), distribution.model="sstd")
garch11.fit = ugarchfit(spec = spec, data =loss_stock[-na.pos], solver.control=list(trace = 1),solver = "hybrid")
##
## Iter: 1 fn: 7473.8248 Pars: -0.04453 -0.07113 0.06168 0.10975 0.88111 1.02609 5.40679
## Iter: 2 fn: 7473.8248 Pars: -0.04453 -0.07113 0.06168 0.10976 0.88111 1.02610 5.40640
## solnp--> Completed in 2 iterations
### Calcualte VaR for individual stock
nu=coef(garch11.fit)["shape"]; ga=coef(garch11.fit)["skew"]
qmodel = qdist("sstd",p=0.99,mu=0,sigma=1,shape=nu,skew=ga)
# VaR95 = VaR.forecasts(fit=garch11.fit,qmodel=qmodel,alpha=0.95,ret_z = FALSE)
VaR99 = VaR.forecasts(fit=garch11.fit,qmodel=qmodel,alpha=0.99,ret_z = FALSE)
##### ARMA-Garch Filter -- Index ###
garch11.fit.Index = ugarchfit(spec = spec, data = -R_com[-na.pos,INDEX_id], solver.control=list(trace = 1),solver = "hybrid")
##
## Iter: 1 fn: 5976.3353 Pars: -0.05197 -0.08092 0.01545 0.10291 0.89270 1.08213 7.20901
## Iter: 2 fn: 5976.3353 Pars: -0.05197 -0.08092 0.01545 0.10290 0.89270 1.08212 7.20866
## solnp--> Completed in 2 iterations
#### DCC Filter ##########
library(bayesDccGarch)
### Get de-mean residuals from ARMA filter above
resid_s = residuals(garch11.fit); mut_s = fitted(garch11.fit)
resid_I = residuals(garch11.fit.Index); mut_I = fitted(garch11.fit.Index)
### Fit DCC model to residuals
sim_y = cbind(array(resid_s), array(resid_I)) #Loss
bayesDcc <- bayesDccGarch(sim_y, nSim = 1000)
## Maximizing the log-posterior density function.
## Done.
## One approximation for covariance matrix of parameters cannot be directly computed through the hessian matrix.
## Calibrating the standard deviations for simulation:
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate:
## phi_1 phi_2 phi_3 phi_4 phi_5 phi_6 phi_7 phi_8 phi_9 phi_10
## 0.34 0.09 0.23 0.07 0.12 0.08 0.21 0.05 0.12 0.05
## phi_11
## 0.03
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate:
## phi_1 phi_2 phi_3 phi_4 phi_5 phi_6 phi_7 phi_8 phi_9 phi_10
## 0.35 0.15 0.25 0.12 0.16 0.15 0.21 0.11 0.20 0.05
## phi_11
## 0.02
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate:
## phi_1 phi_2 phi_3 phi_4 phi_5 phi_6 phi_7 phi_8 phi_9 phi_10
## 0.39 0.24 0.23 0.17 0.19 0.23 0.22 0.17 0.16 0.10
## phi_11
## 0.06
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate:
## phi_1 phi_2 phi_3 phi_4 phi_5 phi_6 phi_7 phi_8 phi_9 phi_10
## 0.37 0.24 0.26 0.19 0.16 0.22 0.20 0.17 0.15 0.13
## phi_11
## 0.10
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate:
## phi_1 phi_2 phi_3 phi_4 phi_5 phi_6 phi_7 phi_8 phi_9 phi_10
## 0.36 0.24 0.25 0.19 0.19 0.23 0.20 0.19 0.29 0.18
## phi_11
## 0.13
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate:
## phi_1 phi_2 phi_3 phi_4 phi_5 phi_6 phi_7 phi_8 phi_9 phi_10
## 0.35 0.22 0.22 0.21 0.18 0.24 0.21 0.22 0.28 0.23
## phi_11
## 0.28
## Computing the covariance matrix of pilot sample.
## Done.
## Calibrating the Lambda coefficient:
## lambda: 0.5
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate: 0.05
## lambda: 0.4
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate: 0.05
## lambda: 0.32
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate: 0.11
## lambda: 0.256
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate: 0.11
## lambda: 0.2048
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate: 0.11
## lambda: 0.16384
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Accept Rate: 0.19
## Done.
## Starting the simulation by one-block random walk Metropolis-Hasting algorithm.
## Simulation number = 100
## Simulation number = 200
## Simulation number = 300
## Simulation number = 400
## Simulation number = 500
## Simulation number = 600
## Simulation number = 700
## Simulation number = 800
## Simulation number = 900
## Simulation number = 1000
## Done.
H = bayesDcc$H ### Sigma function
Z = matrix(NA, nrow(H), 2)
Sigma.t = array(NA,dim=c(2,2,nrow(H)) )
### Calculated standarized residuals and store in Z
for (i in 1:nrow(H)){
Sigma.t[,,i] = matrix(H[i,],2,2)
tmp1 = matrix(sim_y[i,],1,2)
tmp2 = Sigma.t[,,i]%^%(-1/2)
Z[i,] = tmp1 %*% tmp2
}
# Since we use Baysian method, we drop first 50 observations to avoid non-converenge
library(skewt)
begin = 50
end = nrow(Z)
#### Fit EVT method ######
fit = New_cov_update(Z[begin:end,], prob = 0.85)

print(c("alpha1","alpha2","rho","nu","sd1","sd2"))
## [1] "alpha1" "alpha2" "rho" "nu" "sd1" "sd2"
print(fit$EVT)
## [1] -0.04345775 0.12461728 0.16131336 4.15373426 0.74021534 0.85045754
library(gld)
print(fit.gpd(apply(Z[begin:500,],1,function(x) sqrt(x[1]^2 + x[2]^2))))
## $estA
## alpha beta delta lambda
## 0.6657047 0.9903079 0.8168256 0.1489984
##
## $estB
## alpha beta delta lambda
## 2.1696639 13.0308369 0.3080824 4.2219394
##
## $param
## [1] "gpd"
##
## attr(,"class")
## [1] "GldFitMultiple"
#### Extract parameters for multivariate skew-t from DCC model
nu = summary(bayesDcc)$statistics[1,1]
gamma1 = summary(bayesDcc)$statistics[2,1]
gamma2 = summary(bayesDcc)$statistics[6,1]
gamma = c(gamma1, gamma2)
#### Calculate CoVaR ##########
CoVaR = function(x, q, fit, VaR, Sigma, mu_s, mu_I){ # x is CoVaR
z = (c(VaR, x) - c(mu_s, mu_I)) %*% (Sigma%^%(-1/2))
diag_inv_EVT = matrix(c(1/fit$EVT[5], 0,0,1/fit$EVT[6]),2,2)
tmp_value_EVT = diag_inv_EVT %*% t(z)
z_EVT = tmp_value_EVT[2] / tmp_value_EVT[1] - fit$EVT[3]
theorm_EVT = 1-Thrm4_1(z_EVT, fit$EVT[1], fit$EVT[2], fit$EVT[3], fit$EVT[4])
# return(theorm_EVT-q)
return( (theorm_EVT - q)^2*10^10 )
}
CoVaR_Skew <- function (x, VaR, Sigma, gamma, nu, q, marginal, mu_s, mu_I) { # x is CoVaR
z = (c(VaR, x)- c(mu_s, mu_I)) %*% (Sigma%^%(-1/2))
joint = hcubature(f=dsst,lowerLimit = z, upperLimit = c(10^6,10^6) , tol = 1e-8, gamma = gamma, nu = nu)$integral
return( (joint - q*marginal)^2*10^10 )
}
CoVaR_func <- function(fit, VaR95, VaR99, Sigma.t,pos, gamma, nu, mut_s, mut_I,Z){
##### Marginal VaR #########
# VaR_Z95 = as.numeric((VaR95$evt[pos] - VaR95$mut[pos])/VaR95$sigt[pos])
VaR_Z99 = as.numeric((VaR99$evt[pos] - VaR99$mut[pos])/VaR99$sigt[pos])
# marginal95 = sum(Z[,1]>VaR_Z95)/length(Z[,1]) #1 - pskt(VaR_Z95, nu, gamma = gamma[1])
marginal99 = 1 - pskt(VaR_Z99, nu, gamma = gamma[1]) #sum(Z[,1]>VaR_Z99)/length(Z[,1]) #
tmp95_Skew =NA; tmp99_Skew = NA; tmp95 = NA; tmp99 = NA;
##### Parametric method ###########
# try(tmp95_Skew <- as.numeric(uniroot(CoVaR_Skew, q = 0.05, VaR = as.numeric(VaR95$evt[pos]), Sigma = Sigma.t[,,pos], gamma = gamma, nu = nu, marginal = marginal95, mu_s = as.numeric(mut_s[pos]), mu_I = as.numeric(mut_I[pos]), lower = 0.1, upper = 10, tol = 8e-6)$root, print =1))
try(tmp99_Skew<-as.numeric(nlminb(start=5, objective=CoVaR_Skew,q = 0.01, VaR = as.numeric(VaR99$evt[pos]), Sigma = Sigma.t[,,pos], gamma = gamma, nu = nu, marginal = marginal99, mu_s = as.numeric(mut_s[pos]), mu_I = as.numeric(mut_I[pos]))$par))
##### EVT method ###############
# try(tmp99 <- as.numeric(uniroot(CoVaR, q = 0.01, fit = fit, VaR = as.numeric(VaR99$evt[pos]), Sigma = Sigma.t[,,pos], mu_s = as.numeric(mut_s[pos]), mu_I = as.numeric(mut_I[pos]), lower = max(0.5,(tmp99_Skew-2)), upper = (tmp99_Skew+2), tol = 8e-6)$root, print =1))
try(tmp99 <- as.numeric(nlminb(start=tmp99_Skew, objective=CoVaR,q = 0.01, fit = fit, VaR = as.numeric(VaR99$evt[pos]), Sigma = Sigma.t[,,pos], mu_s = as.numeric(mut_s[pos]), mu_I = as.numeric(mut_I[pos]))$par))
return(c(marginal99, tmp99, tmp99_Skew))
}
pos = 50
all_pos = matrix(1:ndays, ndays,1)
all_pos = all_pos[-na.pos]
tmp = CoVaR_func(fit, VaR95, VaR99, Sigma.t, pos, gamma, nu, mut_s, mut_I, Z)
df = data.table(date = days[all_pos[pos]], firm = colnames(R_com)[k], marginal99 = tmp[1], CoVaR_evt99 = tmp[2], CoVaR_fp99 = tmp[3], VaR99 = as.numeric(VaR99$evt[pos]), Loss_stock = as.numeric(-R_com[all_pos[pos],k]), Loss_Index = as.numeric(-R_com[all_pos[pos], INDEX_id]))
print(df)
## date firm marginal99 CoVaR_evt99 CoVaR_fp99 VaR99 Loss_stock
## 1: 11761 10138 0.02008714 5.025907 5.469257 4.162123 -0.5865119
## Loss_Index
## 1: -1.767393