Imagine the following scenario:
You’re offered to flip a coin. If it lands on heads, you receive $10, but if it lands on tails, you have to pay $5. Would you take the bet? You likely would, since you know that on average, you are making money.
Now imagine this: Once again, you flip a coin. If it lands on heads this time, you receive $100,000, but if it lands on tails, you’re required to pay $50,000. Would you do it? The game itself didn’t change, only the amount you play for did. But because you know how much losing $50,000 would hurt you and your life, the smart move probably is to miss out on the expected value and prioritize safety.
Our bankroll contract faces the same decision
Whenever a bet (actually a roll, more on that later) is placed in our bankroll contract is placed, it needs to decide whether to accept it or not. Two opposing needs have to be considered: On the one hand, we want to offer 3rd party developers, and consequently our end users to place big bets if they are feeling lucky. And because of the increased expected value gained, that also benefits the bankroll investors. On the other hand though, nobody benefits when the bankroll gets crippled by just a few unlucky bets. The players couldn’t continue playing the games that they want, and the investors would lose a significant part of their investment.
This is where bankroll management comes in.
What we need is an algorithm, that takes into account both sides and finds a compromise that benefits everyone. To be precise, an input (the data of one roll) has to be transformed into a binary value: Should this roll be accepted or not. Traditionally, casinos have often used fixed borders for deciding which bets to accept. For example, if you sit down at a blackjack table, there might be a fixed maximum bet of $500 per hand. This is a sufficient solution for casinos only offering a single game and which have a relatively stable bankroll.
Neither of these prerequisites are fulfilled by our contract. The amount of WAX in our bankroll is subject to change significantly, as new investors come in and old investors cash out. And the bets that are available aren’t static. In fact, like hinted at earlier, the contract doesn’t just accept single bets but rolls. A roll is a combination of multiple bets, that all bet on the same result.
For example, there could be a roll with a possible result between 1–100. Player A could bet 50 WAX on the result being between 1–50, Player B bets 20 WAX on the result beeing between 20–40 and Player C bets 80 WAX on the result being between 40–100.
As you can see, these bets can overlap and cancel each other out. All of this makes for a scenario where traditional bankroll management methods simply don’t work.
We created our own system. And here’s how:
To start off, we coded a small Python script to simulate rolls with fully customizable bets. This allowed us to get a first overview about how overlapping bets would interact with each other and how that would affect the risk for the bankroll.
We had to choose some sort of metric that we wanted our bankroll management to optimize towards. What we chose was the following:
After 100 consecutive rolls
The odds of the bankroll losing more than half of its initial value
Should not be higher than 10%-15%
Those 3 variable are more or less arbitrary, we merely found that they produced the results that we desired.
At first, we looked at the simplest case: One bet per roll
By manually trying out different bet values for various different multipliers, we collected data on how big single bets could get to be in the 10–15% window that we specified earlier. We got the following values:
The correlation is still difficult to see, but when putting both axis on a logarithmic scale…
… the correlation becomes obvious. This let us know that we could likely find a relatively simple graph that accurately matches our values. After using various graph fitting algorithms and smoothing out their outputs to be more readable, we got a graph that is very close to the values that we found:
percentage = 5 / sqrt(multiplier - 1) - 0.2and:required bankroll = bet amount / (percentage / 100)
So we found a solution for single bets!
But how can this solution be applied to multiple bets per roll? For that, it is important to understand how two bets can be combined in ranges. For example, let’s say the max possible result is 100:
Bet A 50 Wax - 1-50 (odds: 50%) - 100 Wax payout
Bet B 20 Wax - 41-65 (odds: 25%) - 80 Wax payoutCombined:
Total Bet: 70 WaxRange 1, 1-40 (odds: 40%) - 100 Wax payout
Range 2, 40-50 (odds: 11%) - 180 Wax payout
Range 3, 51-65 (odds: 15%) - 80 Wax payout
Range 4, 66-100 (odds: 34%) - 0 Wax payout(later, only ranges with a payout greater than the total bet are considered)
The idea is two replace two (or more) different bets, that have to be evaluated individually, into ranges, of which exactly one will “win”.
The question now is: How do we calculate the required bankroll for those ranges? This is probably the part that seems the least intuitive. The ranges are converted back to bets. Let’s look at the complete process for the first range:
effective profit = 100 Wax - 70 Wax = 30 Wax
effective bet = 100 Wax * 0.40 = 40 Waxeffective payout = effective profit + effective bet = 70 Waxbet amount = odds * effective payout = 0.40 * 70 Wax = 28 Wax
bet multiplier = 1 / odds = 1 / 0.40 = 2.50
We now have both the bet amount and the multiplier, which is all that we need to calculate the required bankroll (for a single bet).
percentage = 5 / sqrt(multiplier - 1) - 0.2
percentage = 5 / sqrt(2.5 - 1) - 0.2
percentage = 3.88required bankroll = bet amount / (percentage / 100)
required bankroll = 28 Wax / (3.88 / 100)
required bankroll = 721 Wax
Do we simply add the required bankrolls of each of these bets now?
No, not quite. Linearly adding these required bankrolls does work when the different bets all have the same bet amount and multiplier. However, it doesn’t if one bet requires a significantly higher bankroll that the others. This makes intuitive sense:
Say you have a 100 WAX bet with a 2x multiplier that requires a bankroll of ~2000 WAX. Now add a second 50 WAX bet with the same 2x multiplier. Whether the bankroll wins or not is still exclusively decided by the outcome of the 100 WAX bet. The 50 WAX bet still has a statistical effect, but not as high as half that of the 100 WAX bet. Therefore, the required bankroll isn’t 3000 WAX, but actually closer to ~2400 WAX
It turns out that the risk associated with a bet grows proportional to the cube of its’ required bankroll value. For a static bankroll, the risk of losing more than 50% of the bankroll after 100 bets goes up by 8x if the bet doubles.
This leads us to the solution: Summing the cubed required bankroll values of the range bets, and taking the cube root of that sum. This will ensure that smaller bets don’t throw off the total required bankroll value more than they should.
We admit that this might be a little much to take in all at once.
That’s why we have published a Python script for you to play with here. It includes both the code for calculating the minimum required bankroll for any amount of fully customizable bets, as well as a part that statistically analyzes the bets by running thousands of simulations.
Note that the code looks a little different than what is described in this article. It still does precisely the same.
We hope that you enjoyed this deep dive into our bankroll management.
In the next few days, we will also be covering
- A technical look at the pink.network bankroll contract
- Guide: Getting started with the pink.network API
Are you interested in keeping up to date with our project? Follow us on Twitter and you won’t miss any news. Are you interested in using our bankroll contract/ API to build your own awesome site? Check out our documentation, and feel free to contact us. We will be glad to assist you!