使用 Rglpk_solve_LP 与 LSopt 优化 CVaR 投资组合会产生不同的结果。从绝对值来看,Rglpk_solve_LP 的 CVaR 比 LSopt 的 CVaR 更大(即更负)。我相当确定这归结为对投资组合产生的平均回报的不同处理,因为如果我将所有资产的预期回报输入为零,差异就会消失。
如何更改 Rglpk_solve_LP 方法以生成考虑投资组合平均回报的 CVaR?
library(neighbours)
library(NMOF)
library(Rglpk)
# Return / vol
ret <- c(0.039, 0.036, 0.092, 0.139, 0.094)
# ret <- rep(rep(0,5)
vol <- c(0.125, 0.074, 0.101, 0.204, 0.167)
ns <- 1000
na <- length(ret)
R <- randomReturns(na, ns, mean=ret, sd = vol)
b <- 0.95
## Optimisation with Rglpk_solve_LP
f.obj <- c(alpha = 1, x = rep(0, na), u = 1/rep((1 - b)*ns, ns))
C <- cbind(1, R, diag(nrow(R)))
C <- rbind(c(alpha = 0, x = rep(1, na), u = rep(0, nrow(R))), C)
const.dir <- c("==", rep(">=", nrow(C) - 1))
const.rhs <- c(1, rep(0, nrow(C) - 1))
sol.lp <- Rglpk_solve_LP(f.obj,
C,
const.dir,
rhs = const.rhs,
control = list(verbose = TRUE, presolve = TRUE))
lp.w <- sol.lp$solution[2:(1+na)]
## Optimisation with LSopt
CVaR <- function(w, R, b) {
Rw <- R %*% w
mean(Rw[Rw >= quantile(Rw, b)])
}
nb <- neighbourfun(0, 1, type = "numeric", stepsize = 0.05)
sol.ls <- LSopt(CVaR,
list(x0 = rep(1/na, na),
neighbour = nb,
nI = 1000),
R = R, b = b)
ls.w <- sol.ls$xbest
# Compare results
CVaR(lp.w, R, b)
CVaR(ls.w, R, b)
代码看起来很像最小化条件风险价值 (CVaR)。
问题/混乱来自于处理损失或退货。尝试这个目标函数,它与返回一起使用,用于本地搜索:
CVaR <- function(w, R, b) {
Rw <- R %*% w
-mean(Rw[Rw <= quantile(Rw, 1 - b)])
}
NMOF
包已在函数minCVaR
中实现了CVaR。因此,在使用更新后的目标函数 LSopt
运行代码后,所有三个表达式应该给出大致相同的结果:
CVaR(lp.w, R, b)
CVaR(ls.w, R, b)
CVaR(NMOF::minCVaR(R, q = 1 - b), R, b)
NMOF
。)