最小化投资组合方差,限制为与基准投资组合足够相似
Minimize portfolio variance, constrained to be sufficiently similar to a benchmark portfolio
我正在执行投资组合优化,我想通过以下内容扩展讨论 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) = 1
和 Ss(min) > 0.7
的约束下最小化方差 (=MMULT(TRANSPOSE(H8:H10),MMULT(H3:J5,H8:H10))
)
正如您所注意到的,棘手的约束是 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
),其中wpf_i
是i
在我们选择的投资组合(决策变量)中的比例,wbench_i
是i
在我们选择的投资组合中的比例基准投资组合(输入数据)。这将 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 填充协方差矩阵(将放置在优化 objective 中)。我们可以这样做:
(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 >= 0.7
,接下来的三行是 -y_i >= -wbench_i
约束,最后三行是 ypf_i-y_i >= 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_1
和y_2
取的最小值来自我们的新投资组合,y_3
取的最小值来自基准投资组合。我们看到由于约束,最优投资组合的方差相对增加了 9.0%。
我正在执行投资组合优化,我想通过以下内容扩展讨论 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) = 1
和 Ss(min) > 0.7
=MMULT(TRANSPOSE(H8:H10),MMULT(H3:J5,H8:H10))
)
正如您所注意到的,棘手的约束是 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
),其中wpf_i
是i
在我们选择的投资组合(决策变量)中的比例,wbench_i
是i
在我们选择的投资组合中的比例基准投资组合(输入数据)。这将 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 填充协方差矩阵(将放置在优化 objective 中)。我们可以这样做:
(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 >= 0.7
,接下来的三行是 -y_i >= -wbench_i
约束,最后三行是 ypf_i-y_i >= 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_1
和y_2
取的最小值来自我们的新投资组合,y_3
取的最小值来自基准投资组合。我们看到由于约束,最优投资组合的方差相对增加了 9.0%。