Clayton Estey
Clayton Estey

Reputation: 21

Extracting bestSol from ga-class in R is getting NULL

I'm using the GA package in R to optimize portfolio weights with a genetic algorithm. I made a custom monitor function mon that is supposed to update a plot of the annualized mean return calculated from the current best solution weights at each iteration. This is what I've done after referring to the source code found on https://rdrr.io/cran/GA/src/R/ga.R.

options(scipen=999)
options(stringsAsFactors=F)
library(GA)

#Constraint parameters: 
set.seed(123)
n=3
returns=matrix(c(rep(0.001,5*365),rep(0.0008,5*365),rep(0.0005,5*365)),
               ncol=n,nrow=5*365,byrow=F)
pop=30
elit=.1*pop
#a is cost scalar.
a=50
maxiter=500
#box constraints
max_x=0.05
min_x=0

#Making monitor function 
mon = function(obj){
  
  iter=obj@iter
  print(mode(obj@bestSol[[iter]]))
  
  plot(x=iter,y=(1+mean(returns%*%obj@bestSol[[iter]]))^365-1,
         xlab="Gen",ylab="Mean Return",xlim=c(0,maxiter),ylim=c(0,1),
         main=paste("Iteration =",iter),type="b",log="x")
  Sys.sleep(0.2)  
    
}

#Fitness function
fit = function(x) { 
 
  target=sum(returns%*%x)
  cost=a*((sum(x)-1)^2+sum(max(0,x-max_x)^2)+sum(max(0,min_x-x)^2))
  return (-target+cost)
  
}


#Set 1% of initial population as 1/N baseline solution
sug=matrix(rep(1/n,n*ceiling(0.01*pop)),nrow=ceiling(0.01*pop),ncol=n,byrow=T)

ga_res_Best = ga(type="real-valued",function(x){-fit(x)},lower=rep(min_x,n),
               upper = rep(max_x,n),maxiter=maxiter,run=100,parallel=T,
               monitor=mon,popSize = pop,elitism = elit,suggestions = sug,
               keepBest=T,optim = F)

Everything was working fine until I tried to add the custom monitor function. I was getting this error after running ga_res_Best:

 Error in returns %*% obj@bestSol[[iter]] : 
  requires numeric/complex matrix/vector arguments

Since I added print(mode(obj@bestSol[[iter]])) to the monitor function I found that I'm getting NULL as the output to obj@bestSol[[iter]] when I'm expecting it to return a numeric vector of weights, which is the same syntax used in the source code link above.

EDIT: I added the fitness function fit and the returns data to make it reproducible.

Upvotes: 1

Views: 154

Answers (1)

Clayton Estey
Clayton Estey

Reputation: 21

I'm answering my own question. GA from CRAN is not fully updated to reflect this issue. GA needs to be downloaded from GitHub directly. Here are the commands for that:

install.packages(c("devtools","pkgbuild"))
library(pkgbuild)

devtools::install_github("luca-scr/GA",build_vignettes=T)

Upvotes: 1

Related Questions