About

This worksheet looks at VaR calculations for the two cases of single and multiple equity asset. We will also demonstrate VaR calculations for a fixed income investment.

Task 1: VaR Calculations: Single Equity Asset

Consider the time series of a stock of your choice (we looked at Fedex stock) and for the time-period from Jan 1, 2018 to present.

We will first generate the historical time series of daily log returns, and calculate the mean and standard deviation of the time series.

Calculate the historical daily log returns, mean and standard deviation

#Install package quantmod 
#install.packages("quantmod")
library("quantmod")
## Warning: package 'quantmod' was built under R version 4.2.1
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.2.1
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.2.1
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.2.1
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
getSymbols("FDX", from = "2015-01-01", to = Sys.Date())
## [1] "FDX"
price = FDX$FDX.Adjusted
price = as.numeric(price)
ret = diff(log(price))
mu = mean(ret)
sigma = sd(ret)

sprintf("Mean is: %f", mu )
## [1] "Mean is: 0.000005"
sprintf("standard deviation is: %f",sigma)
## [1] "standard deviation is: 0.020765"

Given a time series we can generate a histogram and mark the quantile value that corresponds to the 95% confidence level. The quantile value in this case is the critical value for which 95% of the data is on the right (higher) of the critical value as represented by the histogram. The remaining 5% will be on the left. To find the quantile value you will need to use the function quantile() with the proper arguments. For example quantile(xts,probs=0.01) applies to a time series xts and return the critical value correspondng to 99% confidence level.

hist(ret, main = "Historical FDX Log Returns", breaks = 50)
q = quantile(ret, probs = 0.05)
abline(v = q, col = "blue")

Given the above, we can calculate a VaR value for a given investment and time horizon. Assume $2000 investment in the stock, calculate the 95% VaR for a 5 day time horizon.

As calculated we get VaR(with log return) for a 5 day time horizon and 2,000USD investment = ~59.227379USD. In practical terms, this means there is a 5% chance of losing at least ~59.227379USD over a 5 day time horizon.

T = 5
alpha = 0.05
V = 2000
VaR = V * (exp(quantile(ret, probs = 0.05))-1)
 
sprintf("VaR(value at risk ) is: %f", VaR )
## [1] "VaR(value at risk ) is: -59.168451"

How does the VaR calculation change if we assume simple returns instead of the log returns?

VaR(with Simple return) for a 5 day time horizon and 2,000USD investment = ~59.360998USD. In practical terms, this means there is a 5% chance of losing at least ~59.360998USD over a 5 day time horizon.

ret2 = periodReturn(FDX, period = "daily", type = "arithmetic")
mu2 = mean(ret2)
sigma2 = sd(ret2)

hist(ret2, main = "FDX Simple Returns", breaks = 50)
q = quantile(ret2, probs = 0.05)
abline(v=q, col = "red")

T = 5
alpha = 0.05
V = 2000
VarSim = V*quantile(ret2, probs=0.05)
VarSim
##        5% 
## -59.33727
sprintf("Var(value at risk ) with simple returns is: %f", VarSim )
## [1] "Var(value at risk ) with simple returns is: -59.337268"

Since log returns are continuously compounded returns, it is normal to see that the log returns VaR are lower than simple returns.

Task 2: VaR Calculations: Multiple Equity Portfolio VaR Test

In this section we will consider the equity stocks we chose for our group portfolio. The portfolio includes the following stocks: PFE, JNJ, MRNA, META, COST, WMT, KR, BAC and HSBC for the time-period from Jan 1,2018 to present. The total cash amount invested in these assets is $62,499,375 with different allocations distributed among all nine stocks.

To calculate the portfolio VaR we will follow the methodolgy described by the variance-covariance method. First the covariance matrix needs to be computed. We then calculate the variance or volatility of the portolio as expressed in the varaince-covariance method taking into account the weights associated with each asset in the portfolio. Finally we compute the mean or expected return of the portfolio also taking into account the weights. Given the expected return and volatility we should be able to compute the VaR of the portfolio. The assumption is we have a normal distribution of log returns.

First we calculate the overall portfolio VaR.

Calculate the portfolio 99% VaR for 3 day, and 5 days for the invested amount.

symbols = c("PFE", "JNJ", "MRNA", "META", "COST", "WMT", "KR", "BAC", "HSBC")
getSymbols(symbols, src = "yahoo", from = "2018-01-01", to = Sys.Date())
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## pausing 1 second between requests for more than 5 symbols
## [1] "PFE"  "JNJ"  "MRNA" "META" "COST" "WMT"  "KR"   "BAC"  "HSBC"
PfeRd = as.numeric(periodReturn(PFE$PFE.Adjusted, period ="daily", type = "log"))
JnjRd = as.numeric(periodReturn(JNJ$JNJ.Adjusted, period ="daily", type = "log"))
MrnaRd = as.numeric(periodReturn(MRNA$MRNA.Adjusted, period ="daily", type = "log"))
MetaRd = as.numeric(periodReturn(META$META.Adjusted, period ="daily", type = "log"))
CostRd = as.numeric(periodReturn(COST$COST.Adjusted, period ="daily", type = "log"))
WmtRd = as.numeric(periodReturn(WMT$WMT.Adjusted, period ="daily", type = "log"))
KrRd = as.numeric(periodReturn(KR$KR.Adjusted, period ="daily", type = "log"))
BacRd = as.numeric(periodReturn(BAC$BAC.Adjusted, period ="daily", type = "log"))
HsbcRd = as.numeric(periodReturn(HSBC$HSBC.Adjusted, period ="daily", type = "log"))

m = cbind(PfeRd, JnjRd, MrnaRd, MetaRd, CostRd, WmtRd, KrRd, BacRd, HsbcRd)
## Warning in cbind(PfeRd, JnjRd, MrnaRd, MetaRd, CostRd, WmtRd, KrRd, BacRd, :
## number of rows of result is not a multiple of vector length (arg 3)
cor(m)
##             PfeRd       JnjRd      MrnaRd      MetaRd      CostRd       WmtRd
## PfeRd   1.0000000  0.55551789 -0.03833670  0.24812131  0.36067508  0.31269818
## JnjRd   0.5555179  1.00000000 -0.05316568  0.26710589  0.48346548  0.42397347
## MrnaRd -0.0383367 -0.05316568  1.00000000 -0.07430618 -0.04323382 -0.02710226
## MetaRd  0.2481213  0.26710589 -0.07430618  1.00000000  0.40317386  0.24612199
## CostRd  0.3606751  0.48346548 -0.04323382  0.40317386  1.00000000  0.61297987
## WmtRd   0.3126982  0.42397347 -0.02710226  0.24612199  0.61297987  1.00000000
## KrRd    0.1761112  0.25108913  0.02422973  0.09506977  0.37052136  0.40497419
## BacRd   0.3711906  0.42026661 -0.03575439  0.37402845  0.33369865  0.29037034
## HsbcRd  0.2712280  0.31532454 -0.05571856  0.26720359  0.23828866  0.19306388
##              KrRd       BacRd      HsbcRd
## PfeRd  0.17611115  0.37119061  0.27122800
## JnjRd  0.25108913  0.42026661  0.31532454
## MrnaRd 0.02422973 -0.03575439 -0.05571856
## MetaRd 0.09506977  0.37402845  0.26720359
## CostRd 0.37052136  0.33369865  0.23828866
## WmtRd  0.40497419  0.29037034  0.19306388
## KrRd   1.00000000  0.14405187  0.09734446
## BacRd  0.14405187  1.00000000  0.65641093
## HsbcRd 0.09734446  0.65641093  1.00000000
w = c(0.05, 0.42, 0.07, 0.02,   0.04,   0.18,   0.08,   0.08, 0.06)

var_p = t(w) %*% cov(m) %*% w

mu_p = colMeans(m) %*% w 



T = 3
alpha = 0.01 
V = 62499375
Var3 = V*(exp(qnorm(alpha, mean = T*mu_p, sd= sqrt(T*var_p)))-1)
sprintf("Portfolio Var for 3 days is %f",Var3)
## [1] "Portfolio Var for 3 days is -2578702.303047"
T = 5
alpha = 0.01 
V = 62499375
Var5 = V*(exp(qnorm(alpha, mean = T*mu_p, sd= sqrt(T*var_p)))-1)
sprintf("Portfolio Var for 5 days is %f",Var5)
## [1] "Portfolio Var for 5 days is -3285536.029749"

Calculate the nine-individual asset 99% VaR for 3 days.

muPfe = mean(PfeRd)
sigmaPfe = sd(PfeRd)

T = 3
alpha = 0.01
V = 62499375 * 0.05
VaRPfe = V*(exp(qnorm(alpha, mean=T*muPfe, sd=sqrt(T)*sigmaPfe))-1)
sprintf("individual PFE Var for 3 days is %f",VaRPfe)
## [1] "individual PFE Var for 3 days is -197899.714979"
muJnj = mean(JnjRd)
sigmaJnj = sd(JnjRd)

T = 3
alpha = 0.01
V = 62499375 * 0.42
VaRJnj = V*(exp(qnorm(alpha, mean=T*muJnj, sd=sqrt(T)*sigmaJnj))-1)
sprintf("individual JNJ Var for 3 days is %f",VaRJnj)
## [1] "individual JNJ Var for 3 days is -1355396.446273"
muMrna = mean(MrnaRd)
sigmaMrna = sd(MrnaRd)

T = 3
alpha = 0.01
V = 62499375 * 0.07
VaRMrna = V*(exp(qnorm(alpha, mean=T*muMrna, sd=sqrt(T)*sigmaMrna))-1)
sprintf("individual MRNA Var for 3 days is %f",VaRMrna)
## [1] "individual MRNA Var for 3 days is -780226.961273"
muMeta = mean(MetaRd)
sigmaMeta = sd(MetaRd)

T = 3
alpha = 0.01
V = 62499375 * 0.02
VaRMeta = V*(exp(qnorm(alpha, mean=T*muMeta, sd=sqrt(T)*sigmaMeta))-1)
sprintf("individual META Var for 3 days is %f",VaRMeta)
## [1] "individual META Var for 3 days is -127060.895893"
muCost = mean(CostRd)
sigmaCost = sd(CostRd)

T = 3
alpha = 0.01
V = 62499375 * 0.04
VaRCost = V*(exp(qnorm(alpha, mean=T*muCost, sd=sqrt(T)*sigmaCost))-1)
sprintf("individual COST Var for 3 days is %f",VaRCost)
## [1] "individual COST Var for 3 days is -142281.263188"
muWmt = mean(WmtRd)
sigmaWmt = sd(WmtRd)

T = 3
alpha = 0.01
V = 62499375 * 0.18
VaRWmt = V*(exp(qnorm(alpha, mean=T*muWmt, sd=sqrt(T)*sigmaWmt))-1)
sprintf("individual WMT Var for 3 days is %f",VaRWmt)
## [1] "individual WMT Var for 3 days is -643121.772228"
muKr = mean(KrRd)
sigmaKr = sd(KrRd)

T = 3
alpha = 0.01
V = 62499375 * 0.08
VaRKr = V*(exp(qnorm(alpha, mean=T*muKr, sd=sqrt(T)*sigmaKr))-1)
sprintf("individual KR Var for 3 days is %f",VaRKr)
## [1] "individual KR Var for 3 days is -381513.720653"
muBac = mean(BacRd)
sigmaBac = sd(BacRd)

T = 3
alpha = 0.01
V = 62499375 * 0.08
VaRBac = V*(exp(qnorm(alpha, mean=T*muBac, sd=sqrt(T)*sigmaBac))-1)
sprintf("individual BAC Var for 3 days is %f",VaRBac)
## [1] "individual BAC Var for 3 days is -429988.609133"
muHsbc = mean(HsbcRd)
sigmaHsbc = sd(HsbcRd)

T = 3
alpha = 0.01
V = 62499375 * 0.06
VaRHsbc = V*(exp(qnorm(alpha, mean=T*muHsbc, sd=sqrt(T)*sigmaHsbc))-1)
sprintf("individual HSBC Var for 3 days is %f",VaRHsbc)
## [1] "individual HSBC Var for 3 days is -261908.225230"
totalIndVar = VaRPfe + VaRJnj + VaRMrna + VaRMeta + VaRCost + VaRWmt + VaRKr + VaRBac + VaRHsbc
sprintf("sum of individual investments VaR for 3 days is %f",totalIndVar)
## [1] "sum of individual investments VaR for 3 days is -4319397.608849"
sprintf("Overall Portfolio VaR for 3 days is %f",Var3)
## [1] "Overall Portfolio VaR for 3 days is -2578702.303047"

Based on the results we can see that the significant reduction in VaR for the overall portfolio relative to the sum of the individual assets’ VaR is due to the benefit of portfolio diversification.

Task 3: VaR Calculations: Fixed Income Investment

Our group also considered keeping risk low- and consistent-income earnings via dividends and coupons. About 49% of our investments went into Fixed Income Funds.

Calculating the VaR for fixed income investment will be done on a fund by fund basis, as our portfolio includes a combination of US Investment Grade Fixed Income, US Equities and EM Government Bonds ETFs.

We’ll start with the calculation of VaR for the US Equities, which include S&P 500 ETF and Nasdaq 100 ETF.

getSymbols("QQQ", from = "2015-01-01", to = Sys.Date())
## [1] "QQQ"
getSymbols("SPY", from = "2015-01-01", to = Sys.Date())
## [1] "SPY"
QqqRd = as.numeric(periodReturn(QQQ$QQQ.Adjusted, period ="daily", type = "log"))
SpyRd = as.numeric(periodReturn(SPY$SPY.Adjusted, period ="daily", type = "log"))

m2 = cbind(QqqRd, SpyRd)
cor(m2)
##           QqqRd     SpyRd
## QqqRd 1.0000000 0.9285253
## SpyRd 0.9285253 1.0000000
w2 = c(0.5, 0.5)

var_p2 = t(w2) %*% cov(m2) %*% w2

mu_p2 = colMeans(m2) %*% w2 



T = 1
alpha = 0.01 
V = 30625000
Var1 = V*(exp(qnorm(alpha, mean = T*mu_p2, sd= sqrt(T*var_p2)))-1)
sprintf("Portfolio VaR for 1 day is %f",Var1)
## [1] "Portfolio VaR for 1 day is -875394.822278"

Now we’ll continue by calculating the VaR for US Investment Grade Fixed Income, which include AGG (Core US Aggregate Bond ETF)

getSymbols("AGG", from = "2015-01-01", to = Sys.Date())
## [1] "AGG"
AggRd = as.numeric(periodReturn(AGG$AGG.Adjusted, period ="daily", type = "log"))

muAgg = mean(AggRd)
sigmaAgg = sd(AggRd)

T = 1
alpha = 0.01 
V = 18375000
VaRAgg = V*(exp(qnorm(alpha, mean=T*muAgg, sd=sqrt(T)*sigmaAgg))-1)
sprintf("individual AGG Var for 1 day is %f",VaRAgg)
## [1] "individual AGG Var for 1 day is -128891.506964"

Lastly, we will calculate the VaR for EM Government Bonds, which include EMB (USD Emerging Markets Bond ETF)

getSymbols("EMB", from = "2015-01-01", to = Sys.Date())
## [1] "EMB"
EmbRd = as.numeric(periodReturn(EMB$EMB.Adjusted, period ="daily", type = "log"))

muEmb = mean(EmbRd)
sigmaEmb = sd(EmbRd)

T = 1
alpha = 0.01 
V = 12250000
VaREmb = V*(exp(qnorm(alpha, mean=T*muEmb, sd=sqrt(T)*sigmaEmb))-1)
sprintf("individual EMB Var for 1 day is %f",VaREmb)
## [1] "individual EMB Var for 1 day is -178209.007198"

Conclusion

Based on the results we can see that the significant reduction in VaR for the overall portfolio relative to the sum of the individual assets’ VaR is due to the benefit of portfolio diversification.