Money-Puck: Optimizing Your Fantasy Hockey Draft Using Statistics and Ruby

1. Introduction

2. What is Fantasy Hockey?

Fortunately for my leagues, the draft order is generated for us by Yahoo! Fantasy Sports.

3. Hockey Homework

  • Compare skaters to only their peers in the league (forwards only against forwards, defensemen only against defensemen) to ensure we don’t undervalue defensemen who don’t usually score the points that forwards do but are still key pieces in a fantasy team (they often do more of the shot-blocking and hitting).
  • Analyze the most recent NHL season’s player stats but also look at stats from the last few seasons to avoid filtering out players like Josh Anderson who had an off-year last season.
  • Be able to prorate stats over a full standard 82 game season to put the players on an even footing and not ignore players like Vladimir Tarasenko who was injured for most of last season (and is still recovering) but put up 10 points in 10 games beforehand and has generally been a high scoring forward for most of his career.
  • Be configurable to include a different set of categories for each fantasy league.
  • Filter out low-end and outlier players that negatively skewed the results of the high-end players that you do want to draft. When there are more and more players who do not contribute to the stat categories factored in, it makes it harder to distinguish between the better players.
  • Be scalable and dynamic so I could quickly generate Fantasy Score rankings for different sets of stat categories, positions, and settings without waiting around for possibly thousands of calculations, database reads/writes and HTTP calls to execute.
  • It had to help project the most effective, smart, and reliable skaters to draft based on history without team allegiance or emotions getting involved (for goalies, that's another story I’ll dig into later on).

4. Fantasy Hockey Helper Dot See Eh

4.1 Dynamic Fantasy Score Rankings

4.2 Mock Draft Your Team

4.3 Color Coded Assessment

The Fantasy Score is generated by an aggregation of the numbers that also define this color legend (10–0).
In this example, we are only looking at the top 15 Forwards with prorated stats from just last season for the categories presented in the table.

5. Technology

6. Draft Results

6.1 Draft 1: “Chel 21”

  • There was no prorated stats option yet.
  • Only last season’s stats were loaded into the system.
  • The Fantasy Score algorithm needed some further tinkering and optimizations.
Note the stats presented in this view are just from last season and not prorated.
  • Max Pacioretty does it all in the key categories! A complete player not nearly appreciated enough during his time in Montreal.
  • Tony DeAngelo is an awful human but he plays a pretty okay game of fantasy hockey. Real hockey though, not so much
  • I’ve got some heavy reliance on the duo of Danault & Tatar who play on the Habs top line with Brendan Gallagher and are absolutely elite at 5-on-5 play (not something currently factored into my algorithm and not exactly a bonus since we have categories for powerplay and shorthanded points but not for even-strength).
  • Bryan Rust is ranked very high on my rankings (#5) and I was quite pleased to pick him up so late. This is a clear example of FantasyHockeyHelper helping me identify high quality and not-obvious talent.
  • There was no “Hide Player” functionality implemented then (I hadn’t even considered it yet) but during the draft I very quickly began to lose track of which players in my rankings were still available in the pool, making it harder to make picks in a timely manner.
  • Only factoring in last season’s stats caused a serious recency bias to affect my Fantasy Score rankings.

6.2 Draft 2: “Canada Cup”

  • I had implemented the “Hide Player” functionality.
  • I rewrote the entire Fantasy Score algorithm and underlying data model over 2 days to load in the last 3 years of NHL stats and offer statistic options for considering only last season, the last 3 seasons equally, and the last 3 seasons with a recency bias towards last season (my personal favorite option).
  • I implemented a new Players filter to return just players on Canadian teams which also required writing a rake script to make updates to all players that joined or left Canadian teams over the off-season (welcome to the Habs Tyler Toffoli).
Forgive my css skills…
  • Mark Scheifele is highly underrated! He is a top 5 centerman in the North Division.
  • I never thought I would be so happy to be able to draft Tyler Myers in a fantasy pool.
  • I only went off the board from my Fantasy Score rankings list once when I drafted Jonathan Drouin in round 11 because I have faith he is going to tear it up this season with Nick Suzuki and newly acquired “PowerHorse” Josh Anderson. Before getting injured last season, he had 15 points in 19 games, got injured, and returned too soon to lack-luster results. Then after the COVID-break, he was tied for the team-lead in scoring over the Habs’ 2 round summer Playoff run. The algorithm I put together doesn't take playoff scoring into account nor does it consider the healthiness of players after returning from an injury.
  • Unfortunately for me, JT Miller is now in a 2-week quarantine due to a possible COVID exposure. I picked up Ilya “Soup” Mikheyev (TOR) off of waivers to temporarily fill that void. I have similar hopes for him that I do for Jonathan Drouin.
  • Luca Sbisa got stolen off of waivers by Nashville after the draft so I had to drop him as per league rules. I picked up Travis Hamonic (VAN) as a replacement purely because he had the highest Fantasy Score of the remaining defensemen. In FantasyHockeyHelper we trust!

7. Feedback and Findings

  • Factoring in the age of the player would be another interesting variable to include in the Fantasy Score calculation. Forwards often hit the prime of their career in their mid-late 20s and begin to slow down in their early 30s.
  • Ranking players by Fantasy Score definitely helps you pick a player to draft in each round but you also need to factor in what round is the best to draft a player in. If you think you can pick up a very underrated player with a high Fantasy Score in a later round and draft someone more obvious in an earlier round, it's important to not leave value on the table to go for the sleeper picks that FantasyHockeyHelper may be providing. This is why in Draft 1, I waited to pick up Bryan Rust in round 9 despite being ranked at position 5 last season (prorated).
  • The Fantasy Score ranking ideally pushes you to draft players that are strong in all categories but does not (yet) dynamically compare your under-construction Fantasy Team to the remaining players to recommend players that are strong in your weak categories. This would require a large change to the algorithm though.
  • The AVG row in the “My Fantasy Team” page does not factor in which draft position each player was taken at and likely looks pretty blue or purple on the Color Assessment gradient after a long draft. Max Pacioretty is a good pick in the second round but I would argue that my pick of Ryan Getzlaf in the 13th round was a more valuable pickup in comparison to the talent still available at that time. But that doesn’t get factored in.
  • I need better data. All Forwards are marked as position = “F” when ideally I would like Centerman marked as position = “C” so I can ensure that we only factor in the Faceoff-Wins category for Centerman. Right now if that statistic is included then the Forward rankings skew towards Centermen.

8. What’s Next?

  • MEDIUM10




Staff Software Engineer @ Copper CRM

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Southern Garrett channels “Hoosiers” in first state finals appearance in 18 years

Basketball: All-star vs all-star

Football’s racism failure is for everyone to tackle

Virat Kohli Most Successful Captain in India | Virat Kohli Record as Test Captain– Vacancysquare

Virat Kohli Most Successful Captain in India | Virat Kohli Record as Test Captain– Vacancysquare

Greatness is Often Defined by the Adversity One is Willing to Overcome

2017 NBA Offseason Review: Orlando Magic

Victory for ex-HSV trainer Fink at the debut in Latvia

FC Schalke 04: Danny Latza lives the new self-confidence

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Tom Pedron

Tom Pedron

Staff Software Engineer @ Copper CRM

More from Medium

Ruby: Change the start value of Array index

Attribute Readers/Writers/Accessors

Using The ‘Faker’ Ruby Gem

When and Why use React with Ruby on Rails?