[R-SIG-Finance] Using optimize.portfolio

Brian G. Peterson br|@n @end|ng |rom br@verock@com
Mon Jun 8 02:59:08 CEST 2020


Roger,
If no Return cleaning method is specified, the default portfolio
moments function will use pairwise complete observations:

if you pass momentargs, the internal calculations for mu and sigma will
be replaced by momentargs$mu and momentargs$sigma
Alexios has already pointed out the return target, which is not
specified in your objectives for optimize.portfolio.
I also note that you're using DEoptim, which is unecessarily slow (and
may not always converge to the same result) for a simple mean variance
optimization.  You probably want optimize.method='ROI', which will use
the same direct quadratic approach.  DEoptim (or 'random' or 'GEnSA',
or 'pso') make sense for more complex objectives that aren't amenable
to convex solvers.
Regards,
Brian
 
-- 
Brian G. Peterson
ph: +1.773.459.4973
im: bgpbraverock
On Sun, 2020-06-07 at 20:14 -0400, Roger Bos wrote:
> 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
> optimizeportfolio, a custom function and using momentargs list.  The
> example codeat the end of this email uses both of those methods, as
> well as the defaultmethod.  I also compare those to portfolio.optim
> and parma.
> I get quite different results for each method.  I know that they will
> notbe exactly the same, but surely I am doing something wrong given
> theresults I am getting.  I would hope that all three optimize
> portfoliomethods would give me the same results.  Here are the
> results I am getting:
>              opt.portf opt.portf.fun opt.portf.args portfolio.optim
> parmaMSFT     0.372         0.190          0.448           0.253
> 0.000AAPL     0.008         0.094          0.044           0.208
> 0.357AMZN     0.000         0.076          0.000           0.055
> 0.119NVDA     0.020         0.000          0.000           0.020
> 0.169CSCO     0.000         0.004          0.002           0.000
> 0.000ADBE     0.004         0.040          0.002           0.033
> 0.032AMGN     0.298         0.348          0.382           0.253
> 0.000ORCL     0.068         0.072          0.010           0.002
> 0.000QCOM    0.072         0.000          0.000           0.000
> 0.000GILD       0.158         0.176          0.112           0.177
> 0.322
> opt.portf is optimize.portfolio with internal mu and
> sigmaopt.portf.fun is optimize.portfolio with mu and sigma provided
> in momentFUNopt.portf.args is optimize.portfolio with mu and sigma
> provided inmomentargs
> So if optimize portfolio just uses the column means for mu and cov
> forsigma, why am I getting different results than when I use a custom
> functionor pass in the moments?  Obviously I am doing something wrong
> since I getdifferent results when using momentFUN and
> momentargs.  Thanks in advancefor any help, Roger.
> ###
> library(tidyquant)symbols <-
> c("MSFT","AAPL","AMZN","NVDA","CSCO","ADBE","AMGN","ORCL","QCOM","GIL
> D")
> 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 packagelibrary(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
> > > > PortfolioAnalyticspackage toportfolio.optim from the tseries
> > > > package.  portfolio.optim seems abiteasier to use, but I like
> > > > the set up of optimize.portfolio.  I havecreateda minimal
> > > > reprex below that compares the output of both in casethat
> > > > helpsanswer my questions.Here are my two primary questions:
> > > > 1) What if I wanted to pass a custom covariance matrix
> > > > tooptimize.portfolio, like from a risk model.  Is that
> > > > possible?  Ican passit to portfolio.optim because covmat is one
> > > > of the parameters.2) What if I wanted to pass forecasted
> > > > returns tooptimize.portfolio?  Howwould that be done.
> > > > If there is anything that can be improved in this example,
> > > > thatwould behelpful 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
> > > > ","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 packagelibrary(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="retu
> > > > rn",                       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'
> > > perdefault computes means and covariances in the standard way,
> > > you couldcreate input data (time series) that have exactly the
> > > desiredcovariances 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
> > wouldexpect.
> > As I already told the OP, the user may pass mu and sigma and m3 and
> > m4directly, or may construct custom moment functions to compute
> > themoments 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]]
> _______________________________________________R-SIG-Finance using r-
> project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.--
> Also note that this is not the r-help list where general R questions
> should go.
cov(tmpR, use = "pairwise.complete.obs")

	[[alternative HTML version deleted]]



More information about the R-SIG-Finance mailing list