You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在无卖空约束的最小方差投资组合优化中得到负权重?

无卖空约束下最小方差投资组合求解问题

我需要使用CVXR库求解包含183只资产的最小方差投资组合权重,优化问题如下:

  1. 目标函数:$\min_{w} \frac{1}{2}w^T\sigma w$
  2. 约束条件:
    • $\sum w = 1$
    • $w \geq 0$

其中:

  • $\sigma$是183×183的半正定方差-协方差矩阵,由313条资产历史收益率估计得到
  • $w$为各资产的组合权重

我尝试了以下代码,但验证发现权重出现极小的负值,违反了无卖空约束:

library(readxl)
library(matrixcalc)
Library(CVXR) # 大小写错误

Return <- read_excel ("datasets.xlsx")
Return <- as.data.frame(Return)

sigma <- cov(Return)
is.positive.definite(sigma)
[1] TRUE


#quadratic programming

w <- Variable(183)

objective <- Minimize((1/2) %*% (quad_form(w, sigma))) # 目标函数写法错误

constraints <- list( w >= 0,   sum(w) == 1 )

problem <- Problem(objective, constraints)

soln <- solve(problem)

b <- soln$getValue(w)


#verify

sum(b)
[1] 1

min(b)
[1] -5.781906e-22

问题原因及修正方案

  1. R包加载的大小写错误:R语言对大小写敏感,Library(CVXR)必须改为library(CVXR),否则无法正确加载CVXR库。
  2. 目标函数的语法错误:CVXR中quad_form(w, sigma)已经返回合法的二次型表达式,不能用矩阵乘法运算符%*%来乘以1/2,需改用普通标量乘法*。错误写法会导致求解器解析异常,间接影响约束处理。
  3. 极小负值的数值精度问题:你得到的-5.781906e-22是浮点运算的精度误差,本质上与0无差异。可以通过截断极小负值为0,或给求解器设置更高精度参数来处理。

修正后的代码

library(readxl)
library(matrixcalc)
library(CVXR) # 修正大小写

Return <- read_excel("datasets.xlsx")
Return <- as.data.frame(Return)

sigma <- cov(Return)
is.positive.definite(sigma)

# 二次规划求解
w <- Variable(183)

# 修正目标函数写法
objective <- Minimize(0.5 * quad_form(w, sigma))

constraints <- list(w >= 0, sum(w) == 1)

problem <- Problem(objective, constraints)
# 设置更高求解精度,减少浮点误差
soln <- solve(problem, solver = "ECOS", control = list(abstol = 1e-10, reltol = 1e-10))

b <- soln$getValue(w)

# 处理精度误差:将极小负值设为0
b[b < 0] <- 0
# 重新归一化确保权重和为1
b <- b / sum(b)

# 验证
sum(b)
min(b)

额外说明

  • 对于半正定矩阵的二次规划问题,CVXR默认求解器可正常处理,提高精度参数能进一步减少浮点误差带来的极小负值。
  • 截断极小负值并重新归一化是这类数值问题的常用处理方式,不会对组合方差产生显著影响。

内容的提问来源于stack exchange,提问作者Vito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 11:37:12