def best_transfer_suggestions(n_transfer, session_id, dbsession=DBSESSION): """ Use our predicted playerscores to suggest the best transfers. """ n_transfer = int(n_transfer) if not n_transfer in range(1,3): raise RuntimeError("Need to choose 1 or 2 transfers") if not validate_session_squad(session_id, dbsession): raise RuntimeError("Cannot suggest transfer without complete squad") budget = get_session_budget(session_id, dbsession) players = [p["id"] for p in get_session_players(session_id, dbsession)] t = Team(budget) for p in players: added_ok = t.add_player(p) if not added_ok: raise RuntimeError("Cannot add player {}".format(p)) pred_tag = get_latest_prediction_tag() gw=get_next_gameweek(CURRENT_SEASON, dbsession) if n_transfer == 1: new_team, pid_out, pid_in = make_optimum_transfer(t, pred_tag) elif n_transfer == 2: new_team, pid_out, pid_in = make_optimum_double_transfer(t, pred_tag) return { "transfers_out": pid_out, "transfers_in": pid_in }
def get_session_predictions(session_id, dbsession=DBSESSION): """ Query the fixture and predictedscore tables for all players in our session squad """ pids = [p["id"] for p in get_session_players(session_id, dbsession)] pred_tag = get_latest_prediction_tag() gw = get_next_gameweek(CURRENT_SEASON, dbsession) pred_scores = {} for pid in players: pred_scores[pid] = get_session_prediction(pid, session_id, gw, pred_tag, dbsession) return pred_scores
def get_session_prediction(player_id, session_id, gw=None, pred_tag=None, dbsession=DBSESSION): """ Query the fixture and predictedscore tables for a specified player """ if not gw: gw = get_next_gameweek(CURRENT_SEASON, dbsession) if not pred_tag: pred_tag = get_latest_prediction_tag() return_dict = { "predicted_score": get_predicted_points_for_player(pid, pred_tag, CURRENT_SEASON, dbsession)[gw], "fixture": get_next_fixture_for_player(pid,CURRENT_SEASON,dbsession) } return return_dict
def fill_attributes_table_from_api(season, gw_start=1, dbsession=session): """ use the FPL API to get player attributes info for the current season """ fetcher = FPLDataFetcher() next_gw = get_next_gameweek(season=season, dbsession=dbsession) # needed for selected by calculation from percentage below n_players = fetcher.get_current_summary_data()["total_players"] input_data = fetcher.get_player_summary_data() for player_api_id in input_data.keys(): # find the player in the player table player = get_player_from_api_id(player_api_id, dbsession=dbsession) if not player: print("ATTRIBUTES {} No player found with id {}".format( season, player_api_id)) continue print("ATTRIBUTES {} {}".format(season, player.name)) # First update the current gameweek using the summary data p_summary = input_data[player_api_id] position = positions[p_summary["element_type"]] pa = get_player_attributes(player.player_id, season=season, gameweek=next_gw, dbsession=dbsession) if pa: # found pre-existing attributes for this gameweek update = True else: # no attributes for this gameweek for this player yet pa = PlayerAttributes() update = False pa.player = player pa.player_id = player.player_id pa.season = season pa.gameweek = next_gw pa.price = int(p_summary["now_cost"]) pa.team = get_team_name(p_summary["team"], season=season, dbsession=dbsession) pa.position = positions[p_summary["element_type"]] pa.selected = int( float(p_summary["selected_by_percent"]) * n_players / 100) pa.transfers_in = int(p_summary["transfers_in_event"]) pa.transfers_out = int(p_summary["transfers_out_event"]) pa.transfers_balance = pa.transfers_in - pa.transfers_out pa.chance_of_playing_next_round = p_summary[ "chance_of_playing_next_round"] pa.news = p_summary["news"] if (pa.chance_of_playing_next_round is not None and pa.chance_of_playing_next_round <= 50): pa.return_gameweek = get_return_gameweek_from_news( p_summary["news"], season=season, dbsession=dbsession, ) if not update: # only need to add to the dbsession for new entries, if we're doing # an update the final dbsession.commit() is enough dbsession.add(pa) # now get data for previous gameweeks if next_gw > 1: player_data = fetcher.get_gameweek_data_for_player(player_api_id) if not player_data: print("Failed to get data for", player.name) continue for gameweek, data in player_data.items(): if gameweek < gw_start: continue for result in data: # check whether there are pre-existing attributes to update pa = get_player_attributes( player.player_id, season=season, gameweek=gameweek, dbsession=dbsession, ) if pa: update = True else: pa = PlayerAttributes() update = False # determine the team the player played for in this fixture opponent_id = result["opponent_team"] was_home = result["was_home"] kickoff_time = result["kickoff_time"] team = get_player_team_from_fixture( gameweek, opponent_id, was_home, kickoff_time, season=season, dbsession=dbsession, ) pa.player = player pa.player_id = player.player_id pa.season = season pa.gameweek = gameweek pa.price = int(result["value"]) pa.team = team pa.position = position # does not change during season pa.transfers_balance = int(result["transfers_balance"]) pa.selected = int(result["selected"]) pa.transfers_in = int(result["transfers_in"]) pa.transfers_out = int(result["transfers_out"]) if not update: # don't need to add to dbsession if updating pre-existing row dbsession.add(pa) break # done this gameweek now
def main(): """ The main function, to be used as entrypoint. """ parser = argparse.ArgumentParser( description="Try some different transfer strategies") parser.add_argument("--weeks_ahead", help="how many weeks ahead", type=int) parser.add_argument("--gw_start", help="first gameweek to consider", type=int) parser.add_argument("--gw_end", help="last gameweek to consider", type=int) parser.add_argument("--tag", help="specify a string identifying prediction set") parser.add_argument( "--wildcard_week", help="play wildcard in the specified week. Choose 0 for 'any week'.", type=int, default=-1, ) parser.add_argument( "--free_hit_week", help="play free hit in the specified week. Choose 0 for 'any week'.", type=int, default=-1, ) parser.add_argument( "--triple_captain_week", help= "play triple captain in the specified week. Choose 0 for 'any week'.", type=int, default=-1, ) parser.add_argument( "--bench_boost_week", help="play bench_boost in the specified week. Choose 0 for 'any week'.", type=int, default=-1, ) parser.add_argument("--num_free_transfers", help="how many free transfers do we have", type=int) parser.add_argument( "--max_hit", help="maximum number of points to spend on additional transfers", type=int, default=8, ) parser.add_argument( "--allow_unused", help="if set, include strategies that waste free transfers", action="store_true", ) parser.add_argument( "--num_iterations", help="how many iterations to use for Wildcard/Free Hit optimization", type=int, default=100, ) parser.add_argument("--num_thread", help="how many threads to use", type=int, default=4) parser.add_argument( "--season", help="what season, in format e.g. '2021'", type=str, default=CURRENT_SEASON, ) parser.add_argument( "--profile", help="For developers: Profile strategy execution time", action="store_true", ) parser.add_argument( "--fpl_team_id", help="specify fpl team id", type=int, required=False, ) args = parser.parse_args() fpl_team_id = args.fpl_team_id or None sanity_check_args(args) season = args.season # default weeks ahead is not specified (or gw_end is not specified) is three if args.weeks_ahead: gameweeks = get_gameweeks_array(args.weeks_ahead) elif args.gw_start: if args.gw_end: gameweeks = list(range(args.gw_start, args.gw_end)) else: gameweeks = list(range(args.gw_start, args.gw_start + 3)) else: gameweeks = list(range(get_next_gameweek(), get_next_gameweek() + 3)) num_iterations = args.num_iterations if args.num_free_transfers: num_free_transfers = args.num_free_transfers else: num_free_transfers = None # will work it out in run_optimization tag = args.tag or get_latest_prediction_tag(season=season) max_total_hit = args.max_hit allow_unused_transfers = args.allow_unused num_thread = args.num_thread profile = args.profile or False chip_gameweeks = { "wildcard": args.wildcard_week, "free_hit": args.free_hit_week, "triple_captain": args.triple_captain_week, "bench_boost": args.bench_boost_week, } if not check_tag_valid(tag, gameweeks, season=season): print( "ERROR: Database does not contain predictions", "for all the specified optimsation gameweeks.\n", "Please run 'airsenal_run_prediction' first with the", "same input gameweeks and season you specified here.", ) sys.exit(1) set_multiprocessing_start_method(num_thread) with warnings.catch_warnings(): warnings.simplefilter("ignore", TqdmWarning) run_optimization( gameweeks, tag, season, fpl_team_id, chip_gameweeks, num_free_transfers, max_total_hit, allow_unused_transfers, 2, num_iterations, num_thread, profile, )
def main(): """ The main function, to be used as entrypoint. """ parser = argparse.ArgumentParser( description="Try some different transfer strategies") parser.add_argument("--weeks_ahead", help="how many weeks ahead", type=int) parser.add_argument("--gw_start", help="first gameweek to consider", type=int) parser.add_argument("--gw_end", help="last gameweek to consider", type=int) parser.add_argument("--tag", help="specify a string identifying prediction set") parser.add_argument( "--allow_wildcard", help="include possibility of wildcarding in one of the weeks", action="store_true", ) parser.add_argument( "--allow_free_hit", help="include possibility of playing free hit in one of the weeks", action="store_true", ) parser.add_argument( "--allow_triple_captain", help= "include possibility of playing triple captain in one of the weeks", action="store_true", ) parser.add_argument( "--allow_bench_boost", help="include possibility of playing bench boost in one of the weeks", action="store_true", ) parser.add_argument("--num_free_transfers", help="how many free transfers do we have", type=int) parser.add_argument( "--num_iterations", help="how many iterations to use for Wildcard/Free Hit optimization", type=int, default=100, ) parser.add_argument("--num_thread", help="how many threads to use", type=int, default=4) parser.add_argument( "--season", help="what season, in format e.g. '2021'", type=str, default=CURRENT_SEASON, ) parser.add_argument( "--profile", help="For developers: Profile strategy execution time", action="store_true", ) args = parser.parse_args() args_ok = sanity_check_args(args) season = args.season if args.weeks_ahead: gameweeks = list( range(get_next_gameweek(), get_next_gameweek() + args.weeks_ahead)) else: gameweeks = list(range(args.gw_start, args.gw_end)) num_iterations = args.num_iterations if args.allow_wildcard: wildcard = True else: wildcard = False if args.allow_free_hit: free_hit = True else: free_hit = False if args.allow_triple_captain: triple_captain = True else: triple_captain = False if args.allow_bench_boost: bench_boost = True else: bench_boost = False if args.num_free_transfers: num_free_transfers = args.num_free_transfers else: num_free_transfers = None # will work it out in run_optimization if args.tag: tag = args.tag else: ## get most recent set of predictions from DB table tag = get_latest_prediction_tag() num_thread = args.num_thread profile = args.profile if args.profile else False run_optimization( gameweeks, tag, season, wildcard, free_hit, triple_captain, bench_boost, num_free_transfers, num_iterations, num_thread, )