/// <summary>
/// Determines the optimal bet size (in a series of bets) to minimise risk & maximise returns...
/// Assumptions:
/// Given a profitable situation to begin with...(and the probability estimate is accurate)
/// No associated transaction costs or taxes
/// If you lose - then you lose all of the bet (and not just a portion)
/// See. http://en.wikipedia.org/wiki/Kelly_criterion
/// </summary>
/// <param name="P">Probability of winning the bet. A number between [0,1]</param>
/// <param name="b">Potential earnings/profit/payout or the odds expressed as a decimal</param>
/// <param name="availableBankroll">The amount of capital available for gambling. Default value is 50</param>
/// <returns></returns>
public static string GetKellyCriteria(double P, double b, double availableBankroll = 50)
{
#region Sanitation
if( (P<0.0) || (P>1.0) )
throw new Exception ("Probability should be between [0,1]");
if (availableBankroll == 0)
throw new Exception("Available bankroll is required");
if (b == 0)
throw new Exception("Potential payout is required");
#endregion
#region Kelly Criteria Calc
double q = 1 - P;
double kellyValue = ((P * b) - q) / b;
double optimalBet = Math.Round(((kellyValue * availableBankroll)), 2);
#endregion
#region Interpretation
if (kellyValue > 0)
{
return string.Format("Kelly Criteria: +{0}%. Optimal bet = +{1} out of {2}. Consider betting...", Math.Round(kellyValue*100.0, 2), optimalBet, availableBankroll);
}
else if (kellyValue == 0)
{
return string.Format("Kelly Critria: {0}%. Optimal bet = {1}. No edge. Do nothing.", Math.Round(kellyValue*100.0, 2), optimalBet);
}
else
{
return string.Format("Kelly Criteria: {0}%. Optimal bet = -{1}. Consider laying if available.", Math.Round(kellyValue*100.0,2), optimalBet);
}
#endregion
}