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 <br...@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@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]] _______________________________________________ R-SIG-Finance@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.