我正在尝试使用solve.QP来求解一个有三个约束的二次程序:
- 所有总和为 1(这工作正常)
- 全部必须大于 0(这也可以)
- 所有都必须小于 0.30(这是行不通的)
一、测试数据:
n <- 6
r <- array(rnorm(n^2, mean=1), c(100,n)) # the 'returns'
colnames(r) <- c("A", "B", "C", "D", "E", "F")
我的功能:
eff.frontier <- function (returns, short="no", max.allocation=NULL, risk.premium.up=.5, risk.increment=.005){
covariance <- cov(returns)
n <- ncol(covariance)
Amat <- matrix (1, nrow=n)
bvec <- 1
meq <- 1
if(short=="no"){
Amat <- cbind(1, diag(n))
bvec <- c(bvec, rep(0, n))
}
if(!is.null(max.allocation)){
if(max.allocation > 1 | max.allocation <0){
stop("max.allocation must be greater than 0 and less than 1")
}
Amat <- cbind(Amat, -1*diag(n))
# This seems to be the issue area....
bvec <- c(bvec, rep(-max.allocation, n))
print(bvec)
}
loops <- risk.premium.up / risk.increment + 1
loop <- 1
#Initialize a matrix to contain allocation and statistics
eff <- matrix(nrow=loops, ncol=n+3)
# Now I need to give the matrix column names
colnames(eff) <- c(colnames(returns), "Std.Dev", "Exp.Return", "sharpe")
# Loop through the quadratic program solver
for (i in seq(from=0, to=risk.premium.up, by=risk.increment)){
dvec <- colMeans(returns) * i
sol <- solve.QP(covariance, dvec=dvec, Amat=Amat, bvec=bvec, meq=meq)
eff[loop,"Std.Dev"] <- sqrt(sum(sol$solution *colSums((covariance * sol$solution))))
eff[loop,"Exp.Return"] <- as.numeric(sol$solution %*% colMeans(returns))
eff[loop,"sharpe"] <- eff[loop,"Exp.Return"] / eff[loop,"Std.Dev"]
eff[loop,1:n] <- sol$solution
loop <- loop+1
}
return(as.data.frame(eff))
}
当我不尝试设置分配最大值时,这可以正常工作。但无论我尝试将什么设置为 max.allocation,它总是会失败。
我是否错误地设置了 Amat 或 bvec?
这是错误:
> eff <- eff.frontier(returns=r, short="yes", risk.premium.up=.5, risk.increment=.001, max.allocation=.15)
Error in solve.QP(covariance, dvec = dvec, Amat = Amat, bvec = bvec, meq = meq) :
constraints are inconsistent, no solution!
这是阿马特:
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 -1 0 0 0 0 0
[2,] 1 0 -1 0 0 0 0
[3,] 1 0 0 -1 0 0 0
[4,] 1 0 0 0 -1 0 0
[5,] 1 0 0 0 0 -1 0
[6,] 1 0 0 0 0 0 -1
这是 bvec:
[1] 1.00 -0.15 -0.15 -0.15 -0.15 -0.15 -0.15
这些怎么不一致??
谢谢,
安德鲁