【问题标题】:Sequential Quadratic Programming in R to find optimal weights of an Equally-Weighted Risk Contribution PortfolioR中的顺序二次规划以找到等权风险贡献组合的最佳权重
【发布时间】:2018-08-27 06:23:50
【问题描述】:

问题介绍

我正在尝试在 R 中编写代码,以便获得等权贡献 (ERC) 投资组合的权重。你们有些人可能知道,投资组合的构建是由Maillard, Roncalli and Teiletche 提出的。

跳过技术细节,为了找到 ERC 投资组合的最佳权重,需要解决以下顺序二次规划问题:

与:

假设我们正在分析 N 个资产。在上述公式中,我们有 x 是一个 (N x 1) 投资组合权重向量,而 Σ 是 (N x N) 个资产收益方差-协方差矩阵。

到目前为止我做了什么

使用解决SQP问题的包nloptr的函数slsqp,我想解决上述最小化问题。这是我的代码。首先,要最小化的目标函数:

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 理解该做什么。 有人可以帮助我了解如何解决问题并获得我想要的结果吗?


更新一:正如@jogo 在 cmets 中指出的那样,我已经更新了代码,但它仍然会产生错误。上面的代码和错误现已更新。


更新 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)

【问题讨论】:

  • 根据文档rdocumentation.org/packages/nloptr/versions/1.0.4/topics/slsqp fn= 应该是一个函数 - 而不是对函数的调用。所以最终应该是:slsqp(x0 = x0, fn = ObjFuncERC, Sigma = Sigma, ...)
  • @jogo 好点!我已经更新了代码,但现在它返回了 'f' must be a univariate function of 2 variables。在这一点上,我开始认为 slsqp 可能不是解决我的问题的正确功能,但我不知道应该使用什么。上面确实是一个顺序二次规划问题……
  • 您的代码没有重现该问题。请在新的 R 会话中检查这一点并相应地添加其他信息(包、变量..)。谢谢。
  • 如果Sigma 是常量,您可以定义一个函数来构造您的目标函数:defObj &lt;- function(Sigma) function(x) ObjFuncERC(x, Sigma); myObj &lt;- defOBJ(Sigma); slsqp(x0 = x0, fn = myOBJ, ...)
  • 您的目标函数似乎与function (x, Sigma) { R &lt;- Sigma %*% x; xR &lt;- x*R; sum(outer(FUN='-', xR, xR)^2) }等价

标签: r finance portfolio quantitative-finance


【解决方案1】:

我在您的代码中发现了几个错误。例如,ObjFuncERC 没有返回任何值。您应该改用以下内容:

# 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 也没有返回任何东西,我也稍微改变了你的功能

heqERC <- function (x) {
    sum(x) - 1
}

我进行了这些更改并尝试了 slsqp 没有 lowerupper 并且它起作用了。不过,要考虑的另一件事是您将lowerERCupperERC 设置为矩阵。请改用以下内容:

lowerERC <- rep(0,N)
upperERC <- rep(1,N) 

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2020-05-20
    • 2011-12-02
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2010-09-22
    相关资源
    最近更新 更多