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

基于已知预期收益的R语言Markowitz投资组合优化问题

解决方案:自定义预期收益/协方差的Markowitz投资组合优化(R实现)

核心逻辑

完全可以通过R的二次规划求解器手动实现,不需要依赖那些直接绑定历史收益的工具包——这种方式反而更灵活,能完美适配你自己计算的预期收益、协方差矩阵。Markowitz方差优化的本质是带约束的二次规划问题,直接套公式就能落地。

步骤1:明确优化目标与约束

以最基础的两类场景为例:

场景1:最小方差组合(无目标收益要求)

目标函数:

minimize w^T * Σ * w

约束条件:

  • 权重和为1:sum(w) = 1
  • 权重非负(禁止做空,可选):w_i ≥ 0

场景2:目标收益下的最小方差组合

在上述约束基础上,新增:

  • 组合预期收益达标:sum(w * μ) = target_return

步骤2:用quadprog包实现(推荐)

quadprog是专门解决二次规划问题的R包,完全支持自定义输入的协方差矩阵和预期收益,不需要历史原始数据。以下是具体代码示例:

前置准备

假设你已经有:

  • mu:自定义的资产预期收益向量(长度为n)
  • Sigma:自定义的n×n协方差矩阵

例1:求解最小方差组合

# 安装并加载包
install.packages("quadprog")
library(quadprog)

# 适配quadprog的目标函数格式(要求为(1/2)w^T D w,所以乘2抵消系数)
Dmat <- 2 * Sigma
dvec <- rep(0, length(mu))

# 构造约束矩阵:第一列是权重和为1的等式约束,后续列是非负约束
Amat <- cbind(rep(1, length(mu)), diag(length(mu)))
bvec <- c(1, rep(0, length(mu)))

# 求解:meq=1表示第一个约束是等式,其余为不等式(≥)
result <- solve.QP(Dmat = Dmat, dvec = dvec, Amat = Amat, bvec = bvec, meq = 1)

# 提取最优权重
optimal_weights <- result$solution

例2:求解目标收益下的最小方差组合

target_return <- 0.06  # 自定义目标收益

# 更新约束矩阵:新增预期收益达标等式
Amat <- cbind(rep(1, length(mu)), mu, diag(length(mu)))
bvec <- c(1, target_return, rep(0, length(mu)))

# 求解:meq=2表示前两个约束是等式
result <- solve.QP(Dmat = Dmat, dvec = dvec, Amat = Amat, bvec = bvec, meq = 2)
optimal_weights <- result$solution

步骤3:批量处理多周期

把优化逻辑封装成函数,用循环或purrr批量处理各周期的mu和Sigma:

# 定义通用优化函数
optimize_portfolio <- function(mu, Sigma, target_return = NULL, allow_short = FALSE) {
  Dmat <- 2 * Sigma
  dvec <- rep(0, length(mu))
  
  # 基础约束:权重和为1
  base_constraint <- cbind(rep(1, length(mu)))
  base_bvec <- c(1)
  
  # 添加目标收益约束(如果需要)
  if (!is.null(target_return)) {
    base_constraint <- cbind(base_constraint, mu)
    base_bvec <- c(base_bvec, target_return)
  }
  
  # 添加非负约束(如果禁止做空)
  if (!allow_short) {
    base_constraint <- cbind(base_constraint, diag(length(mu)))
    base_bvec <- c(base_bvec, rep(0, length(mu)))
  }
  
  # 等式约束的数量
  meq <- 1 + ifelse(is.null(target_return), 0, 1)
  
  result <- solve.QP(Dmat = Dmat, dvec = dvec, Amat = base_constraint, bvec = base_bvec, meq = meq)
  return(result$solution)
}

# 模拟多周期数据
periods_data <- list(
  period1 = list(mu = c(0.05, 0.08), Sigma = matrix(c(0.01, 0.002, 0.002, 0.02), nrow=2)),
  period2 = list(mu = c(0.06, 0.07), Sigma = matrix(c(0.012, 0.001, 0.001, 0.018), nrow=2))
)

# 批量求解各周期权重
library(purrr)
all_weights <- map(periods_data, ~optimize_portfolio(.x$mu, .x$Sigma))

步骤4:回测实现

用得到的权重与实际历史收益计算组合收益:

# 模拟实际历史收益矩阵(每行对应一个周期,每列对应资产)
actual_returns <- matrix(c(0.04, 0.09, 0.07, 0.06), nrow=2)

# 计算组合回测收益
portfolio_returns <- map2_dbl(all_weights, split(actual_returns, 1:nrow(actual_returns)), ~sum(.x * .y))

关于手动实现的疑问

不需要从零编写求解逻辑,quadprog这类成熟包已经封装了高效的二次规划求解器,完全能满足你的自定义输入需求,效率远高于Excel。那些直接用历史收益的工具包本质也是类似逻辑,你手动调用底层求解器反而能完全掌控输入,适配自己的计算结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:25:55