[R-SIG-Finance] Using optimize.portfolio

Roger Bos roger@bo@ @end|ng |rom gm@||@com
Mon Jun 8 02:14:55 CEST 2020


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 using braverock.com>
wrote:

> On Sat, 2020-06-06 at 14:33 +0200, Enrico Schumann wrote:
> > On Fri, 05 Jun 2020, Roger Bos writes:
> >
> > > All,
> > >
> > > I am comparing optimize.portfolio from the PortfolioAnalytics
> > > package to
> > > portfolio.optim from the tseries package.  portfolio.optim seems a
> > > bit
> > > easier to use, but I like the set up of optimize.portfolio.  I have
> > > created
> > > a minimal reprex below that compares the output of both in case
> > > that helps
> > > answer my questions.
> > > Here are my two primary questions:
> > >
> > > 1) What if I wanted to pass a custom covariance matrix to
> > > optimize.portfolio, like from a risk model.  Is that possible?  I
> > > can pass
> > > it to portfolio.optim because covmat is one of the parameters.
> > > 2) What if I wanted to pass forecasted returns to
> > > optimize.portfolio?  How
> > > would that be done.
> > >
> > > If there is anything that can be improved in this example, that
> > > would be
> > > helpful as well.  Thank you in advance for any assistance, Roger.
> > >
> > > ###
> > >
> > > library(PortfolioAnalytics)
> > > library(tidyquant)
> > >
> > > symbols <-
> > > c("MSFT","AAPL","AMZN","NVDA","CSCO","ADBE","AMGN","ORCL","QCOM","G
> > > ILD")
> > >
> > > 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)
> > > sigma <- cov(returns)
> > > reslow <- rep(0, ncol(returns))
> > > reshigh <- rep(1, ncol(returns))
> > > popt <- portfolio.optim(x = returns, covmat = sigma, reslow =
> > > reslow,
> > > reshigh = reshigh)
> > > popt$pw
> > >
> > > 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", )
> > > data.frame(optimize.portfolio = opt$weights, portfolio.optim =
> > > round(popt$pw, 3))
> > >
> >
> > If all else fails, and supposing that 'PortfolioAnalytics' per
> > default computes means and covariances in the standard way, you could
> > create input data (time series) that have exactly the desired
> > covariances and means:
> >
> >
> >
> https://stackoverflow.com/questions/58293991/how-to-use-fportfolio-package-in-r-for-non-time-series-input/58302451#58302451
> >
>
> per default, PortfolioAnalytics uses sample moments as most users would
> expect.
>
> As I already told the OP, the user may pass mu and sigma and m3 and m4
> directly, or may construct custom moment functions to compute the
> moments using any method they choose.
>
> This is outlined in section 2 of the vignette:
>
>
> https://cran.r-project.org/web/packages/PortfolioAnalytics/vignettes/custom_moments_objectives.pdf
>
>
> and, of course, in the manual.
>
>

	[[alternative HTML version deleted]]



More information about the R-SIG-Finance mailing list