Applied Portfolio VaR Decomposition
19 Jan 2015To install Systematic Investor Toolbox (SIT) please visit About page.
Pawel Lachowicz published very good tutorial at Applied Portfolio VaR Decomposition. (1) Marginal and Component VaR..
Additional info:
Below I will try to adapt his code:
#*****************************************************************
# Load historical data
#*****************************************************************
library(SIT)
load.packages('quantmod')
tickers = spl('AAPL,DIS,IBM,JNJ,KO,NKE,TXN')
data <- new.env()
data$symbolnames = tickers
getSymbols(tickers, src = 'yahoo', from = '1970-01-01', env = data, auto.assign = T)
for(i in data$symbolnames) data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)
bt.prep(data, align='remove.na')
#*****************************************************************
# Setup
#*****************************************************************
prices = last(data$prices, 3*252)
n = ncol(prices)
last.price = last(prices)
last.date = index(last(prices))
rets = prices / mlag(prices) - 1
#rets = diff(log(prices))
rets = coredata(na.omit(rets))
shares = list(AAPL = 530, DIS = 1050, IBM = 150, JNJ = 12700, KO = 3100, NKE = 3500, TXN = 19650)
shares = unlist(shares[colnames(prices)])
capital = sum(last.price * shares)
exposure = last.price * shares
weight = exposure / capital
#*****************************************************************
# Compute VaR
#*****************************************************************
compute.VaR = function(rets = NULL, cov.mat = cov(rets),
weight = rep(1/nrow(cov.mat), nrow(cov.mat)),
capital = 1, con.levl = 0.95, date = Sys.Date())
{
z.stat = qnorm(con.levl)
weight = as.vector(weight)
asset.vol = abs(weight) * sqrt(diag(cov.mat))
asset.VaR = z.stat * asset.vol
undiversified.VaR = sum(asset.VaR)
port.vol = sqrt(t(weight) %*% cov.mat %*% weight)[1]
port.VaR = z.stat * port.vol
beta = (cov.mat %*% weight) / port.vol^2
marginal.VaR = z.stat * (cov.mat %*% weight) / port.vol
component.VaR = marginal.VaR * weight
list(con.levl = con.levl,
date = date,
n = nrow(cov.mat),
capital = capital,
weight = weight,
tickers = colnames(cov.mat),
undiversified.VaR = capital * undiversified.VaR,
port.vol = sqrt(252) * port.vol,
port.VaR = capital * port.VaR,
asset.VaR = capital * asset.VaR,
component.VaR = capital * component.VaR,
component.VaR.percent = component.VaR / port.VaR,
marginal.VaR = marginal.VaR
)
}
#*****************************************************************
# Helper function to display VaR
#*****************************************************************
summary.VaR = function(data.VaR, capital = 1) {
plot.data = list(
'Portfolio Risk Report as of' = format(data.VaR$date, '%d-%b-%Y'),
'VaR estimation at' = paste(to.percent(data.VaR$con.levl), 'confidence level'),
'Number of assets:' = data.VaR$n,
'Current exposure:' = to.cash(capital * data.VaR$capital),
'Portfolio VaR (undiversified):' = to.cash(capital * data.VaR$undiversified.VaR),
'Portfolio VaR (diversified):' = to.cash(capital * data.VaR$port.VaR),
'Component VaR [individual VaR]' = ''
)
plot.data1 = cbind(
to.percent(data.VaR$component.VaR.percent),
to.cash(capital * data.VaR$component.VaR),
to.cash(capital * data.VaR$asset.VaR)
)
rbind(cbind(sapply(plot.data,identity),'',''), plot.data1)
}
#*****************************************************************
# Compute VaR
#*****************************************************************
base.VaR = compute.VaR(rets, weight = weight, capital = capital, date = last.date)
print(summary.VaR(base.VaR))
Portfolio Risk Report as of | 20-Jan-2015 | ||
---|---|---|---|
VaR estimation at | 95% confidence level | ||
Number of assets: | 7 | ||
Current exposure: | $2,985,822 | ||
Portfolio VaR (undiversified): | $53,389.94 | ||
Portfolio VaR (diversified): | $39,584.48 | ||
Component VaR [individual VaR] | |||
AAPL | 1.39% | $ 550.53 | $ 1,611.14 |
DIS | 2.84% | $ 1,122.53 | $ 1,831.47 |
IBM | 0.48% | $ 190.06 | $ 426.25 |
JNJ | 32.53% | $12,878.04 | $16,899.04 |
KO | 2.50% | $ 987.73 | $ 2,024.83 |
NKE | 9.77% | $ 3,865.66 | $ 7,352.19 |
TXN | 50.50% | $19,989.94 | $23,245.03 |
# compute min risk portfolio
ia = create.ia(rets)
ia$cov = cov(rets)
load.packages('quadprog')
weight = min.var.portfolio(ia, create.basic.constraints(n))
min.risk.VaR = compute.VaR(rets, weight = weight, capital = capital, date = last.date)
print(summary.VaR(min.risk.VaR))
Portfolio Risk Report as of | 20-Jan-2015 | ||
---|---|---|---|
VaR estimation at | 95% confidence level | ||
Number of assets: | 7 | ||
Current exposure: | $2,985,822 | ||
Portfolio VaR (undiversified): | $48,371.92 | ||
Portfolio VaR (diversified): | $32,915.71 | ||
Component VaR [individual VaR] | |||
AAPL | 6.77% | $ 2,227.32 | $ 5,649.27 |
DIS | 1.79% | $ 588.23 | $ 982.39 |
IBM | 14.93% | $ 4,914.08 | $ 8,070.68 |
JNJ | 43.53% | $14,329.55 | $17,075.95 |
KO | 25.24% | $ 8,306.86 | $11,403.60 |
NKE | 7.75% | $ 2,549.66 | $ 5,190.02 |
TXN | 0.00% | $ 0.00 | $ 0.00 |
#*****************************************************************
# Helper function to display VaR comparison for two portfolios
#*****************************************************************
compare.VaR = function(base.VaR, test.VaR) {
plot.data = list(
'Original position' = to.percent(base.VaR$weight),
'Marginal VaR' = to.cash(base.VaR$marginal.VaR,5),
'New position' = to.percent(test.VaR$weight),
'Marginal VaR' = to.cash(test.VaR$marginal.VaR,5)
)
plot.data1 = list(
'Portfolio VaR' = to.cash(c(base.VaR$port.VaR, test.VaR$port.VaR)),
' ' = c('', to.percent(test.VaR$port.VaR / base.VaR$port.VaR - 1)),
'Annulized Vol' = to.percent(c(base.VaR$port.vol, test.VaR$port.vol))
)
plot.data1 = sapply(plot.data1,identity)
plot.data1 = col.name2row(plot.data1)
rbind(cbind(base.VaR$ticker, sapply(plot.data,identity)),
cbind(plot.data1[1,], plot.data1[2,],'',plot.data1[3,],'')
)
}
print('Risk-Minimising Position scenario:')
Risk-Minimising Position scenario:
print(compare.VaR(base.VaR, min.risk.VaR))
Original position | Marginal VaR | New position | Marginal VaR | |
---|---|---|---|---|
AAPL | 1.93% | $0.00955 | 6.77% | $0.01102 |
DIS | 3.33% | $0.01128 | 1.79% | $0.01102 |
IBM | 0.79% | $0.00807 | 14.93% | $0.01102 |
JNJ | 43.08% | $0.01001 | 43.53% | $0.01102 |
KO | 4.48% | $0.00738 | 25.24% | $0.01102 |
NKE | 10.97% | $0.01180 | 7.75% | $0.01102 |
TXN | 35.41% | $0.01891 | 0.00% | $0.01110 |
Portfolio VaR | $39,584.48 | $32,915.71 | ||
-16.85% | ||||
Annulized Vol | 12.79% | 10.64% |
(this report was produced on: 2015-01-22)