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
答案 0 :(得分: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有几个不同之处。
我不是投资组合优化的专家,所以我不知道这些额外限制背后的解释是什么,以及它们是否应该首先出现在那里,但至少你可以看到究竟是什么导致了这些差异
答案 1 :(得分: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)
}