Kelly criterion with more than two outcomes

Return to the derivation of the Kelly criterion: Suppose you have $n$ outcomes, which happen with probabilities $p_1$, $p_2$, ..., $p_n$. If outcome $i$ happens, you multiply your bet by $b_i$ (and get back the original bet as well). So for you, $(p_1, p_2, p_3) = (0.7, 0.2, 0.1)$ and $(b_1, b_2, b_3) = (-1, 10, 30)$.

If you have $M$ dollars and bet $xM$ dollars, then the expected value of the log of your bankroll at the next step is $$\sum p_i \log((1-x) M + x M + b_i x M) = \sum p_i \log (1+b_i x) + \log M.$$ You want to maximize $\sum p_i \log(1+b_i x)$. (See most discussions of the Kelly criterion for why this is the right thing to maximize, for example, this one.)

So we want $$\frac{d}{dx} \sum p_i \log(1+b_i x) =0$$ or $$\sum \frac{p_i b_i}{1+b_i x} =0.$$

I don't see a simple formula for the root of this equation, but any computer algebra system will get you a good numeric answer. In your example, we want to maximize $$f(x) = 0.7 \log(1-x) + 0.2 \log(1+10 x) + 0.1 \log (1+30 x)$$ enter image description here

I get that the optimum occurs at $x=0.248$, with $f(0.248) = 0.263$. In other words, if you bet a little under a quarter of your bankroll, you should expect your bankroll to grow on average by $e^{0.263} = 1.30$ for every bet.


David Speyer provided an outstanding response that really helped me out during a project, and I thought as a thank you I would provide the code I generated using his approach. Included in the code is a method to solve for the correct percentage using Newton's method and it is very fast. It is coded in MATLAB, and while currently formatted as a script, commenting out the definition of matCurr (which uses the values defined for this question) and uncommenting the function definition will have it operate as a function. Also commented out at the bottom is the ability to plot the ln(growth) in terms of the percentage wagered, as David also demonstrated above:

% function valPercent = funcKellyCriterionThroughNewton(matCurr)
% Peirano, Daniel
% [email protected]

% This function will get argument matCurr as defined in
% scriptOptimalTourney so that the first column defines b and the second
% column defines p.  Using the equation defined at
% http://math.stackexchange.com/questions/662104/kelly-criterion-with-more-than-two-outcomes
% combined with Newton's approach, an attempt will be made to solve for 0
% which should be the location of the maximum pay out. 

% Checks for sum of percent greater than 1, and if the matrix isn't
% profitable will also be done.


% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % Debugging
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% clearvars -except matCurr

matCurr = [-1, .7; 10, .2; 30, .1];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Constants
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
valThreshold = 0.000001;
valInitialValue = 0.25;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Code
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Normalize the percentage to 1
if sum(matCurr(:,2)) ~= 1
    matCurr(:,2) = matCurr(:,2) / sum(matCurr(:,2));
end

% Check if the matrix is even profitable
if sum(prod(matCurr, 2)) <= 0
    valPercent = 0;
    return
end

valPast = 0;
valNext = valInitialValue;
%[b p]
b = matCurr(:,1);
p = matCurr(:,2);

boolBump = 0;
while abs(valPast-valNext) > valThreshold
    valPast = valNext;


    valNumerator = sum(p.*b./(1+b*valPast));
    valDenominator = sum(-b.^2.*p./(1+b*valPast).^2);

    valNext = valPast - valNumerator/valDenominator;

    if valNext < 0 && ~boolBump     %Only bump it once
        valNext = 0;
        boolBump = 1;
    end
end

valPercent = valNext;

% x=linspace(0,1,1000);
% y=zeros(size(x));
% for i=1:length(x)
%     y(i) = sum(p.*log(1+b.*x(i)));
% end
% 
% plot(x,y)