Skip to content
Prev 14875 / 15274 Next

Using optimize.portfolio

Thank you to everyone for your suggestions, but I am still having trouble.
I see that there are two ways to pass custom moments into optimize
portfolio, a custom function and using momentargs list.  The example code
at the end of this email uses both of those methods, as well as the default
method.  I also compare those to portfolio.optim and parma.

I get quite different results for each method.  I know that they will not
be exactly the same, but surely I am doing something wrong given the
results I am getting.  I would hope that all three optimize portfolio
methods would give me the same results.  Here are the results I am getting:

             opt.portf opt.portf.fun opt.portf.args portfolio.optim parma
MSFT     0.372         0.190          0.448           0.253 0.000
AAPL     0.008         0.094          0.044           0.208 0.357
AMZN     0.000         0.076          0.000           0.055 0.119
NVDA     0.020         0.000          0.000           0.020 0.169
CSCO     0.000         0.004          0.002           0.000 0.000
ADBE     0.004         0.040          0.002           0.033 0.032
AMGN     0.298         0.348          0.382           0.253 0.000
ORCL     0.068         0.072          0.010           0.002 0.000
QCOM    0.072         0.000          0.000           0.000 0.000
GILD       0.158         0.176          0.112           0.177 0.322

opt.portf is optimize.portfolio with internal mu and sigma
opt.portf.fun is optimize.portfolio with mu and sigma provided in momentFUN
opt.portf.args is optimize.portfolio with mu and sigma provided in
momentargs

So if optimize portfolio just uses the column means for mu and cov for
sigma, why am I getting different results than when I use a custom function
or pass in the moments?  Obviously I am doing something wrong since I get
different results when using momentFUN and momentargs.  Thanks in advance
for any help, Roger.

###

library(tidyquant)
symbols <-
c("MSFT","AAPL","AMZN","NVDA","CSCO","ADBE","AMGN","ORCL","QCOM","GILD")

getYahooReturns <- function(symbols, return_column = "Ad") {
  returns <- list()
  for (symbol in symbols) {
    getSymbols(symbol, from = '2000-01-01', adjustOHLC = TRUE, env =
.GlobalEnv, auto.assign = TRUE)
    return <- Return.calculate(Ad(get(symbol)))
    colnames(return) <- gsub("\\.Adjusted", "", colnames(return))
    returns[[symbol]] <- return
  }
  returns <- do.call(cbind, returns)
  return(returns)
}

returns <- getYahooReturns(symbols)
returns <- returns[-1, ]
returns[is.na(returns)] <- 0

# portfolio.optim from tseries package
library(tseries)
LB <- rep(0, ncol(returns))
UB <- rep(1, ncol(returns))
popt <- portfolio.optim(x = returns, covmat = sigma, reslow = LB, reshigh =
UB)

library(parma)
# optimal reward to risk (covariance matrix)
parmspec <- parmaspec(S = cov(returns), risk = "EV", forecast =
colMeans(returns), riskType = "optimal", LB = LB, UB = UB)
parm <- parmasolve(parmspec)

library(PortfolioAnalytics)
simple.moments <- function(R, ...) {
  num_assets = ncol(R)
  out <- list()
  out$mu <- matrix(colMeans(R), ncol = 1)
  out$sigma <- cov(R)
  # out$m3 <- PerformanceAnalytics:::M3.MM(R)
  # out$m4 <- PerformanceAnalytics:::M4.MM(R)
  out$m3 <- matrix(0, nrow = num_assets, ncol = num_assets^2)
  out$m4 <- matrix(0, nrow = num_assets, ncol = num_assets^3)
  out
}

num_assets = ncol(returns)
momentargs <- list()
momentargs$mu <- matrix(colMeans(returns), ncol = 1)
momentargs$sigma <- cov(returns)
momentargs$m3 <- matrix(0, nrow = num_assets, ncol = num_assets^2)
momentargs$m4 <- matrix(0, nrow = num_assets, ncol = num_assets^3)

pspec <- portfolio.spec(assets = symbols)
pspec <- add.constraint(portfolio=pspec, type="box", min = 0, max = 1,
min_sum = 0.99, max_sum = 1.01)
pspec <- add.objective(portfolio=pspec, type="return", name="mean")
pspec <- add.objective(portfolio=pspec, type="risk", name="var")

opt      <- optimize.portfolio(R = returns, portfolio = pspec,
optimize_method = "DEoptim")
opt.fun  <- optimize.portfolio(R = returns, portfolio = pspec,
optimize_method = "DEoptim", momentFUN = "simple.moments")
opt.args <- optimize.portfolio(R = returns, portfolio = pspec,
optimize_method = "DEoptim", momentargs = momentargs)
data.frame(opt.portf = opt$weights,
           opt.portf.fun = opt.fun$weights,
           opt.portf.args = opt.args$weights,
           portfolio.optim = round(popt$pw, 3),
           parma = round(weights(parm), 3))


On Sat, Jun 6, 2020 at 8:38 AM Brian G. Peterson <brian at braverock.com>
wrote: