【问题标题】:Minimize portfolio variance, constrained to be sufficiently similar to a benchmark portfolio最小化投资组合方差,限制为与基准投资组合足够相似
【发布时间】:2017-12-04 04:55:46
【问题描述】:

我正在执行投资组合优化,我想通过以下内容扩展here 的讨论:

我有一个权重向量w_bench 用作基准。我想优化一个投资组合权重向量w_pf 满足

sum(pmin(w_bench, w_pf)) > 0.7

pmin 这是成对的最小值。这迫使优化的投资组合权重w_pf 与基准权重w_bench 相似,并且右手尺寸(在本例中为0.7)控制它们需要匹配的紧密程度。随着该值变大,我们要求投资组合更加相似。

最初我认为我可以使用fPortfolio 包轻松做到这一点(仍在尝试)。但到目前为止还没有骰子。我也认为用quadprog 解决这个问题会更直观,但我不知道如何将所述功能合并到流程中。

Excel 实施:

协方差矩阵:

0.003015254   -0.000235924  0.000242836
-0.000235924  0.002910845   0.000411308
0.000242836   0.000411308   0.002027183

重量:

    w_pf    w_bench min
V1   0.32    0.40    0.32 
V2   0.31    0.50    0.31 
V3   0.38    0.10    0.10 
Ss   1.00    1.00    0.72 

使用 Ss(w_pf) = 1Ss(min) > 0.7 的约束来最小化方差 (=MMULT(TRANSPOSE(H8:H10),MMULT(H3:J5,H8:H10)))

【问题讨论】:

    标签: r mathematical-optimization quantitative-finance quadratic-programming quadprog


    【解决方案1】:

    正如您所注意到的,棘手的约束是 sum(pmin(w_bench, w_pf)) > 0.7(实际上,严格的不等式是非常困难的,所以我将使用 >= 而不是 >;您当然可以重新用>= 0.7+epsilon 解决一些小epsilon)。为了解决这个问题,我们将为投资组合中的每个元素i 创建一个新变量y_i,我们将添加约束y_i <= wpf_i(又名wpf_i - y_i >= 0)和y_i <= wbench_i(又名-y_i >= -wbench_i),其中@ 987654331@ 是i 在我们选择的投资组合(决策变量)中的比例,wbench_ii 在基准投资组合(输入数据)中的比例。这将y_i 限制为不大于这两个值的最小值。最后,我们将添加约束\sum_i y_i >= 0.7,要求这些最小值之和至少为0.7。

    剩下的就是在quadprog 包中实现它。使用您的问题数据进行设置:

    cov.mat <- rbind(c(0.003015254, -0.000235924, 0.000242836), c(-0.000235924, 0.002910845, 0.000411308), c(0.000242836, 0.000411308, 0.002027183))
    w.bench <- c(.4, .5, .1)
    n <- length(w.bench)
    

    由于我们要添加新变量,我们将在与这些新变量对应的行和列中用 0 填充协方差矩阵(将放置在优化目标中)。我们可以这样做:

    (cov.mat.exp <- cbind(rbind(cov.mat, matrix(0, n, n)), matrix(0, 2*n, n)))
    #              [,1]         [,2]        [,3] [,4] [,5] [,6]
    # [1,]  0.003015254 -0.000235924 0.000242836    0    0    0
    # [2,] -0.000235924  0.002910845 0.000411308    0    0    0
    # [3,]  0.000242836  0.000411308 0.002027183    0    0    0
    # [4,]  0.000000000  0.000000000 0.000000000    0    0    0
    # [5,]  0.000000000  0.000000000 0.000000000    0    0    0
    # [6,]  0.000000000  0.000000000 0.000000000    0    0    0
    

    现在我们要为所有约束创建一个约束矩阵:

    (consts <- rbind(rep(c(1, 0), c(n, n)),
                     rep(c(0, 1), c(n, n)),
                     cbind(matrix(0, n, n), -diag(n)),
                     cbind(diag(n), -diag(n))))
    #      [,1] [,2] [,3] [,4] [,5] [,6]
    # [1,]    1    1    1    0    0    0
    # [2,]    0    0    0    1    1    1
    # [3,]    0    0    0   -1    0    0
    # [4,]    0    0    0    0   -1    0
    # [5,]    0    0    0    0    0   -1
    # [6,]    1    0    0   -1    0    0
    # [7,]    0    1    0    0   -1    0
    # [8,]    0    0    1    0    0   -1
    (rhs <- c(1, 0.7, -w.bench, rep(0, n)))
    # [1]  1.0  0.7 -0.4 -0.5 -0.1  0.0  0.0  0.0
    

    第一行将强制投资组合权重总和为 1,下一行将强制执行 \sum_i y_i &gt;= 0.7,接下来的三个是 -y_i &gt;= -wbench_i 约束,最后三个是 ypf_i-y_i &gt;= 0 约束。

    剩下的就是将它们放入 solve.QP 函数所期望的格式中:

    library(quadprog)
    mod <- solve.QP(cov.mat.exp, rep(0, 2*n), t(consts), rhs, 1)
    # Error in solve.QP(cov.mat.exp, rep(0, 2 * n), t(consts), rhs, 1) : 
    #   matrix D in quadratic function is not positive definite!
    

    哎呀!因为我们用额外的 0 填充了新变量的协方差矩阵,所以它是半正定的,但不是正定的。让我们在主对角线上添加一个微小的正常数,然后再试一次:

    library(quadprog)
    mod <- solve.QP(cov.mat.exp + 1e-8*diag(2*n), rep(0, 2*n), t(consts), rhs, 1)
    (w.pf <- head(mod$solution, n))
    # [1] 0.3153442 0.3055084 0.3791474
    (y <- tail(mod$solution, n))
    # [1] 0.3 0.3 0.1
    (opt.variance <- as.vector(t(w.pf) %*% cov.mat %*% w.pf))
    # [1] 0.0009708365
    

    我们可以看到这不是一个特别有趣的案例,因为我们努力添加的约束不是绑定的。让我们将右手边从 0.7 增加到 0.9 来看看约束的作用:

    (rhs <- c(1, 0.9, -w.bench, rep(0, n)))
    # [1]  1.0  0.9 -0.4 -0.5 -0.1  0.0  0.0  0.0
    mod <- solve.QP(cov.mat.exp + 1e-8*diag(2*n), rep(0, 2*n), t(consts), rhs, 1)
    (w.pf <- head(mod$solution, n))
    # [1] 0.3987388 0.4012612 0.2000000
    (y <- tail(mod$solution, n))
    # [1] 0.3987388 0.4012612 0.1000000
    (opt.variance <- as.vector(t(w.pf) %*% cov.mat %*% w.pf))
    # [1] 0.00105842
    

    在这种情况下,约束是绑定的; y_1y_2 的最小值来自我们的新组合,y_3 的最小值来自基准组合。我们看到,由于约束,最优组合的方差相对增加了 9.0%。

    【讨论】:

    • 干得好,谢谢。我离开了我的机器,但我会尽快彻底了解它。
    • quadprog 文档没有提供有关该函数的详细信息。如果您能推荐资源以了解有关填充 covar 矩阵、设置约束向量和 bvec 以及 meq 的规范的更多信息,我将不胜感激。再次感谢。
    • @AK88 可以从 ?quadprog 中读取,solve.QP(D, d, A, b, 0) 解决 QP min -d'x + 1/2 * x'Dx s.t. A'x &gt;= b,您可以将最后一个参数更改为 k 以使第一个 k 约束相等的不平等。所有其他东西(填充协方差矩阵和设置约束向量)都依赖于基本的 R 矩阵操作。互联网上有许多 R 矩阵教程可能对此有所帮助。
    • 这看起来不错你是否也在 R 之外实现了这个?在 python 中,我正在使用 cvxpy 并试图限制活动共享 >= 阈值并且我正在苦苦挣扎
    • @Markus.london 我相信您也可以在 python 中执行此操作,但最好在单独的问题中询问如何执行此操作的详细信息。
    猜你喜欢
    • 2011-11-16
    • 2021-08-20
    • 2022-11-18
    • 1970-01-01
    • 2021-01-11
    • 2016-10-08
    • 2016-12-08
    • 2020-09-26
    • 2013-04-20
    相关资源
    最近更新 更多