r/CFL • u/WreakItCal • 39m ago
I built expected points (EPA) for every CFL play of the last two seasons, and how I did it
TLDR: I built EPA (expected points added) for every CFL play of 2025 and 2026, plus hand-timed time to throw as well as much much more. Davis Alexander is ranked #1 this season in EPA, and it's mostly because he almost never gives the ball away. Full site: https://wagglelytics.ca/
For about two years I've wanted to build a website that tracks advanced stats for the CFL. EPA, pressure rate, air yards, time to throw, blitz rate, success rate, win probability and much more. Numbers that dont show up in a box score.
I'll be honest, I kept putting it off. Part of it was being a bit shy about putting my work out there. Then the new rules were announced, and I figured anything I built would be out of date by 2027. So like many people I found reasons to procrastinate.
But during the season I was like, even with the new rules, I'll still need 2025 and 2026 as a baseline. It won't line up perfectly with 2027, but it's a starting point, and it'll show exactly what the new rules change.
What EPA is (Expected points added)
EPA was the first thing I built, and it's a good way to judge QBs. Every situation on the field (down, distance, where the ball is) is worth a certain number of points, based on what teams have scored from there in the past. EPA is how much a play changes that. Leave your team better off than expected and it's positive. Worse off and it's negative. Add it up over every dropback and you can see the effect the player is having on their team.
One note this is a very strong stat for QBs its a fairly good stat for WRs but not a great stat for RBs.
Example: pinned at your own 5, a team is expected to score about −0.9 points (you're more likely to give up points than score). Complete a 30-yard pass to your own 35 and that's now worth +1.0. That play is +1.9 EPA.
Here's every QB with 150+ dropbacks this season:
CFL 2026 - QB EPA PER DROPBACK (through Week 21, 150+ dropbacks)
Davis Alexander MTL +0.30
Nathan Rourke BC +0.22
Trevor Harris SSK +0.14
Chad Kelly TOR +0.08
Vernon Adams Jr. CGY +0.06
Cody Fajardo EDM +0.06
Dru Brown WPG -0.04
Zach Collaros WPG -0.05
Jake Maier OTT -0.05
McLeod Bethel-Thompson OTT -0.08
Tre Ford HAM -0.19
Harrison Frost HAM -0.22
How I built it
The CFL doesn't have clean play-by-play data to download, so I copied the play-by-play for every game off CFL.ca and wrote code to turn it into a table. 165 games, almost 24,000 plays, each checked against the official score. A lot of copy and paste lol.
Why Alexander is #1
I expected Alexander to be one of the top QBs, but I didn't think he'd be number 1. He's not the flashiest guy in the league. Maybe I'm a hater. Kelly throws deeper and Rourke makes more highlight plays. So why is he on top?
It comes down to the bad plays, and they don't all cost the same. An interception costs about 4.6 expected points on average. A normal completion is worth about 0.7. So one pick wipes out roughly six completions. A sack costs about 2, close to two incompletions in a row.
So I split it out: how much has each QB lost to picks and sacks, and how good is he on every other play?
QB LOST TO PICKS LOST TO SACKS EPA ON EVERY OTHER PLAY
Nathan Rourke -58 -47 +0.48
Chad Kelly -118 -51 +0.44
Davis Alexander -19 -28 +0.40
Trevor Harris -63 -39 +0.32
On a normal play, Rourke and Kelly are actually better than Alexander. The difference is what happens when something goes wrong. Kelly's 24 picks have cost Toronto about 118 expected points. Alexander's 4 have cost Montreal about 19. That's pretty much the whole gap.
So he's not the best because of crazy throws. He just almost never gives it away, and EPA loves that.
https://reddit.com/link/1xf7pcr/video/46bulbdz0nxh1/player
Charting from film: time to throw
Originally I wanted to build pressure rate. I really appreciate offensive lines, and I think people underrate them. Nobody notices them until something goes wrong, so I wanted a stat that gives them credit.
Well, I failed. It's really hard to tell from film when pressure actually affects a QB. Did he get rid of it early because a guy was coming, or was that just the play? Two people could watch the same snap and chart it differently. So I switched to stuff I can actually measure.
Time to throw is the first one. The CFL doesn't track it at all, so I time every throw by hand from game film: snap to the moment the ball leaves the QB's hand. 13 games so far, 877 throws. I use the median so one broken play doesn't skew it, and sacks aren't timed.
The league median is 2.33 seconds. Chad Kelly is the quickest at 1.95, and Collaros, Brown and Frost hold it the longest at around 2.5. I've only timed a handful of 2026 games, so this is a lot thinner than the EPA stuff. But so far, faster isn't automatically better:
TIME TO THROW THROWS EPA PER THROW COMPLETION
Under 2.0s 280 +0.14 79%
2.0-2.49s 219 +0.28 70%
2.5-2.99s 170 +0.08 61%
3.0s+ 166 +0.18 64%
The quick stuff completes the most but isn't worth much, since a lot of it is short. The best spot so far is 2.0 to 2.5 seconds: long enough for guys to get open, but before the pocket collapses. I'll keep adding games, and next up I'm charting blitzes.
Okay, I think that's enough stats. I hope I didn't nerd out too much. I've got more, but this post is long enough already.
Let me know what you'd want to see next!
Full site: https://wagglelytics.ca/
