[Returnanalytics-commits] r2540 - in pkg/PortfolioAnalytics: . R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Jul 11 13:13:54 CEST 2013


Author: rossbennett34
Date: 2013-07-11 13:13:54 +0200 (Thu, 11 Jul 2013)
New Revision: 2540

Added:
   pkg/PortfolioAnalytics/man/random_portfolios_v2.Rd
   pkg/PortfolioAnalytics/man/randomize_portfolio_v2.Rd
Modified:
   pkg/PortfolioAnalytics/NAMESPACE
   pkg/PortfolioAnalytics/R/random_portfolios.R
Log:
modifying random portfolios code to accept a portfolio object and updating documentaion

Modified: pkg/PortfolioAnalytics/NAMESPACE
===================================================================
--- pkg/PortfolioAnalytics/NAMESPACE	2013-07-11 03:44:05 UTC (rev 2539)
+++ pkg/PortfolioAnalytics/NAMESPACE	2013-07-11 11:13:54 UTC (rev 2540)
@@ -44,8 +44,10 @@
 export(portfolio.spec)
 export(position_limit_constraint)
 export(print.constraint)
+export(random_portfolios_v2)
 export(random_portfolios)
 export(random_walk_portfolios)
+export(randomize_portfolio_v2)
 export(randomize_portfolio)
 export(return_objective)
 export(risk_budget_objective)

Modified: pkg/PortfolioAnalytics/R/random_portfolios.R
===================================================================
--- pkg/PortfolioAnalytics/R/random_portfolios.R	2013-07-11 03:44:05 UTC (rev 2539)
+++ pkg/PortfolioAnalytics/R/random_portfolios.R	2013-07-11 11:13:54 UTC (rev 2540)
@@ -196,6 +196,150 @@
   return(result)
 }
 
+#' version 2 generate random permutations of a portfolio seed meeting your constraints on the weights of each asset
+#' 
+#' @param portfolio an object of type "portfolio" specifying the constraints for the optimization, see \code{\link{portfolio.spec}}
+#' @param max_permutations integer: maximum number of iterations to try for a valid portfolio, default 200
+#' @param rounding integer how many decimals should we round to
+#' @return named weighting vector
+#' @author Peter Carl, Brian G. Peterson, (based on an idea by Pat Burns)
+#' @export
+randomize_portfolio_v2 <- function (portfolio, max_permutations=200) { 
+  # @author: Peter Carl, Brian Peterson (based on an idea by Pat Burns)
+  # generate random permutations of a portfolio seed meeting your constraints on the weights of each asset
+  # set the portfolio to the seed
+  seed <- portfolio$assets
+  nassets <- length(seed)
+  
+  # get the constraints from the portfolio object
+  constraints <- get_constraints(portfolio)
+  
+  min_mult <- pconstraints$min_mult
+  if(is.null(min_mult)) min_mult <- rep(-Inf,nassets)
+  max_mult <- rpconstraints$max_mult
+  if(is.null(max_mult)) max_mult <- rep(Inf,nassets)
+  min_sum  <- constraints$min_sum
+  max_sum  <- constraints$max_sum
+  weight_seq <- constraints$weight_seq
+  if(is.null(weight_seq)){
+    weight_seq <- generatesequence(min=min(constraints$min), max=max(constraints$max), by=0.002)
+  }
+  weight_seq <- as.vector(weight_seq)
+  max <- rpconstraints$max
+  min <- rpconstraints$min
+  portfolio <- as.vector(seed)
+  rownames(portfolio) <- NULL
+  
+  # initialize our loop
+  permutations <- 1
+  
+  # create a temporary portfolio so we don't return a non-feasible portfolio
+  tportfolio <- portfolio
+  # first randomly permute each element of the temporary portfolio
+  random_index <- sample(1:length(tportfolio), length(tportfolio))
+  for (i in 1:length(tportfolio)) {
+    cur_index <- random_index[i]
+    cur_val <- tportfolio[cur_index]
+    # randomly permute a random portfolio element
+    tportfolio[cur_index] <- sample(weight_seq[(weight_seq >= cur_val * min_mult[cur_index]) & (weight_seq <= cur_val * max_mult[cur_index]) & (weight_seq <= max[cur_index]) & (weight_seq >= min[cur_index])], 1)
+  }
+  
+  #while portfolio is outside min/max sum and we have not reached max_permutations
+  while ((sum(tportfolio) <= min_sum | sum(tportfolio) >= max_sum) & permutations <= max_permutations) {
+    permutations <- permutations+1
+    # check our box constraints on total portfolio weight
+    # reduce(increase) total portfolio size till you get a match
+    # 1> check to see which bound you've failed on, brobably set this as a pair of while loops
+    # 2> randomly select a column and move only in the direction *towards the bound*, maybe call a function inside a function
+    # 3> check and repeat
+    random_index <- sample(1:length(tportfolio), length(tportfolio))
+    i <- 1
+    while (sum(tportfolio) <= min_sum & i <= length(tportfolio)) {
+      # randomly permute and increase a random portfolio element
+      cur_index <- random_index[i]
+      cur_val <- tportfolio[cur_index]
+      if (length(weight_seq[(weight_seq >= cur_val) & (weight_seq <= max[cur_index])]) > 1)
+      {
+        # randomly sample one of the larger weights
+        tportfolio[cur_index] <- sample(weight_seq[(weight_seq >= cur_val) & (weight_seq <= max[cur_index])], 1)
+        # print(paste("new val:",tportfolio[cur_index]))
+      } else {
+        if (length(weight_seq[(weight_seq >= cur_val) & (weight_seq <= max[cur_index])]) == 1) {
+          tportfolio[cur_index] <- weight_seq[(weight_seq >= cur_val) & (weight_seq <= max[cur_index])]
+        }
+      }
+      i <- i + 1 # increment our counter
+    } # end increase loop
+    while (sum(tportfolio) >= max_sum & i <= length(tportfolio)) {
+      # randomly permute and decrease a random portfolio element
+      cur_index <- random_index[i]
+      cur_val <- tportfolio[cur_index]
+      if (length(weight_seq[(weight_seq <= cur_val) & (weight_seq >= min[cur_index])] ) > 1) {
+        # randomly sample one of the smaller weights
+        tportfolio[cur_index] <- sample(weight_seq[(weight_seq <= cur_val) & (weight_seq >= min[cur_index] )], 1)
+      } else {
+        if (length(weight_seq[(weight_seq <= cur_val) & (weight_seq >= min[cur_index])] ) == 1) {
+          tportfolio[cur_index] <- weight_seq[(weight_seq <= cur_val) & (weight_seq >= min[cur_index])]
+        }
+      }
+      i <- i + 1 # increment our counter
+    } # end decrease loop
+  } # end final walk towards the edges
+  
+  portfolio <- tportfolio
+  
+  colnames(portfolio) <- colnames(seed)
+  if (sum(portfolio) <= min_sum | sum(tportfolio) >= max_sum){
+    portfolio <- seed
+    warning("Infeasible portfolio created, defaulting to seed, perhaps increase max_permutations.")
+  }
+  if(isTRUE(all.equal(seed,portfolio))) {
+    if (sum(seed) >= min_sum & sum(seed) <= max_sum) {
+      warning("Unable to generate a feasible portfolio different from seed, perhaps adjust your parameters.")
+      return(seed)
+    } else {
+      warning("Unable to generate a feasible portfolio, perhaps adjust your parameters.")
+      return(NULL)
+    }
+  }
+  return(portfolio)
+}
+
+#' version 2 generate an arbitary number of constrained random portfolios
+#' 
+#' repeatedly calls \code{\link{randomize_portfolio}} to generate an 
+#' arbitrary number of constrained random portfolios.
+#' 
+#' @param portfolio an object of type "portfolio" specifying the constraints for the optimization, see \code{\link{constraint}}
+#' @param permutations integer: number of unique constrained random portfolios to generate
+#' @param \dots any other passthru parameters 
+#' @return matrix of random portfolio weights
+#' @seealso \code{\link{portfolio.spec}}, \code{\link{objective}}, \code{\link{randomize_portfolio_v2}}
+#' @author Peter Carl, Brian G. Peterson, (based on an idea by Pat Burns)
+#' @export
+random_portfolios_v2 <- function( portfolio, permutations=100, ...)
+{ # 
+  # this function generates a series of portfolios that are a "random walk" from the current portfolio
+  seed <- portfolio$assets
+  result <- matrix(nrow=permutations, ncol=length(seed))
+  result[1,] <- seed
+  result[2,] <- rep(1/length(seed),length(seed))
+  # rownames(result)[1]<-"seed.portfolio"
+  # rownames(result)[2]<-"equal.weight"
+  i <- 3
+  while (i <= permutations) {
+    result[i,] <- as.matrix(randomize_portfolio_v2(portfolio=portfolio, ...))
+    if(i == permutations) {
+      result <- unique(result)
+      i <- nrow(result)
+      result <- rbind(result, matrix(nrow=(permutations-i), ncol=length(seed)))
+    }
+    i <- i + 1
+  }
+  colnames(result) <- names(seed)
+  return(result)
+}
+
 # EXAMPLE: start_t<- Sys.time(); x=random_walk_portfolios(rep(1/5,5), generatesequence(min=0.01, max=0.30, by=0.01), max_permutations=500, permutations=5000, min_sum=.99, max_sum=1.01); end_t<-Sys.time(); end_t-start_t;
 # > nrow(unique(x))
 # [1] 4906

Added: pkg/PortfolioAnalytics/man/random_portfolios_v2.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/random_portfolios_v2.Rd	                        (rev 0)
+++ pkg/PortfolioAnalytics/man/random_portfolios_v2.Rd	2013-07-11 11:13:54 UTC (rev 2540)
@@ -0,0 +1,33 @@
+\name{random_portfolios_v2}
+\alias{random_portfolios_v2}
+\title{version 2 generate an arbitary number of constrained random portfolios}
+\usage{
+  random_portfolios_v2(portfolio, permutations = 100, ...)
+}
+\arguments{
+  \item{portfolio}{an object of type "portfolio" specifying
+  the constraints for the optimization, see
+  \code{\link{constraint}}}
+
+  \item{permutations}{integer: number of unique constrained
+  random portfolios to generate}
+
+  \item{\dots}{any other passthru parameters}
+}
+\value{
+  matrix of random portfolio weights
+}
+\description{
+  repeatedly calls \code{\link{randomize_portfolio}} to
+  generate an arbitrary number of constrained random
+  portfolios.
+}
+\author{
+  Peter Carl, Brian G. Peterson, (based on an idea by Pat
+  Burns)
+}
+\seealso{
+  \code{\link{portfolio.spec}}, \code{\link{objective}},
+  \code{\link{randomize_portfolio_v2}}
+}
+

Added: pkg/PortfolioAnalytics/man/randomize_portfolio_v2.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/randomize_portfolio_v2.Rd	                        (rev 0)
+++ pkg/PortfolioAnalytics/man/randomize_portfolio_v2.Rd	2013-07-11 11:13:54 UTC (rev 2540)
@@ -0,0 +1,30 @@
+\name{randomize_portfolio_v2}
+\alias{randomize_portfolio_v2}
+\title{version 2 generate random permutations of a portfolio seed meeting your constraints on the weights of each asset}
+\usage{
+  randomize_portfolio_v2(portfolio, max_permutations = 200)
+}
+\arguments{
+  \item{portfolio}{an object of type "portfolio" specifying
+  the constraints for the optimization, see
+  \code{\link{portfolio.spec}}}
+
+  \item{max_permutations}{integer: maximum number of
+  iterations to try for a valid portfolio, default 200}
+
+  \item{rounding}{integer how many decimals should we round
+  to}
+}
+\value{
+  named weighting vector
+}
+\description{
+  version 2 generate random permutations of a portfolio
+  seed meeting your constraints on the weights of each
+  asset
+}
+\author{
+  Peter Carl, Brian G. Peterson, (based on an idea by Pat
+  Burns)
+}
+



More information about the Returnanalytics-commits mailing list