A resource for the Professional Risk Manager (PRM) exam candidate. Sample PRM exam questions, Excel models, discussion forum and more for the risk professional.
VaR disaggregation in R - Marginal and Component VaR
This is how we will do our analysis:
Download price data for all our securities from Quandl.com. Quandl offers an R package allowing R to download data for a particular stock (or currency, or commodity).
The price data has a large number of columns. We drop all the columns except the closing price.
We do this one by one for each equity asset in our portfolio. We then merge the time series.
Then we calculate daily log returns. R does that very elegantly - with just a one line command.
Now that we have returns data for the period we are interested in, we can calculate the covariance and correlation matrices.
We load up the dollar value for each equity in our portfolio in a column vector.
Now we have everything we need, and we calculate:
Portfolio weights (as a percentage)
Porfolio returns
Covariance matrix
Each stock's covariance to the portfolio
Portfolio volatility, in percent and in dollars
Portfolio VaR, in percent and dollars
Volatility of each stock in the porfolio
VaR for each stock
The total undiversified VaR
Beta for each stock
Marginal VaR
Component VaR
All using the same formulae that have been used in the previous tutorial.
Code:
# The first two lines instal xts and Quandl - you will need to run these only once. install.packages("xts") install.packages("Quandl")
library(xts) library(Quandl)
# d1 to d7 are time series variables that store the data downloaded from Quandl. # We drop all columns other than end of day closing price.
# We merge the 7 datasets d8 = merge(d1,d2,d3,d4,d5,d6,d7)
# We calculate daily log returns, and store it in a time series called returns. returns = diff(log(d8))
# Now we enter our portfolio values. Assume that our portfolio has a total value of $1m. This # is divided between the seven stocks as 5%, 17%, 8%, 17%, 20%, 14%, 19% respectively. # We store this in a matrix called w. Note that this holds the dollar value of the # constituents of the portfolio.
# We put the percentage weights in a matrix called wts. wts = w/sum(w)
# We calculate portfolio returns. Note that %*% is matrix multiplication in R. pf_returns = returns %*% wts
# We calculate the covariance matrix. A one step process. Note that these are daily covariances. # In order to get annual covariances, we will need to multiply by 250 (note that variances and covariances # scale linearly with time, while standard deviation scales by the square root of time)
V = cov(na.omit(returns)) * 250
# We calculate the covariances of asset i to portfolio p. cov_ip = V %*% wts
# Calculate the portfolio volatility, in percent, and in dollars. Note that we # are multiplying by sqrt(250) to annualize the daily volatilities. vol_p_pct = sqrt(t(wts) %*% V %*% wts) # in percent, annual Var vol_p = sqrt(t(w) %*% V %*% w) #in dollars
# Calculate the VaR, in dollars and percent. Note that 'qnorm' is equivalent to Excel's NORMSINV. # Note that we are calculating things here at the 95% confidence level. var_p = qnorm(0.95) * vol_p #Portfolio VaR in dollars var_p_pct = qnorm(0.95) * vol_p_pct #Portfolio VaR in percent
# Calculate the volatility of the i-th asset. We can then calculate the VaR of the i-th asset. vol_i = sqrt(diag(V)) VaRi = qnorm(0.95) * vol_i * d
# We calculate the undiversified VaR as the sum of the VaRs of the individual assets. uVar = sum(VaRi)
# We calculate the beta. Note that this is the same answer # you would get if you did beta = sum(w) * (V %*% w)/as.numeric(vol_p^2) beta = cov_ip/as.numeric(vol_p_pct)^2
# Calculate Marginal VaR mvar = qnorm(0.95) * (V %*% w)/as.numeric(vol_p)
# Calculate Component VaR cvar = mvar * w
# At this point you can print each of the variables by typing them on the R prompt. print ("Portfolio Constituents in Dollars") w print ("Covariance matrix (annualized)") V print ("Annual portfolio volatility/standard deviation as a percent") vol_p_pct print ("Portfolio volatility/standard deviation in dollars") vol_p print ("Portfolio VaR, as a percent") var_p_pct print ("Portfolio VaR, in dollars") var_p print ("VaR of individual stocks in the portfolio (in dollars)") VaRi print ("Total undiversified VaR (sum of VaR of individual stocks") uVar print ("Beta of each stock") beta print ("Marginal VaR of each stock") mvar print ("Component VaR") cvar print ("Sum of component VaR - should be equal to portfolio VaR above") sum(cvar)
So how does this code run in practice? Here is what the output looks like - pretty ugly but is much easier to read on the R console:
> print ("Portfolio Constituents in Dollars") [1] "Portfolio Constituents in Dollars" > w [,1] AAPL 50000 DISCA 170000 IBM 80000 JNJ 170000 KO 200000 NKE 140000 TXN 190000 > print ("Covariance matrix") [1] "Covariance matrix" > V AAPL DISCA IBM JNJ KO NKE TXN AAPL 0.071793333 0.01328617 0.009510680 0.004658095 0.006324530 0.009867259 0.017544753 DISCA 0.013286171 0.22312544 0.014487886 0.010578264 0.012427071 0.019696823 0.024372985 IBM 0.009510680 0.01448789 0.030129963 0.007129105 0.007669291 0.007695426 0.012682422 JNJ 0.004658095 0.01057826 0.007129105 0.015362860 0.007921800 0.007664518 0.010243517 KO 0.006324530 0.01242707 0.007669291 0.007921800 0.021141923 0.007522650 0.009041654 NKE 0.009867259 0.01969682 0.007695426 0.007664518 0.007522650 0.046169126 0.013834770 TXN 0.017544753 0.02437299 0.012682422 0.010243517 0.009041654 0.013834770 0.046970137 > print ("Portfolio volatility/standard deviation as a percent") [1] "Portfolio volatility/standard deviation as a percent" > vol_p_pct [,1] [1,] 0.1430367 > print ("Portfolio volatility/standard deviation in dollars") [1] "Portfolio volatility/standard deviation in dollars" > vol_p [,1] [1,] 143036.7 > print ("Portfolio VaR, as a percent") [1] "Portfolio VaR, as a percent" > var_p_pct [,1] [1,] 0.2352745 > print ("Portfolio VaR, in dollars") [1] "Portfolio VaR, in dollars" > var_p [,1] [1,] 235274.5 > print ("VaR of individual stocks in the portfolio (in dollars)") [1] "VaR of individual stocks in the portfolio (in dollars)" > VaRi [,1] [1,] 24513.657 [2,] 78486.737 [3,] 6683.584 [4,] 269280.534 [5,] 31365.429 [6,] 113494.770 [7,] 373189.729 > print ("Total undiversified VaR (sum of VaR of individual stocks") [1] "Total undiversified VaR (sum of VaR of individual stocks" > uVar [1] 897014.4 > print ("Beta of each stock") [1] "Beta of each stock" > beta [,1] AAPL 0.6540175 DISCA 2.5135905 IBM 0.5660792 JNJ 0.4798204 KO 0.5566386 NKE 0.7994936 TXN 0.9993480 > print ("Marginal VaR of each stock") [1] "Marginal VaR of each stock" > mvar [,1] AAPL 0.1538736 DISCA 0.5913836 IBM 0.1331840 JNJ 0.1128895 KO 0.1309628 NKE 0.1881004 TXN 0.2351211 > print ("Component VaR") [1] "Component VaR" > cvar [,1] AAPL 7693.68 DISCA 100535.22 IBM 10654.72 JNJ 19191.21 KO 26192.57 NKE 26334.06 TXN 44673.00 > print ("Sum of component VaR - should be equal to portfolio VaR above") [1] "Sum of component VaR - should be equal to portfolio VaR above" > sum(cvar) [1] 235274.5