[Returnanalytics-commits] r2148 - pkg/PortfolioAnalytics/R

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Jul 13 03:20:04 CEST 2012


Author: hezkyvaron
Date: 2012-07-13 03:20:02 +0200 (Fri, 13 Jul 2012)
New Revision: 2148

Modified:
   pkg/PortfolioAnalytics/R/optimize.portfolio.R
Log:
- Added a more integrated ROI (method="ROI_new") and pso extensions to optimize.portfolio( )
- Needed: add some more documentation to explain "ROI_new" and what cases it is useful for.  

Modified: pkg/PortfolioAnalytics/R/optimize.portfolio.R
===================================================================
--- pkg/PortfolioAnalytics/R/optimize.portfolio.R	2012-07-12 09:16:32 UTC (rev 2147)
+++ pkg/PortfolioAnalytics/R/optimize.portfolio.R	2012-07-13 01:20:02 UTC (rev 2148)
@@ -36,7 +36,7 @@
 #'  
 #' @param R an xts, vector, matrix, data frame, timeSeries or zoo object of asset returns
 #' @param constraints an object of type "constraints" specifying the constraints for the optimization, see \code{\link{constraint}}, if using closed for solver, need to pass a \code{\link{constraint_ROI}} object.
-#' @param optimize_method one of "DEoptim", "random", "ROI".  For using ROI, need to use a constraint_ROI object in constraints.
+#' @param optimize_method one of "DEoptim", "random", "ROI","ROI_new", "pso".  For using \code{ROI}, need to use a constraint_ROI object in constraints. For using \code{ROI_new}, pass standard \code{constratint} object in \code{constraints} argument.  Presently, ROI has plugins for \code{quadprog} 
 #' @param search_size integer, how many portfolios to test, default 20,000
 #' @param trace TRUE/FALSE if TRUE will attempt to return additional information on the path or portfolios searched
 #' @param \dots any other passthru parameters
@@ -49,7 +49,7 @@
 optimize.portfolio <- function(
 		R,
 		constraints,
-		optimize_method=c("DEoptim","random","ROI"), 
+		optimize_method=c("DEoptim","random","ROI","ROI_new","pso"), 
 		search_size=20000, 
 		trace=FALSE, ..., 
 		rp=NULL,
@@ -200,6 +200,8 @@
     }
     
   } ## end case for DEoptim
+  
+  
   if(optimize_method=="random"){
       #' call random_portfolios() with constraints and search_size to create matrix of portfolios
       if(missing(rp) | is.null(rp)){
@@ -252,6 +254,99 @@
     out$call <- call
   } ## end case for ROI
   
+  
+  if(optimize_method == "ROI_new"){
+    # This takes in a regular constraint object and extracts the desired business objectives
+    # and converts them to matrix form to be inputed into a closed form solver
+    # Applying box constraints
+    bnds <- list(lower = list(ind = seq.int(1L, N), val = rep(constraints$min, N)),
+                 upper = list(ind = seq.int(1L, N), val = rep(constraints$max, N)))
+    # retrive the objectives to minimize, these should either be "var" and/or "mean"
+    # we can eight miniminze variance or maximize quiadratic utility (we will be minimizing the neg. quad. utility)
+    objectives <- do.call(cbind, sapply(constraints$objectives, "[", "name"))
+    moments <- list()
+    for(i in 1:length(objectives)) moments[[i]]<- eval(as.symbol(objectives[i]))(R)
+    names(moments) <- objectives
+    plugin <- ifelse(any(objectives=="var"), "quadprog", "glpk")
+    if(plugin == "quadprog") ROI_objective <- ROI:::Q_objective(Q=2*lambda*moments$var, L=-moments$mean)
+    if(plugin == "glpk") ROI_objective <- ROI:::L_objective(L=-moments$mean)
+    if(!hasArg(constraints$lambda)) constraints$lambda <- 1
+    target.return <- do.call(cbind,sapply(init.constr$objectives, "[", "target"))
+    Amat <- rbind(rep(1, N), rep(1, N))
+    dir.vec <- c(">=","<=")
+    rhs.vec <- c(constraints$min_sum, constraints$max_sum)
+    if(!is.null(target.return)) {
+      Amat <- rbind(Amat, moments$mean)
+      dir.vec <- cbind(dir.vec, "=="))
+      rhs.vec <- cbind(rhs.vec, target.return)
+    }
+    q.prob <- ROI:::OP(objective=ROI_objective, 
+                       constraints=L_constraint(L=Amat, dir=dir.vec, rhs=rhs.vec),
+                       bounds=bnds)
+    roi.results <- ROI:::ROI_solve(x=q.prob, solver=plugin)
+    weights <- roi.result$solution
+    names(weights) <- colnames(R)
+    out$weights <- weights
+    out$objective_measures <- roi.result$objval
+    out$call <- call
+  } ## end case for ROI
+
+  
+  
+  
+  
+  ## case if method=pso---particle swarm
+  if(optimize_method=="pso"){
+    stopifnot("package:pso" %in% search()  ||  require("pso",quietly = TRUE) )
+    # DEoptim does 200 generations by default, so lets set the size of each generation to search_size/200)
+    if(hasArg(maxit)) maxit=match.call(expand.dots=TRUE)$maxit else maxit=N*50
+    PSOcformals  <- formals(psoptim.control)
+    PSOcargs <- names(PSOcformals)
+    if( is.list(dotargs) ){
+      pm <- pmatch(names(dotargs), PSOcargs, nomatch = 0L)
+      names(dotargs[pm > 0L]) <- PSOcargs[pm]
+      DEcformals$maxit <- maxit
+      if(!hasArg(reltol)) PSOcformals$reltol=.000001 # 1/1000 of 1% change in objective is significant
+      if(!hasArg(fnscale)) PSOcformals$fnscale=1
+      if(!hasArg(abstol)) PSOcformals$asbtol=-Inf
+      if(!hasArg(trace)) PSOcformals$trace=FALSE
+    }
+    
+    # get upper and lower weights parameters from constraints
+    upper = constraints$max
+    lower = constraints$min
+    
+    controlPSO <- do.call(psoptim.control,PSOcformals)
+    
+    minw = try(psoptim( constrained_objective ,  lower = lower[1:N] , upper = upper[1:N] , 
+                        control = controlPSO, R=R, constraints=constraints, nargs = dotargs , ...=...)) # add ,silent=TRUE here?
+    
+    if(inherits(minw,"try-error")) { minw=NULL }
+    if(is.null(minw)){
+      message(paste("Optimizer was unable to find a solution for target"))
+      return (paste("Optimizer was unable to find a solution for target"))
+    }
+    
+    if(isTRUE(tmptrace)) trace <- tmptrace
+    
+    weights = as.vector( minw$optim$bestmem)
+    weights <- normalize_weights(weights)
+    names(weights) = colnames(R)
+    
+    out = list(weights=weights, 
+               objective_measures=constrained_objective(w=weights,R=R,constraints,trace=TRUE)$objective_measures,
+               out=minw$optim$bestval, 
+               call=call)
+    if (isTRUE(trace)){
+      out$PSOoutput=minw
+      out$psoptim_objective_results<-try(get('.objectivestorage',pos='.GlobalEnv'),silent=TRUE)
+      rm('.objectivestorage',pos='.GlobalEnv')
+    }
+    
+  } ## end case for pso
+  
+  
+  
     end_t<-Sys.time()
     # print(c("elapsed time:",round(end_t-start_t,2),":diff:",round(diff,2), ":stats: ", round(out$stats,4), ":targets:",out$targets))
     message(c("elapsed time:",end_t-start_t))



More information about the Returnanalytics-commits mailing list