portfolio optimization in R

1.1k views Asked by At

I am unfamiliar to portfolio optimization. For a given portfolio weight w, expected return and variance are respectively, w'μ=q and w' Σ w. We define the portfolio selection problem as: to minimize the variance w' Σ w subject to w' e=1 and w' μ=q, q is the expected rate of return. And short selling is prohibited. I want equally weighted portfolio. How can I do it? This code is correct for it? The other problem, e is the vector of ones do I have to write it or does quadprog already have it? Could you help me?

Dmat <- cov(x)   #covariance matrix
dvec <- colMeans(x)
if(short=="no"){
Amat <- cbind(rep(1,20), diag(20))    # the weights sum up to 1
  bvec <- c(1, rep(0, 20))   # No short-selling
}
portfolio.out <-solve.QP(Dmat, dvec, Amat, bvec, meq=1, factorized=FALSE)
portfolio.out$solution       #portfolio weights
sum(portfolio.out$solution)  #check whether sum up to 1
portfolio.out$value          #portfolio variance
eff.frontier <- function (dvec, Dmat, alpha.min=0, alpha.max=1, nport=10, shorts=FALSE)
eff.frontier$weights
1

There are 1 answers

0
Robert On

Well just to register:

library(MASS)
require(quadprog)

#function to compute the EF
eff.frontier <- function (eret,ermvp,dvec, Dmat, nport=10, shorts=FALSE){
  range.r <- seq(from = min(eret), to = max(eret)*ifelse(shorts,1.6,1), length.out = nport) 
  range.r <- sort(c(ermvp,range.r))
  uAmat=cbind(eret,Amat); # targetRet=range.r[1]
  weigths <- t(sapply(range.r, function(targetRet) { 
    ubvec=c(targetRet,bvec)
    round(solve.QP(Dmat, dvec, uAmat, ubvec, meq=1)$solution,6)
  }))
  colnames(weigths)=colnames(Dmat)
  f.risk=sapply(1:length(range.r),function(ws)(weigths[ws,]%*%Dmat%*%weigths[ws,])^.5)
  f.rets= weigths%*%eret
  list(EF=data.frame(f.risk,f.rets),weigths=weigths)
}

# simulate returns
periods=300
na = 4 #number of assets 

set.seed(1234)
Sigma <- matrix(runif(na*na,3,5),na,na) # to add some correlation
diag(Sigma) <- runif(na,10,20)
Sigma <- Sigma/100
x=mvrnorm(n = periods, seq(0.015, .018, length.out=na), Sigma) #simulate returns
colnames(x) <- sapply(1:na,function(z)
  paste(sample(c( LETTERS,0:9),4, replace=TRUE),collapse="")) #random names

#estimate parameters
eret <- colMeans(x) #Expected returns
Dmat <- cov(x)   #covariance matrix
na <- ncol(Dmat) #number of assets
dvec <- rep(0,na)
shorts=FALSE # short sales not considered
if(!shorts) {
  Amat <-  diag(na) ; bvec <- rep(0, na)   # No short-selling
  Amat=cbind(Amat,rep(1,na),rep(-1,na)) #relax full investment
  bvec=c(bvec,.9995,-1.02) # weights sum up approx 1
} else {cat("Short sales not considered yet!!!")}

#lets find the minimum variance portfolio
portfolio.out <-solve.QP(Dmat, dvec, Amat, bvec, meq=1)
(wgs=portfolio.out$solution)  #portfolio weights
wgs=wgs/sum(wgs) ;sum(wgs) #check whether sum up to 1
portfolio.out$value*2        #minimum variance portfolio sol
wgs%*%Dmat%*%wgs
(wgs%*%Dmat%*%wgs)^.5 # risk = st dev
(ermvp=wgs%*%eret) # min var expected return

# find the EF

efffront=eff.frontier(eret, ermvp, dvec, Dmat,nport=80)
efffront$weigths
efffront$EF #expected risk and return
mvp=which.min(efffront$EF[,1])
cbind(efffront$EF,efffront$weigths)[mvp,] #min risk

#plot the EF
lims=apply(rbind(efffront$EF,cbind(f.risk=diag(Dmat)^.5,f.rets=eret)),2,
           function(z) range(z, na.rm =TRUE)*c(0.98,1.02))
plot(efffront$EF, type ="p", col="darkgreen",
     ylim = lims[,2], xlim = lims[,1], xlab=expression(sigma),
     ylab = "E[r]", main = "Long only EF with solve.QP")
lines(efffront$EF[mvp:length(efffront$EF[,1]),],col="blue",lwd=2)
points(diag(Dmat)^.5,eret,pch=16,col=1:ncol(Dmat))
text(diag(Dmat)^.5,eret,colnames(x),col=1:ncol(Dmat),pos =4,cex=.6)

enter image description here