Quantitative Risk Management

Value at Risk for Individual Assets with 1-year Holding Period

Loading the Required Packages and Getting the Data

library(tidyquant)
## Warning: package 'tidyquant' was built under R version 4.3.1
## Loading required package: lubridate
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
## Loading required package: PerformanceAnalytics
## Warning: package 'PerformanceAnalytics' was built under R version 4.3.1
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
## Loading required package: quantmod
## Warning: package 'quantmod' was built under R version 4.3.1
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.1
## Warning: package 'ggplot2' was built under R version 4.3.1
## Warning: package 'readr' was built under R version 4.3.1
## Warning: package 'purrr' was built under R version 4.3.1
## Warning: package 'forcats' was built under R version 4.3.1
## -- Attaching core tidyverse packages ------------------------ tidyverse 2.0.0 --
## v dplyr   1.1.2     v readr   2.1.4
## v forcats 1.0.0     v stringr 1.5.0
## v ggplot2 3.4.3     v tibble  3.2.1
## v purrr   1.0.2     v tidyr   1.3.0
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::first()  masks xts::first()
## x dplyr::lag()    masks stats::lag()
## x dplyr::last()   masks xts::last()
## i Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
stocks <- c("BBNI.JK", "BBRI.JK", "BMRI.JK", "BBCA.JK", "ARTO.JK")
stocks_data <- tq_get(stocks, get = "stock.prices", from = "2022-01-01")

Choosing Closing Data and Showing the Data in Wide Format

close_stocks_data <- stocks_data |> 
                    select(c(date, symbol, close)) |> 
                    pivot_wider(names_from = symbol, values_from = close)
close_stocks_data
## # A tibble: 427 x 6
##    date       BBNI.JK BBRI.JK BMRI.JK BBCA.JK ARTO.JK
##    <date>       <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
##  1 2022-01-03   3362.    4180   3525     7325   17325
##  2 2022-01-04   3512.    4160   3588.    7400   17400
##  3 2022-01-05   3475     4210   3512.    7450   17775
##  4 2022-01-06   3475     4160   3512.    7475   18550
##  5 2022-01-07   3538.    4190   3525     7650   18800
##  6 2022-01-10   3525     4180   3525     7600   18950
##  7 2022-01-11   3512.    4150   3525     7700   18325
##  8 2022-01-12   3525     4160   3575     7700   17850
##  9 2022-01-13   3512.    4190   3562.    7700   17375
## 10 2022-01-14   3550     4180   3588.    7850   18575
## # i 417 more rows

Calculating the Profit/Loss for Each Assets

pl_BBNI <- NULL
pl_BBRI <- NULL
pl_BMRI <- NULL
pl_BBCA <- NULL
pl_ARTO <- NULL

for (i in seq_len(length(close_stocks_data$date) - 1)) {
  pl_BBNI[i + 1] <- close_stocks_data$BBNI.JK[i + 1] - close_stocks_data$BBNI.JK[i]
  pl_BBRI[i + 1] <- close_stocks_data$BBRI.JK[i + 1] - close_stocks_data$BBRI.JK[i]
  pl_BMRI[i + 1] <- close_stocks_data$BMRI.JK[i + 1] - close_stocks_data$BMRI.JK[i]
  pl_BBCA[i + 1] <- close_stocks_data$BBCA.JK[i + 1] - close_stocks_data$BBCA.JK[i]
  pl_ARTO[i + 1] <- close_stocks_data$ARTO.JK[i + 1] - close_stocks_data$ARTO.JK[i]
}

Calculating the Value at Risk for 1-year Holding Period and 95% Confidence Level for Each Assets

alpha_cl <- qnorm(0.05)
holding_period <- 264

VaR_BBNI <- -alpha_cl * sqrt(holding_period) * STDEV(pl_BBNI) - holding_period * AVERAGE(pl_BBNI)
VaR_BBRI <- -alpha_cl * sqrt(holding_period) * STDEV(pl_BBRI) - holding_period * AVERAGE(pl_BBRI)
VaR_BMRI <- -alpha_cl * sqrt(holding_period) * STDEV(pl_BMRI) - holding_period * AVERAGE(pl_BMRI)
VaR_BBCA <- -alpha_cl * sqrt(holding_period) * STDEV(pl_BBCA) - holding_period * AVERAGE(pl_BBCA)
VaR_ARTO <- -alpha_cl * sqrt(holding_period) * STDEV(pl_ARTO) - holding_period * AVERAGE(pl_ARTO)

VaR_summary <- tibble(VaR_BBNI, VaR_BBRI, VaR_BMRI, VaR_BBCA, VaR_ARTO)
VaR_summary
## # A tibble: 1 x 5
##   VaR_BBNI VaR_BBRI VaR_BMRI VaR_BBCA VaR_ARTO
##      <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
## 1     681.    1218.    7947.    1790.   17854.

Calculating Portfolio VaR if the Weight is 0.2 for Each of the Assets

pl_stocks <- tibble(pl_BBNI, pl_BBRI, pl_BMRI, pl_BBCA, pl_ARTO)
pl_stocks <- pl_stocks[-1,]

sigma_pl_stocks <- cov(pl_stocks)
weights_stocks <- c(0.2, 0.2, 0.2, 0.2, 0.2)

VaR_portfolio <- - (alpha_cl * sqrt(holding_period) * sqrt(t(weights_stocks) %*% sigma_pl_stocks %*% weights_stocks) + holding_period * t(weights_stocks) %*% colMeans(pl_stocks))
VaR_portfolio
##          [,1]
## [1,] 4050.899