Making big, smart(er) bets

I’ve been trying to code an algorithm to suggest bets in 1X2 (weighted) games.

Basically, each game has a set of matches (home vs away teams):

  • 1: home wins
  • X: draw
  • 2: away wins

BWin 1X2 Betting Game

For each match and symbol (1, X and 2), I will assign a percentage that represents the chances / likelihood of that symbol being the correct match outcome. Here is an array representing the structure:

$game = array
(
    'match #1' => array // stdev = 0.0471
    (
        '1' => 0.3,     // 30%     home wins
        'X' => 0.4,     // 40%     draw
        '2' => 0.3,     // 30%     away wins
    ),

    'match #2' => array // stdev = 0.4714
    (
        '1' => 0.0,     //   0%    home wins
        'X' => 0.0,     //   0%    draw
        '2' => 1.0,     // 100%    away wins
    ),

    'match #3' => array // stdev = 0.4027
    (
        '1' => 0.1,     //  10%    home wins
        'X' => 0.0,     //   0%    draw
        '2' => 0.9,     //  90%    away wins
    ),
);

I also calculate the standard deviation for each bet (commented in the above snippet); higher standard deviations represent a higher certainty, while the matches with the lowest standard deviations translate to a higher level of uncertainty, and, ideally, should be covered with a double or triple bet, if possible.

The following pseudo-algorithm should describe the overall workflow:

for each match, sorted by std. dev         // "uncertain" matches first
    if still can make triple bets
        mark top 3 symbols of match        // mark 3 (all) symbols
    else if still can make double bets
        mark top 2 symbols of match        // mark 2 (highest) symbols
    else if can only make single bets      // always does
        mark top symbol of match           // mark 1 (highest) symbol

So far so good, but I need to tell the algorithm how much I want to spend. Lets say a single bet costs 1 in whatever currency, the formula to calculate how much a multiple bet costs is:

2^double_bets * 3^triple_bets * cost_per_bet (= 1)

Obviously, the algorithm should try to allocate as much money available as possible into the bet suggestion (it wouldn’t make much sense otherwise), and now is where this gets trickier…

Lets say I wanna pay a maximum of 4, listing all possible multiples in PHP (@ IDEOne):

$cost = 1; // cost per single bet
$result = array();
$max_cost = 4; // maximum amount to bet

foreach (range(0, 3) as $double)
{
	foreach (range(0, 3) as $triple)
	{
		if (($double + $triple) <= 3) // game only has 3 matches
		{
			$bets = pow(2, $double) * pow(3, $triple); // # of bets

            $result[$bets] = array
            (
                'cost'      => $bets * $cost, // total cost of this bet
                'double'    => $double,
				'triple'    => $triple,
            );

            if ($result[$bets]['cost'] > $max_cost)
			{
				unset($result[$bets]);
            }
        }
    }
}

ksort($result);

Yields the following output:

Array
(
    [1] => Array
        (
            [cost] => 1
            [double] => 0
            [triple] => 0
        )

    [2] => Array
        (
            [cost] => 2
            [double] => 1
            [triple] => 0
        )

    [3] => Array
        (
            [cost] => 3
            [double] => 0
            [triple] => 1
        )

    [4] => Array
        (
            [cost] => 4
            [double] => 2
            [triple] => 0
        )
)

The Problem

If I choose to play the maximum amount of money available (4) I would have to bet with two doubles, if I use the pseudo-algorithm I described above I would end up with the following bet suggestion:

  • match #1 => X1
  • match #2 => 2
  • match #3 => 12

Which seems sub-optimal when compared to a triple bet that costs 3 and covers more uncertainty:

  • match #1 => X12
  • match #2 => 2
  • match #3 => 2

The above example gains even more relevance if you consider that match #3 odds could be:

$game['match #3'] = array // stdev = 0.4714
(
    '1' => 0.0,           //   0%    home wins
    'X' => 0.0,           //   0%    draw
    '2' => 1.0,           // 100%    away wins
);

In this case I would be wasting a double for no good reason.

Basically, I can only choose the biggest (possibly stupid) bet and not the smartest, biggest bet.

I’ve been banging my head against the wall for some days now, hoping I get some kind of epiphany but so far I’ve only been able to come up with two half-[bad-]solutions:


1) Draw a “Line”

Basically I would say that matches with a stdev lower than a specific value would be triple, matches with a stdev a big higher would be double bets and the rest single bets.

The problem with this, of course, is finding out the appropriate specific boundaries – and even if I do find the perfect values for the “smartest” bet, I still don’t know if I have enough money to play the suggested bet or if I could make a even bigger (also smart) bet…


2) Bruteforce

I came up with this idea while writing this question and I know it won’t make perfect sense in the context I described but I think I could make it work using somewhat different metrics. Basically, I could make the program suggest bets (# of triple and double bets) for every possible amount of money I could play (from 1 to 4 in my example), applying the pseudo-algorithm I described above and calculating a global ranking value (something like % of symbols * match stdev – I know, it doesn’t make sense).

The bet with the highest ranking (covering uncertainty) would be the suggested bet. The problem with this approach (besides the fact that it doesn’t make any sense yet) is that the games my program is going to work with are not limited to 3 matches and the number of double and triple bet combinations for those matches would be substantially higher.


I feel like there is an elegant solution, but I just can’t grasp it…

Any help cracking this problem is greatly appreciated, thanks.


There seems to be some confusion regarding my problem, I’ve already addressed this in this question and also in the comments but the misinterpretation still seems to prevail, at least to some.

I need to know how many triple, double and single bets I will play
for a specific game
(all matches). I already know what
symbols I want to play by looking at each match individually.

Answer

I think I came up with a workable bruteforce solution, it goes like this:


  • 1) calculate every possible combination of multiple bets I can make

For the example and amounts I provided in my question, this would be:

  • 3 single, 0 double, 0 triple = equivalent to 1 single bet
  • 2 single, 1 double, 0 triple = equivalent to 2 single bets
  • 2 single, 0 double, 1 triple = equivalent to 3 single bets
  • 1 single, 2 double, 0 triple = equivalent to 4 single bets

  • 2) calculate the standard deviation of the symbol odds for every match

             |    1    |    X    |    2    |  stdev  |
             |---------|---------|---------|---------|
    Match #1 |   0.3   |   0.4   |   0.3   |  0.047  |
             |---------|---------|---------|---------|
    Match #2 |   0.1   |   0.0   |   0.9   |  0.402  |
             |---------|---------|---------|---------|
    Match #3 |   0.0   |   0.0   |   1.0   |  0.471  |
    

  • 3) for every multiple bet combination (step 1) compute a ranking using the formula:

    ranking = (#n(x) [+ #n(y) [+ #n(z)]]) / stdev(#n)

Where #n is a specific match and #n(x|y|z) is the ordered odds of the symbols.

  • Matches are processed from low to high standard deviations.
  • Individual symbols in each match are processed from high to low odds.

Test for a 1 single, 2 double, 0 triple bet:

  • (#1(X) + #1(1)) / stdev(#1) = (0.4 + 0.3) / 0.047 = 14.89
  • (#2(2) + #2(1)) / stdev(#2) = (0.9 + 0.1) / 0.402 = 2.48
  • #3(2) / stdev(#3) = 1.0 / 0.471 = 2.12

This bet gives me global ranking of 14.89 + 2.48 + 2.12 = 19.49.


Test for a 2 single, 0 double, 1 triple bet:

  • (#1(X) + #1(1) + #1(2)) / stdev(#1) = (0.4 + 0.3 + 0.3) / 0.047 = 21.28
  • #2(2) / stdev(#2) = 0.9 / 0.402 = 2.24
  • #3(2) / stdev(#3) = 1.0 / 0.471 = 2.12

Which gives me a global ranking of 21.28 + 2.24 + 2.12 = 25.64. 🙂


All the remaining bets will clearly be inferior so there is no point in testing them.

This method seems to work but I came up with it via trial and error and following my gut, I lack the mathematical understanding to judge whether it is correct or even if there is a better way…

Any pointers?

PS: Sorry for the bad formatting but the MD parser seems to be different from StackOverflow.

Attribution
Source : Link , Question Author : Alix Axel , Answer Author : Alix Axel

Leave a Comment