The 8 assets and their historical returns are stored in a csv file along with the covariance matrix.
US Bonds 0.08% Intnl Bonds 0.67% US Large Growth 6.41% US Large Value 4.08% US Small Growth 7.43% US small Value 3.70% Intnl Dev Equity 4.80% Intnl Emerg. Equity 6.60%
##R Code:
#Loading the covariance matrix
cov<-read.csv("C:\\Users\\Lenovo\\Desktop\\Term2\\Financial Analytics\\Assignment\\cov.csv",header=TRUE)
str(cov)
covar<-as.matrix(cov[,2:9])
colnames(covar)<-c("UB","IB","ULG","ULV","USG","USV","IDE","IEE")
rownames(covar)<-c("UB","IB","ULG","ULV","USG","USV","IDE","IEE")
#Loading the Means of Assets
meanas<-read.csv("C:\\Users\\Lenovo\\Desktop\\Term2\\Financial Analytics\\Assignment\\means.csv",header=TRUE)
meanas$AssetClass<-c("UB","IB","ULG","ULV","USG","USV","IDE","IEE")
#Define the QP
Dmat <- 2*covar
dvec <- rep(0,8)
Amat <- matrix(c(meanas$m,-meanas$m,rep(1,8),rep(-1,8),diag(length(meanas$m))),8,12)
# compute efficient frontier for eight stocks
varP=vector()
sigmaP=vector()
w1=vector()
w2=vector()
w3=vector()
w4=vector()
w5=vector()
w6=vector()
w7=vector()
w8=vector()
#Expected Returns 20 values
Rvals=seq(min(meanas$m)+0.1^10,max(meanas$m)-0.1^10,length.out=20);
for (i in 1:length(Rvals)) {
R=Rvals[i]
bvec <- c(R,-R,1,-1,0,0,0,0,0,0,0,0)
qpSol=solve.QP(Dmat,dvec,Amat,bvec)
varP[i]=qpSol$value
sigmaP[i]=sqrt(varP[i])
w1[i]=qpSol$solution[1];
w2[i]=qpSol$solution[2];
w3[i]=qpSol$solution[3];
w4[i]=qpSol$solution[4];
w5[i]=qpSol$solution[5];
w6[i]=qpSol$solution[6];
w7[i]=qpSol$solution[7];
w8[i]=qpSol$solution[8];
}
#Portfolio weights
weightsoutput<-data.frame(w1,w2,w3,w4,w5,w6,w7,w8)
#Checking whether summation is equal to one
weightsum<-apply(weightsoutput,1,sum)
#Efficient frontier Plot
Markowitz <- plot(sigmaP,Rvals,type = 'l',lty = 1,lwd=3, xlab = 'Risk',ylab = 'Returns',
main = 'Simple mean variance method',col = 'blue')
plot(Rvals,w1,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = 'Weights of Assets' ,
main = 'Visualization of Asset Weights vs Returns', col = 'red')
lines(Rvals,w2,"l",lty = 1,lwd=3,col = 'black')
lines(Rvals,w3,"l",lty = 1,lwd=3,col='green')
lines(Rvals,w4,"l",lty = 1,lwd=3,col = 'blue')
lines(Rvals,w5,"l",lty = 1,lwd=3,col='grey')
lines(Rvals,w6,"l",lty = 1,lwd=3,col = 'dark green')
lines(Rvals,w7,"l",lty = 1,lwd=3,col='violet')
lines(Rvals,w8,"l",lty = 1,lwd=3,col='yellow')
legend('topleft', c("UB","IB","ULG","ULV","USG","USV","IDE","IEE"), pch = 17,
col = c('red','black','green','blue','grey','dark green','violet','yellow'),
text.col = c('red','black','green','blue','grey','dark green','violet','yellow'), cex = .6)
par(mfrow = c(1,1))
plot(Rvals,w1,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = 'Weights of Assets' ,
main = 'Visualization of Asset Weights vs Returns', col = 'red')
lines(Rvals,w2,"l",lty = 1,lwd=3,col = 'black')
lines(Rvals,w3,"l",lty = 1,lwd=3,col='green')
lines(Rvals,w4,"l",lty = 1,lwd=3,col = 'blue')
lines(Rvals,w5,"l",lty = 1,lwd=3,col='grey')
lines(Rvals,w6,"l",lty = 1,lwd=3,col = 'dark green')
lines(Rvals,w7,"l",lty = 1,lwd=3,col='violet')
lines(Rvals,w8,"l",lty = 1,lwd=3,col='yellow')
legend('topleft', c("UB","IB","ULG","ULV","USG","USV","IDE","IEE"), pch = 17,
col = c('red','black','green','blue','grey','dark green','violet','yellow'), text.col = c('red','black','green','blue','grey','dark green','violet','yellow'), cex = .6)
#Weights of portfolio assets vs expected returns in separate plots
par(mfrow = c(2,4))
plot(Rvals,w1,type = 'l', lty = 1,lwd=3, xlab ='' ,ylab = 'Weight' , main = 'US Bonds', col = 'red')
plot(Rvals,w2,type = 'l', lty = 1,lwd=3,xlab ='' ,ylab = '' , main = "Int'l Bonds", col = 'black')
plot(Rvals,w3,type = 'l', lty = 1, lwd=3,xlab ='' ,ylab = '' , main = "US Large Growth", col = 'green')
plot(Rvals,w4,type = 'l', lty = 1,lwd=3, xlab ='' ,ylab = '' , main = "US Large Value", col = 'blue')
plot(Rvals,w5,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = 'Weight' , main = "US Small Growth", col = 'grey')
plot(Rvals,w6,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = '' , main = "US Small Value", col = 'dark green')
plot(Rvals,w7,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = '' , main = "Int'l Dev Equity", col = 'violet')
plot(Rvals,w8,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = '' , main = "Int'l Emerg Equity", col = 'yellow')
Black-Litterman Model takes the Markowitz Model one step further. It incorporates an investor’s own views in determining asset allocations.
Key Assumptions:
Assume tscalar = 0.25
Implied returns + investors views = expected returns.
We have defined P and Q using the views as below:
P = matrix( c(0,0,0,0,0,0,0,0, -1,0,0,0,0,0,1,1, 0,0,0,-1,0,0,1,0),3,8)
Omega = matrix(c(0.000801,0,0, 0,0.009546,0, 0,0,0.00084),3,3)
With the given formula for Black Litterman’s we were able to get the below value for returns:
US Bonds 0.0718% Intnl Bonds 0.6747% US Large Growth 6.787% US Large Value 4.518% US Small Growth 7.64% US small Value 4.03% Intnl Dev Equity 5.09% Intnl Emerg. Equity 6.84%
Now, let’s visualize the returns versus asset weights
Also, let’s have a look at the weightage of individual assets against their returns
#R code for Black Litterman
library(MASS)
tscalar <- 0.25
C <- covar
var1 <- ginv(tscalar * C)
P <- matrix( c(0,0,0,0,0,0,0,0,
-1,0,0,0,0,0,1,1,
0,0,0,-1,0,0,1,0),3,8)
Omega <- matrix(c(0.000801,0,0,
0,0.009546,0,
0,0,0.00084),3,3)
var2 <- t(P) %*% ginv(Omega) %*% P
Q <- c(0.041,0.016,0.008)
var12 <- ginv(var1+var2)
var3 <- (t(P) %*% ginv(Omega) %*% Q) + (var1 %*% meanas$m)
mhat <- var12 %*% var3
mhat
#Define the QP
Dmat1 <- 2*covar
dvec1 <- rep(0,8)
Amat1 <- matrix(c(mhat,-mhat,rep(1,8),rep(-1,8),diag(length(mhat))),8,12)
# compute efficient frontier for eight stocks - BL
BvarP=vector()
BsigmaP=vector()
Bw1=vector()
Bw2=vector()
Bw3=vector()
Bw4=vector()
Bw5=vector()
Bw6=vector()
Bw7=vector()
Bw8=vector()
#Expected Returns 20 values
BRvals=seq(min(mhat)+0.1^10,max(mhat)-0.1^10,length.out=20);
for (i in 1:length(Rvals)) {
BR=BRvals[i]
bvec1 <- c(BR,-BR,1,-1,0,0,0,0,0,0,0,0)
BqpSol=solve.QP(Dmat1,dvec1,Amat1,bvec1)
BvarP[i]=BqpSol$value
BsigmaP[i]=sqrt(BvarP[i])
Bw1[i]=BqpSol$solution[1];
Bw2[i]=BqpSol$solution[2];
Bw3[i]=BqpSol$solution[3];
Bw4[i]=BqpSol$solution[4];
Bw5[i]=BqpSol$solution[5];
Bw6[i]=BqpSol$solution[6];
Bw7[i]=BqpSol$solution[7];
Bw8[i]=BqpSol$solution[8];
}
#Portfolio weights
Bweightsoutput<-data.frame(Bw1,Bw2,Bw3,Bw4,Bw5,Bw6,Bw7,Bw8)
#Checking whether summation is equal to one
weightsum<-apply(Bweightsoutput,1,sum)
#Efficient frontier Plot - BL
BLplot <- plot(BsigmaP,BRvals,type = 'l',lty = 1,lwd=3, xlab = 'Risk',ylab = 'Returns', main = 'Simple mean variance method',col = 'blue')
#Weights of portfolio assets vs expected returns in one plot - BL
par(mfrow = c(1,1))
plot(BRvals,Bw1,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = 'Weights of Assets' , main = 'Visualization of Asset Weights vs Returns', col = 'red')
lines(BRvals,Bw2,"l",lty = 1,lwd=3,col = 'black')
lines(BRvals,Bw3,"l",lty = 1,lwd=3,col='green')
lines(BRvals,Bw4,"l",lty = 1,lwd=3,col = 'blue')
lines(BRvals,Bw5,"l",lty = 1,lwd=3,col='grey')
lines(BRvals,Bw6,"l",lty = 1,lwd=3,col = 'dark green')
lines(BRvals,Bw7,"l",lty = 1,lwd=3,col='violet')
lines(BRvals,Bw8,"l",lty = 1,lwd=3,col='yellow')
legend('topleft', c("UB","IB","ULG","ULV","USG","USV","IDE","IEE"), pch = 17,
col = c('red','black','green','blue','grey','dark green','violet','yellow'), text.col = c('red','black','green','blue','grey','dark green','violet','yellow'), cex = .6)
#Weights of portfolio assets vs expected returns in separate plots - BL
par(mfrow = c(2,4))
plot(BRvals,Bw1,type = 'l', lty = 1,lwd=3, xlab ='' ,ylab = 'Weight' , main = 'US Bonds', col = 'red')
plot(BRvals,Bw2,type = 'l', lty = 1,lwd=3,xlab ='' ,ylab = '' , main = "Int'l Bonds", col = 'black')
plot(BRvals,Bw3,type = 'l', lty = 1, lwd=3,xlab ='' ,ylab = '' , main = "US Large Growth", col = 'green')
plot(BRvals,Bw4,type = 'l', lty = 1,lwd=3, xlab ='' ,ylab = '' , main = "US Large Value", col = 'blue')
plot(BRvals,Bw5,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = 'Weight' , main = "US Small Growth", col = 'grey')
plot(BRvals,Bw6,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = '' , main = "US Small Value", col = 'dark green')
plot(BRvals,Bw7,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = '' , main = "Int'l Dev Equity", col = 'violet')
plot(BRvals,Bw8,type = 'l', lty = 1,lwd=3, xlab ='Returns' ,ylab = '' , main = "Int'l Emerg Equity", col = 'yellow')
Now let’s plot the efficient frontiers of both the models and try to compare.
it’s obvious from the graph that the returns for the Black Litterman’s model is higher than the the Markowitz model for a given sigma.
Also let’s plot and compare the weightage of the individual assets for Markowitz and the Black Littermans model.
# Two plots comparison
Markowitz <- plot(sigmaP,Rvals,type = 'l',lty = 1,lwd=3, xlab = 'Risk',ylab = 'Returns',
main = 'Simple mean variance method',col = 'blue')
BLplot <- plot(BsigmaP,BRvals,type = 'l',lty = 1,lwd=3, xlab = 'Risk',ylab = 'Returns',
main = 'Simple mean variance method',col = 'blue')
plot(sigmaP,Rvals,type = 'l',lty = 1,lwd=3, xlab = 'Risk',ylab = 'Returns',
main = 'Markowitz Vs Black Littermans',col = 'blue')
lines(BsigmaP,BRvals,"l",lty = 1,lwd=3,col = 'red')
Though the efficiency frontier of Black Litterman’s model seems to look good when compared to the Markowitz model, it is more intuitive representation as the investor has complete control on the confience level of his views. This follows the Bayesian approach stating, given the views are independant to each other and reasonably correct, the black litterman’s model gives the best possible portfolio.
We did not observe major differences in the asset allocation given a view and the market equilibrium weights
However, as per view 1, US small growth should get a premium of 4.10%. Though the excess return is only 33 basis points as per the above table, the same is higher by 8.9%
By comparing the returns against view 2, the US small cap growth is not out performing US developed equity by 1.60%
By comparing view three, US small cap growth has out performed the large cap growth by 12.5%
The New Combined Return Vector leads to intuitive, well-diversified portfolios. The two parameters of the Black-Litterman model that control the relative importance placed on the equilibrium returns vs. the view returns, the scalar ( ??) and the uncertainty in the views (??), are very difficult to specify. The Black-Litterman formula with 100% certainty in the views enables one to determine the implied confidence in a view.
Using this implied confidence framework, a new method for controlling the tilts and the final portfolio weights caused by the views is introduced. The method asserts that the magnitude of the tilts should be controlled by the user-specified confidence level based on an intuitive 0% to 100% confidence level. Overall, the Black-Litterman model overcomes the most-often cited weaknesses of mean-variance optimization (unintuitive, highly concentrated portfolios, input-sensitivity, and estimation error-maximization) helping users to realize the benefits of the Markowitz paradigm. Likewise, the proposed new method for incorporating user-specified confidence levels should increase the intuitiveness and the usability of the Black-Litterman model.