[Returnanalytics-commits] r3213 - pkg/PortfolioAnalytics/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Mon Oct 7 20:21:03 CEST 2013
Author: rossbennett34
Date: 2013-10-07 20:21:02 +0200 (Mon, 07 Oct 2013)
New Revision: 3213
Modified:
pkg/PortfolioAnalytics/R/optFUN.R
pkg/PortfolioAnalytics/R/optimize.portfolio.R
Log:
Adding functionality for max Sharpe Ratio using ROI
Modified: pkg/PortfolioAnalytics/R/optFUN.R
===================================================================
--- pkg/PortfolioAnalytics/R/optFUN.R 2013-10-07 14:22:25 UTC (rev 3212)
+++ pkg/PortfolioAnalytics/R/optFUN.R 2013-10-07 18:21:02 UTC (rev 3213)
@@ -790,8 +790,7 @@
mid_mean <- as.numeric(t(mid_weights) %*% fmean)
mid_etl <- as.numeric(mid$out)
mid_starr <- mid_mean / mid_etl
- }
- if(mid_starr > lb_starr){
+ } else if(mid_starr > lb_starr){
# if mid_starr > lb_starr then mid_starr becomes the new lower bound
lb_mean <- mid_mean
lb_starr <- mid_starr
@@ -810,3 +809,72 @@
}
return(new_ret)
}
+
+max_sr_opt <- function(R, constraints, moments, lambda, target, lambda_hhi, conc_groups, tol=.Machine$double.eps^0.5, maxit=50){
+ # This function returns the target mean return that maximizes mean / sd (i.e. sharpe ratio)
+
+ # get the forecast mean from moments
+ fmean <- matrix(moments$mean, ncol=1)
+
+ # Find the maximum return
+ max_ret <- PortfolioAnalytics:::maxret_opt(R=R, moments=moments, constraints=constraints, target=NA)
+ max_mean <- as.numeric(-max_ret$out)
+
+ # Calculate the sr at the maximum mean return portfolio
+ ub_weights <- matrix(max_ret$weights, ncol=1)
+ ub_mean <- max_mean
+ ub_sd <- as.numeric(sqrt(t(ub_weights) %*% moments$var %*% ub_weights))
+ # sr at the upper bound
+ ub_sr <- ub_mean / ub_sd
+
+ # Calculate the sr at the miminum var portfolio
+ lb_sr <- PortfolioAnalytics:::gmv_opt(R=R, constraints=constraints, moments=moments, lambda=1e6, target=NA, lambda_hhi=lambda_hhi, conc_groups=conc_groups)
+ lb_weights <- matrix(lb_sr$weights)
+ lb_mean <- as.numeric(t(lb_weights) %*% fmean)
+ lb_sd <- as.numeric(sqrt(t(lb_weights) %*% moments$var %*% lb_weights))
+ # sr at the lower bound
+ lb_sr <- lb_mean / lb_sd
+
+ # want to find the return that maximizes mean / sd
+ i <- 1
+ while((abs(ub_sr - lb_sr) > tol) & (i < maxit)){
+ # bisection method to find the maximum mean / sd
+
+ # Find the starr at the mean return midpoint
+ new_ret <- (lb_mean + ub_mean) / 2
+ mid <- PortfolioAnalytics:::gmv_opt(R=R, constraints=constraints, moments=moments, lambda=1e6, target=new_ret, lambda_hhi=lambda_hhi, conc_groups=conc_groups)
+ mid_weights <- matrix(mid$weights, ncol=1)
+ mid_mean <- as.numeric(t(mid_weights) %*% fmean)
+ mid_sd <- as.numeric(sqrt(t(mid_weights) %*% moments$var %*% mid_weights))
+ mid_sr <- mid_mean / mid_sd
+ # tmp_sr <- mid_sr
+
+ # print(i)
+ # print(mid_sr)
+ # print("**********")
+
+ if(mid_sr > ub_sr){
+ # if mid_sr > ub_sr then mid_sr becomes the new upper bound
+ ub_mean <- mid_mean
+ ub_sr <- mid_sr
+ new_ret <- (lb_mean + ub_mean) / 2
+ mid <- PortfolioAnalytics:::gmv_opt(R=R, constraints=constraints, moments=moments, lambda=1e6, target=new_ret, lambda_hhi=lambda_hhi, conc_groups=conc_groups)
+ mid_weights <- matrix(mid$weights, ncol=1)
+ mid_mean <- as.numeric(t(mid_weights) %*% fmean)
+ mid_sd <- as.numeric(sqrt(t(mid_weights) %*% moments$var %*% mid_weights))
+ mid_sr <- mid_mean / mid_sd
+ } else if(mid_sr > lb_sr){
+ # if mid_sr > lb_sr then mid_sr becomes the new lower bound
+ lb_mean <- mid_mean
+ lb_sr <- mid_sr
+ new_ret <- (lb_mean + ub_mean) / 2
+ mid <- PortfolioAnalytics:::gmv_opt(R=R, constraints=constraints, moments=moments, lambda=1e6, target=new_ret, lambda_hhi=lambda_hhi, conc_groups=conc_groups)
+ mid_weights <- matrix(mid$weights, ncol=1)
+ mid_mean <- as.numeric(t(mid_weights) %*% fmean)
+ mid_sd <- as.numeric(sqrt(t(mid_weights) %*% moments$var %*% mid_weights))
+ mid_sr <- mid_mean / mid_sd
+ }
+ i <- i + 1
+ }
+ return(new_ret)
+}
Modified: pkg/PortfolioAnalytics/R/optimize.portfolio.R
===================================================================
--- pkg/PortfolioAnalytics/R/optimize.portfolio.R 2013-10-07 14:22:25 UTC (rev 3212)
+++ pkg/PortfolioAnalytics/R/optimize.portfolio.R 2013-10-07 18:21:02 UTC (rev 3213)
@@ -772,6 +772,11 @@
out <- list(weights=weights, objective_measures=obj_vals, opt_values=obj_vals, out=qp_result$out, call=call)
}
} else {
+ # if(hasArg(ef)) ef=match.call(expand.dots=TRUE)$ef else ef=FALSE
+ if(hasArg(maxSR)) maxSR=match.call(expand.dots=TRUE)$maxSR else maxSR=FALSE
+ if(maxSR){
+ target <- max_sr_opt(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, lambda_hhi=lambda_hhi, conc_groups=conc_groups)
+ }
roi_result <- gmv_opt(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, lambda_hhi=lambda_hhi, conc_groups=conc_groups)
weights <- roi_result$weights
obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
@@ -796,11 +801,12 @@
}
if( any(c("CVaR", "ES", "ETL") %in% names(moments)) ) {
if(hasArg(ef)) ef=match.call(expand.dots=TRUE)$ef else ef=FALSE
+ if(hasArg(maxSTARR)) maxSTARR=match.call(expand.dots=TRUE)$maxSTARR else maxSTARR=TRUE
if(ef) meanetl <- TRUE else meanetl <- FALSE
tmpnames <- c("CVaR", "ES", "ETL")
idx <- which(tmpnames %in% names(moments))
# Minimize sample ETL/ES/CVaR if CVaR, ETL, or ES is specified as an objective
- if(length(moments) == 2 & all(moments$mean != 0) & ef==FALSE){
+ if(length(moments) == 2 & all(moments$mean != 0) & ef==FALSE & maxSTARR){
# This is called by meanetl.efficient.frontier and we do not want that, need to have ef==FALSE
target <- mean_etl_opt(R=R, constraints=constraints, moments=moments, target=target, alpha=alpha)
meanetl <- TRUE
More information about the Returnanalytics-commits
mailing list