The last time Hackerfall tried to access this page, it returned a not found error.
A cached version of the page is below, or click here to continue anyway

Mar 25, 2015 Nathan Epstein Follow @Epstein_N

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 .

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 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[0].wealth
bet = population[0].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
```

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.

softdroid.net: : .