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

为投资组合优化函数的wi添加求和为0的约束求助

你需要让优化过程中生成的wi满足每行和为0的约束(即每个时期的资产权重总和为0),这里有两种可行的方案,分别适配不同的需求:


方案一:直接调整wi满足约束(无需修改优化方法)

这种方法会在计算出原始wi后,自动调整每个时期的权重向量,使其总和为0,不需要约束优化参数x,可以继续使用BFGS方法。

修改后的目标函数pps如下:

pps = function(x, wb, nt, ret, m12, mktcap, btm, rr){
  # 计算原始权重
  wi = wb + nt * (x[1]*m12 + x[2]*mktcap + x[3]*btm)
  # 调整权重,确保每行(每个时期)的权重和为0
  asset_count = ncol(wi)
  row_total = rowSums(wi)
  wi_neutral = wi - row_total / asset_count
  
  # 计算加权收益并返回目标值
  wret = rowSums(wi_neutral * ret, na.rm = TRUE)
  ut = ((1 + wret)^(1 - rr))/(1 - rr)
  u = -mean(ut)
  return(u)
}

你的循环代码不需要做任何修改,优化逻辑还是针对参数x,只是目标函数内部自动处理了wi的约束。


方案二:使用带约束的优化方法(constrOptim)

如果希望严格通过约束参数x来保证wi的和为0(而非事后调整),可以将约束转化为线性约束,使用constrOptim替代optim。

步骤1:推导线性约束

约束条件为每个时期的sum(wi[t, ]) = 0,展开后得到:
sum(wb[t, ]) + nt*(x1*sum(m12[t, ]) + x2*sum(mktcap[t, ]) + x3*sum(btm[t, ])) = 0
整理为线性约束形式:A %*% x = b,其中:

  • A是每行对应c(sum(m12[t, ]), sum(mktcap[t, ]), sum(btm[t, ]))的矩阵
  • b是每个元素为-sum(wb[t, ])/nt的向量

步骤2:修改循环代码

res_save = matrix(NA, 330, 3)
weights = matrix(NA, 330, ncol(ret))

for(i in 1:330){
  # 提取当前窗口的数据
  window_ret = ret[1:(48 + i), ]
  window_m12 = m12[1:(48 + i), ]
  window_mktcap = mktcap[1:(48 + i), ]
  window_btm = btm[1:(48 + i), ]
  window_wb = wb[1:(48 + i), ]
  
  # 构造约束矩阵A和向量b
  A = cbind(rowSums(window_m12), rowSums(window_mktcap), rowSums(window_btm))
  b = -rowSums(window_wb)/nt
  
  # 使用constrOptim进行带约束优化(等式约束需要同时设置upper和lower)
  opt = constrOptim(
    par = c(0, 0, 0),
    f = pps,
    grad = NULL, # 让函数自动计算梯度
    ui = rbind(A, -A),
    ci = c(b, -b),
    wb = window_wb, nt = nt, ret = window_ret, 
    m12 = window_m12, mktcap = window_mktcap, btm = window_btm, rr = rr
  )
  
  res = opt$par
  w = wb[i + 49, ] + nt*(res[1]*m12[i + 49, ] + res[2]*mktcap[i + 49, ] + res[3]*btm[i + 49, ])
  # 验证权重和是否为0(可选)
  # stopifnot(abs(sum(w)) < 1e-6)
  weights[i, ] = w
  res_save[i, ] = res
}

注意事项:

  • 这种方法要求约束是可行的(即存在x满足所有时期的约束),如果约束之间线性无关且数量超过3,会导致无解,此时建议使用方案一。
  • constrOptim的速度会比BFGS慢一些,因为需要处理约束。

两种方案中,方案一更简单且鲁棒,适合大多数场景;方案二更严格,适合需要直接通过参数约束来保证wi性质的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:47:37