File size: 4,383 Bytes
119b2bf
 
10c821a
 
119b2bf
 
 
 
2bbbfdd
119b2bf
 
33beedc
2bbbfdd
119b2bf
02245bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55b8b36
02245bb
55b8b36
 
 
 
 
119b2bf
55b8b36
 
119b2bf
55b8b36
 
 
 
 
 
119b2bf
55b8b36
 
119b2bf
55b8b36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119b2bf
55b8b36
 
 
 
 
 
 
 
 
 
 
02245bb
55b8b36
 
dca21a5
55b8b36
119b2bf
433242b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import pandas as pd
import math
from global_func.small_field_preset import small_field_preset
from global_func.large_field_preset import large_field_preset

def hedging_preset(portfolio: pd.DataFrame, lineup_target: int, projections_file: pd.DataFrame):
    
    excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Similarity Score']
    list_size = 3

    check_own_df = projections_file.copy()
    check_own_df = check_own_df.sort_values(by='ownership', ascending=False)
    top_owned = check_own_df['player_names'].head(list_size).tolist()

    def get_team_hitter_ownership(projections_file: pd.DataFrame):
        """
        Calculate the sum ownership of hitters on each team.
        Excludes SP and P positions and sums ownership by team.
        
        Args:
            projections_file (pd.DataFrame): DataFrame with 'position', 'team', and 'ownership' columns
            
        Returns:
            pd.Series: Series with team names as index and total hitter ownership as values, sorted descending
        """
        # Filter out pitchers (SP and P positions)
        hitters_df = projections_file[~projections_file['position'].isin(['P', 'SP'])]
        
        # Group by team and sum ownership
        team_ownership = hitters_df.groupby('team')['ownership'].sum().sort_values(ascending=False)
    
        return team_ownership

    team_ownership = get_team_hitter_ownership(projections_file)
    top_owned_teams = team_ownership.head(list_size).index.tolist()
    init_counter = 6

    for runs in range(1, 5):
        concat_portfolio = pd.DataFrame(columns=portfolio.columns)
        for player in top_owned:
            print(player)
            working_df = portfolio.copy()

            # Create mask for lineups that contain any of the removed players
            player_columns = [col for col in working_df.columns if col not in excluded_cols]

            remove_mask = working_df[player_columns].apply(
                lambda row: player not in list(row), axis=1
            )
            lock_mask = working_df[player_columns].apply(
                lambda row: player in list(row), axis=1
            )

            removed_df = working_df[remove_mask]
            locked_df = working_df[lock_mask]

            removed_lineups = small_field_preset(removed_df, math.ceil(lineup_target / (list_size * init_counter)), excluded_cols)
            print(len(removed_lineups))
            # Check if locked_df is empty before calling large_field_preset
            if not locked_df.empty:
                locked_lineups = large_field_preset(locked_df, math.ceil(lineup_target / (list_size * init_counter)), excluded_cols)
                print(len(locked_lineups))
                concat_portfolio = pd.concat([concat_portfolio, removed_lineups, locked_lineups])
            else:
                # If no lineups contain this player, just add the removed lineups
                print(f"No lineups found containing {player}")
                concat_portfolio = pd.concat([concat_portfolio, removed_lineups])
        
        for team in top_owned_teams:
            working_df = portfolio.copy()
            removed_df = working_df[working_df['Stack'] != team]
            teams_df = working_df[working_df['Stack'] == team]

            removed_lineups = small_field_preset(removed_df, math.ceil(lineup_target / (list_size * init_counter)), excluded_cols)
            # Check if teams_df is empty before calling large_field_preset
            if not teams_df.empty:
                team_lineups = large_field_preset(teams_df, math.ceil(lineup_target / (list_size * init_counter)), excluded_cols)
                concat_portfolio = pd.concat([concat_portfolio, removed_lineups, team_lineups])
            else:
                # If no lineups have this team stacked, just add the removed lineups
                print(f"No lineups found with {team} stacked")
                concat_portfolio = pd.concat([concat_portfolio, removed_lineups])

        concat_portfolio = concat_portfolio.drop_duplicates(subset=['median', 'Own', 'Lineup Edge', 'Similarity Score'])

        if len(concat_portfolio) >= lineup_target:
            return concat_portfolio.head(lineup_target)
        else:
            init_counter -= 1

    return concat_portfolio.head(lineup_target)