Source

privateer / risky_business / privateer_sim.py

Full commit
# encoding: utf-8
"""

.. module:: privateer_sim
   :synopsis: actual sim worker

.. moduleauthor:: Dan MacKinlay <fillmewithspam@email.possumpalace.org>

"""
from pyevolve import G1DList
from pyevolve import GSimpleGA
from pyevolve import Selectors
from pyevolve import Statistics
# from pyevolve import DBAdapters
from pyevolve import Selectors, Crossovers, Consts, Initializators, Mutators, Scaling


import numpy as np
import matplotlib.pyplot as plt
import market
import PrivateerCrossovers
import PrivateerMutators

import argparse

mean_fitness = []
peak_fitness = []
leader_gamma = []
median_gamma = []
median_fitness = []
   
def main():
    import privateers
    parser = argparse.ArgumentParser(description="simulate some traders in a  stochastic market")
    parser.add_argument('--trader-class', help='Trader class name', default='CARATrader' )
    parser.add_argument('--seed', help='seed value', default=None )
    values = parser.parse_args()
    trader_class = getattr(privateers, values.trader_class)
    run_sim(trader_class, values.seed)
    
def run_sim(trader_class, seed):
    mean_fitness = []
    peak_fitness = []
    gamma_of_leader = []
    median_gamma = []
    # Genome instance, 1D List of 1 element
    population = 100
    elitism_rate = .6*population
    genome = G1DList.G1DList(1)
    generations = 200
    
    # Sets the range max and min of the 1D List
    genome.setParams(rangemin=-8.0, rangemax=8.0)
        
    genome.initializator.set(Initializators.G1DListInitializatorReal)
    
    # The evaluator function (evaluation function)
    def value_of_lifetime(gen):        
        return market.value_of_lifetime(gen, Klass=trader_class)
    
    genome.evaluator.set(value_of_lifetime)
    
    # Mutator function 
    # genome.mutator.set(Mutators.G1DListMutatorRealGaussian)
    # genome.mutator.set(Mutators.G1DListMutatorRealRange)
    genome.mutator.set(PrivateerMutators.G1DListMutatorRealPseudoBitwise)
    
    # Crossover function must be set to something that can handle 1-elem list
    # genome.crossover.set(Crossovers.G1DListCrossoverUniform)
    # genome.crossover.set(PrivateerCrossovers.G1DListCrossoverMean)
    genome.crossover.set(PrivateerCrossovers.G1DListCrossoverBitwise)
    
    # Genetic Algorithm Instance
    ga_engine = GSimpleGA.GSimpleGA(genome,seed=seed)

    ga_engine.selector.set(Selectors.GTournamentSelector)
    # ga_engine.selector.set(Selectors.GRouletteWheel)
    #ga_engine.selector.set(Selectors.GTournamentSelectorAlternative)

    # Set the selector method, the number of generations and
    # the termination criteria
        
    ga_engine.setGenerations(generations)
    
    #Don't check to convergence - it converges on false minima all the time
    # ga_engine.terminationCriteria.set(GSimplega_engine.ConvergenceCriteria)
    
    ga_engine.setMinimax(Consts.minimaxType["maximize"])
    
    pop = ga_engine.getPopulation()
    pop.scaleMethod.set(Scaling.SigmaTruncScaling)
    
    ga_engine.stepCallback.add(update_plot)
    ga_engine.stepCallback.add(update_stats)
    
    ga_engine.setMutationRate(0.01)
    
    ga_engine.setPopulationSize(population)
    ga_engine.setElitism(True)
    ga_engine.setElitismReplacement(elitism_rate)
    
    # # Sets the DB Adapter, the resetDB flag will make the Adapter recreate
    # # the database and erase all data every run, you should use this flag
    # # just in the first time, after the pyevolve.db was created, you can
    # # omit it.
    # sqlite_adapter = DBAdapters.DBSQLite(identify="ex1", resetDB=True)
    # ga_engine.setDBAdapter(sqlite_adapter)
    
    # ga_engine.setInteractiveMode(True)
    
    # Do the evolution, with stats dump
    # frequency of 20 generations
    ga_engine.evolve(freq_stats=0)
    
    # Best individual
    print ga_engine.bestIndividual()
    
    plot_stats()
    raw_input()

plot_line = None
plt.ion()

def update_plot(ga_engine):
    global plot_line
    generation = ga_engine.getCurrentGeneration()

    # import pdb; pdb.set_trace()
    genomes = []
    fitnesses = []
    
    for individual in ga_engine.getPopulation():
        genomes.append(individual.genomeList[0])
        fitnesses.append(individual.fitness)
    # plt.clf()
    # series = plt.gca().lines
    # if len(series): del(series[0])
    
    if plot_line is None:
        plot_line, = plt.plot(genomes, fitnesses)
    plot_line.set_ydata(fitnesses)
    plot_line.set_xdata(genomes)
    plt.title('fitness versus gamma')
    plt.draw()

    return False

def update_stats(ga_engine):
    global mean_fitness, peak_fitness, median_fitness, leader_gamma, median_gamma
    pop = ga_engine.getPopulation()
    mean_fitness.append(dict(pop.getStatistics().items())['rawAve'])
    leader = pop[0]
    peak_fitness.append(pop[0].fitness)
    leader_gamma.append(leader.genomeList[0])
    median = pop[len(pop)/2]
    median_fitness.append(median.fitness)
    median_gamma.append(median.genomeList[0])
    
    return False
    
def plot_stats():
    global mean_fitness, peak_fitness, median_fitness, leader_gamma, median_gamma
    x = range(len(peak_fitness))
    plt.figure(2)
    plt.subplot(211)
    plt.plot(x, peak_fitness, 'r', x, median_fitness, 'b')
    plt.title('peak and median fitness')
    plt.subplot(212)
    plt.plot(x, leader_gamma, 'r', x, median_gamma, 'b')
    plt.title('peak and median gamma')
    

if __name__ == "__main__":
   main()