Open SamoPP opened 4 years ago
I have found the exact point in the code where PortfolioAnalztics fails for this particular case.
In function max_sr_opt
(https://github.com/braverock/PortfolioAnalytics/blob/master/R/optFUN.R)
# This function uses optimize() to find the target return value that
# results in the maximum sharpe ratio (mean / sd).
# returns the target return value
max_sr_opt <- function(R, constraints, moments, lambda_hhi, conc_groups, solver, control){
# create a copy of the moments that can be modified
tmp_moments <- moments
# Find the maximum return
max_ret <- maxret_opt(R=R, moments=moments, constraints=constraints,
target=NA, solver="glpk", control=control)
max_mean <- as.numeric(-max_ret$out)
# Find the minimum return
tmp_moments$mean <- -1 * moments$mean
min_ret <- maxret_opt(R=R, moments=tmp_moments, constraints=constraints,
target=NA, solver="glpk", control=control)
min_mean <- as.numeric(min_ret$out)
# use optimize() to find the target return value that maximizes sharpe ratio
opt <- try(optimize(f=sharpe_obj_fun, R=R, constraints=constraints,
solver=solver, lambda_hhi=lambda_hhi,
conc_groups=conc_groups, moments=moments, control=control,
lower=min_mean, upper=max_mean,
maximum=TRUE, tol=.Machine$double.eps),
silent=TRUE)
if(inherits(opt, "try-error")){
stop(paste("Objective function failed with message\n", opt))
return(NULL)
}
return(opt$maximum)
}
What actually happens is that for this particular example max_mean
and min_mean
are equal/identical and of course call to optimize()
fails:
Browse[2]> max_mean
[1] 2.286604e-05
Browse[2]> min_mean
[1] 2.286604e-05
I tried with increasing max_mean
and decreasing min_mean
a bit before calling optimize()
but the solution is then heavily unstable and dependent on how much I increase and decrease max_mean
and min_mean
:
if (max_mean == min_mean) {
epsilon <- 0.01
max_mean <- max_mean*(1.0 + epsilon)
min_mean <- min_mean*(1.0 - epsilon)
}
This are the results for different values of epsilon
:
# epsilon <- 0.01
#> extractWeights(maxSROpt)
#NEAR MINT
#NA NA
# epsilon <- 0.001
#> extractWeights(maxSROpt)
#NEAR MINT
#0.4452578 0.5547422
# epsilon <- 0.0001
#> extractWeights(maxSROpt)
#NEAR MINT
#0.8923873 0.1076127
# epsilon <- 0.00001
#> extractWeights(maxSROpt)
#NEAR MINT
#0.98926189 0.01073811
# epsilon <- 0.000001
#> extractWeights(maxSROpt)
#NEAR MINT
#0.998951981 0.001048019
# epsilon <- 0.0000001
#> extractWeights(maxSROpt)
#NEAR MINT
#9.999111e-01 8.890042e-05
Any ideas or better approach to solve this problem or find a workaround?
I have come across an issue in PortfolioAnalytics. It might be that my data (downloaded from Yahoo Finance) simply has issues but I guess this should not lead PortfolioAnalytics to fail. I also doubt this is data issue since just directly using ROI package solves for Max Sharpe portfolio without any issues (see ROI example code below).
Below is reproducible code that shows the problem:
This is the output in R when I run the code above:
My sessionInfo():
I have also posted this as a question on R-SIG-Finance a couple of days ago.
This works with pure ROI implementation without any problems:
Output in R console: