【问题标题】:using quadprog for portfolio optimization使用 quadprog 进行投资组合优化
【发布时间】:2020-10-15 23:41:07
【问题描述】:

我有我的输入参数 mu(平均向量 μ)、Q(协方差矩阵 Q)和 tau(风险容忍度 τ),我需要返回使以下效用函数 U 最大化的向量 h(资产权重) :

U(h)= −1/2h^T*Q*h + τ*h^T*μ

受约束:

0 ≤ h ≤ 0.1 for all h
and sum of all h is equal to 1: h^T*e = 1

TAU 包含从 0 到 0.5 的数字,步长为 0.001。我如何为这个问题定义参数:Dmat、dvec、Amat 和 bvec?我知道财务概念,但不知道如何正确编程。

谢谢

这不起作用,因为我仍然有表示卖空的负权重:(

frontieropti <- c(NULL)
i <- 1
for (i in 1:nrow(TAU)){
  solQP <- solve.QP(Dmat,TAU[i]*mu, Amat, bvec, meq = 1, factorized = F)
  sol <- c(i,solQP$value)
  frontieropti <- rbind(frontieropti,sol)
  i <- i +1
}
solQP <- solve.QP(Dmat, TAU[1]*mu, Amat, bvec, meq = 1, factorized = F)
solQP

【问题讨论】:

  • 这些幻灯片enricoschumann.net/files/slides_rimini_2016_qp.pdf 展示了如何使用包quadprog 进行均值方差优化。参考代码在enricoschumann.net/files/mv.R
  • 我很欣赏这些材料,但我已经有了幻灯片和类似的代码。我只是在寻找一些代码来解决我的问题,以便我可以继续处理我需要完成的其他部分。就像我的变量的非常明确的定义一样。等于或小于 10% 是让我绊倒的原因,以及如何在 Amat 中正确定义它。
  • 你是故意跳过所有i吗?
  • @Jan 你能解释一下吗? i 正在查看 TAU,它要么是一个从零到 0.5 的数字数组,增量为 0.001,或者,正如我所写的,具有相同数字的矩阵的不同行。我只是在TAU 矩阵中逐行进行,但我是否无意中跳过了所有事件???
  • for 循环负责增量本身。声明 i &lt;- i+1 是额外的,不需要。但是,我只是尝试了一下,R 完全忽略了额外的i+1statement。所以, 它没有任何害处, 我的怀疑是错误的。所以,你说得对。

标签: r optimization finance portfolio quadratic


【解决方案1】:

设置Amat:

na <- 5  ## number of assets

我只使用 5 个资产和 40% 的最大权重,以便我可以显示结果矩阵:

wmin <- 0
wmax <- 0.4
A <- rbind(1,-diag(na), diag(na))
bvec <- c(1, -rep(wmax, na), rep(wmin, na))
cbind(A, bvec)
##                      bvec
##  [1,]  1  1  1  1  1  1.0
##  [2,] -1  0  0  0  0 -0.4
##  [3,]  0 -1  0  0  0 -0.4
##  [4,]  0  0 -1  0  0 -0.4
##  [5,]  0  0  0 -1  0 -0.4
##  [6,]  0  0  0  0 -1 -0.4
##  [7,]  1  0  0  0  0  0.0
##  [8,]  0  1  0  0  0  0.0
##  [9,]  0  0  1  0  0  0.0
## [10,]  0  0  0  1  0  0.0
## [11,]  0  0  0  0  1  0.0

注意Amat的第一行是预算约束,所以你需要将参数meq设置为1。另外,solve.QP想要Amat的转置,即t(Amat)


所以这是一个完整的例子:

library("quadprog")
library("NMOF")

我首先为 30 个资产创建一些随机数据。

na <- 30
R <- randomReturns(na = na, ns = 120, rho = 0.5, sd = 0.03)
mu <- colMeans(R)
V <- cov(R)


wmin <- 0
wmax <- 0.1
A <- rbind(1,-diag(na), diag(na))
b <- c(1, -rep(wmax, na), rep(wmin, na))

TAU <- seq(0, 0.5, by = 0.01) ## choose an appropriate stepsize

在循环之前初始化数据结构是个好习惯, 而不是“增长”它们。 (尽管在这个例子中它并不重要。)

results <- numeric(length(TAU))
weights <- array(NA, dim = c(na, length(TAU)))
for (i in seq_along(TAU)) {
    solQP <- solve.QP(Dmat = V,
                      dvec = TAU[i]*mu,
                      Amat = t(A),
                      bvec = b, meq = 1)

    ## an equivalent computation    
    ## NMOF::mvPortfolio(mu, V, wmax = 0.1, lambda = c(TAU[i], 0.5))

    results[i] <- solQP$value
    weights[, i] <- solQP$solution
}

请注意,由于舍入误差,某些结果可能为负数。 因此,将结果四舍五入到小数点后 8 位。

weights <- round(weights, 8)
barplot(weights)

【讨论】:

  • 感谢您的回答,我正在关注您的想法,但有几个跟进。我的 dvec 会是什么,因为我在二次函数 τ*h^T*μ 的第二项中包含了风险容忍度 tau。我为我的案例更改了您的代码(我有 30 个资产,最多 10%,没有卖空)。此外,如果 A 在您的代码中是 Amat,您是说 solve.QP 只会将 t(A) 作为输入?感谢您的帮助,这是一个如此大的矩阵并没有帮助。我很感激你
  • 我在上面的原始问题中包含了我的解决方案循环,但它仍然给我表示卖空的负权重。
  • 我已添加到我的答案中。
  • 这太棒了,我按照你的逻辑,似乎奏效了。然而,快速跟进。您是否只是在第一个回复中包含 cbind(A, b) 以在一个输出中显示 A 和 b?我的印象是 Amat 是定义我们希望最小化二次函数的约束条件的矩阵。那么为什么 bvec 不是 Amat 的一部分呢?我试图区分为什么重量约束也不是 Amat 的一部分?
  • 另外,有没有办法区分最优投资组合的预期收益和收益的标准差。根据您的逻辑,results 存储循环每次迭代的每个解决方案。那么这个结果矩阵的最大值是否只是具有最佳可能回报的投资组合以及相应的权重?我正在尝试存储每个投资组合收益和标准差,然后绘制有效边界。我对这些优化很陌生,但我非常接近理解。非常感谢
猜你喜欢
  • 2018-03-06
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
  • 2017-12-25
相关资源
最近更新 更多