Introduction
Roulette is a game characterized by pure chance and probability, and I came across it shortly after taking a course in engineering probability. This prompted me to look into the game and its different strategies, and to try and make a model that will get me the best results.
Background
Roulette is a popular casino game of chance that involves a spinning wheel divided into numbered and colored pockets. Players place bets on where a small ball will land after the wheel comes to a stop. Players have multiple betting options, including wagering on specific numbers, colors, or groups of numbers. Payouts in roulette are determined by the probability of a particular outcome occurring, with more specific bets yielding higher payouts; for instance, correctly predicting an individual number results in a higher payout than betting on a broader category such as red or black.
There are two versions of Roulette commonly played: American and European.
- American Roulette wheel: 38 slots with two green slots
- European Roulette wheel: 37 slots with one green slot
This slight variation changes the odds of certain bets, as you can see in the table.
The Martingale Strategy
Suppose we have a game where the payout for a win is 1:1, like betting on a color in Roulette. The Martingale strategy involves doubling a bet every time a loss is faced. Let's say you bet $10. If you win, you earn $10. If you lose, you double your bet to $20. If you win the new bet, you will have lost $10 and won $20, giving you a net profit of $10. So with a string of losses, using the Martingale strategy, only one win is needed to put you at a positive net profit.
Term Definition
There are a few terms I'll be using throughout this article that I will define here:
- Stack: Amount of money you have to make bets with
- Initial Stack: Amount of money that you have before your first bet
- Conversion Rate: Percentage of games that end with positive return
Challenge
The problem I wanted to solve is this: Given an initial stack, what is the maximum/optimal initial Martingale bet size?
There are many different subsets of problems that exist within this one, but we will narrow down our focus to a specific problem: Given an initial stack, what is the maximum initial Martingale bet size with a 90% certainty of positive return?
Context: In solving this problem, bets will only be made on outside bets (betting on a color) and I will be simulating under American Roulette conditions. Outside bets have a slightly less than 50% chance of winning and the payout for an outside bet win is equal to the size of the bet. In this way, we can model each game of roulette as a Bernoulli random variable with a discrete probability distribution. I will be using Python to run simulations.
Approach
1. Data Generation
Here are the steps I took in solving this problem with simulation:
Step 1: Create a function that simulates one game of roulette and returns the new stack size.
def roulette(stack_size, bet_size, win_probability):
...
return updated_stack_size
Step 2: Create a function that simulates a chain of roulette games under the Martingale strategy. The bet size will double if a loss occurs. The function will return a list of values representing the stack size after each game of roulette.
def martingale(stack_size, bet_size, win_probability):
...
return [stack_sizes]
Step 3: Create a function that will simulate many Martingale chains at different bet values. In my case, I want to simulate Martingale chains with initial stack = 100, bet values from 0 to 100 at intervals of 0.1, and 20,000 simulated chains at each bet value.
def conversion_rates_sim(stack_size = 100, bet_values = np.linspace(0,100,1001), num_sims = 20000):
...
return [bet_values], [conversion_rates]
2. Data Analysis
Looking at the data we generated, we can see a unique behavior. The data splits into two trends from bet sizes between 0 and 30, and there is a piecewise behavior after bet sizes of 30. We are going to look into bet sizes between 0 and 30, as that range of bet sizes covers the conversion rates between 0.7 and 1.
Specifically, I am simulating 1329 bet sizes linearly spaced between bet size 0 and 33.2, with 20,000 simulations at each bet size:
conversion_rates_sim(stack_size = 100, bet_values = np.linspace(0,33.2,1329), num_sims = 20000)
The data seems to fit two trend lines, but I will be taking the average trend to model the true value. I will be fitting a second-degree polynomial regression line over the data.
Model: The model I will use to approximate the function of bet size vs. conversion rate is the following:
Let x = bet size, y = conversion rate
y = -0.014156x² + 0.00016576x + 0.9991425
Work in progress. To be continued!