R语言带约束投资组合优化:如何修正最小方差组合权重为负问题
解决最小方差投资组合权重非负的问题
嘿,我来帮你搞定这个问题!你遇到的核心问题很明确:你的代码只设置了权重和为1的等式约束,但完全没加入权重≥0的约束条件,所以求解器自然会忽略非负限制,算出负权重来。
要修正这个问题,我们需要用二次规划来求解——因为最小方差投资组合本质就是一个带约束的二次优化问题:目标是最小化投资组合方差(即$\frac{1}{2}w'\Sigma w$,$\Sigma$是资产协方差矩阵),约束条件是$\sum w_i=1$且$w_i≥0$。
下面是具体的修正步骤和代码:
步骤1:用quadprog包处理二次规划
quadprog是R里专门用于求解二次规划问题的包,非常适合这个场景。如果还没安装,先执行:
install.packages("quadprog")
步骤2:完整的修正代码
# 加载包 library(quadprog) # 你的原始数据处理部分(简化写法) Dataset <- as.matrix(Dataset) nAss <- ncol(Dataset) # 直接用ncol获取资产数量,比dim更简洁 # 关键:计算资产的协方差矩阵,这是最小方差的核心输入 cov_mat <- cov(Dataset) # 构造二次规划的目标矩阵:quadprog的目标是(1/2)w'Dmat w + dvec'w,所以Dmat设为2*协方差矩阵 Dmat <- 2 * cov_mat # dvec是全0向量,因为我们没有线性目标项 dvec <- rep(0, nAss) # 构造约束矩阵Amat: # 第一列是权重和为1的等式约束(全1向量),后面nAss列是权重≥0的不等式约束(单位矩阵的列) Amat <- cbind(rep(1, nAss), diag(nAss)) # 约束值bvec:第一个值是1(权重和为1),后面全是0(权重≥0) bvec <- c(1, rep(0, nAss)) # 求解二次规划:meq=1表示第一个约束是等式,其余是≥的不等式约束 result <- solve.QP(Dmat = Dmat, dvec = dvec, Amat = Amat, bvec = bvec, meq = 1) # 提取并查看最优权重 optimal_weights <- result$solution # 给权重加上资产名称,更直观 names(optimal_weights) <- colnames(Dataset) print(optimal_weights)
为什么这个代码能解决问题?
- 我们明确把权重≥0的约束加入到了
Amat和bvec中,diag(nAss)生成的单位矩阵对应每个资产权重≥0的限制 meq=1告诉求解器:第一个约束(权重和为1)是等式,剩下的约束都是不等式(≥0)- 最终得到的权重会同时满足权重和为1和所有权重非负两个条件
如果你觉得quadprog的写法有点繁琐,也可以用更封装的PortfolioAnalytics包,它专门做投资组合优化,代码会更简洁,但quadprog是基础实现,能让你更清楚约束的逻辑。
内容的提问来源于stack exchange,提问作者Andrea93




