DimaKudosh / pydfs-lineup-optimizer

Daily Fantasy Sports lineup optimzer for all popular daily fantasy sports sites
MIT License
424 stars 157 forks source link

Game stack with stack:opposing player #344

Open austinjohnson opened 2 years ago

austinjohnson commented 2 years ago

How can I do a game stack with the specified stack 3:1? The game stack rule only allows a 3:2, etc... Is there a way to do a game stack with only one run back?

Pro1spect commented 2 years ago

I think: optimizer.add_stack(GameStack(4, min_from_team=1))

BenikaH commented 1 month ago

I have a another solution if interested. I kept getting solver errors using the force_positions function. You'll have to update the GameStack function in Stacks.py. Comment the current one out, in case you don't like the lineups and paste this. Make sure that GameStack is imported already.

class GameStack(BaseStack):
    def __init__(
            self,
            size: int,
            max_exposure: Optional[float] = None,
            min_from_team: int = 1,
            positions_for_team: Optional[List[str]] = None,  # Positions for home team
            positions_for_opposing_team: Optional[List[str]] = None,  # Positions for away team
            teams: Optional[List[str]] = None  # Specify teams to include in stacking
    ):
        self.size = size
        self.max_exposure = max_exposure
        self.min_from_team = min_from_team
        self.positions_for_team = positions_for_team  # Store positions for home team
        self.positions_for_opposing_team = positions_for_opposing_team  # Store positions for away team
        self.teams = teams  # Store specific teams to include

    def build_stacks(self, players, optimizer):
        players_by_teams = get_players_grouped_by_teams(players)
        all_groups: List[BaseGroup] = []

        for game in optimizer.games:
            # Check if the current game's teams are in the specified teams list (if provided)
            if self.teams and game.home_team not in self.teams and game.away_team not in self.teams:
                continue  # Skip this game if neither team is in the specified list

            home_team_players = players_by_teams.get(game.home_team, [])
            away_team_players = players_by_teams.get(game.away_team, [])

            # Filter players by specified positions for home and opposing teams if provided
            if self.positions_for_team:
                home_team_players = [player for player in home_team_players if player.positions[0] in self.positions_for_team]
            if self.positions_for_opposing_team:
                away_team_players = [player for player in away_team_players if player.positions[0] in self.positions_for_opposing_team]

            # Build the groups for home and away teams
            groups = [PlayersGroup(
                players=home_team_players,
                min_from_group=self.min_from_team,
            ), PlayersGroup(
                players=away_team_players,
                min_from_group=self.min_from_team,
            ), PlayersGroup(
                players=[*home_team_players, *away_team_players],
                min_from_group=self.size,
            )]

            # Create the nested group and append to all_groups
            nested_group = NestedPlayersGroup(
                groups=groups,
                max_exposure=self.max_exposure,
            )
            all_groups.append(nested_group)

        return [OptimizerStack(groups=all_groups)]

    def validate(self, optimizer) -> None:
        if floor(self.size / 2) < self.min_from_team:
            raise LineupOptimizerException('min_from_team is greater than stack size')

You can then add the GameStack like so.

optimizer.add_stack(GameStack(
                size=3,
                min_from_team=2,
                positions_for_team=['QB', 'WR'],  # Home team positions
                positions_for_opposing_team=['WR'],  # Opposing team positions
                teams=['KC','TB'],  # Only stack players from Kansas City and Tampa Bay games
                max_exposure=0.3
            ))