Roulette: The Martingale Strategy

The Martingale strategy appears to always end in positive earnings, regardless of how unlucky a string of spins may be but is the strategy actually profitable?

Posted by Alfred Prah on March 15, 2020 · 14 mins read

Introduction

The Martingale strategy appears to always end in positive earnings, regardless of how unlucky a string of spins may be but is the strategy actually profitable?

Parameters Values
Starting Budget (B) $200
Winnings threshold for stopping (W) $300 (Starting budget + $100 winnings)
Time threshold for stopping (L) 1000 plays
Casino’s maximum wager (M) $100

To make these parameters more practical, let's create a user named Tom.
  • B: Tom walks into the casino with $200
  • W: Tom is happy to leave the casino with A $100 profit. Ie, the $200 he started with + $100 from playing
  • L: Tom will stop playing after 1000 plays
  • M: Tom cannot wager more than $100 in a single play

Few things to note/remember:
  • B: The range of any probability is 0-1. An impossible event has a probability of 0 and an event that is absolutely certain to occur has a probability of 1
  • W: Even though the game of gambling is generally considered to be 50/50, the casino always has the upper hand because the 2 green pockets in the total 38 pockets result in the casino's having a probability of 20/38 = 0.53 compareed to Tom's 18/38 = 0.47

From a similation with the B,W,L and M values listed above, we get the following output:

Estimated probability of walking out with extra cash

#### > mean(walk_out_money > 200) #### [1] 0.5096 ### Estimated earnings #### > mean(walk_out_money - 200) #### [1] -47.1043 This means: - The probability of Tom leaving the casino with an amount more than the $200 he started with, is about 50-51%. this is calculated by taking the average of the number of simulations that result in Tom's having more than $200 in hand. Regardless of how many different simulations are run, the range of the probability and the estimated earnings stay the same. - We can also see that from this particular simulation, Tom lost money. Tom actually lost an average of $47 per series. This was calculated by subtractiong Tom's "walk out money" from the $200 he started with, after each simulation, and taking the average of the values. To calculate the average earnings, the sample code that was provided used the values assigned to each of the parameters: B, W, L, M. During the simulation, for the hypothetical "1000" plays, Tom's budget increases or decreases, depending on whether a Red or Black pocket is the resulting outcome. The code includes a for loop, which is expected to run from 1:L where L is the "Time threshold for stopping". In this case, 1000 plays. The outcome of the simulation, black or red, is returned to the function "one_play", and the values of the parameters are updated before the next simulation, with the help of the function "get_last". Simplifications or other sources of uncertaunty: - The gambler wages a single dollar for every single play. - The only conditions for termination are that the gambler becomes bankrupt, reaches his target profit, or reaches his play limit. No other conditions are accounted for. - There is no money on standby or on reserve for the gambler. When he/she is out of money, he/she is out of the game. - The fact that only 36 pockets are accounted for. Ie, the simulation does not account for the fact that the casino is a real winner, with a probability of 20/38. ```r library(tidyverse) ``` ```r #' A single play of the Martingale strategy #' #' Takes a state list, spins the roulette wheel, returns the state list with updated values (for example, budget, plays, etc) #' @param state A list with the following entries: #' B number, the budget #' W number, the budget threshold for successfully stoping #' L number, the maximum number of plays #' M number, the casino wager limit #' plays integer, the number of plays executed #' previous_wager number, the wager in the previous play (0 at first play) #' previous_win TRUE/FALSE, indicator if the previous play was a win (TRUE at first play) #' @return The updated state list one_play <- function(state){ # Wager proposed_wager <- ifelse(state$previous_win, 1, 2*state$previous_wager) wager <- min(proposed_wager, state$M, state$B) # Spin of the wheel red <- rbinom(1,1,18/38) # Update state state$plays <- state$plays + 1 state$previous_wager <- wager if(red){ # WIN state$B <- state$B + wager state$previous_win <- TRUE }else{ # LOSE state$B <- state$B - wager state$previous_win <- FALSE } state } #' Stopping rule #' #' Takes the state list and determines if the gambler has to stop #' @param state A list. See one_play #' @return TRUE/FALSE stop_play <- function(state){ if(state$B <= 0) return(TRUE) if(state$plays >= state$L) return(TRUE) if(state$B >= state$W) return(TRUE) FALSE } #' Play roulette to either bankruptcy, success, or play limits #' #' @param B number, the starting budget #' @param W number, the budget threshold for successfully stoping #' @param L number, the maximum number of plays #' @param M number, the casino wager limit #' @return A vector of budget values calculated after each play. one_series <- function( B = 200 , W = 300 , L = 1000 , M = 100 ){ # initial state state <- list( B = B , W = W , L = L , M = M , plays = 0 , previous_wager = 0 , previous_win = TRUE ) # vector to store budget over series of plays budget <- rep(NA, L) # For loop of plays for(i in 1:L){ new_state <- state %>% one_play budget[i] <- new_state$B if(new_state %>% stop_play){ return(budget[1:i]) } state <- new_state } budget } # helper function get_last <- function(x) x[length(x)] # Simulation walk_out_money <- rep(NA, 10000) for(j in seq_along(walk_out_money)){ walk_out_money[j] <- one_series(B = 200, W = 300, L = 1000, M = 100) %>% get_last() } # Walk out money distribution hist(walk_out_money, breaks = 100) # Estimated probability of walking out with extra cash mean(walk_out_money > 200) # Estimated earnings mean(walk_out_money - 200) ``` ### How the computer simulation is used to estimate the average number of plays before stopping ```r total_plays <- rep(NA, 10000) for(j in seq_along(total_plays)){ total_plays[j] <- one_series(B = 200, W = 300, L = 1000, M = 100) %>% length } mean (total_plays) ``` The code chunk above is one of my favorites in the entire simulation. "total_plays" uses the default values of B, W, L and M to run a simulation 10,000 times. "total_plays" employs a for loop which creates a vector that contains the duration of each simulation. This creates the opportunity to calculate the average number of plays before stopping. Ie, mean(total_plays). This calculated average means that on average, by the 201st play, out of the 1000 possible plays, 1 of 3 things happen: - Tom becomes bankrupt (B<0). - Tom reaches his target profit (winnings, W). - Tom reaches his play limit (L). ### Evolution of earnings over a series of wagers A graph to show how the gambler's earnings evolve over a series of wagers at the roulette level: Since we are using simulations, I am plotting several graphs with the same inputs so that we can have a "general" idea of the graph that is produced from the simulations The observed trend is that there is a positive correlation between the wager numbers and the earnings. ```r s1<- one_series(B = 200, W = 300, L = 1000, M = 100) plot(s1, type = "b", xlab = "wager number", ylab = "budget left") ```

NOTE

The average earnings of Tom is calculated after 1 of the following conditions are met: - Tom becomes bankrupt (B<0) - Tom reaches his target profit (winnings, W). - Tom reaches his play limit (L). To calculate this, the code returns Tom's remaining money (budget) after each iteration to the variable called stop_play, which runs through the 3 different conditions required for play termination. The conditions are: - If the budget, B is less than 0, terminate the game. - If Tom places a bet 1000 times, L, terminate the game. - If Tom's current desired winning threshold, W, is realized, terminate the game. If none of these 3 conditions are aopplicable, continue the simulation. Code chunk to determine if the simulation should be terminated, depending on the whether the conditions above are met. ```r stop_play <- function(state){ if(state$B <= 0) return(TRUE) if(state$plays >= state$L) return(TRUE) if(state$B >= state$W) return(TRUE) FALSE } ```

Varying a Parameter (L)

- The reason why a good number of people believe in the Martingale Strategy is because the total amount lost prior to the current wager can be recovered, provided that the gambler has enough money to keep playing. Is this belief actually true? If proven to be false, I believe that it will discredit the Martingale Strategy. In the graph below, I supply different values of L, the Time Threshold for Stopping, to the function "one_series." This function takes in the the parameters: B, W, L and M, and uses the outputs to update the number of plays, the previous wager and the previous win. Each time, the updated outputs are passed on to the function "stop_play". "Stop play" evaluates the current value of each of the parameters and terminates a game play if any of the conditions for termination are met. (inputs for "stop_play" referenced in the previous code chunk). ```r Ls <- c(10,50,100,400,600,800,1000) earnings <- vector() for (i in 1:length(Ls)){ earnings[i] <- one_series(B = 200, W = 300, L = Ls[i], M = 100) %>% get_last() - 200 } plot(Ls,earnings, type = "b", xlab= "Time Threshold for Stopping, L", ylab = "Earnings") ```

Limitations of the simulation

- The most obvious limitation of our simulation is the arbitrary profit limit. In both cases, we set this value at $100, meaning that each run of games stopped after the player budget reached $100 above the initial budget. - In reality, gamblers would all have different budgets and earnings thresholds. It would be very difficult to generate averages such as those above from real-world scenarios, given the variation in this and other factors. - Another limitation of the simulation is the casino limit on maximum wager. Again, this would vary significantly in a real-world situation, as different casinos have different rules.

Conclusion

- From the above graph, I can see why so many people choose to believe in the "Martingale Strategy". As I mentioned above, the strategy appears to always end in positive earnings, regardless of how unlucky a string of spins may be. However, a key determining factor of this is whether the player has enough money to keep playing. All in all, the strategy presents an interesting approach to what appears to be a game of chance (with the casino having an upper hand, of course). Players around the world believe that employing this strategy gives you a little more than a 50/50 shot at leaving the casino with a profit but the simulations above, together with the different values for the Threshold for Stopping a simulation we explored, prove that even at the 1000th play, there is no guarantee that a player would leave the casino with any earnings. Ie, The player could leave with more money than they entered with, or leave with less money. Unfortunately, the Martingale Strategy is no guarantee.