1

Portfolio.optim {tseries} 的文档说solve.QP {quadprog} 用于生成解决方案,以找到使夏普比率最大化的切线投资组合。这意味着结果应该与任一函数相同。我可能忽略了一些东西,但在这个简单的例子中,我得到了类似但不完全相同的解决方案,用于使用portfolio.optim 和solve.QP 估计最优投资组合权重。结果不应该相同吗?如果是这样,我哪里错了?这是代码:

library(tseries)
library(quadprog)


# 1. Generate solution with solve.QP via: comisef.wikidot.com/tutorial:tangencyportfolio

# create artifical data
set.seed(1)
nO     <- 100     # number of observations
nA     <- 10      # number of assets
mData  <- array(rnorm(nO * nA, mean = 0.001, sd = 0.01), dim = c(nO, nA))
rf     <- 0.0001     # riskfree rate (2.5% pa)
mu     <- apply(mData, 2, mean)    # means
mu2    <- mu - rf                  # excess means

# qp
aMat  <- as.matrix(mu2)
bVec  <- 1
zeros <- array(0, dim = c(nA,1))
solQP <- solve.QP(cov(mData), zeros, aMat, bVec, meq = 1)

# rescale variables to obtain weights
w <- as.matrix(solQP$solution/sum(solQP$solution))

# 2. Generate solution with portfolio.optim (using artificial data from above)
port.1 <-portfolio.optim(mData,riskless=rf)
port.1.w <-port.1$pw
port.1.w <-matrix(port.1.w)

# 3. Compare portfolio weights from the two methodologies:

compare <-cbind(w,port.1$pw)

compare

             [,1]        [,2]
 [1,]  0.337932967 0.181547633
 [2,]  0.073836572 0.055100415
 [3,]  0.160612441 0.095800361
 [4,]  0.164491490 0.102811562
 [5,]  0.005034532 0.003214622
 [6,]  0.147473396 0.088792283
 [7,] -0.122882875 0.000000000
 [8,]  0.127924865 0.067705050
 [9,]  0.026626940 0.012507530
[10,]  0.078949672 0.054834759
4

2 回答 2

3

处理这种情况的唯一方法是浏览源代码。在您的情况下,可以通过tseries:::portfolio.optim.default.

现在,为了找出这两个调用之间的区别,我们可以通过定义一个等效的辅助函数来缩小问题范围:

foo <- function(x, pm = mean(x), covmat = cov(x), riskless = FALSE, rf = 0) 
{
  x <- mData
  pm <- mean(x)
  covmat <- cov(x)
  k <- dim(x)[2]
  Dmat <- covmat
  dvec <- rep.int(0, k)
  a1 <- colMeans(x) - rf
  a2 <- matrix(0, k, k)
  diag(a2) <- 1
  b2 <- rep.int(0, k)
  Amat <- t(rbind(a1, a2))
  b0 <- c(pm - rf, b2)
  solve.QP(Dmat, dvec, Amat, bvec = b0, meq = 1)$sol
}

identical(portfolio.optim(mData, riskless=TRUE, rf=rf)$pw,
          foo(mData, riskless=TRUE, rf=rf))
#[1] TRUE

这样,您可以看到 1)riskless=rf不是预期的方式,riskless=TRUE, rf=rf而是正确的方式;2) Amat 和 bvec 有几个不同之处。

我不是投资组合优化方面的专家,所以我不知道这些额外限制背后的解释是什么,以及它们是否应该首先存在,但至少你可以看到究竟是什么导致了这种差异。

于 2014-08-25T07:36:28.113 回答
1

您的示例中的差异是由于 tseries::portfolio.optim() 中的默认值 'shorts=FALSE' 而发生的。因此,您必须更改参数或在您的 solve.QP 问题中添加非负性限制才能达到相同的结果。

编辑:虽然答案仍然成立,但 tseries::portfolio.optim() 似乎还有一些其他奇怪的默认值。例如,它将最小回报要求设置为 pm = mean(x),导致效率前沿上的随机投资组合,而不是在没有回报要求的情况下返回全局最小方差投资组合。底线:坚持使用您的 quadprog::solve.QP 解决方案。附上我使用的包装函数的示例(我刚开始使用 R,虽然我很确定这会提供数学上正确的结果,但它可能不是最干净的代码):

# --------------------------------------------------------------------------
#' Quadratic Optimization
#' @description Wrapper for quadratic optimization to calculate the general
#'              mean-variance portfolio.
#' @param S           [matrix] Covariance matrix.
#' @param mu          [numeric] Optional. Vector of expected returns.
#' @param wmin        [numeric] Optional. Min weight per asset.
#' @param wmax        [numeric] Optional. Max weight per asset.
#' @param mu_target   [numeric] Optional. Required return, if empty the optimization returns the global minimum variance portfolio
#' @return Returns the mean-variance portfolio or the global minimum variance portfolio
# --------------------------------------------------------------------------

meanvar.pf <- function(S,
                      mu=NULL,
                      wmin=-1000,
                      wmax=1000,
                      mu_target=NULL){
  if (!try(require(quadprog)))
    stop("Execute 'install.packages('quadprog')' and try again")
  if (missing(S))
    stop("Covariance matrix is missing")
  if (!is.null(mu) & dim(S)[1] != length(mu))
    stop("S and mu have non-conformable dimensions")
  N <- ncol(S)
  if (wmin >= 1/N)
    stop("wmin >= 1/N is not feasible")
  if (wmax <= 1/N)
    stop("wmax <= 1/N is not feasible")    
  meq <- 1
  bvec <- c(1, rep(wmin,N), -rep(wmax,N))
  Amat <- cbind(rep(1, N), diag(N), -diag(N))
  if (!is.null(mu_target)) {
    if (is.null(mu))
      stop("Vector of asset returns is missing")
    Amat <- cbind(mu, Amat)
    bvec <- c(mu_target, bvec)
    meq <- 2
  }
  result <- quadprog::solve.QP(Dmat=S, 
                              dvec=rep(0, N), 
                              Amat=Amat, 
                              bvec=bvec, 
                              meq=meq)
  return(result)
}
于 2015-08-18T12:20:35.957 回答