我对投资组合优化不熟悉。对于给定的投资组合权重w,预期收益和方差分别为w'μ= q和w'Σw。我们将投资组合选择问题定义为:为了使方差w'Σ最小化,w'e = 1且w'μ= q,q是预期收益率。禁止卖空。我想要同样加权的投资组合我该怎么做?这段代码是否正确?另一个问题,e是我必须写的那个矢量还是quadprog已经拥有它?你可以帮帮我吗?
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
答案 0 :(得分:1)
刚好注册:
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)