derek-adair / nflgame

A working snapshot of nflgame (for historic purposes). This project is no longer active.
http://nflgame.derekadair.com
The Unlicense
331 stars 100 forks source link

Fastest way to calculate fantasy points for nfl.com scoring? #5

Closed benlindsay closed 6 years ago

benlindsay commented 6 years ago

I'm very comfortable with Python, but I'm just starting to play around with nflgame, so very much a beginner in that sense. I'll be doing an nfl.com fantasy league and am hoping to use this to make myself a custom dashboard. I found this script that calculates fantasy scores for all players in a given week. However, it looks like the nfl.com scoring might be a little more complicated, especially for defense and special teams. This seems like something someone out there has probably already done, and I'm not big on reinventing wheels, but I'm not seeing any examples more specific to nfl.com.

Are there any further resources out there for what I'm looking to do, or is my best bet to just figure out how to calculate each stat one by one and add those to the script?

Thanks in advance!

derek-adair commented 6 years ago

Hello there!

I'm taking over the managment of this code, and I am no expert either. I've exclusively used this for games win/loss tracking. So i know how the schedule code works quite well.

Glancing at the player code it looks like there is no effort towards calculating fantasy points. I'm pretty sure thats out of the scope of this particular project anyhow.

Looking at nfldb, a project that puts the data this project pulls into a relational database, there is no mention of points or anything like that either.

However, it is likely trivial to write your own point rules. This project and the other related ones are more like the code to enable and make writing your own fantasy league possible.... not so much a drop in fantasy football app.

ochawkeye commented 6 years ago

As @derek-adair mentioned, calculating fantasy scores falls outside the scope of this project, but the data this library grants access to gives you everything you need to calculate scores yourself.

For a simple scoring system something like this would suffice:

import nflgame

def base_fantasy_points(player):
    """
    Baseline points consist of only passing, rushing, receiving, and extra
    point stat categories.

    All punt returns, kick returns, and field goals are calculated later by
    evaluating all plays and are generated separately.
    """
    points = +1*getattr(player, 'passing_yds')
    points += +60*getattr(player, 'passing_tds')
    points += -45*getattr(player, 'passing_ints')
    points += -2*getattr(player, 'passing_att')
    points += +2*getattr(player, 'passing_cmp')
    points += +2*getattr(player, 'rushing_yds')
    points += +60*getattr(player, 'rushing_tds')
    points += +2*getattr(player, 'receiving_rec')
    points += +2*getattr(player, 'receiving_yds')
    points += +60*getattr(player, 'receiving_tds')
    points += -45*getattr(player, 'fumbles_lost')
    points += +20*getattr(player, 'passing_twoptm')
    points += +20*getattr(player, 'rushing_twoptm')
    points += +20*getattr(player, 'receiving_twoptm')
    points += +10*getattr(player, 'kicking_xpmade')
    points += -20*getattr(player, 'kicking_xpmissed')
    return points

games = nflgame.games(2018, week=1, kind='PRE', home='MIN', away='MIN')
players = nflgame.combine_max_stats(games)

for game in games:
    print game

for player in sorted(players, key=lambda x: base_fantasy_points(x), reverse=True):
    if base_fantasy_points(player):
        print player.player.name, player.team, base_fantasy_points(player)
        print player.formatted_stats()
MIN (42) at DEN (28)
Roc Thomas RB MIN 388
receiving_tds: 2, receiving_yac_yds: 91, receiving_rec: 3, rushing_yds: 29, receiving_yds: 102, rushing_att: 8, receiving_tar: 3, rushing_lngtd: 0, receiving_twopta: 0, receiving_lng: 78, rushing_tds: 0, rushing_twopta: 0, rushing_lng: 9, receiving_lngtd: 78, receiving_twoptm: 0, rushing_twoptm: 0
Chad Kelly QB DEN 314
passing_incmp_air_yds: 42, passing_sk: 1, passing_att: 21, passing_sk_yds: -8, passing_int: 1, passing_yds: 177, passing_incmp: 7, passing_cmp: 14, rushing_yds: 38, rushing_att: 3, passing_tds: 2, passing_cmp_air_yds: 99, rushing_lngtd: 0, passing_twoptm: 0, passing_twopta: 0, rushing_tds: 0, rushing_twopta: 0, rushing_lng: 18, passing_ints: 1, rushing_twoptm: 0
Kyle Sloter QB MIN 243
passing_sk: 1, passing_incmp_air_yds: 10, passing_att: 11, passing_sk_yds: -6, passing_twoptm: 1, passing_twopta: 1, rushing_tds: 1, passing_yds: 69, passing_incmp: 2, passing_cmp: 9, rushing_yds: 19, rushing_att: 2, passing_tds: 1, passing_cmp_air_yds: 49, rushing_lngtd: 14, rushing_twopta: 0, rushing_lng: 14, passing_ints: 0, rushing_twoptm: 0
Trevor Siemian QB MIN 228
passing_incmp_air_yds: 29, passing_sk: 2, passing_att: 17, passing_sk_yds: -11, passing_int: 1, passing_yds: 165, passing_incmp: 6, passing_cmp: 11, passing_tds: 2, passing_cmp_air_yds: 55, passing_twoptm: 0, passing_twopta: 0, passing_ints: 1
Phillip Lindsay RB DEN 160
receiving_tds: 1, receiving_yac_yds: 37, kickret_yds: 34, receiving_rec: 3, rushing_yds: 7, receiving_yds: 40, rushing_att: 2, receiving_tar: 4, kickret_ret: 1, kickret_lngtd: 0, rushing_lngtd: 0, kickret_lng: 34, receiving_twopta: 0, receiving_lng: 19, rushing_tds: 0, kickret_avg: 34, rushing_twopta: 0, rushing_lng: 5, receiving_lngtd: 19, receiving_twoptm: 0, rushing_twoptm: 0, kickret_tds: 0
...
Case Keenum QB DEN -1
passing_incmp_air_yds: 13, passing_att: 4, passing_yds: 5, passing_incmp: 3, passing_cmp: 1, passing_cmp_air_yds: 2, passing_twoptm: 0, passing_twopta: 0, passing_ints: 0, passing_tds: 0
Paxton Lynch QB DEN -25
passing_incmp_air_yds: 33, passing_sk: 1, passing_att: 11, passing_sk_yds: -9, passing_int: 1, passing_yds: 24, passing_incmp: 5, passing_cmp: 6, rushing_yds: 3, rushing_att: 1, passing_cmp_air_yds: 11, rushing_lngtd: 0, passing_twoptm: 0, passing_twopta: 0, rushing_tds: 0, rushing_twopta: 0, rushing_lng: 3, passing_ints: 1, passing_tds: 0, rushing_twoptm: 0

When your scoring gets more complicated (ie. points based on longer field goals, etc), you can utilize the play-by-play data.

    plays = nflgame.combine_plays(games)
    plays40 = plays.filter(kicking_fgm__ge=1, kicking_fgm_yds__ge=40, kicking_fgm_yds__lt=50)
    for player in plays40.players().kicking():
        fantasy_players_dict[player.playerid].medium_fgs += player.kicking_fgm
benlindsay commented 6 years ago

Thanks for the input! I ended up hacking something together like that to match my league's scoring for players and teams (at least I think it does it right). Still a work in progress but found here