Importing Library

#Import all libraries
library('quantmod')
library('tidyquant')
library(forecast)
library('rugarch')
library('copula')
library('VGAM')
library('ggplot2')
library('GoFKernel')
library('mistr')
library('tseries')
library('stats')
library('fDMA')
library('corrplot')
library('xlsx')
library(quantmod)
library(PortfolioAnalytics)
library(DEoptim)
library(ROI)
library(ROI.plugin.quadprog)
library(PerformanceAnalytics)

Downloading data

data<-read.xlsx('C:/Users/Khanh Hoa/OneDrive/UFM/OLP/OLP_data.xlsx', sheetIndex = 1, header = T)

data <- xts(data[,-1],order.by = data$Date)

port_data <- data["2010-01-01/2019-01-02"]

var_data <- data["2019-01-02/2025-03-03"]

Descriptive Statistics

# For portfolio data
summary(port_data)
##      Index                 VCB                  HPG            
##  Min.   :2010-01-05   Min.   :-0.0722747   Min.   :-0.0723145  
##  1st Qu.:2012-04-09   1st Qu.:-0.0101105   1st Qu.:-0.0102718  
##  Median :2014-07-09   Median : 0.0000000   Median : 0.0000000  
##  Mean   :2014-07-07   Mean   : 0.0004984   Mean   : 0.0007592  
##  3rd Qu.:2016-10-05   3rd Qu.: 0.0103265   3rd Qu.: 0.0119661  
##  Max.   :2019-01-02   Max.   : 0.0675896   Max.   : 0.0676352  
##       SSI                  FPT            
##  Min.   :-7.235e-02   Min.   :-0.0720671  
##  1st Qu.:-1.184e-02   1st Qu.:-0.0079692  
##  Median : 0.000e+00   Median : 0.0000000  
##  Mean   : 4.705e-05   Mean   : 0.0004301  
##  3rd Qu.: 1.111e-02   3rd Qu.: 0.0085015  
##  Max.   : 6.701e-02   Max.   : 0.0664456
sd(port_data$VCB)
## [1] 0.02021038
sd(port_data$SSI)
## [1] 0.02147379
sd(port_data$FPT)
## [1] 0.01603776
sd(port_data$HPG)
## [1] 0.0209489
# For var data
summary(var_data)
##      Index                 VCB                  HPG            
##  Min.   :2019-01-02   Min.   :-0.1615367   Min.   :-0.0725861  
##  1st Qu.:2020-07-20   1st Qu.:-0.0073801   1st Qu.:-0.0096247  
##  Median :2022-01-26   Median : 0.0000000   Median : 0.0000000  
##  Mean   :2022-01-30   Mean   : 0.0005336   Mean   : 0.0006143  
##  3rd Qu.:2023-08-14   3rd Qu.: 0.0082053   3rd Qu.: 0.0111733  
##  Max.   :2025-02-28   Max.   : 0.0668684   Max.   : 0.0671171  
##       SSI                  FPT           
##  Min.   :-0.2311711   Min.   :-0.166182  
##  1st Qu.:-0.0102369   1st Qu.:-0.006483  
##  Median : 0.0000000   Median : 0.001040  
##  Mean   : 0.0004153   Mean   : 0.001205  
##  3rd Qu.: 0.0118753   3rd Qu.: 0.009389  
##  Max.   : 0.0848469   Max.   : 0.067628
sd(var_data$VCB)
## [1] 0.01634404
sd(var_data$SSI)
## [1] 0.02633791
sd(var_data$FPT)
## [1] 0.01766609
sd(var_data$HPG)
## [1] 0.02135287
# Plot the volatile chart
library(gridExtra)
split_date <- as.Date("2019-01-02")
p1 <- ggplot(data, aes(x = index(data), y = data$VCB)) +
  geom_line(color = "#669933") +
  geom_vline(xintercept = as.numeric(split_date), color = "red", size = 0.5) +
  coord_cartesian(ylim = c(-0.2, 0.2)) +
  labs(title = "VCB", x = "Ngày", y = "Lợi suất") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(
    axis.title.x = element_blank(), 
    axis.title.y = element_blank()
  )

p2 <- ggplot(data, aes(x = index(data), y = data$HPG)) +
  geom_line(color = "#FF9933") +
  geom_vline(xintercept = as.numeric(split_date), color = "red", size = 0.5) +
  coord_cartesian(ylim = c(-0.2, 0.2)) +
  labs(title = "HPG", x = "Ngày", y = "Lợi suất") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(
    axis.title.x = element_blank(), 
    axis.title.y = element_blank()
  )

p3 <- ggplot(data, aes(x = index(data), y = data$SSI)) +
  geom_line(color = "#3366CC") +
  geom_vline(xintercept = as.numeric(split_date), color = "red", size = 0.5) +
  coord_cartesian(ylim = c(-0.2, 0.2)) +
  labs(title = "SSI", x = "Ngày", y = "Lợi suất") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(
    axis.title.x = element_blank(), 
    axis.title.y = element_blank()
  )

p4 <- ggplot(data, aes(x = index(data), y = data$FPT)) +
  geom_line(color = "#EEE8AA") +
  geom_vline(xintercept = as.numeric(split_date), color = "red", size = 0.5) +
  coord_cartesian(ylim = c(-0.2, 0.2)) +
  labs(title = "FPT", x = "Ngày", y = "Lợi suất") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(
    axis.title.x = element_blank(), 
    axis.title.y = element_blank()
  )

grid.arrange(p1, p2, p3, p4, ncol = 2)

Correlation matrix

library(corrplot)

cor_matrix <- cor(data)
corrplot(cor_matrix,
         method = "color",
         type = "full",
         tl.col = "black",        
         tl.srt = 0,            
         addCoef.col = "black",  
         number.cex = 0.7,
         rect.col = "red")        

Optimizing portfolio

Portfolio is optimized by mean-variance analysis, with data as port_data object.

library(quantmod)
tickers <- c("VCB", "HPG", "SSI", "FPT")

# Lấy giá đóng cửa

returns <- port_data

Max mean, min std

library(PortfolioAnalytics)

# Khởi tạo danh mục
port <- portfolio.spec(assets = tickers)

# Thêm ràng buộc: tổng trọng số = 1 và không bán khống
port <- add.constraint(portfolio = port, type = "full_investment")
port <- add.constraint(portfolio = port, type = "long_only")

# Thêm mục tiêu: tối đa hóa lợi suất kỳ vọng và tối thiểu hóa phương sai
port <- add.objective(portfolio = port, type = "return", name = "mean")
port <- add.objective(portfolio = port, type = "risk", name = "var")

library(DEoptim)
library(ROI)
library(ROI.plugin.quadprog)

opt_result <- optimize.portfolio(R = returns, portfolio = port, 
                                 optimize_method = "ROI", trace = TRUE)

# Kết quả trọng số
print(extractWeights(opt_result))
##           VCB           HPG           SSI           FPT 
##  9.583907e-02  6.393141e-01 -4.003742e-18  2.648468e-01
# Tóm tắt
summary(opt_result)
## **************************************************
## PortfolioAnalytics Optimization Summary 
## **************************************************
## 
## Call:
## optimize.portfolio(R = returns, portfolio = port, optimize_method = "ROI", 
##     trace = TRUE)
## 
## Optimal Weights:
##    VCB    HPG    SSI    FPT 
## 0.0958 0.6393 0.0000 0.2648 
## 
## Objective Measures:
##     mean 
## 0.000647 
## 
## 
##  StdDev 
## 0.01683 
## 
## 
## Portfolio Assets and Initial Weights:
##  VCB  HPG  SSI  FPT 
## 0.25 0.25 0.25 0.25 
## 
## **************************************************
## PortfolioAnalytics Portfolio Specification 
## **************************************************
## 
## Call:
## portfolio.spec(assets = tickers)
## 
## Number of assets: 4 
## Asset Names
## [1] "VCB" "HPG" "SSI" "FPT"
## 
## Constraints
## Enabled constraint types
##      - full_investment 
##      - long_only 
## 
## Objectives:
## Enabled objective names
##      - mean 
##      - var 
## 
## ****************************************
## Constraints
## ****************************************
## Leverage Constraint:
## min_sum = 1
## max_sum = 1
## actual_leverage = 1
## 
## Box Constraints:
## min:
## VCB HPG SSI FPT 
##   0   0   0   0 
## max:
## VCB HPG SSI FPT 
##   1   1   1   1 
## 
## Position Limit Constraints:
## Maximum number of non-zero weights, max_pos:
## [1] "Unconstrained"
## Realized number of non-zero weights (i.e. positions):
## [1] 3
## 
## Maximum number of long positions, max_pos_long:
## [1] "Unconstrained"
## Realized number of long positions:
## [1] 3
## 
## Maximum number of short positions, max_pos_short:
## [1] "Unconstrained"
## Realized number of short positions:
## [1] 0
## 
## 
## Diversification Target Constraint:
## [1] "Unconstrained"
## 
## Realized diversification:
## [1] 0.5119485
## 
## Turnover Target Constraint:
## [1] "Unconstrained"
## 
## Realized turnover from initial weights:
## [1] 0.2020805
## 
## ****************************************
## Objectives
## ****************************************
## 
## Objective: return_objective 
## $name
## [1] "mean"
## 
## $target
## NULL
## 
## $arguments
## list()
## 
## $enabled
## [1] TRUE
## 
## $multiplier
## [1] -1
## 
## $call
## add.objective(portfolio = port, type = "return", name = "mean")
## 
## attr(,"class")
## [1] "return_objective" "objective"       
## 
## ****************************************
## Objective: portfolio_risk_objective 
## $name
## [1] "var"
## 
## $target
## NULL
## 
## $arguments
## $arguments$portfolio_method
## [1] "single"
## 
## 
## $enabled
## [1] TRUE
## 
## $multiplier
## [1] 1
## 
## $call
## add.objective(portfolio = port, type = "risk", name = "var")
## 
## attr(,"class")
## [1] "portfolio_risk_objective" "objective"               
## 
## ****************************************
## 
## Elapsed Time:
## Time difference of 0.03496504 secs

Min std

According to the descriptive statistics, the mean value ranges from 0.0047% to 0.07%. Hence, we decide that an acceptable return is 0.05%

library(PortfolioAnalytics)

port <- portfolio.spec(assets = tickers)

# constrain: sum of weights = 1 and not short
port <- add.constraint(portfolio = port, type = "full_investment")
port <- add.constraint(portfolio = port, type = "long_only")

# constrain: expected return >= 0.05%
expected_return_target <- 0.0005

port <- add.constraint(portfolio = port, type = "return", return_target = expected_return_target)

# Objective
port <- add.objective(portfolio = port, type = "risk", name = "var")
library(ROI)
library(ROI.plugin.quadprog)

opt_result <- optimize.portfolio(R = returns,
                                 portfolio = port,
                                 optimize_method = "ROI",
                                 trace = TRUE)

# Results
print(extractWeights(opt_result))
##         VCB         HPG         SSI         FPT 
## 0.224017862 0.174905849 0.007661966 0.593414323
expected_return <- sum(extractWeights(opt_result) * colMeans(returns))
portfolio_sd <- sqrt(t(extractWeights(opt_result)) %*% cov(returns) %*% extractWeights(opt_result))

cat("Expected Return:", expected_return, "\n")
## Expected Return: 5e-04
cat("Portfolio Std Dev:", portfolio_sd, "\n")
## Portfolio Std Dev: 0.01451558

Measuring risk

Using the asset weights optimized in the previous section, we measure the portfolio risk with the var_data data.

Standardize deviation

# normal portfolio
weight <- c(0.25, 0.25,0.25,0.25)
normal_portfolio_sd <- sqrt(t(weight) %*% cov(var_data) %*% weight)

# optimized portfolio
op_portfolio_sd <- sqrt(t(extractWeights(opt_result)) %*% cov(var_data) %*% extractWeights(opt_result))
normal_portfolio_sd
##            [,1]
## [1,] 0.01570012
op_portfolio_sd
##            [,1]
## [1,] 0.01466956

Historical VaR

# Calculate portfolio return
nor_port_return <-(weight[1]*var_data$FPT)+(weight[2]*var_data$HPG)+(weight[3]*var_data$SSI)+(weight[4]*var_data$VCB)

opt_port_return <-(opt_result$weights[1]*var_data$VCB)+(opt_result$weights[2]*var_data$HPG)+(opt_result$weights[3]*var_data$SSI)+(opt_result$weights[4]*var_data$FPT)

# HVaR 99
nor_hvar99 <- quantile(x = nor_port_return, p = 0.01)
opt_hvar99 <- quantile(x = opt_port_return, p = 0.01)
# HVaR 95
nor_hvar95 <- quantile(x = nor_port_return, p = 0.05)
opt_hvar95 <- quantile(x = opt_port_return, p = 0.05)
# HVaR 90
nor_hvar90 <- quantile(x = nor_port_return, p = 0.1)
opt_hvar90 <- quantile(x = opt_port_return, p = 0.1)

# Result
cat("Normal Portfolio Historical VaR 99%:", nor_hvar99, "\n")
## Normal Portfolio Historical VaR 99%: -0.05084429
cat("Optimized Portfolio Historical VaR 99%:", opt_hvar99, "\n")
## Optimized Portfolio Historical VaR 99%: -0.0470031
cat("Normal Portfolio Historical VaR 95%:", nor_hvar95, "\n")
## Normal Portfolio Historical VaR 95%: -0.02475714
cat("Optimized Portfolio Historical VaR 95%:", opt_hvar95, "\n")
## Optimized Portfolio Historical VaR 95%: -0.02105234
cat("Normal Portfolio Historical VaR 90%:", nor_hvar90, "\n")
## Normal Portfolio Historical VaR 90%: -0.01620939
cat("Optimized Portfolio Historical VaR 90%:", opt_hvar90, "\n")
## Optimized Portfolio Historical VaR 90%: -0.01409418

Parametric VaR

Gaus distribution assumption

# Param VaR 99%
nor_paramvar99 <- mean(nor_port_return) + qnorm(0.01)*normal_portfolio_sd
opt_paramvar99 <- mean(opt_port_return) + qnorm(0.01)*op_portfolio_sd
# Param VaR 95%
nor_paramvar95 <- mean(nor_port_return) + qnorm(0.05)*normal_portfolio_sd
opt_paramvar95 <- mean(opt_port_return) + qnorm(0.05)*op_portfolio_sd
# Param VaR 90%
nor_paramvar90 <- mean(nor_port_return) + qnorm(0.1)*normal_portfolio_sd
opt_paramvar90 <- mean(opt_port_return) + qnorm(0.1)*op_portfolio_sd

# Print results
cat("Normal Portfolio Parametric VaR 99%:", nor_paramvar99, "\n")
## Normal Portfolio Parametric VaR 99%: -0.03583176
cat("Optimized Portfolio Parametric VaR 99%:", opt_paramvar99, "\n")
## Optimized Portfolio Parametric VaR 99%: -0.03318102
cat("Normal Portfolio Parametric VaR 95%:", nor_paramvar95, "\n")
## Normal Portfolio Parametric VaR 95%: -0.02513222
cat("Optimized Portfolio Parametric VaR 95%:", opt_hvar95, "\n")
## Optimized Portfolio Parametric VaR 95%: -0.02105234
cat("Normal Portfolio Parametric VaR 90%:", nor_paramvar90, "\n")
## Normal Portfolio Parametric VaR 90%: -0.01942834
cat("Optimized Portfolio Parametric VaR 90%:", opt_paramvar90, "\n")
## Optimized Portfolio Parametric VaR 90%: -0.01785432

Garch

Estimate

# Estimate
nor_garchspec <- ugarchspec(
  mean.model=list(armaOrder=c(0,0),
  variance.model=list(model = "sGARCH",garchOrder = c(1, 1)),
  distribution.model = "norm"))
## Warning: unidentified option(s) in mean.model:
##  variance.model distribution.model
nor_garchfit <- ugarchfit(data=nor_port_return,spec=nor_garchspec)

opt_garchspec <- ugarchspec(
  mean.model=list(armaOrder=c(0,0),
  variance.model=list(model = "sGARCH",garchOrder = c(1, 1)),
  distribution.model = "norm"))
## Warning: unidentified option(s) in mean.model:
##  variance.model distribution.model
opt_garchfit <- ugarchfit(data=opt_port_return,spec=opt_garchspec)

nor_garchfit
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(1,1)
## Mean Model   : ARFIMA(0,0,0)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.000852    0.000319  2.67633 0.007443
## omega   0.000005    0.000006  0.84192 0.399831
## alpha1  0.090782    0.003625 25.04478 0.000000
## beta1   0.888156    0.016009 55.47717 0.000000
## 
## Robust Standard Errors:
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.000852    0.000379  2.25192 0.024328
## omega   0.000005    0.000044  0.12129 0.903459
## alpha1  0.090782    0.071504  1.26961 0.204224
## beta1   0.888156    0.136169  6.52244 0.000000
## 
## LogLikelihood : 4382.062 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -5.6969
## Bayes        -5.6830
## Shibata      -5.6969
## Hannan-Quinn -5.6917
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                      1.004  0.3163
## Lag[2*(p+q)+(p+q)-1][2]     1.005  0.4966
## Lag[4*(p+q)+(p+q)-1][5]     1.289  0.7916
## d.o.f=0
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.3177  0.5730
## Lag[2*(p+q)+(p+q)-1][5]    0.8155  0.8998
## Lag[4*(p+q)+(p+q)-1][9]    1.1142  0.9810
## d.o.f=2
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[3]    0.1435 0.500 2.000  0.7048
## ARCH Lag[5]    0.3394 1.440 1.667  0.9296
## ARCH Lag[7]    0.5440 2.315 1.543  0.9742
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  0.5611
## Individual Statistics:              
## mu     0.07824
## omega  0.26319
## alpha1 0.18040
## beta1  0.15443
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.07 1.24 1.6
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value    prob sig
## Sign Bias           0.7552 0.45025    
## Negative Sign Bias  1.4503 0.14718    
## Positive Sign Bias  1.0524 0.29279    
## Joint Effect       11.1403 0.01099  **
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     71.97    4.322e-08
## 2    30     82.43    5.072e-07
## 3    40    103.68    8.916e-08
## 4    50    120.74    5.465e-08
## 
## 
## Elapsed time : 0.148509
opt_garchfit
## 
## *---------------------------------*
## *          GARCH Model Fit        *
## *---------------------------------*
## 
## Conditional Variance Dynamics    
## -----------------------------------
## GARCH Model  : sGARCH(1,1)
## Mean Model   : ARFIMA(0,0,0)
## Distribution : norm 
## 
## Optimal Parameters
## ------------------------------------
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.001100    0.000309   3.5604  0.00037
## omega   0.000007    0.000001   7.8149  0.00000
## alpha1  0.093001    0.008611  10.7998  0.00000
## beta1   0.872273    0.010097  86.3900  0.00000
## 
## Robust Standard Errors:
##         Estimate  Std. Error  t value Pr(>|t|)
## mu      0.001100    0.000314   3.5043 0.000458
## omega   0.000007    0.000001   4.9776 0.000001
## alpha1  0.093001    0.007863  11.8283 0.000000
## beta1   0.872273    0.012560  69.4457 0.000000
## 
## LogLikelihood : 4458.947 
## 
## Information Criteria
## ------------------------------------
##                     
## Akaike       -5.7969
## Bayes        -5.7830
## Shibata      -5.7970
## Hannan-Quinn -5.7918
## 
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                     0.4883  0.4847
## Lag[2*(p+q)+(p+q)-1][2]    0.9133  0.5272
## Lag[4*(p+q)+(p+q)-1][5]    1.5114  0.7371
## d.o.f=0
## H0 : No serial correlation
## 
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
##                         statistic p-value
## Lag[1]                    0.03135  0.8595
## Lag[2*(p+q)+(p+q)-1][5]   0.84268  0.8941
## Lag[4*(p+q)+(p+q)-1][9]   2.23456  0.8752
## d.o.f=2
## 
## Weighted ARCH LM Tests
## ------------------------------------
##             Statistic Shape Scale P-Value
## ARCH Lag[3]  0.002518 0.500 2.000  0.9600
## ARCH Lag[5]  1.644435 1.440 1.667  0.5552
## ARCH Lag[7]  2.644877 2.315 1.543  0.5830
## 
## Nyblom stability test
## ------------------------------------
## Joint Statistic:  7.174
## Individual Statistics:             
## mu     0.0818
## omega  1.7833
## alpha1 0.1502
## beta1  0.1558
## 
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic:          1.07 1.24 1.6
## Individual Statistic:     0.35 0.47 0.75
## 
## Sign Bias Test
## ------------------------------------
##                    t-value   prob sig
## Sign Bias           0.8131 0.4163    
## Negative Sign Bias  1.0369 0.3000    
## Positive Sign Bias  0.2901 0.7718    
## Joint Effect        5.2310 0.1556    
## 
## 
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
##   group statistic p-value(g-1)
## 1    20     63.27    1.162e-06
## 2    30     83.25    3.831e-07
## 3    40     89.57    7.485e-06
## 4    50    120.74    5.465e-08
## 
## 
## Elapsed time : 0.1608062
nor_pre_mu <- fitted(nor_garchfit)
nor_pre_sigma <- sigma(nor_garchfit)

Forecast and calculate VaR

# Forecast
nor_pre_mu <- fitted(nor_garchfit)
nor_pre_sigma <- sigma(nor_garchfit)
opt_pre_mu <- fitted(opt_garchfit)
opt_pre_sigma <- sigma(opt_garchfit)
# Calculate var
# Param VaR 99%
nor_garchvar99 <- nor_pre_mu + qnorm(0.01)*nor_pre_sigma
opt_garchvar99 <- opt_pre_mu + qnorm(0.01)*opt_pre_sigma
# Param VaR 95%
nor_garchvar95 <- nor_pre_mu + qnorm(0.05)*nor_pre_sigma
opt_garchvar95 <- opt_pre_mu + qnorm(0.05)*opt_pre_sigma
# Param VaR 90%
nor_garchvar90 <- nor_pre_mu + qnorm(0.1)*nor_pre_sigma
opt_garchvar90 <- opt_pre_mu + qnorm(0.1)*opt_pre_sigma

# Plot 

plot(cbind(nor_garchvar99,opt_garchvar99),ylim=c(-0.09,0.09),col=c("blue","darkorange2"),main="VaR 99%",lwd=1)

addLegend("topright", c("Danh mục không tối ưu","Danh mục tối ưu"),
       c("blue","darkorange2"), lty=1.5, cex=1)

plot(cbind(nor_garchvar95,opt_garchvar95),ylim=c(-0.09,0.09),col=c("blue","darkorange2"),main="VaR 95%",lwd=1)

addLegend("topright", c("Danh mục không tối ưu","Danh mục tối ưu"),
       c("blue","darkorange2"), lty=1.5, cex=1)

plot(cbind(nor_garchvar90,opt_garchvar90),ylim=c(-0.09,0.09),col=c("blue","darkorange2"),main="VaR 90%",lwd=1)

addLegend("topright", c("Danh mục không tối ưu","Danh mục tối ưu"),
       c("blue","darkorange2"), lty=1.5, cex=1)

Conditional VaR

# For historical var
nor_CVaR99 <- mean(nor_port_return[nor_port_return <= nor_hvar99])
opt_CVaR99 <- mean(opt_port_return[opt_port_return <= opt_hvar99])
nor_CVaR95 <- mean(nor_port_return[nor_port_return <= nor_hvar95])
opt_CVaR95 <- mean(opt_port_return[opt_port_return <= opt_hvar95])
nor_CVaR90 <- mean(nor_port_return[nor_port_return <= nor_hvar90])
opt_CVaR90 <- mean(opt_port_return[opt_port_return <= opt_hvar90])

cat("Normal Portfolio Historical CVaR (99%):", nor_CVaR99, "\n")
## Normal Portfolio Historical CVaR (99%): -0.05901504
cat("Optimized Portfolio Historical CVaR (99%):", opt_CVaR99, "\n")
## Optimized Portfolio Historical CVaR (99%): -0.06204509
cat("Normal Portfolio Historical CVaR (95%):", nor_CVaR95, "\n")
## Normal Portfolio Historical CVaR (95%): -0.04058577
cat("Optimized Portfolio Historical CVaR (95%):", opt_CVaR95, "\n")
## Optimized Portfolio Historical CVaR (95%): -0.0366862
cat("Normal Portfolio Historical CVaR (90%):", nor_CVaR90, "\n")
## Normal Portfolio Historical CVaR (90%): -0.03023092
cat("Optimized Portfolio Historical CVaR (90%):", opt_CVaR90, "\n")
## Optimized Portfolio Historical CVaR (90%): -0.0267804
# For Parametric var
nor_mu <- mean(nor_port_return)
nor_sigma <- sd(nor_port_return)
opt_mu <- mean(opt_port_return)
opt_sigma <- sd(opt_port_return)

z_99 <- qnorm(0.01) 
z_95 <- qnorm(0.05) 
z_90 <- qnorm(0.1) 

CVaR_parametric <- nor_mu - nor_sigma * dnorm(z_99) / 0.01

nor_param_CVaR99 <- nor_mu - nor_sigma * dnorm(z_99) / 0.01
opt_param_CVaR99 <- opt_mu - opt_sigma * dnorm(z_99) / 0.01
nor_param_CVaR95 <- nor_mu - nor_sigma * dnorm(z_95) / 0.05
opt_param_CVaR95 <- opt_mu - opt_sigma * dnorm(z_95) / 0.05
nor_param_CVaR90 <- nor_mu - nor_sigma * dnorm(z_90) / 0.1
opt_param_CVaR90 <- opt_mu - opt_sigma * dnorm(z_90) / 0.1

cat("Normal Portfolio Parametric CVaR (99%):", nor_param_CVaR99, "\n")
## Normal Portfolio Parametric CVaR (99%): -0.04115201
cat("Optimized Portfolio Parametric CVaR (99%):", opt_param_CVaR99, "\n")
## Optimized Portfolio Parametric CVaR (99%): -0.03815204
cat("Normal Portfolio Parametric CVaR (95%):", nor_param_CVaR95, "\n")
## Normal Portfolio Parametric CVaR (95%): -0.03169266
cat("Optimized Portfolio Parametric CVaR (95%):", opt_param_CVaR95, "\n")
## Optimized Portfolio Parametric CVaR (95%): -0.02931361
cat("Normal Portfolio Parametric CVaR (90%):", nor_param_CVaR90, "\n")
## Normal Portfolio Parametric CVaR (90%): -0.02686127
cat("Optimized Portfolio Parametric CVaR (90%):", opt_param_CVaR90, "\n")
## Optimized Portfolio Parametric CVaR (90%): -0.02479935
# For GARCH(1,1) var

nor_garch_CVaR99 <- nor_pre_mu - nor_pre_sigma * dnorm(z_99) / 0.01
opt_garch_CVaR99 <- opt_pre_mu - opt_pre_sigma * dnorm(z_99) / 0.01
nor_garch_CVaR95 <- nor_pre_mu - nor_pre_sigma * dnorm(z_95) / 0.05
opt_garch_CVaR95 <- opt_pre_mu - opt_pre_sigma * dnorm(z_95) / 0.05
nor_garch_CVaR90 <- nor_pre_mu - nor_pre_sigma * dnorm(z_90) / 0.1
opt_garch_CVaR90 <- opt_pre_mu - nor_pre_sigma * dnorm(z_90) / 0.1

#Plot
plot(cbind(nor_garch_CVaR99,opt_garch_CVaR99),ylim=c(-0.09,0.09),col=c("#669933","#BB0000"),main="VaR 99%",lwd=1)

addLegend("topright", c("Danh mục không tối ưu","Danh mục tối ưu"),
       c("#669933","#BB0000"), lty=1.5, cex=1)

plot(cbind(nor_garch_CVaR95,opt_garch_CVaR95),ylim=c(-0.09,0.09),col=c("#669933","#BB0000"),main="VaR 95%",lwd=1)

addLegend("topright", c("Danh mục không tối ưu","Danh mục tối ưu"),
       c("#669933","#BB0000"), lty=1.5, cex=1)

plot(cbind(nor_garch_CVaR90,opt_garch_CVaR90),ylim=c(-0.05,0.05),col=c("#669933","#BB0000"),main="VaR 90%",lwd=1)

addLegend("topright", c("Danh mục không tối ưu","Danh mục tối ưu"),
       c("#669933","#BB0000"), lty=1.5, cex=1)