For context, you can read my previous post on alphadraft betting for CS:GO here.

After we have developed a concrete model for drafting our line-ups, we want to focus more on the bettor's bankroll management over time to minimize risk, maximize return and reduce our probability of ruin. In this blog post, I will first describe the typical scenarios behind Alphadraft contests and how that can be translated to our probability model for win/loss (Beta-Beta Model). We can then modify the standard Kelly Criterion to fit our case and calculate the optimal % bankroll to bet per game. Note that the concepts here can be applied to any contest with daily fantasy sports, not just eSports.

Common Betting Scenario

As with regular daily fantasy sports, the contests usually last within one day where you draft your best picks and earn points based on their performance. Usually, you are able to choose your wager (buy-in) and style of play (risk) for the same match ups that day (I'll refer to this as being a unique contest). The style of play on Alphadraft usually come in many forms:

Top 50% of contestants will win 1.8 times the buy-in. This is known as Half-Will-Win

Tournament style where approximately top 25% of contestants win at an increasing payout (Arcade/Tournament). For example, first place can have odds of 10 while 25th place usually break even out of 100 entrants.

Two contestants, highest scoring person wins (Heads up)

The wagers range from 1 cent up to $250. You are not limited to entering one contest just once. For example, given a $0.1 buy-in, you are able to enter up to the total prize placements (since anything beyond that you don't get paid). Picture below is an example of available contests on CSGO

Contestants are usually free to adjust their picks for each contest entry meaning that you don't have to have one portfolio for everything but rather can spread them over many different bets even given the same wager/style of play. While this could be an interesting option to consider, I've never analyzed much into it so for now we will assume that all contests we can enter will contain the same portfolio. Lastly, the most important part: you are paid relative to the points scored against other contestants with their portfolio.

The Beta-Beta Bayesian Model

We need to develop a data-driven model to understand our performances versus other contestants. We can't use the raw score to compare across daily contests since many different match-ups lead to different possible scores. Therefore, we need to first re-scale each contest result so that it is , where 0 indicates the worst outcome (last place) and 1 indicates the best outcome (1st place). Let's take all my unique contests (Wager/Style), perform the transformation and provide a histogram plot of them. Note that in the image, the pivot table is used to average over the normalized score for unique contests that I have entered multiple times.

As we can see, it's skewed to the left with the majority of results clustering around 0.7 or the 70% percentile of contestant. Inspired by approaches Fader and Hardie in Marketing Analytics have used (I'll talk more about them in my next post), I propose a Bayesian-esque process called the Beta-Beta model to analyze our relative performance. The Beta-Beta model utilizes two beta distributions, one for modelling our data and one for inferring the level of competition. Why infer the level of competition? We have no additional information about our competitors (other contestants) and how efficient they are at drafting their portfolios. It is also intuitive that bettors at a higher wagers are often more knowledgeable about team and player dynamics. We will utilize our second beta distribution to model the heterogeneity in competition. See box below for technical details.

Mathematical Box: Beta-Beta Model

The Beta distribution is simply a probability density distribution to model continuous data between 0 and 1. Let be a reparameterized beta distributed random variable representing the relative score of the unique contest. With and . The pdf of is defined as Where is the beta function. It is worth noting that since the Beta distribution doesn't actually support extreme values: while my data has them, we need to slightly reshift the data such that . According to this stackoverflow post on beta regression, the follow adjustment can be made: Where is some constant, a reasonable choice would be .5. Now that we have a distribution for our relative score, we need want to model the level of competition in different contests. I want to assume that the expected value of ( ) changes as the level of competition change but the variance of is the same across all levels of competitions. Let be a beta distributed random variable with pdf Lastly, we can fit the model by traditional maximization of log likelihood. Given a sample of , the log-likelihood is equal to Is there a closed form solution to the integral? I don't think so. If anyone does know, please let me know in the comments. Fortunately, as a programmer, I can always approximate it numerically (see after this box for the code). Below is a plot of the fitted distribution of after fitting the data

Now let's fit the model and look at how well it approximate the histogram. So we can see that the distribution is indeed a good fit of the data and our expected average placement is at the 71 percentile.

Python Box: Numerical Estimation of Beta-Beta Model

1 - Load the Data and adjust the re-scaled points (as discussed in the above mathematical box) 1 2 h = pd. read_csv ( 'Documents/ipynb/asset/pts.csv' ) h = ( h* ( len ( h ) - 1 ) + 0.5 ) / len ( h ) h = pd.read_csv('Documents/ipynb/asset/pts.csv') h = (h*(len(h)-1)+0.5)/len(h) 2 - Plotting the data (above hist) 1 h. plot ( kind = 'hist' , bins = 15 , figsize = ( 8 , 6 ) ) h.plot(kind='hist', bins=15, figsize=(8,6)) 3 - Our Beta-Beta PDF (recall ) 1 2 def BetaBeta ( mu , x , a , b , phi ) : return ( beta. pdf ( x , a = mu*phi , b = ( 1 .-mu ) *phi ) * beta. pdf ( mu , a = a , b = b ) ) def BetaBeta(mu, x,a,b,phi): return ( beta.pdf(x, a=mu*phi, b=(1.-mu)*phi) * beta.pdf(mu, a=a, b=b) ) 4 -Develop our log-likelihood function 1 2 3 def loglikelihood ( params , x ) : a , b , phi = params return x. apply ( lambda x: -np. log ( integrate. quad ( BetaBeta , 0 , 1 , args = ( i , a , b , phi ) ) [ 0 ] ) ) . sum ( ) def loglikelihood(params,x): a,b,phi = params return x.apply(lambda x: -np.log(integrate.quad(BetaBeta, 0, 1, args=(i, a, b, phi))[0])).sum() 5 - Using scipy.optimize.minimize, find optimal parameters by minimizing the negative log-likelihood 1 2 g = minimize ( loglikelihood , x0 = [ 1 . , 1 . , 5 . ] , args = ( h , ) , bounds = [ ( 0 , None ) , ( 0 , None ) , ( 0 , None ) ] ) g g = minimize(loglikelihood, x0 = [1.,1.,5.], args=(h,), bounds=[(0,None),(0,None),(0,None)] ) g status: 0 success: True nfev: 165 fun: -52.296295582942605 x: array([ 3.64879272, 2.23302626, 13.37849621]) message: 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH' jac: array([ 8.17124146e-05, 1.98951966e-05, 3.26849658e-05]) nit: 21

The BB model can provide a robust solution to any subjective beliefs or empirical evidence. For example, let's say next week is a major competition where there are multiple matches and many players/teams to draft from. You might have a subjective interpretation that you will perform worse due to an increase in better contestants or even uncertainty from so many teams. Thus, you believe you'd have a placement at only the 55th percentile. Using the Beta-Beta model we can mix in a subjective belief and derive a new Bayesian distribution, here's what it would look like if we believe we expect a placement at the 55%.

The blue curve is our new distribution given our subjective expectation or empirical observation. The red curve is our original data. When I fed it the 55% expectation, the curve shifted to the left along with a bit more certainty (less variance). The new expected placement is at 59%.

Mathematical/Python Box: Bayesian Adjustment

Given our subjective belief or empirically observed statistic: , according to Baye's Theorem Where is the posterior distribution of . 1 2 3 4 5 # The denominator and numerator is separated to save calculation time def bayes ( obs_mu , theta , a , b , phi ) : return ( ( beta. pdf ( obs_mu , a = theta*phi , b = ( 1 .-theta ) *phi ) *beta. pdf ( theta , a = a , b = b ) ) ) def bayes_denom ( obs_mu , a , b , phi ) : return integrate. quad ( BetaBeta , 0 , 1 , args = ( obs_mu , a , b , phi ) ) [ 0 ] # The denominator and numerator is separated to save calculation time def bayes(obs_mu, theta, a,b,phi): return ( (beta.pdf(obs_mu, a=theta*phi, b=(1.-theta)*phi)*beta.pdf(theta, a=a, b=b)) ) def bayes_denom(obs_mu, a,b,phi): return integrate.quad(BetaBeta, 0, 1, args=(obs_mu, a, b, phi))[0] Note that is not to be confused with a realization of but rather a realization of , indeed we can feed it multiple realizations as products of the likelihood and it will adjust the posterior accordingly. Moving on, the final distribution for our relative score is just a matter of substituting for to find the posterior predictive. 1 2 3 4 5 6 7 def BBB ( x , model , obs ) : denom = bayes_denom ( obs , a , b , phi ) def BBB_sub ( mu , x , model , obs , denom ) : a , b , phi = model return beta. pdf ( x , a = mu*phi , b = ( 1 .-mu ) *phi ) *bayes ( obs , mu , a , b , phi ) /denom return integrate. quad ( BBB_sub , 0 , 1 , args = ( x , model , obs , denom ) ) [ 0 ] def BBB(x, model, obs): denom = bayes_denom(obs, a,b,phi) def BBB_sub(mu, x,model,obs, denom): a,b,phi = model return beta.pdf(x, a=mu*phi, b=(1.-mu)*phi)*bayes(obs, mu, a,b,phi)/denom return integrate.quad(BBB_sub, 0, 1, args=(x, model, obs, denom))[0]

Now we can leverage the BB Model to help us infer our probability of placing within certain positions. For example, given that we are betting in a half will win contest, the probability that we'll end up being in the money is equivalent to the probability that the relative score is between 0.5 and 1. For my data, that's approximately 70.43% of being in the money.

Mathematical/Python Box: Moneyness

To find your probability of placing within the percentile, e.g . It is simply the CDF of the BB distribution: We can numerically estimate this from using double quadrature in scipy. Using the previous example of half will win, 1 integrate. dblquad ( BetaBeta , 0.5 , 1 , lambda x: 0 , lambda x: 1 , args = ( a , b , phi ) ) integrate.dblquad(BetaBeta, 0.5, 1, lambda x: 0, lambda x: 1, args=(a, b, phi)) (0.7042841763509285, 3.922401927702879e-07)

Optimizing your Bets via Kelly Criterion

The Kelly Criterion has traditionally been one of those stories where a bunch of genius mathematicians show up to a gambling den and clear the entire house. The purpose of the Kelly strategy is simple: given an adversary that offers you unlimited betting opportunities with net odds ($ amount that you stand to gain) and probability of winning, what is the optimal percentage of your total bankroll should you bet on each gamble in order to maximize your expected wealth? The answer is % of your bankroll. Now that's simple to use but it's not necessarily applicable to daily fantasy. Within one day, we can be entered into contests with different possible outcomes and winnings. We need to break down the original formula and modify its components to reach our own solution.

Examining the Recipe

Let's say entering into a given contest allows you to earn dollars for each dollar you wager (alternatively, % return). If you bet an % of bankroll, at each gamble you stand to gain times your bankroll or lose % of it. Over gambles your wealth (if starting at $1) equals to , taking the log and exponential . Applying law of large numbers and assuming is identically distributed and independent over gambles, the wealth equation becomes

The bettor has an average return of per gamble. What is ? That's simply the summation of each log outcome multiplied by its probability or given number of outcomes

Putting it in Practice

Now I'll demonstrate a common betting scenario on Alphadraft. For the ESL Pro League that runs 4 times per week, we want to see what's the optimal bankroll to bet into a series of different wagers/play-styles. The example payout table is illustrated below

Contest ITM Percentile Net Odds Quarter Half-Will-Win 50% 0.8 Nickel Arcade 76.7% - 83.3% 0 (refund) 83.3% - 90% 1.4 90% - 96.7% 3.8 96.7% 9

We want to find our optimal proportions for both contests that we should enter into . Ad hoc, we can treat both contest as two separate independent return streams and the average log return is just equal to the sum of the two expected log returns. In reality, this is a bit inaccurate but adding dependence can complicate the process especially with more than two contests. For the sake of simplicity and to fully leverage the BB model, I assume that the two contests returns are independent. Lastly, for the sake of keeping this post short, let's say we believe the level of competition is about the same at the original fitted model level. The table below adds on the calculated probability of ITM and OTM calculated from the BB model.

Contest ITM Percentile Net Odds P(ITM) P(OTM) Quarter Half-Will-Win 50% 0.8 70.43% 29.57% Nickel Arcade 75% - 80% 0 (refund) 7.89% 68% 80% - 90% 1.4 14.08% '' 90% - 95% 3.8 5.59% '' 95% 9 4.40% ''

Below is the resulting heatmap of expected log return per gamble as a function of % of our bankroll bet in half will win ( ) and nickel arcade ( ). The red dot is the optimal point where the return per gamble is maximized at 4.8%. Anything above the 0 mark indicates positive return which is approximately the light green to dark green areas.

Thus, the modified Kelly recommends betting 33% of your bankroll into half will wins and 3% into arcades. Clearly, it seems that arcade contests, given our distribution, is not an attractive option unless we had more confidence in our ability to place within the money. This methodology can be applied to as many unique contests as the bettors can enter into.

Ruin and Fractional Kelly

One common critique of the Kelly criterion is that it does not consider probability of ruin (losing all your bankroll through an unlucky streak). That's why many practitioners propose a fractional Kelly system which is simply to bet a percentage of the recommended Kelly output. For example, if we were use a 50% fractional Kelly, our percentage bankroll bet would be 16.5% and 1.5% into half will win and arcade respectively. For a good piece on the vanilla Kelly Criterion as well as on finding your preferred fractions, see here.

Conclusion and Future Considerations

In this blog post, I demonstrated how we can leverage probability models and data to derive our optimal betting strategy for Alphadraft. Practioners applying this methodology should continually update their distribution as new data arrives and actively take advantage of the subjective statistic to control risk.

There are two points to further consider on improving the model, I have already mentioned the first one of modelling dependence among different contest types. In the long run, the outcomes of one unique contest should be independent of other contests but in the short run, results will heavily depend on each other as you will be betting against identical opponents across many contests.

Secondly, since we're able to enter into the same contest multiple times, this raises the question of what is the optimal number of entries we should have per unique contest? For example, given a contest with 100 entrants and top 50 get paid. Our optimal number of entries should be between 1 and 50. I have mostly solved this through some simple logic and excel solver but have yet to incorporate it into this model. Why? They're both sort of mutually exclusive as the modified Kelly solves for optimal % of bankroll while the other solves for number of entries which, when tied with $ entry fees, tells you optimal $ amount. I believe there is still a way to synthesize both methods for a more general and applicable approach but I have yet to spend enough time to fully think it through.

Hope you enjoyed this post and stay tuned for more 🙂