• Courtney Perigo

Risk Assessment of Daily Fantasy Baseball Games Using Monte Carlo Simulation

No, you probably won't win that online daily fantasy sports game you want to try. Here's the analytics that tells you why.

Photo by Mark Duffel on Unsplash

This summer, I wanted to test my operations research skills on a problem that has been troubling me. Why am I so bad at online daily fantasy baseball?

If you’re reading this, you probably know what I’m talking about. I’m assuming you’re the type who wanted to do a little research and maybe stumbled on this data science blog post looking for tips on how to build your team.

Spoiler Alert: I have bad news for you.

In this blog, you’ll learn why online fantasy sports is difficult. You’ll see that the economy created by these online game providers is efficient; and you’ll need to put in a lot of time if you want to game the system.

What is online fantasy baseball?

If you’re not familiar with anything I’m talking about than this paragraph is for you. According to one online gambling website that will go nameless, online fantasy sports betting is a $48 billion dollar industry. In fantasy sports, you choose players who are playing that day and see if they can make you money by performing well. In the baseball version, you choose a roster of 8 position players and 2 pitchers; and their salary can’t go above the league’s salary cap. Their performance that day dictate the points you score. You don’t have to do anything but pick the best players that day.

Simple, right?

Image by author: Fantasy baseball (classic rules)

What am I so bad at online fantasy baseball?

Image by Author. My fantasy baseball logo.

Enter my fantasy team, the Chicago Red Line Hustlers. Yes, I did build a logo for my make believe team. What’s it to you?

We’re not that good. I’ve been playing for a month or so and my team has lost money. Not a lot, I’m not putting a bunch on the line. However, I can’t quit my day job; and I want to know why.

Monte Carlo Simulation Helps Us Assess the Risk in Fantasy Sports

To understand why I’m so bad at this game, I reached into my decision analytics toolkit and dusted off the old tried and true portfolio analytics tool — the Monte Carlo simulation. The simulation will helps me understand the risk in personnel decisions — specifically which ten players should be picked given our constraint of being below the league salary cap.

The simulation will use real-life results for major league baseball players from 2018 to the day prior to the game we’re simulating. I achieve that by obtaining daily statistics from’s public API for all active major leaguers. (Note: data engineering is beyond the scope of this blog.)

Once stats are collected, we must collect the eligible players involved in the fantasy game we’re interested in simulating. I achieve that by interacting with public API of a operator of online sport gambling specializing in daily fantasy sports. (Note: data engineering is beyond the scope of this blog.)

After data is collected and eligible players are identified the simulation can do an exhausted search, modified by novel constraint propagation, to find the best performing lineup; or a user can define a lineup and assess its performance.

Objective Function

The simulations’ objective is to simulate the potential outcomes of baseball games played by a lineup of 2 pitchers and 8 position players. Those outcomes are scored using the classic rules of the online provider’s daily fantasy baseball contest.

Image by Author: Typical classic scoring template used by online fantasy baseball providers.

The Monte Carlo Simulation

With data available, we could go about experimenting and modeling expected outcomes from our real-world data. Our goal is to identify the fantasy scoring for 8 position players (representing all 8 fielding positions in baseball) and 2 pitchers. Our model will need to address the position players and pitchers, separately.

Batting Simulation: Plate Appearances Matter

For position players, scoring is highly skewed towards batting outcomes. For position players, our focus will be on simulating plate appearances and the corresponding potential outcomes of that plate appearance.

We achieve this by simulating outcomes of offense and we only care about plate appearances as this is the only chance a player can impact the fantasy game. The flowchart of our simulation shows how our model will proceed to identify plate appearances and their potential outcomes.

Image by Author: Batting simulation flowchart

Plate Appearances

Players can have a variety of plate appearances in each game, and it mostly is associated with the order they appear in the lineup. A position player in the back of the lineup tends to have less plate appearances than a player in the top (beginning) of the lineup. Our model has access to the number of plate appearances a player has had historically; but doesn’t have access to the order in the lineup they appeared in for that game. That’s the first limitation to the accuracy of our simulation. I model plate appearances based on historical outcomes not on actual expectations based on the batting order for the upcoming game.

To accomplish our simulation, we empirically sample plate appearances from past games by using a random number generator to select plate appearances from an ordered list of historical plate appearances for each position player.

Image by Author: Python code to return plate appearances

For each game simulated, this random selection of plate appearances is performed. This methodology is very accurate for matching expected results for each player.

Image by Author: Plate appearances actual performance vs simulated performance.

Plate Appearance Outcomes

Once plate appearances are simulated, we now need to identify the model for determining which outcomes are possible and leverage a nested probability to select an outcome that represents what the player is expected to achieve. The first stop in our nested or chained probability is sampling from the player’s ability to turn a plate appearance into an offensive outcome. This ratio can be applied to the simulations plate appearances to identify how many outcomes the player achieved that game.

Image by Author: Python code to return outcome ratio

With the number of outcomes determined, we can the use the player’s historical outcomes achieved to simulate what that player is capable of. For example, if we’re simulating a player known for hitting a lot of home runs — we’d see many homeruns in his historical performances.

Image by Author: Outcomes for two different MLB position players showing a unique outcome distribution.

The simulation will empirically sample from the distribution of outcomes that the player has achieved in the past. The outcome can then be scored according to the online fantasy provider’s score card and further processed to simulate additional outcomes based on the state of the game when that outcome occurred.

Image by Author: Python code to return player outcomes.

Simulating On Base Status and Ultimate Outcome of the Plate Appearance

The game state when an outcome occurs will also impact three final outcomes our simulation must model. Those three outcomes depend on events that occurred before, during and after the outcome is achieved by the player. The final layer of our flowchart shows runs, stolen bases, and RBIs being only possible when certain outcomes occur.

In addition, the amount of those three events is also impacted by the outcome. For example, if a player hits a home run, they are awarded at least one RBI and one run. They also have no chance of achieving a stolen base because of that outcome. We model all these rules in an additional layer of nested probability and empirically sampled based on past player performances to simulate game states the player was performing in. An example of one of these outcomes is below, modeling runs.

Image by Author: Python code to return player runs as a function of outcome type

Simulating Batting Outcomes

With all our functions defined, I can now simulate unlimited games for any player with enough sample performances to draw from. The result performs very well. Here’s an example of simulated Trea Turner from the LA Dodgers.

Image by Author: Trea Turner Simulation (2 games)

Image by Author: Boxplot of Trea Turner Fantasy Points (simulated) Vs. his actual performance (50 games)

Pitcher Simulation: Innings Pitched Matter

With batters accounted for in the simulation, the model must also be able to simulate pitcher outcomes. The fantasy scoring for pitchers only considers the results of plate appearances and outcomes of the batters they face.

Image by Author: Pitching simulation flowchart.

For pitchers, the model starts with simulating innings pitched. This is important as my own novel research suggests that pitchers who pitch more innings tend to perform better (by reducing runs, hits, and improving their win percentage as the game progresses, etc.)

Image by Author: Pitcher’s win probability by innings pitched (rounded)

This observation is intuitive as a manager is less likely to pull a strong pitcher having a good outing from the game in preference for another pitcher.

Innings Pitched

To accomplish our simulation, we empirically sample innings pitched from past games by using a random number generator to select innings pitched from an ordered list of historical innings pitched for each pitcher. The code to achieve this is like the plate appearances function for batters. For each game simulated, this random selection is performed. This methodology is very accurate for matching expected innings pitched for each pitcher.

Image by Author: Innings pitched by a MLB pitcher simulation vs actual.

Pitching Outcomes

Pitcher outcomes are evaluated based on the number of innings pitched. As I indicated previously, I do this because player performance is different depending on how deep into the game the pitcher plays.

There are three outcomes that we care about— they are the number of wins, runs, hits, walks, and strike outs pitched. I simulate these outcomes by sampling empirically for subsets of pitcher data corresponding to the innings pitched. This process ensures we respect pitcher performance as a function of innings pitched.

Image by Author: Python code to return earned runs as a function of innings pitched.

The final outcomes are a check for simulation status after each run. The model scores complete games whenever the simulated pitcher pitches 9 complete innings. It credits the pitcher with a complete game shutout whenever the simulated pitcher throws 9 complete innings and has no earned runs. Finally, the model credits the simulated pitcher with a no hitter if the simulation produces a pitcher that completed all 9 innings and achieved no hits.

Simulating Pitcher Games Played

With all our pitching functions defined, I can now simulate unlimited games for any pitcher with sufficient sample data. The simulated data is very similar to actual MLB performances for the pitchers we’ve modeled.

Image by Author: Corbin Burnes simulated pitching performances

Image by Author: Corbin Burnes Fantasy Points Actual vs Simulated

Computational Experiment and Results:

The goal of this project was to assess the risk in selecting lineups for a daily fantasy sport game. To achieve this, I built a function that randomly fills out a valid lineup by spending up to the $50,000 salary cap indicated in classic rules of a fantasy baseball provider. I did this 500 times to create 500 random, valid lineups to simulate. Each player in the valid lineup was put through their own simulation — simulating 50 games of performance each.

The results were not surprising.

It appears that baseball outcomes have a lot of randomness in them.

Here’s a summary of the simulated performance of the top 10 random lineups chosen by the ratio of points to variability — like a Sharpe Ratio in finance. These lineups represent the least risky, but most effective options.

Image by Author: Top Sharpe Ratios acquired by random, valid lineups (top 10 performances viewed)

Here’s the same visual but selecting the top scoring valid lineups.

Image by Author: Top simulated fantasy random, valid lineups (top 10 performances viewed)

These images show valid lineups with strong performance; but all these lineups have expected values that are very near each other. Through this broad search, we couldn’t find a lineup that significantly outperforms all other lineups. Our simulation was successful in showing that fantasy baseball games, without significant detailed player analysis and assessment, are simply games of chance.

Discussion and Conclusions

In conclusion, simulation is a very useful tool for understanding the risks associated with decision making. It has been applied successfully in a wide range of applications including product design, pilot training, queuing research, and now fantasy sports.

The results of this specific simulation show that baseball in the short term, is very much random. Any player, on any given day, can have a good or bad game. Matchups can come into play; and game situations can influence a player’s decision.

We achieved the ability to model a very complex system and get very real-world results. Over the long term, I expect my simulation would generate players who perform similarly to their real-life counterparts.

The simulations can be improved. For example, we do not have data on the game state for any performance outcome. We simulate based on past achievements; but an improved model would simulate the game state as well. This would be an important next step as other player decisions and game state would impact the player’s ability to generate outcomes. In addition, the model cannot simulate matchups — a crucial topic in fantasy sports. Batters perform differently depending on the pitcher they face or the team they’re playing.

In the end, I hope to install new improvements that consider matchups and make incremental improvements to my ability to assess short term player performance.

7 views0 comments