Search code examples
roptimizationpluginsportfolior-portfolioanalytics

PortfolioAnalytics error while creating efficient frontier


I'm trying to run portfolio optimization problems, everything runs smoothly, except when I try to create the efficient frontier.

I've tried to mess around with all the function parameters, I've installed all packages and plugins recommended by the documentation. But even when I try to run the code in the efficient frontier demo in the package's GitHub repository I get the same error message. I suspect it is a missing plugin or an error in the recommended packages installation. Can someone at least give me a hint on whats going on?

The code I have is pretty simple, but my main conclusion is that I don't have any problems in it since I get the same error while running the code located in: https://github.com/R-Finance/PortfolioAnalytics/blob/master/demo/demo_efficient_frontier.R

my code:

base_pf <- portfolio.spec(colnames(monthly_returns_with_rf[,-selic_col]))

base_pf <- add.constraint(portfolio = base_pf, type = 'full_investment')

base_pf <- add.constraint(portfolio = base_pf, type = 'long_only')

moments <- set.portfolio.moments(monthly_returns_with_rf[,-selic_col], portfolio = base_pf, method = 'boudt', k = 3)

base_pf <- add.constraint(portfolio = base_pf, type = 'box', min = 0, max = 0.4)

base_pf <- add.objective(portfolio = base_pf, type = 'return', name = 'mean')

base_pf <- add.objective(portfolio = base_pf, type = 'risk', name = 'var')

ef_fr <- create.EfficientFrontier(R=monthly_returns_with_rf[,-selic_col], portfolio=base_pf, type="mean-StdDev", match.col = 'StdDev')

opt_base <- optimize.portfolio(monthly_returns_with_rf[,- selic_col], portfolio = base_pf, optimize_method = 'ROI')
print(opt_base)

th error message I get is:

Error in maxret_opt(R = R, constraints = constraints, moments = moments, : paste0("package:", plugin) %in% search() || requireNamespace(plugin,  .... is not TRUE
Traceback:

1. create.EfficientFrontier(R = monthly_returns_with_rf[, -selic_col], 
 .     portfolio = base_pf, type = "mean-StdDev", match.col = "StdDev")
2. meanvar.efficient.frontier(portfolio = portfolio, R = R, n.portfolios = n.portfolios, 
 .     risk_aversion = risk_aversion, ... = ...)
3. optimize.portfolio(R = R, portfolio = portfolio, optimize_method = "ROI", 
 .     ... = ...)
4. maxret_opt(R = R, constraints = constraints, moments = moments, 
 .     target = target, solver = solver, control = control)
5. stopifnot(paste0("package:", plugin) %in% search() || 
requireNamespace(plugin, 
 .     quietly = TRUE))

Any help would be much appreciated! Thank you!


Solution

  • We can trace the error back to find what caused it. From your error message, the function that causes this error is the maxret_opt() function. This is a function called by optimize.portfolio(), as you can see from the steps, likewise optimize.portfolio() is called by meanvar.efficient.frontier(), itself called by create.EfficientFrontier(), which is from your script.

    Now to the error. Looking at the source code of the maxret_opt() function, I find the following:

    function (R, moments, constraints, target, solver = "glpk", 
      control = NULL) 
    {
      stopifnot("package:ROI" %in% search() || requireNamespace("ROI", 
        quietly = TRUE))
      plugin <- paste0("ROI.plugin.", solver)
      stopifnot(paste0("package:", plugin) %in% search() || requireNamespace(plugin, 
        quietly = TRUE))
    

    The solver argument is passed as "glpk". The object plugin is saved as the a string by concatenating the strings "ROI.plugin." and "glpk" (saved in solver). The search() function returns attached packages, in the form of "package:PerformanceAnalytics". That is why in the stopifnot() call, "package:" is concatenated with the string in plugin, which gives the string "package:ROI.plugin.glpk". This is then checked if this string is among the strings returned by search(), it also tries to attach the package with the || requireNamespace(plugin, quietly = TRUE)). If the string isn't in the attached packages, it uses the string to attach the package. If both of these fail, then the function is stopped.

    Therefore, you need to install the ROI.plugin.glpk package. You should also install ROI.plugin.quadprog. I installed both and the example efficient frontier works for me. This is a long winded answer, but hopely you can learn how to debug errors in the future using the logic above.