I tried to backtest different portfolio optimization methods with the “PortfolioAnalytics” package in R. First, I ran the “standard” optimization method, and then optimizing with two different robust estimates for the variance-covariance matrix of asset returns, using the “MASS” package.
Lastly, I also wanted to use optimize.portfolio.rebalancing with “boudt”-estimates for the asset return moments. This returns two warning messages, and a flawed portfolio output:
1: In Return.portfolio(ret, weights = extractWeights(opt_Boudt)) :
number of assets in beginning_weights is less than number of columns in returns, so subsetting returns.
2: In Return.portfolio.geometric(R = R, weights = weights, wealth.index = wealth.index, :
The weights for one or more periods do not sum up to 1: assuming a return of 0 for the residual weights
Here is my reproducible code:
library(xts)
library(PortfolioAnalytics)
library(ROI)
library(MASS)
data("edhec")
ret = edhec[,1:6]
port <- portfolio.spec(assets = colnames(ret))
port <- add.constraint(port, "long_only")
port <- add.constraint(port, "full_investment")
port <- add.objective(port, type = "Risk", name = "StdDev")
port <- add.objective(port, type = "return", name = "mean")
#Standard Optimization
opt_norm <- optimize.portfolio.rebalancing(R = ret, portfolio = port, optimize_method = "ROI", rebalance_on = "months", training_period = 60, rolling_window = NULL)
summary(opt_norm)
rr_norm <- Return.portfolio(ret, weights = extractWeights(opt_norm))
charts.PerformanceSummary(rr_norm)
#Robust MCD-VarCov Optimization
custom_fun <- function(R, portfolio, rob_method = "mcd"){
out <- list()
out$sigma <- cov.rob(R, method = rob_method)
return(out)
}
opt_MCD <- optimize.portfolio.rebalancing(R = ret, portfolio = port, optimize_method = "ROI", momentFUN = custom_fun, rob_method = "mcd", rebalance_on = "months", training_period = 60, rolling_window = NULL)
summary(opt_MCD)
rr_MCD <- Return.portfolio(ret, weights = extractWeights(opt_MCD))
charts.PerformanceSummary(rr_MCD)
#Robust MVE-VarCov Optimization
opt_MVE <- optimize.portfolio.rebalancing(R = ret, portfolio = port, optimize_method = "ROI", momentFUN = custom_fun, rob_method = "mve", rebalance_on = "months", training_period = 60, rolling_window = NULL)
summary(opt_MVE)
rr_MVE <- Return.portfolio(ret, weights = extractWeights(opt_MVE))
charts.PerformanceSummary(rr_MVE)
#Boudt Optimization
boudt_moments <- set.portfolio.moments(R = ret, portfolio = port, method = "boudt", k = 1)
opt_Boudt <- optimize.portfolio.rebalancing(R = ret, portfolio = port, optimize_method = "ROI", momentFUN = boudt_moments, rebalance_on = "months", training_period = 60, rolling_window = NULL)
rr_Boudt <- Return.portfolio(ret, weights = extractWeights(opt_Boudt))
charts.PerformanceSummary(rr_Boudt)
I now have two separate questions:
- How is it possible, that the first three optimization backtests (1. Standard, 2. MCD-VarCov, 3. MVE-VarCov) return exactly the same results, which can be seen when comparing the performance plots e.g.?
- What am I doing wrong when trying to use “boudt”-estimates for the asset return moments?
As this is my first time asking a question here, I would also be happy to receive comments on how to improve in regard to asking questions on stackoverflow.
Thank you all in advance!