Size Matters – Kelly Optimization

The formula

When you have >50% chance to win in a game, how much money would you bet each time? If you bet 100% of your money, you may lose it all just because of bad luck; if you bet 1% every time, your capital could grow so slow that the game is not worth playing. According to Kelly Optimization Model (the original Kelly paper), the relationship between the probability of winning p and the optimal bet size f is:

— — — — — — — — — — — — — — — — —   GEEK ZONE  — — — — — — — — — — — — — — — — — — — —


— — — — — — — — — — — — — — — — —   GEEK ZONE  — — — — — — — — — — — — — — — — — — — —

A Quick Example

In this game, you put your bet and blindly pick one card out of a deck. If you got a spade, you would lose 100% of your bet; if you got anything else, you would gain 100%. So no matter how much you bet for each game, you either double it or lose it all. Theoretically, your expected return,  (1 / 4) * (-100%) + (3 / 4) * 100% = 50%, is in your favour. But in real world, if you lose all your money in just one game, you wouldn’t have any equity left to enjoy the infinite 50%s in the future.

To find out the optimal allocation in R:

f <- seq(0, 1, 1/1000)
test <- rep(1, 1000)
test[which(rbinom(1000, 1, 1/4) == 1)] <- -1
gain <- function(f) prod(1 + f * test)
rets <- sapply(f, gain)
plot(f, rets, type = 'l')

The test shows the optimal allocation that maximizes your total return in the long-run is 50%, which equals to the result by using Kelly:  3 /4 * 2 – 1 = 50%.

An Implementation

To find out if Kelly can help improve investment strategies, I plugged it into a RSI(14)50/50 model. The RSI(14) indicator, measures oversold and overbought with a percentage number, makes itself a good proxy for the chance to win (p in Kelly formula).

Note: Reminded by friend Mark Leeds, I noticed this implementation actually doesn’t meet all pre-conditions required by Kelly Criterion. Kelly Criterion is only applicable with a binomial outcome between 100% and -100% like in the example above. This implementation ignores that the gain/loss in trading is a variable that is proportional to initial investments. Although this test seems effective (probably because in this test the investor assumes he’s in a much more risky environment than he really is), the Kelly formula should be substituted by Optimal f (found in this journal) here.

And to better illustrate the effects brought by Kelly.

As shown above, Kelly strategy has the same winning rate as RSI(14) but much less volatile returns. By implementing this bet sizing strategy, we effectively reduced our exposure to the fat-tail risk of RSI(14).



The Value of Backtest

“The study of history lies at the foundation of all sound military conclusions and practice.” 
― Alfred Thayer Mahan, The Influence of Sea Power Upon History 1660-1783

If you are a commander of a modern warship, you probably have studied history and tactics of tall ships in a naval college. The purpose, obviously, is not for getting you prepared for a battle with tall ships and cannons. Instead, it’s to show you the evolution of sea warfare and build up your instincts as a sea wolf. From manpower and wind to nuclear power and steam, from muskets and cannon to CWIS and missiles, although the technology never stops changing, the importance of speed, timing, relative position, and fire power has been deciding the results of sea battles since the first time in history that two people fought in Canoes with their paddles.

Battle of Trafalgar – by Robert Taylor

Crossing the T Tactic used by Lord Nelson in Trafalgar

It’s a very good analogy for investors and backtests. A sound analyst should not get excited solely for good backtest results. He ought to know the reasons behind and what do they mean in real-time trading. An impressive backtests, in some cases, is probably not suitable for trading, but might be very valuable in terms of finding market behaviours and confirming insights in investments. If  possible, two equally good analysts living in different eras should draw the same conclusion through performing a backtest on Reuter’s carrier pigeons (read more) and modern HF trading.

On top of that, in order to fully utilize the value of backtest, I believe an analyst should be able to think in terms of arrays instead of separated numbers. The distribution of returns or drawdowns of a strategy usually contains more valuable information than its annualized return and volatility.


Monty Hall Paradox Test

The Monty Hall Paradox is an interesting probability problem I read online. The rules and discussion can be find here and you can actually play it here.

Although this binomial tree has well demonstrated why the player should always change his original choice in this game, a lot of people still belive the chance is always 50/50 no matter how you play. And I found their argument, based on the fact that the player will always have to choose one out of two doors at the end of the game, actually makes a lot sense intuitively, which makes it harder to argue against.

So why don’t we just make a test? And instead of manually testing it 20 or 30 times using an online simulator like the one above, why not to have a program that loops this game as many time as you want (or as your machine can bear).

In order to do that, I wrote a program in java. This program will ask you how many times you want to play the game and what strategy you want to stick with. Then it will start to simulate the game in the way you instructed and print out the final statistics. To make it completely fair, the program uses a random generator to decide which door the prize is hidden behind and which door the player chooses at the begining. The only thing that won’t change is the strategy you specify.

/*********************************** Java code ***********************************/
import acm.program.*;
import acm.util.*;

public class MontyHallGame extends ConsoleProgram {
	private int NUM_OF_CHOICES = 3;
	public static void main(String[] args) {
		new MontyHallGame().start(args);
	public void run() {
		setFont("Courier New-18-bold");
		while (true) {
			int trails = readInt("Time of experiments: ");
			boolean change = readBoolean("Always switch choice?(true/false): ");
			int wins = 0;
			int loses = 0;
			for (int i = 0; i < trails; i++) {
			/** Assign the prize to a random choice */
				int[] choices = new int[NUM_OF_CHOICES];
				for (int j = 0; j < choices.length; j++) {
					choices[j] = 0;
				int prize = rgen.nextInt(0, choices.length - 1);
				choices[prize] = 1;
			/** Make the first call and remove one of the wrong choices */
				int firstChoice = rgen.nextInt(0, choices.length - 1);
				int removedChoice = firstChoice;
				while (removedChoice == firstChoice || removedChoice == prize) {
					removedChoice = rgen.nextInt(0, 2);
			/** Decide to switch choice or not */
				int finalChoice = firstChoice;
				if (change) {
					while (finalChoice == firstChoice || finalChoice == removedChoice) {
						finalChoice = rgen.nextInt(0, choices.length - 1);
				if (finalChoice == prize) {
				} else {
			/** display results */	
			println("Wins: " + wins);
			println("Loses: " + loses);
			println("Winning chance: " + (double)wins / (double)trails * 100 + "%");
	// private instance random generator
	private RandomGenerator rgen = RandomGenerator.getInstance();
}/*********************************** Java code ***********************************/

So, here are the results of playing “no” strategy 5000, 10000, and 100000 times respectively. (“No” is equal to “false” in the program. Sorry I was too lazy to enumarte the booleans with strings.) The chance of winning are 33.28%, 32.87%, and 33.331%.

(Approxy wins: 33%)

And the results for “yes” strategy under the same conditions. The chance of winning are 65.92%, 66.91%, and 66.767%.

(Approxy chance to win: 66%)

And to sum it up.

I’m glad to see the results are consistant with the outcomes of the binomial tree and hopefully this can be a satisfying answer to the 50/50 group.


Initial Post

As a recent university graduate majored in Finance, I have a fascination for capital markets, statistics, and computer science.

I deem myself as a late starter among those people who seek real knowledge and discernible skills. But I will keep learning as well as posting.

I learned VBA, Java, and R mostly by myself. I will use them to test investment strategies or other decision-making models in this blog.

Image(Karel says hi.)