R 中的顺序二次规划以找到等权重风险贡献组合的最佳权重
Sequential Quadratic Programming in R to find optimal weights of an Equally-Weighted Risk Contribution Portfolio
问题介绍
我正在尝试在 R 中写下一段代码,以获得等权重贡献 (ERC) 投资组合的权重。正如你们中的一些人所知,投资组合构建是由 Maillard, Roncalli and Teiletche.
提出的
跳过技术细节,为了找到 ERC 投资组合的最佳权重,需要解决以下顺序二次规划问题:
与:
假设我们正在分析 N 项资产。在上面的公式中,我们有 x 是投资组合权重的 (N x 1) 向量,Σ 是资产 returns 的 (N x N) 方差-协方差矩阵.
到目前为止我做了什么
使用解决SQP问题的函数slsqp of the package nloptr,我想解决上面的最小化问题。这是我的代码。首先,要最小化的objective函数:
ObjFuncERC <- function (x, Sigma) {
sum <- 0
R <- Sigma %*% x
for (i in 1:N) {
for (j in 1:N) {
sum <- sum + (x[i]*R[i] - x[j]*R[j])^2
}
}
}
其次,起点(我们从一个等权重的投资组合开始):
x0 <- matrix(1/N, nrow = N, ncol = 1)
然后,等式约束(权重之和必须为一,即:权重之和减一等于零):
heqERC <- function (x) {
h <- numeric(1)
h[1] <- (t(matrix(1, nrow = N, ncol = 1)) %*% x) - 1
return(h)
}
最后,下限和上限约束(权重不能超过1且不能小于0):
lowerERC <- matrix(0, nrow = N, ncol = 1)
upperERC <- matrix(1, nrow = N, ncol = 1)
所以应该输出最佳权重的函数是:
slsqp(x0 = x0, fn = ObjFuncERC, Sigma = Sigma, lower = lowerERC, upper = upperERC, heq = heqERC)
不幸的是,我不知道如何与您分享我的方差-协方差矩阵(其名称为 Sigma 并且是一个 (29 x 29) 矩阵,因此 N = 29)以便重现我的结果,您仍然可以模拟一个
输出错误
运行 上面的代码会产生以下错误:
Error in nl.grad(x, fn) :
Function 'f' must be a univariate function of 2 variables.
伙计们,我不知道该怎么办。可能我误解了必须如何写下来才能让函数 slsqp
理解要做什么。 有人可以帮助我了解如何解决问题并获得我想要的结果吗?
UPDATE ONE:正如@jogo 在评论中指出的那样,我已经更新了代码,但它仍然会产生错误。上面的代码和错误现已更新。
更新 2:根据@jaySf 的要求,这是允许您重现我的错误的完整代码。
## ERC Portfolio Test
# Preliminary Operations
rm(list=ls())
require(quantmod)
require(nloptr)
# Load Stock Data in R through Yahoo! Finance
stockData <- new.env()
start <- as.Date('2014-12-31')
end <- as.Date('2017-12-31')
tickers <-c('AAPL','AXP','BA','CAT','CSCO','CVX','DIS','GE','GS','HD','IBM','INTC','JNJ','JPM','KO','MCD','MMM','MRK','MSFT','NKE','PFE','PG','TRV','UNH','UTX','V','VZ','WMT','XOM')
getSymbols.yahoo(tickers, env = stockData, from = start, to = end, periodicity = 'monthly')
# Create a matrix containing the price of all assets
prices <- do.call(cbind,eapply(stockData, Op))
prices <- prices[-1, order(colnames(prices))]
colnames(prices) <- tickers
# Compute Returns
returns <- diff(prices)/lag(prices)[-1,]
# Compute variance-covariance matrix
Sigma <- var(returns)
N <- 29
# Set up the minimization problem
ObjFuncERC <- function (x, Sigma) {
sum <- 0
R <- Sigma %*% x
for (i in 1:N) {
for (j in 1:N) {
sum <- sum + (x[i]*R[i] - x[j]*R[j])^2
}
}
}
x0 <- matrix(1/N, nrow = N, ncol = 1)
heqERC <- function (x) {
h <- numeric(1)
h[1] <- t(matrix(1, nrow = N, ncol = 1)) %*% x - 1
}
lowerERC <- matrix(0, nrow = N, ncol = 1)
upperERC <- matrix(1, nrow = N, ncol = 1)
slsqp(x0 = x0, fn = ObjFuncERC, Sigma = Sigma, lower = lowerERC, upper = upperERC, heq = heqERC)
我在您的代码中发现了几个错误。例如,ObjFuncERC
没有 returning 任何值。您应该改用以下内容:
# Set up the minimization problem
ObjFuncERC <- function (x, Sigma) {
sum <- 0
R <- Sigma %*% x
for (i in 1:N) {
for (j in 1:N) {
sum <- sum + (x[i]*R[i] - x[j]*R[j])^2
}
}
sum
}
heqERC
也没有return什么,我也稍微改变了你的功能
heqERC <- function (x) {
sum(x) - 1
}
我进行了这些更改并尝试了 slsqp
而不使用 lower
和 upper
,并且成功了。不过,要考虑的另一件事是将 lowerERC
和 upperERC
设置为矩阵。请改用以下内容:
lowerERC <- rep(0,N)
upperERC <- rep(1,N)
希望对您有所帮助。
问题介绍
我正在尝试在 R 中写下一段代码,以获得等权重贡献 (ERC) 投资组合的权重。正如你们中的一些人所知,投资组合构建是由 Maillard, Roncalli and Teiletche.
提出的跳过技术细节,为了找到 ERC 投资组合的最佳权重,需要解决以下顺序二次规划问题:
与:
假设我们正在分析 N 项资产。在上面的公式中,我们有 x 是投资组合权重的 (N x 1) 向量,Σ 是资产 returns 的 (N x N) 方差-协方差矩阵.
到目前为止我做了什么
使用解决SQP问题的函数slsqp of the package nloptr,我想解决上面的最小化问题。这是我的代码。首先,要最小化的objective函数:
ObjFuncERC <- function (x, Sigma) {
sum <- 0
R <- Sigma %*% x
for (i in 1:N) {
for (j in 1:N) {
sum <- sum + (x[i]*R[i] - x[j]*R[j])^2
}
}
}
其次,起点(我们从一个等权重的投资组合开始):
x0 <- matrix(1/N, nrow = N, ncol = 1)
然后,等式约束(权重之和必须为一,即:权重之和减一等于零):
heqERC <- function (x) {
h <- numeric(1)
h[1] <- (t(matrix(1, nrow = N, ncol = 1)) %*% x) - 1
return(h)
}
最后,下限和上限约束(权重不能超过1且不能小于0):
lowerERC <- matrix(0, nrow = N, ncol = 1)
upperERC <- matrix(1, nrow = N, ncol = 1)
所以应该输出最佳权重的函数是:
slsqp(x0 = x0, fn = ObjFuncERC, Sigma = Sigma, lower = lowerERC, upper = upperERC, heq = heqERC)
不幸的是,我不知道如何与您分享我的方差-协方差矩阵(其名称为 Sigma 并且是一个 (29 x 29) 矩阵,因此 N = 29)以便重现我的结果,您仍然可以模拟一个
输出错误
运行 上面的代码会产生以下错误:
Error in nl.grad(x, fn) :
Function 'f' must be a univariate function of 2 variables.
伙计们,我不知道该怎么办。可能我误解了必须如何写下来才能让函数 slsqp
理解要做什么。 有人可以帮助我了解如何解决问题并获得我想要的结果吗?
UPDATE ONE:正如@jogo 在评论中指出的那样,我已经更新了代码,但它仍然会产生错误。上面的代码和错误现已更新。
更新 2:根据@jaySf 的要求,这是允许您重现我的错误的完整代码。
## ERC Portfolio Test
# Preliminary Operations
rm(list=ls())
require(quantmod)
require(nloptr)
# Load Stock Data in R through Yahoo! Finance
stockData <- new.env()
start <- as.Date('2014-12-31')
end <- as.Date('2017-12-31')
tickers <-c('AAPL','AXP','BA','CAT','CSCO','CVX','DIS','GE','GS','HD','IBM','INTC','JNJ','JPM','KO','MCD','MMM','MRK','MSFT','NKE','PFE','PG','TRV','UNH','UTX','V','VZ','WMT','XOM')
getSymbols.yahoo(tickers, env = stockData, from = start, to = end, periodicity = 'monthly')
# Create a matrix containing the price of all assets
prices <- do.call(cbind,eapply(stockData, Op))
prices <- prices[-1, order(colnames(prices))]
colnames(prices) <- tickers
# Compute Returns
returns <- diff(prices)/lag(prices)[-1,]
# Compute variance-covariance matrix
Sigma <- var(returns)
N <- 29
# Set up the minimization problem
ObjFuncERC <- function (x, Sigma) {
sum <- 0
R <- Sigma %*% x
for (i in 1:N) {
for (j in 1:N) {
sum <- sum + (x[i]*R[i] - x[j]*R[j])^2
}
}
}
x0 <- matrix(1/N, nrow = N, ncol = 1)
heqERC <- function (x) {
h <- numeric(1)
h[1] <- t(matrix(1, nrow = N, ncol = 1)) %*% x - 1
}
lowerERC <- matrix(0, nrow = N, ncol = 1)
upperERC <- matrix(1, nrow = N, ncol = 1)
slsqp(x0 = x0, fn = ObjFuncERC, Sigma = Sigma, lower = lowerERC, upper = upperERC, heq = heqERC)
我在您的代码中发现了几个错误。例如,ObjFuncERC
没有 returning 任何值。您应该改用以下内容:
# Set up the minimization problem
ObjFuncERC <- function (x, Sigma) {
sum <- 0
R <- Sigma %*% x
for (i in 1:N) {
for (j in 1:N) {
sum <- sum + (x[i]*R[i] - x[j]*R[j])^2
}
}
sum
}
heqERC
也没有return什么,我也稍微改变了你的功能
heqERC <- function (x) {
sum(x) - 1
}
我进行了这些更改并尝试了 slsqp
而不使用 lower
和 upper
,并且成功了。不过,要考虑的另一件事是将 lowerERC
和 upperERC
设置为矩阵。请改用以下内容:
lowerERC <- rep(0,N)
upperERC <- rep(1,N)
希望对您有所帮助。