<

Kelly Criterion

Decision Making Under Risk in Finance and Insurance

Suppose you have an unbiased coin (50/50). If you guess the outcome of the coin correctly, you win 100% of what you have. If you lose, you suffer a loss of 100%. Since probabilities are multiplicative, it will take only about five iterations of this game to pretty much lose everything. The probability of ruin can be calculated as: $$1-p^n$$ with n being the number of iterations. 1-(.5^5) = 96.875% chance of losing everything. Given an event with equal outcomes and equal payoffs, it seems that engaging in this risk is unnecessary. In fact, one could put the money in a risk free government bond and earn interest instead. What if the probability of a coin flip is 100% one-sided? It would make sense to engage indefinitely in such a game since the chance of losing everything is 1-(0^n)= 0% Let's go to an extreme and say what if the probability of a coin flip is 99% heads? The probability of ruin after five iterations is 2.97%. Keep playing? One would have to run this experiment 345 times to have the chance of losing be equal to the 50/50 scenario (1-(.99^345)=96.875%), yet one would still lose everything eventually. The correct strategy would be to not bet everything, but only bet a portion of what one has. What is that portion? The Kelly criterion.

The Kelly approach is an optimization function that maximizes a value under risk. In our case it evaluates the probabilities and the payoffs associated with the probabilities to determine the optimum betting amount to ensure the best compounding in the long run. It was inherently derived from utility functions, but I will show how this can be derived from time value of money and used in corporate finance and portfolio allocation later on. The simplest formula for the Kelly criterion bet with equal gains and losses such as a coinflip would be: $$P-(1-P)$$ this simplifies to: $$ 2P-1 $$

If you are facing a 50/50 outcome with equal payoffs, then you would bet 0% of everything you have. $$2P-1 = 2\times.5 -1 = 0 $$ If you are facing a 100/0 outcome with equal payoffs, then you would bet 100% of everything you have.$$2P-1 = 2\times1 -1 = 1$$ If you are facing a 51/49 outcome with equal payoffs, then you would bet 2% of everything. $$2P-1 = 2\times.51-1=.02 $$ Using the 51% example, let's run an experiment with 2000 coins over 500 iterations and allocate above the Kelly criterion, below the Kelly criterion, and at the Kelly criterion of 2% currently recommended. We start with $1 and see how it will evolve over the 500 iterations for 2000 players by first overbetting 7% on a game of coinflips with 51/49 odds.

By overbetting to 7% of our capital we get a lot of high returns on our $1 start with a high average final value of $1.82 after 500 iterations. Unfortunately, this average is highly skewed as seen in the histogram above. In fact, a median of 0.59 tells us that over half of all our returns wind up being below .59 cents with most approaching zero. By overallocating too much capital into such odds, what if an opportunity with better odds like 60/40 comes along and we allocated too much into the 51/49? We would have to re-allocate.

Overallocating above the Kelly criterion
damages compounding and increases risk.

Let's now underbet below the Kelly portion and allocate only 1% to our experiment.

By underbetting and allocating 1% of our capital we get an average final value of $1.11 with half of our observations being above $1.08, which is pretty good, but we are not taking full advantage of compounding. Let's now bet the Kelly amount of 2%.

By betting the Kelly amount we ensure that we have a strong average final value and also the highest average median value of all the possible bets $1.11 . In fact, we can see how the average and the median evolve over time in our case of overbetting at 7% below:

If we bet the 2% Kelly amount, our mean and median don't drift apart, but rather climb together as time goes on. We take advantage of compounding since half the time our capital slowly drifts upwards, allowing for a higher present value after each iteration.

As can be seen, the Kelly approach of 2% gives one the best outcomes if one wishes to exit such a game over time given the best upward drifting median.

If we underbet as time goes on, we do not take advantage of compounding. If we overbet as time goes on the likelihood of us losing our money upon an exit out of this game increases over time.

Coin Flipping Code in Python

If you wish to do your own experiment and see how the coin flipping simulation turns out with different odds and betting amounts, use the Python code below.

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib import pyplot

# p=probability, kelly=the betting amount

def coinflip(p,kelly):
    flips=-np.ones([1,100])
    for i in xrange(int(round(p))):
        flips[[0][0]][i]=1
    return flips[0]*kelly

# n=number of paths, t=time intervals

def simulation(n,t,data):
    a=np.array([])
    b=np.array([])
    for i in range(n):
        a=np.column_stack(np.random.choice(data,size=t,replace=True))
        b=np.append(a,b)
    b=b.reshape(t,n)
    mc = pd.DataFrame(b, index=np.arange(0,t,1), columns=np.arange(0,n,1))
    mc=1+mc
    mc=mc.cumprod()
    data_median=[]
    data_mean=[]
    for i in xrange(t):
        data_median.append(np.median(mc.values[i]))
        data_mean.append(mc.values[i].mean())
    plt.plot( np.array(data_median), 'r-',  np.array(data_mean), 'k')
    plt.legend(['Median Final Value' +str(np.array(data_median[-1:])), 'Average Final Value' +str(np.array(data_mean[-1:]))])
    plt.ylabel('Value')
    plt.xlabel('Iterations')
    plt.title('Mean and Median Evolution with Kelly Over-Betting')
    plt.show()
    plt.figure(1)
    plt.subplot(211)
    plt.xlabel('Iterations')
    plt.ylabel('Gains')
    plt.title('Monte Carlo Simulation | Average Final Value ' + str(round(mc.values[-1].mean(),2))+ ' | Standard Deviation ' + str(round(mc.values[-1].std(),2))+ ' | Return/Risk Ratio ' + str(round(((mc.values[-1].mean())-1)/mc.values[-1].std(),2)))
    plt.plot(mc, label='$y = {i}x + {i}$'.format(i=i), linewidth=1, alpha=0.5)
    plt.subplot(212)
    plt.xlabel('Gains after Iterations')
    plt.ylabel('Frequency')
    plt.hist(mc.values[-1], bins=100, facecolor='#636363', alpha=0.75, linewidth=.2, edgecolor='black')
    plt.axvline(mc.values[-1].mean(), color='k', linestyle='dashed', linewidth=1)
    plt.axvline(np.median(mc.values[-1]), color='blue', linestyle='dashed', linewidth=1)
    plt.legend(['Average value of '  + str(round(mc.values[-1].mean(),2)), 'Median value of '+  str(round(np.median(mc.values[-1]),2)) ])
    pyplot.show()

coin_data=coinflip(51,0.02)

simulation(1000,500,coin_data)

Kelly Betting with Varied Payoffs

In the real world the payoffs (gains/losses of probabilities) are usually different. To compensate for that, we can assign the amount of winning (G) and losing (L): $$\frac{P}{L} - \frac{(1-P)}{G}$$ In our initial example, the losses equaled the gains so the formula just simplified to P/(1-P)=2P-1, but if one faces 50/50 odds where heads gives a gain of 200% and tails gives a loss of 100%, then: $$\frac{.5}{1} - \frac{(1-.5)}{2} =.25$$ We would bet 25% of our capital under the Kelly criterion to ensure the best long-term growth.

One can also solve the formula above backwards and ask oneself if one should take a costly bet. This can be useful when buying financial options and to evaluate if insurance or lottery tickets are too expensive. We can express the loss L as the price for a lottery ticket, insurance, or an option. $$L=P \frac{G}{(1-P)}$$ The above formula will give us the cost at which participating in such a game is not worth the time or money. Suppose you start with $100 initial capital. A lottery ticket has a 0.01% chance of winning $1,000 dollars. How much should the price of such a ticket be, on average, to not make money if one keeps buying it in the long run? The answer is exactly $1.001001001. As can be demonstrated by the experiment below:

By starting with $100 at a price of $1.001001001 for a lottery ticket one will ensure that on average no money will be made (we wind up back at $99.68, approximately $100) and that most of the players will lose with only a select few making a couple of thousand. There's some interesting strategies to beating this game. Since one can't control the price of a lottery ticket (L), one can wait until the pool of winnings increases (G increases) or buy up all of the tickets (P>>1). Both such strategies were pursued by a professional mathematician to systematically win the lottery 14 times until the authorities made such practices illegal.

To run your own experiment with different payoffs and probabilities feel free to use the code below in Python.

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

#x=capital, p=probability of success, g=payoff/gain, l=loss/cost, t=time interval, n=number of paths

n=500

def simulate(x,p,g,l,t):
    x=[x]
    for i in xrange(t):
        outcome=int(np.random.choice([1,-1],1,p=[p,1-p,]))
        if (x[i] <= l):
            x.append(0)
        else:
            if outcome==abs(outcome):
                x.append(x[i] + outcome*g)
            else:
                x.append(x[i] + outcome*l)
    return x

simulation=np.column_stack(simulate(100,.001,1000,1,500) for i in xrange(n))

print 'average final value ' + str(sum(simulation[-1])/len(simulation[-1]))
print 'median value ' + str(np.median(simulation[-1]))
print 'mode value ' + str(stats.mode(simulation[-1])[0])
print 'number of bankruptcies: ' + str(np.count_nonzero(simulation[-1] == 0))
print 'probability of being bankrupt at the end: ' + str(round(np.count_nonzero(simulation[-1] == 0)/n*100,2)) + '%'

avg=[]
median=[]
for i in xrange(len(simulation)):
    avg.append(sum(simulation[i])/len(simulation[i]))
    median.append(np.median(simulation[i]))
	
plt.plot(simulation, color=[0.15,0.2,0.3,0.35])
plt.plot(avg, color='r')
plt.plot(median, color='#52a0d8')
plt.ylabel('Gains')
plt.xlabel('Time')
plt.legend(['Average final value ' + str(round(sum(simulation[-1])/len(simulation[-1]),2))])
plt.title('Monte Carlo Simulation ')
plt.show()

Kelly Criterion from Time Value of Money

The famous time value of money formula where FV=future value, PV=present value, R=return, n=periods is expressed as: $$ FV=PV(1+R)^n$$ The return from PV to FV can be expressed as a result of multiple periods with differing values of R: $$ FV=PV(1+R_1)(1+R_2) ... (1+R_i)$$ If we invest a portion in this project or stock we can denote that portion with an x such as: $$ FV=PV(1+xR_1)(1+xR_2) ... (1+xR_i)$$ If x is zero, our FV=PV. We do not participate in the gains or losses of such an investment. If x is one, we take a full ride. If we have a lot of different returns we can express our final return as: $$\frac{FV}{PV}=\prod_{i=n}^n(1+xR_i)$$ To solve for the Kelly criterion, we have to find an x such that we get the best continuously compounding rate. We take the natural log of our returns: $$ ln \Biggl(\frac{FV}{PV}\Biggr)= ln\Biggl(\prod_{i=n}^n(1+xR_i)\Biggr)$$ We proceed to find an x that maximizes our compounding rate. This gives us the Kelly criterion from time value of money: $$ \mathop{\arg\,\max}\limits_x \Biggl[ ln\Bigl(\prod_{i=n}^n(1+xR_i)\Bigr) \Biggr]$$ To use our example of a 50/50 outcome with a 200% gain on heads and a 100% loss on tails, we could take the derivative to get the highest value:

$$ \frac{d}{dx} \Biggl[ ln\Bigl( (1+2x)(1-1x)\Bigr) \Biggr]$$ $$ \frac{d}{dx} \Biggl[ ln(1+2x)+ ln(1-1x) \Biggr]$$ $$ \frac{2}{2x+1} - \frac{1}{1-x} $$ $$ x=0.25 $$

This is exactly the same 0.25 Kelly bet we solved for before in our coinflip example. We can apply this concept to hundreds of data points and outcomes without the need to solve for derivatives by simply letting a computer solve for the maximum value of x through excel's solver or a coding language. Here's an example in Excel where one can substitute one's own data for future returns and calculate the Kelly criterion with the example above as default.

Kelly Criterion for Portfolio Construction

The Kelly criterion can be further extended to create portfolios that maximize the rate of compounding of multiple assets by adjusting the weights of a portfolio. This approach is different from Modern Portfolio Theory, which does not target compounding when adjusting weights. To solve for a Kelly portfolio with two assets (a,b) and weights (wa+wb=1) we can start with the future value of our portfolio: $$ FV_\pi=PV_\pi(1+w_a R_a +w_b R_b)$$ If the weight of asset a is 1, then weight of asset b is 0 and the above formula just simplifies to our simple time value of money formula: $$ FV_\pi=PV_\pi(1+w_a R_a)=PV_\pi(1+R_a)$$ If the weight of asset b is 1, then weight of asset a is 0 and we get: $$ FV_\pi=PV_\pi(1+w_b R_b)=PV_\pi(1+R_b)$$ Seeing how this dynamic plays out, we can now move the present value to the left and take the natural log to find the best compounding rate: $$ ln \Biggl(\frac{FV_\pi}{PV_\pi}\Biggr)= ln\Biggl(\prod_{}^{}(1+w_a R_a +w_b R_b)\Biggr) $$ $$ \mathop{\arg\,\max}\limits_w \Biggl[ ln\Biggl(\prod_{}^{}(1+w_a R_a +w_b R_b)\Biggr) \Biggr]$$ Maximizing the above equation will result in the best weights for compounding in the long run. This can be done by taking the derivative with respect to w or allowing a computer to find the value for w through a finite difference method. To use an example, suppose asset a has returns Ra and b has returns Rb: $$ R_a=[t_1:30\%, t_2:-15\%] $$ $$ R_b=[t_1:-5\%, t_2: \quad 20\%] $$ In our example as a goes up, b goes down. We wish to find the weights that will give us the best compounding rate for our portfolio. $$ FV_\pi=PV_\pi(1+30\%w_a -5\%w_b )(1-15\%w_a +20\%w_b )$$ $$ ln \Biggl(\frac{FV_\pi}{PV_\pi}\Biggr)= ln\Bigl((1+30\%w_a -5\%w_b)(1-15\%w_a + 20\%w_a )\Bigr) $$ $$ \mathop{\arg\,\max}\limits_w \Bigl[ ln\Bigl((1+30\%w_a -5\%w_b)(1-15\%w_a + 20\%w_a )\Bigr) \Bigr]$$ Running this calculation while plugging different values of w to get the highest compounding rate, visually this process appears as:

We find that the highest compounded rate for our portfolio is given by the following weights: $$ w_a=35\% $$ $$w_b=1-w_a=65\% $$ An Excel version of the above example is available here . If we have multiple assets and wish to diversify while maximizing our compounding growth, we can write out the Kelly portfolio as follows: $$ \mathop{\arg\,\max}\limits_w \Bigl[ ln\Bigl(\prod_{t}^{}(1+ \sum_{i}^{}w_i R^i_t )\Bigr) \Bigr]$$ $$ \lambda_1 : \sum_{i}^{}w_i=1 $$ $$ \lambda_2 : -1 \le w_i \le 1 $$ Solving for multiple weights is not simple in Excel and requires coding. Python code for constructing a Kelly portfolio for constructing multiple assets is available below.

 
import numpy as np
from scipy.optimize import minimize
import math


def objective(x, sign=-1.0):
    w1=x[0]
    w2=x[1]
    w3=x[2]
    a=np.array([0.3,-.15])
    b=np.array([-0.05,0.2])
    c=np.array([0.05,0.1])
    fx=math.log(np.prod(1+w1*a+w2*b+w3*c))
    return sign*(fx)

def weight_sum(x):
    return x[0]+x[1]+x[2]-1.0

b=(-1,1)
bounds=(b,b,b)

cons={'type': 'eq', 'fun': weight_sum}

x_default=np.zeros(3)
sol = minimize(objective, x_default,method='SLSQP', bounds=bounds, constraints=[cons])

print sol
print 'Kelly portfolio weights are as follows ' + str(sol.x*100)
 

Our three assets in the code example are: $$ R_a=[t_1:30\%, t_2:-15\%] \quad R_b=[t_1:-5\%, t_2: 20\%] \quad R_c=[t_1:5\%, t_2: 10\%] $$ The weight solution for such a Kelly portfolio for maximum compounding of 14.46% becomes: $$ w_a=25.64\% \quad w_b=39.10\% \quad w_a=35.26\% $$ Additionally, the Kelly portfolio weight solution also gives us the minimum compounding standard deviation, which makes perfect sense since in order to best compound a process in the long run, it must avoid volatility as much as possible.

Summary on Kelly usage:

Next