# Agent Based Kelly Formula

Mar 25, 2015 Nathan Epstein Follow @Epstein_N

## Introduction

The objective of this post is to provide an empirical demonstration of the Kelly criterion using an agent based simulation model. Hopefully, this approach is more agreeable to programmers than a traditional mathematical derivation.

The Kelly criterion is a well known formula used to determine the optimal size of a series of bets. The size of the bet is a proportion of current bankroll determined to optimize the growth rate over sequential bets. It is a function of both the probability of winning each bet (call it p) and the odds being given (call it b).

The formula for the optimal bet size is given by .

## The Experiment

We create a simulation experiment in which agents bet on a series of (unfair) coin flips. We track the performance of the agents to determine which strategies grow fastest for each value p (probability of heads).

Each agent has a parameter, bet_on_heads, the proportion of their wealth to bet on heads (this goes from -1 to 1 with -1 being all wealth on tails and 1 being all on heads). If the agent guesses correctly - they receive the amount bet. If the agent guesses incorrectly - they lose amount bet (i.e. the odds are 1-1 or b=1).

We create a simulation for each p in 0, 0.01, , 1. In each simulation, we create 1000 agents and flip 1000 times. This allows us to track the performance of each betting strategy for each value of p.

In each simulation we get the strategy of the most successful agent and the wealth-weighted-average strategy (the average strategy weighted by success of each agent). Ultimately, these wind up being nearly identical.

## The Code

The code used for the simulation (written in ruby) is presented below. It can also be found in this gist.

```require 'csv' class Simulation attr_reader :population def initialize(prob_H, num_agents) @prob_H = prob_H @population = [] for i in 1..num_agents amount_on_heads = 2 * (i.to_f / num_agents) - 1 #uniform from -1 to 1 @population.push(Agent.new(amount_on_heads)) end end def flip(iterations) for i in 1..iterations outcome = rand < @prob_H ? 'H' : 'T' population.each do |agent| agent.bet(outcome) end end end end class Agent attr_reader :wealth, :amount_on_heads def initialize(amount_on_heads) @amount_on_heads = amount_on_heads @wealth = 1 end def bet(outcome) @wealth = outcome == 'H' ? @wealth * (1 + @amount_on_heads) : @wealth * (1 - @amount_on_heads) end end # CONVENIENCE FUNCTIONS def avg_weighted_bet(population) total_wealth = population.map { |agent| agent.wealth }.reduce(:+) population.map { |agent| agent.amount_on_heads * (agent.wealth.to_f / total_wealth) }.reduce(:+) end def max_wealth_bet(population) max_wealth = population.wealth bet = population.amount_on_heads population.each do |agent| if agent.wealth > max_wealth max_wealth = agent.wealth bet = agent.amount_on_heads end end bet end # RUN THE SIMULATION FOR EACH PROBABILITY kelly_values = [] max_values = [] avg_values = [] for i in 0..100 prob_H = i.to_f / 100 num_agents = 1000 kelly_values.push(2 * prob_H - 1) s = Simulation.new(prob_H, num_agents) s.flip(1000) max_values.push(max_wealth_bet(s.population)) avg_values.push(avg_weighted_bet(s.population)) end CSV.open('./results.csv','w') do |csv| csv << kelly_values csv << max_values csv << avg_values end```

## The Results

This first plot is the wealth-weighted-average strategy (red line) and Kelly strategy (grey line) as a function of p.

The next plot is the maximum-wealth strategy (red line) and Kelly strategy (grey line) as a function of p.

Its clear from inspection that maximum-wealth and wealth-weighted-average produce nearly identical results and that both clearly straddle the Kelly strategy line.

Thus, the prescribed strategy from the agent based model follows the mathematically derived result of the Kelly criterion.

## Russian Translation

softdroid.net: : .