1. dan mackinlay
  2. privateer

Source

privateer / risky_business / privateers.py

from math import exp

class Trader(object):
    """encapsulate trader logic"""
    def __init__(self, genome, *args, **kwargs):
        super(Trader, self).__init__(*args, **kwargs)
        self.genome = genome
        self.wealth = 0
    
    def utility_of_lottery(self, lottery):
        raise NotImplementedError
    
    def choose_lottery(self, lottery_list):
        """look through a list of lotteries and choose the best one by my
        utility function
        
        In fact, although this is written for arbitrary lists, it shouldn't be
        used for lists of length>2, since that reduces selection pressure on
        the utility function. Pfff."""
        chosen = lottery_list.pop()
        best_utility = self.utility_of_lottery(chosen)
        for next_lottery in lottery_list:
            next_utility = self.utility_of_lottery(next_lottery)
            if next_utility>best_utility:
                best_utility = next_utility
                chosen = next_lottery
        return chosen

""";;; Bob Mark's reference impementation of CARA payoff values from
;;; http://www.agsm.edu.au/bobm/teaching/SimSS/NetLogo4-models/RA-CARA-EU-3l2p.html
;;;

to-report lottery-values ; turtle procedure. Set up two three-outcome lotteries, where 
                 ; each outcome is chosen randomly from [-10 +10], and the
                 ; two probabilities of each of lottery are chosen.
                 ; Calculate the mean and variance of the lotteries, and
                 ; an outcome of the lotteries. The agent (turtle) chooses one of the
                 ; two lotteries, based on a mean-variance ranking, which assumes a normal
                 ; distribution for each lottery and an exponential (constant
                 ; risk-profile) utility function.  The agent's fitness is its final
                 ; wealth after N choices. If an agent's wealth falls below -10, then
                 ; the agent becomes bankrupt, and "dies".  Each agent starts with an
                 ; endowment of 50, before facing N pairs of lotteries to choose between.
  
   setup-prizes
   create-lottery
   ;; let lmean (((item 0 prizes) * (item 0 lottery)) + 
             ;; ( (item 1 prizes) * (item 1 lottery)) )
   ;; let lvar ((((item 0 prizes) - lmean) ^ 2) * (item 0 lottery) + 
             ;; (((item 1 prizes) - lmean) ^ 2) * (item 1 lottery))
   let utprize1      (1 - e ^ (- gamma * (item 0 prizes)))
   let utprize2      (1 - e ^ (- gamma * (item 1 prizes)))
   let exputil ((item 0 lottery) * utprize1) + ((item 1 lottery) * utprize2)               
   let l-prob random-float 1
   let act-val-lot   
     ifelse-value (l-prob <= (item 0 lottery))
        [(item 0 prizes)]
        [ (item 1 prizes)]   
    report (list  exputil act-val-lot  )   
end

to create-lottery
  let probabilities n-values 2 [random-float 1]
  let sum-of-probabilities (sum probabilities)
  set lottery map [? / sum-of-probabilities] probabilities
  ;; lottery is a list of two random probs summing to 1
end

to-report payoff    ;; turtle procedure. Choose the highest-utility lottery of three
 let lot1 lottery-values
 let lot2 lottery-values
 let lot3 lottery-values
 report ifelse-value (item 0 lot1 >= item 0 lot2)
   [ifelse-value (item 0 lot1 >= item 0 lot3)
     [(item 1 lot1)]
     [(item 1 lot3)]]
   [ifelse-value (item 0 lot2 >= item 0 lot3) 
     [(item 1 lot2)]
     [(item 1 lot3)]]
   
end"""

class CARATrader(Trader):
    """encapsulate trader logic"""
    
    def utility_of_lottery(self, lottery):
        return cara_utility_of_lottery(self.genome, lottery)

def cara_utility_of_prize(gamma, prize):
    return (1.0 - exp(-gamma * prize))

def cara_utility_of_lottery(genome, lottery):
    [gamma] = genome
    return cara_utility_of_prize(gamma, lottery['lower']) *\
       lottery['lowerweight'] +\
           cara_utility_of_prize(gamma, lottery['upper']) *\
       (1.0-lottery['lowerweight'])



""";;; The CRRA version of the aforementioned

to-report lottery-values ; turtle procedure. Set up two three-outcome lotteries, where 
                 ; each outcome is chosen randomly from [-10 +10], and the
                 ; two probabilities of each of lottery are chosen.
                 ; Calculate the mean and variance of the lotteries, and
                 ; an outcome of the lotteries. The agent (turtle) chooses one of the
                 ; two lotteries, based on a mean-variance ranking, which assumes a normal
                 ; distribution for each lottery and a CRRA utility function.  
                 ; The agent's fitness is its final wealth after N choices.
                 ; (Not yet: If an agent's wealth falls below -10, then
                 ; the agent becomes bankrupt, and "dies".  Each agent starts with an
                 ; endowment of 50, before facing N pairs of lotteries to choose between.)
  
   setup-prizes
   create-lottery
   let utprize1 ((fitness + (item 0 prizes)) ^ (1 - rho )) / (1 - rho )
   let utprize2 ((fitness + (item 1 prizes)) ^ (1 - rho )) / (1 - rho )
   let exputil ((item 0 lottery) * utprize1) + ((item 1 lottery) * utprize2)          
   let l-prob random-float 1
   let act-val-lot   
     ifelse-value (l-prob <= (item 0 lottery))
        [(item 0 prizes)]
        [(item 1 prizes)]
   ;; show act-val-lot         
   report (list exputil act-val-lot  )  
end


to setup-prizes
  set prizes 0
  set prizes n-values 2 [max-abs-prize - random (2 * max-abs-prize + 1)] 
    ;; two random prizes between -max-abs-prize and +max-abs-prize
    ;; show prizes
end

to create-lottery
  let probabilities 0
  set probabilities n-values 2 [random-float 1]
  let sum-of-probabilities (sum probabilities)
  set lottery map [? / sum-of-probabilities] probabilities
  ;; show lottery
  ;; lottery is a list of two random probs summing to 1
end
 

to-report payoff    ;; turtle procedure. Choose the highest-utility (CRRA) lottery of three
 let lot1 lottery-values
 let lot2 lottery-values
 let lot3 lottery-values
 report ifelse-value (item 0 lot1 >= item 0 lot2)
   [ifelse-value (item 0 lot1 >= item 0 lot3)
     [(item 1 lot1)  ]
     [(item 1 lot3)  ]]
   [ifelse-value (item 0 lot2 >= item 0 lot3) 
     [(item 1 lot2) ]
     [(item 1 lot3) ]]
   
end"""