From 84cd7f1c8e01afaa4403b375d50b5380f64b374c Mon Sep 17 00:00:00 2001 From: sid-plt <218677312+sid-plt@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:21:40 +0200 Subject: [PATCH] Refresh lineup workflows and generated outputs --- README.md | 5 +- .../kickbase_player_name_cross_references.csv | 1 + .../player_name_cross_references.csv | 9 + manual_lineup_helpers.py | 62 +- notebooks/02_odds/02_fotmob_match_odds.ipynb | 14 +- .../01_sofascore_recent_form.ipynb | 849 +- .../02_sofascore_team_stats.ipynb | 39 +- .../03_transfermarkt_squads.ipynb | 21 +- .../03_team_data/04_kbstats_players.ipynb | 19 +- .../05_sofascore_upcoming_matches.ipynb | 100 +- .../02_sofascore_high_rated_players.ipynb | 21 +- .../05_sofascore_player_average_ratings.ipynb | 41 +- ...ts_matchday_qualified_average_points.ipynb | 7 +- ...hday_qualified_last_5_average_points.ipynb | 7 +- .../01_rotowire_lineups.ipynb | 27 +- .../02_ligainsider_lineups.ipynb | 32 +- ...ore_overall_rating_odds_lineup_score.ipynb | 2887 +- .../manually_create_lineup.ipynb | 314 +- .../optimize_squad_all_limits_arena.ipynb | 1845 ++ .../optimize_squad_insider_arena.ipynb | 1765 ++ .../optimize_squad_max_2_per_team.ipynb | 143 +- ...optimize_squad_three_teams_exclusive.ipynb | 317 +- ...ze_squad_three_teams_overlap_allowed.ipynb | 321 +- .../optimize_squad_v1.ipynb | 145 +- ...rage_odds_lineup_20260819_141710_+0200.csv | 469 - ...rage_odds_lineup_20260819_141537_+0200.csv | 469 - ...ting_odds_lineup_20260819_150504_+0200.csv | 469 - ...ting_odds_lineup_20260819_150935_+0200.csv | 469 - ...ting_odds_lineup_20260823_180205_+0200.csv | 470 + ...ting_odds_lineup_20260823_204315_+0200.csv | 470 + ...ting_odds_lineup_20260823_205636_+0200.csv | 470 + ...ting_odds_lineup_20260825_121320_+0200.csv | 470 + .../fotmob/odds/matchday_1_odds_fotmob.json | 28 +- .../kbstats_players_20260823_175739_+0200.csv | 470 + ...kbstats_players_20260823_175739_+0200.json | 24390 ++++++++++++++++ .../kbstats_players_20260825_110735_+0200.csv | 470 + ...kbstats_players_20260825_110735_+0200.json | 24390 ++++++++++++++++ ...se_bundesliga_lineups_20260825_113858.json | 2878 ++ ...er_bundesliga_lineups_20260823_175954.json | 3126 ++ ...er_bundesliga_lineups_20260825_110923.json | 2906 ++ ...821_000810_+0200_20260821_000951_+0200.csv | 12 - ...821_232637_+0200_20260821_232653_+0200.csv | 12 - ...821_232637_+0200_20260821_232759_+0200.csv | 12 - ...823_005325_+0200_20260823_005626_+0200.csv | 12 - ...823_005325_+0200_20260823_005708_+0200.csv | 12 - ...823_005325_+0200_20260823_133038_+0200.csv | 12 - ...825_121320_+0200_20260825_124739_+0200.csv | 12 + ...825_121320_+0200_20260825_125445_+0200.csv | 12 + ...825_121320_+0200_20260825_125710_+0200.csv | 12 + ...825_121320_+0200_20260825_130825_+0200.csv | 12 + ...825_121320_+0200_20260825_190737_+0200.csv | 12 + ...825_121320_+0200_20260825_124229_+0200.csv | 12 + ...825_121320_+0200_20260825_124229_+0200.csv | 12 + ...825_121320_+0200_20260825_190644_+0200.csv | 12 + ...825_121320_+0200_20260825_190644_+0200.csv | 12 + ...825_121320_+0200_20260825_190644_+0200.csv | 12 + ...re_bundesliga_lineups_20260823_175927.json | 1751 ++ ...re_bundesliga_lineups_20260825_110858.json | 1751 ++ .../selected_lineups/all-limits-arena.json | 131 + .../selected_lineups/bundesliga-arena.json | 134 + .../kickbase.insider-arena.json | 84 + .../selected_lineups/kickbasekis-arena.json | 130 + outputs/sofascore/odds/matchday_1_odds.json | 12 +- ...atings_2026-08-18_10-39-16_045127+0200.csv | 336 - ...atings_2026-08-18_12-55-05_288543+0200.csv | 1 - ...tings_2026-08-18_12-55-05_288543+0200.json | 1346 - ...tings_2026-08-23_17-58-37_302679+0200.csv} | 469 +- ...ings_2026-08-23_17-58-37_302679+0200.json} | 7619 +++-- ...tings_2026-08-23_20-55-39_758540+0200.csv} | 514 +- ...ings_2026-08-23_20-55-39_758540+0200.json} | 8625 +++--- ...atings_2026-08-25_11-08-44_203527+0200.csv | 611 + ...ings_2026-08-25_11-08-44_203527+0200.json} | 8652 ++++-- ...atings_2026-08-25_12-05-13_232059+0200.csv | 687 + ...tings_2026-08-25_12-05-13_232059+0200.json | 13571 +++++++++ ...form_2026-08-23_17-55-38_217152+0200.json} | 1524 +- ...form_2026-08-23_20-42-32_490761+0200.json} | 2036 +- ...form_2026-08-23_20-53-57_662850+0200.json} | 2045 +- ..._form_2026-08-25_11-02-05_869307+0200.json | 2502 ++ ..._team_statistics_md_1_20260825T090222Z.csv | 16 + ...team_statistics_md_1_20260825T090222Z.json | 1917 ++ ..._md_2_2026-08-23_17-57-53_708387+0200.json | 674 + ..._md_2_2026-08-25_11-07-45_776026+0200.json | 674 + ...bundesliga_squads_2026_20260823_175610.csv | 546 + ...undesliga_squads_2026_20260823_175610.json | 9569 ++++++ ..._20260823_175610_team_market_value_p80.csv | 119 + ...bundesliga_squads_2026_20260825_110652.csv | 545 + ...undesliga_squads_2026_20260825_110652.json | 9553 ++++++ ..._20260825_110652_team_market_value_p80.csv | 120 + selected_lineups.py | 60 +- tests/test_all_limits_arena_notebook.py | 25 + tests/test_insider_arena_notebook.py | 22 + tests/test_manual_lineup_helpers.py | 46 + tests/test_selected_lineups.py | 89 + 93 files changed, 131144 insertions(+), 18959 deletions(-) create mode 100644 notebooks/07_squad_optimisation/optimize_squad_all_limits_arena.ipynb create mode 100644 notebooks/07_squad_optimisation/optimize_squad_insider_arena.ipynb delete mode 100644 outputs/expected_points/expected_points_20260818_204143_+0200_kbstats_last_5_average_odds_lineup_20260819_141710_+0200.csv delete mode 100644 outputs/expected_points/expected_points_20260818_204143_+0200_kbstats_season_average_odds_lineup_20260819_141537_+0200.csv delete mode 100644 outputs/expected_points/expected_points_20260818_204143_+0200_sofascore_overall_rating_odds_lineup_20260819_150504_+0200.csv delete mode 100644 outputs/expected_points/expected_points_20260818_204143_+0200_sofascore_overall_rating_odds_lineup_20260819_150935_+0200.csv create mode 100644 outputs/expected_points/expected_points_20260823_175739_+0200_sofascore_overall_rating_odds_lineup_20260823_180205_+0200.csv create mode 100644 outputs/expected_points/expected_points_20260823_175739_+0200_sofascore_overall_rating_odds_lineup_20260823_204315_+0200.csv create mode 100644 outputs/expected_points/expected_points_20260823_175739_+0200_sofascore_overall_rating_odds_lineup_20260823_205636_+0200.csv create mode 100644 outputs/expected_points/expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv create mode 100644 outputs/kbstats/players/kbstats_players_20260823_175739_+0200.csv create mode 100644 outputs/kbstats/players/kbstats_players_20260823_175739_+0200.json create mode 100644 outputs/kbstats/players/kbstats_players_20260825_110735_+0200.csv create mode 100644 outputs/kbstats/players/kbstats_players_20260825_110735_+0200.json create mode 100644 outputs/kickbase/predicted_lineups/kickbase_bundesliga_lineups_20260825_113858.json create mode 100644 outputs/ligainsider/predicted_lineups/ligainsider_bundesliga_lineups_20260823_175954.json create mode 100644 outputs/ligainsider/predicted_lineups/ligainsider_bundesliga_lineups_20260825_110923.json delete mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260818_204143_+0200_20260821_000810_+0200_20260821_000951_+0200.csv delete mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260818_204143_+0200_20260821_232637_+0200_20260821_232653_+0200.csv delete mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260818_204143_+0200_20260821_232637_+0200_20260821_232759_+0200.csv delete mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260823_004913_+0200_20260823_005325_+0200_20260823_005626_+0200.csv delete mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260823_004913_+0200_20260823_005325_+0200_20260823_005708_+0200.csv delete mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260823_004913_+0200_20260823_005325_+0200_20260823_133038_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_124739_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125445_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125710_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_130825_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190737_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_three_teams_exclusive_team_2_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_124229_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_three_teams_exclusive_team_3_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_124229_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_1_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190644_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_2_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190644_+0200.csv create mode 100644 outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_3_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190644_+0200.csv create mode 100644 outputs/rotowire/predicted_lineups/rotowire_bundesliga_lineups_20260823_175927.json create mode 100644 outputs/rotowire/predicted_lineups/rotowire_bundesliga_lineups_20260825_110858.json create mode 100644 outputs/selected_lineups/all-limits-arena.json create mode 100644 outputs/selected_lineups/bundesliga-arena.json create mode 100644 outputs/selected_lineups/kickbase.insider-arena.json create mode 100644 outputs/selected_lineups/kickbasekis-arena.json delete mode 100644 outputs/sofascore/player_average_ratings/team_player_average_ratings_2026-08-18_10-39-16_045127+0200.csv delete mode 100644 outputs/sofascore/player_average_ratings/team_player_average_ratings_2026-08-18_12-55-05_288543+0200.csv delete mode 100644 outputs/sofascore/player_average_ratings/team_player_average_ratings_2026-08-18_12-55-05_288543+0200.json rename outputs/sofascore/player_average_ratings/{team_player_average_ratings_2026-08-18_20-43-43_154658+0200.csv => team_player_average_ratings_2026-08-23_17-58-37_302679+0200.csv} (63%) rename outputs/sofascore/player_average_ratings/{team_player_average_ratings_2026-08-18_20-43-43_154658+0200.json => team_player_average_ratings_2026-08-23_17-58-37_302679+0200.json} (87%) rename outputs/sofascore/player_average_ratings/{team_player_average_ratings_2026-08-18_12-55-46_358670+0200.csv => team_player_average_ratings_2026-08-23_20-55-39_758540+0200.csv} (59%) rename outputs/sofascore/player_average_ratings/{team_player_average_ratings_2026-08-18_12-55-46_358670+0200.json => team_player_average_ratings_2026-08-23_20-55-39_758540+0200.json} (84%) create mode 100644 outputs/sofascore/player_average_ratings/team_player_average_ratings_2026-08-25_11-08-44_203527+0200.csv rename outputs/sofascore/player_average_ratings/{team_player_average_ratings_2026-08-18_10-39-16_045127+0200.json => team_player_average_ratings_2026-08-25_11-08-44_203527+0200.json} (65%) create mode 100644 outputs/sofascore/player_average_ratings/team_player_average_ratings_2026-08-25_12-05-13_232059+0200.csv create mode 100644 outputs/sofascore/player_average_ratings/team_player_average_ratings_2026-08-25_12-05-13_232059+0200.json rename outputs/sofascore/team_form/{team_form_2026-08-17_09-49-32_831323+0200.json => team_form_2026-08-23_17-55-38_217152+0200.json} (92%) rename outputs/sofascore/team_form/{team_form_2026-08-10_18-16-58_140922+0200.json => team_form_2026-08-23_20-42-32_490761+0200.json} (86%) rename outputs/sofascore/team_form/{team_form_2026-08-09_20-59-40_227841+0200.json => team_form_2026-08-23_20-53-57_662850+0200.json} (85%) create mode 100644 outputs/sofascore/team_form/team_form_2026-08-25_11-02-05_869307+0200.json create mode 100644 outputs/sofascore/team_stats/bundesliga_team_statistics_md_1_20260825T090222Z.csv create mode 100644 outputs/sofascore/team_stats/bundesliga_team_statistics_md_1_20260825T090222Z.json create mode 100644 outputs/sofascore/upcoming_matches/upcoming_matches_md_2_2026-08-23_17-57-53_708387+0200.json create mode 100644 outputs/sofascore/upcoming_matches/upcoming_matches_md_2_2026-08-25_11-07-45_776026+0200.json create mode 100644 outputs/transfermarkt/squads/transfermarkt_bundesliga_squads_2026_20260823_175610.csv create mode 100644 outputs/transfermarkt/squads/transfermarkt_bundesliga_squads_2026_20260823_175610.json create mode 100644 outputs/transfermarkt/squads/transfermarkt_bundesliga_squads_2026_20260823_175610_team_market_value_p80.csv create mode 100644 outputs/transfermarkt/squads/transfermarkt_bundesliga_squads_2026_20260825_110652.csv create mode 100644 outputs/transfermarkt/squads/transfermarkt_bundesliga_squads_2026_20260825_110652.json create mode 100644 outputs/transfermarkt/squads/transfermarkt_bundesliga_squads_2026_20260825_110652_team_market_value_p80.csv create mode 100644 tests/test_all_limits_arena_notebook.py create mode 100644 tests/test_insider_arena_notebook.py diff --git a/README.md b/README.md index 35bf146..4f6ddef 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,9 @@ player data from SofaScore, FotMob, Transfermarkt, KBStats, and Analyst. KBStats last-five-match-slot analysis. - `notebooks/05_predicted_lineups`: live predicted and confirmed lineup collectors. -- `notebooks/07_squad_optimisation`: optimizer notebooks for Bundesliga Arena - and KickbaseKIS Arena, plus `manually_create_lineup.ipynb` for manual entry. +- `notebooks/07_squad_optimisation`: optimizer notebooks for Bundesliga Arena, + KickbaseKIS Arena, All Limits Arena, and Kickbase.insider Arena, plus + `manually_create_lineup.ipynb` for manual entry. - `notebooks/tests`: diagnostic notebooks that are not production pipeline steps. - `data/reference/kickbase`: curated Kickbase scoring and event-frequency rules. - `outputs/sofascore`: SofaScore match IDs, odds, team reference, form, team diff --git a/data/reference/kickbase_player_name_cross_references.csv b/data/reference/kickbase_player_name_cross_references.csv index 7662d96..1e52674 100644 --- a/data/reference/kickbase_player_name_cross_references.csv +++ b/data/reference/kickbase_player_name_cross_references.csv @@ -2,3 +2,4 @@ schalke,Timo Becker,T. BECKER,2026-08-19T13:29:03+02:00 bremen,Paul Erevbenagie,Erebenagie,2026-08-19T13:29:07+02:00 leipzig,Maarten Vandevoordt,VANDEVOORT,2026-08-19T13:29:30+02:00 +schalke,Vitalie Becker,V. BECKER,2026-08-25T12:10:49+02:00 diff --git a/data/reference/player_name_cross_references.csv b/data/reference/player_name_cross_references.csv index 88d2297..2599140 100644 --- a/data/reference/player_name_cross_references.csv +++ b/data/reference/player_name_cross_references.csv @@ -39,6 +39,10 @@ sofascore,,Lukeba Castello Jr.,976421,Castello Lukeba,2026-08-18T19:50:00+02:00 sofascore,,Frederik Rönnow,137692,Frederik Rønnow,2026-08-18T23:06:02+02:00 sofascore,,Lukasz Poreba,942336,Łukasz Poręba,2026-08-23T00:53:03+02:00 sofascore,,Florian Le Joncour,787816,Florian Yves Le Joncour,2026-08-23T00:53:06+02:00 +sofascore,,Lukas Emanuel Petkov,960017,Lukas Petkov,2026-08-23T18:00:56+02:00 +sofascore,,Albert Frank Millgramm,2122582,Albert Millgramm,2026-08-23T20:56:09+02:00 +sofascore,,Éric Dina Ebimbe,904994,Eric Ebimbe,2026-08-25T12:10:25+02:00 +sofascore,,Tom Rothe,1210666,Tom Alexander Rothe,2026-08-25T12:11:32+02:00 ligainsider,bayern,Kim Minjae,27022,Minjae Kim,2026-08-18T19:37:20+02:00 ligainsider,leverkusen,Ezequiél Fernández,38674,Equi Fernandez,2026-08-18T19:45:31+02:00 ligainsider,frankfurt,Oscar Højlund,37210,Oscar Hoejlund,2026-08-18T19:47:54+02:00 @@ -73,3 +77,8 @@ ligainsider,schalke,Éric Dina Ebimbe,26881,Junior Dina Ebimbe,2026-08-18T23:08: ligainsider,stuttgart,Jeff Chabot,12583,Julian Chabot,2026-08-19T09:19:24+02:00 ligainsider,leipzig,Rômulo,38565,Romulo Cardoso,2026-08-19T09:19:26+02:00 ligainsider,bremen,Niclas Füllkrug,1867,Niclas Fuellkrug,2026-08-23T00:52:59+02:00 +ligainsider,frankfurt,Ayoube Amaimouni,38710,Ayoube Amaimouni Echghouyab,2026-08-23T18:00:58+02:00 +rotowire,mainz,Jae-Sung Lee,32009,Lee Jae-Sung,2026-08-23T18:01:22+02:00 +rotowire,paderborn,Albert Frank Millgramm,48815,Albert Millgramm,2026-08-23T20:56:05+02:00 +ligainsider,frankfurt,Mario Götze,501,Mario Goetze,2026-08-25T12:10:24+02:00 +rotowire,frankfurt,Ayoube Amaimouni,47580,Ayoube Amaimouni-Echghouyab,2026-08-25T12:10:34+02:00 diff --git a/manual_lineup_helpers.py b/manual_lineup_helpers.py index a122612..2f7bbbb 100644 --- a/manual_lineup_helpers.py +++ b/manual_lineup_helpers.py @@ -897,7 +897,7 @@ def prepare_optimization_data( # Manual-only arena, formation, name-resolution, validation, and display helpers. from dataclasses import dataclass from difflib import SequenceMatcher -from typing import Iterable +from typing import Iterable, Mapping from sofascore_average_rating_score import FUZZY_MATCH_THRESHOLD, MAX_PROMPT_CANDIDATES, normalize_name @@ -908,16 +908,49 @@ class ArenaRules: budget_eur: int max_players_per_club: int max_players_per_match: int = 4 + squad_size: int = 11 + formations: Mapping[str, Mapping[str, int]] | None = None + selected_lineup_filename: str | None = None + + +INSIDER_ARENA_FORMATIONS = { + "2-2-1": {"DEF": 2, "MID": 2, "FOR": 1}, + "2-1-2": {"DEF": 2, "MID": 1, "FOR": 2}, + "1-2-2": {"DEF": 1, "MID": 2, "FOR": 2}, +} ARENA_RULES = { - "Bundesliga Arena": ArenaRules("Bundesliga Arena", 250_000_000, 3), - "KickbaseKIS Arena": ArenaRules("KickbaseKIS Arena", 150_000_000, 2), + "Bundesliga Arena": ArenaRules( + "Bundesliga Arena", 250_000_000, 3, formations=ALLOWED_FORMATIONS + ), + "KickbaseKIS Arena": ArenaRules( + "KickbaseKIS Arena", 150_000_000, 2, formations=ALLOWED_FORMATIONS + ), + "All Limits Arena": ArenaRules( + "All Limits Arena", + 150_000_000, + 1, + max_players_per_match=2, + formations=ALLOWED_FORMATIONS, + selected_lineup_filename="all-limits-arena.json", + ), + "Kickbase.insider Arena": ArenaRules( + "Kickbase.insider Arena", + 180_000_000, + 1, + max_players_per_match=2, + squad_size=6, + formations=INSIDER_ARENA_FORMATIONS, + selected_lineup_filename="kickbase.insider-arena.json", + ), } ARENA_ALIASES = { "bundesligaarena": "Bundesliga Arena", "kickbasekisarena": "KickbaseKIS Arena", "kickbasekisarena": "KickbaseKIS Arena", + "alllimitsarena": "All Limits Arena", + "kickbaseinsiderarena": "Kickbase.insider Arena", } @@ -956,16 +989,17 @@ def normalize_formation(value: object) -> str: return re.sub(r"\s+", "", text) -def request_formation() -> tuple[str, dict[str, int]]: - """Prompt until a project-supported eleven-player formation is entered.""" +def request_formation(arena: ArenaRules) -> tuple[str, dict[str, int]]: + """Prompt until a formation valid for the chosen arena is entered.""" + formations = arena.formations or ALLOWED_FORMATIONS while True: - answer = normalize_formation(input(f"Formation ({', '.join(ALLOWED_FORMATIONS)}): ")) - counts = ALLOWED_FORMATIONS.get(answer) - if counts is not None and sum(counts.values()) + 1 == 11: + answer = normalize_formation(input(f"Formation ({', '.join(formations)}): ")) + counts = formations.get(answer) + if counts is not None and sum(counts.values()) + 1 == arena.squad_size: return answer, dict(counts) print( f"{answer!r} is not a supported formation. " - f"Choose one of: {', '.join(ALLOWED_FORMATIONS)}." + f"Choose one of: {', '.join(formations)}." ) @@ -1096,15 +1130,19 @@ def validate_manual_lineup( ) -> dict[str, object]: """Validate every optimizer rule without running the optimizer.""" checks: list[dict[str, object]] = [] - expected = {"GK": 1, **ALLOWED_FORMATIONS[formation]} + formations = arena.formations or ALLOWED_FORMATIONS + expected = {"GK": 1, **formations[formation]} actual_positions = prepared.positions.loc[selected_indices].value_counts().to_dict() - formation_ok = len(selected_indices) == 11 and all( + formation_ok = len(selected_indices) == arena.squad_size and all( actual_positions.get(position, 0) == count for position, count in expected.items() ) checks.append({ "rule": "Formation and squad size", "passed": formation_ok, - "details": f"actual={actual_positions}; expected={expected}; players={len(selected_indices)}/11", + "details": ( + f"actual={actual_positions}; expected={expected}; " + f"players={len(selected_indices)}/{arena.squad_size}" + ), "budget": False, }) ids = prepared.df.loc[selected_indices, prepared.columns["player_id"]].astype(str).str.strip() diff --git a/notebooks/02_odds/02_fotmob_match_odds.ipynb b/notebooks/02_odds/02_fotmob_match_odds.ipynb index 3ba6a9e..e9db749 100644 --- a/notebooks/02_odds/02_fotmob_match_odds.ipynb +++ b/notebooks/02_odds/02_fotmob_match_odds.ipynb @@ -869,9 +869,9 @@ " 'away_team': 'VfB Stuttgart',\n", " 'bookmakers': [{'bookmaker': 'Tipico',\n", " 'bookmaker_source_id': 171,\n", - " 'home_win': 1.27,\n", - " 'draw': 6.7,\n", - " 'away_win': 8.5}],\n", + " 'home_win': 1.25,\n", + " 'draw': 7.0,\n", + " 'away_win': 9.0}],\n", " 'issues': []},\n", " {'match_id': 5881146,\n", " 'home_team': 'Elversberg',\n", @@ -887,9 +887,9 @@ " 'away_team': 'Hoffenheim',\n", " 'bookmakers': [{'bookmaker': 'Tipico',\n", " 'bookmaker_source_id': 171,\n", - " 'home_win': 3.1,\n", + " 'home_win': 3.0,\n", " 'draw': 3.6,\n", - " 'away_win': 2.2}],\n", + " 'away_win': 2.25}],\n", " 'issues': []},\n", " {'match_id': 5881149,\n", " 'home_team': 'Mainz 05',\n", @@ -942,8 +942,8 @@ " 'bookmakers': [{'bookmaker': 'Tipico',\n", " 'bookmaker_source_id': 171,\n", " 'home_win': 2.15,\n", - " 'draw': 3.7,\n", - " 'away_win': 3.1}],\n", + " 'draw': 3.6,\n", + " 'away_win': 3.2}],\n", " 'issues': []}]\n", "\n", "Summary\n", diff --git a/notebooks/03_team_data/01_sofascore_recent_form.ipynb b/notebooks/03_team_data/01_sofascore_recent_form.ipynb index 3bf5824..81269ae 100644 --- a/notebooks/03_team_data/01_sofascore_recent_form.ipynb +++ b/notebooks/03_team_data/01_sofascore_recent_form.ipynb @@ -103,9 +103,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "Execution timestamp: 2026-08-23T00:46:27.454341+02:00\n", + "Execution timestamp: 2026-08-25T11:02:05.869307+02:00\n", "Team input file: C:\\kickbase project\\outputs\\sofascore\\reference\\bundesliga_teams.json\n", - "Snapshot output file: C:\\kickbase project\\outputs\\sofascore\\team_form\\team_form_2026-08-23_00-46-27_454341+0200.json\n" + "Snapshot output file: C:\\kickbase project\\outputs\\sofascore\\team_form\\team_form_2026-08-25_11-02-05_869307+0200.json\n" ] } ], @@ -723,7 +723,7 @@ " 2\n", " 2671\n", " 1. FC Köln\n", - " WWWDW\n", + " WWDWW\n", " 5\n", " DLDLL\n", " 5\n", @@ -741,7 +741,7 @@ " 4\n", " 2547\n", " 1. FC Union Berlin\n", - " LLDWL\n", + " LDWLW\n", " 5\n", " LLDWW\n", " 5\n", @@ -759,7 +759,7 @@ " 6\n", " 2556\n", " 1. FSV Mainz 05\n", - " WWDWW\n", + " WDWWW\n", " 5\n", " DLWLW\n", " 5\n", @@ -768,7 +768,7 @@ " 7\n", " 2561\n", " SC Paderborn 07\n", - " WLWWD\n", + " LWWDW\n", " 5\n", " DD\n", " 2\n", @@ -822,7 +822,7 @@ " 13\n", " 2676\n", " Hamburger SV\n", - " LWLDW\n", + " WLDWW\n", " 5\n", " LLWWD\n", " 5\n", @@ -831,7 +831,7 @@ " 14\n", " 2538\n", " SC Freiburg\n", - " WLWWW\n", + " LWWWW\n", " 5\n", " WLDLW\n", " 5\n", @@ -840,7 +840,7 @@ " 15\n", " 2534\n", " SV Werder Bremen\n", - " WWDLW\n", + " WDLWW\n", " 5\n", " WDLLL\n", " 5\n", @@ -858,7 +858,7 @@ " 17\n", " 2530\n", " FC Schalke 04\n", - " WWWLL\n", + " WWLLD\n", " 5\n", " \n", " 0\n", @@ -871,22 +871,22 @@ " team_id team overall_form overall_match_count \\\n", "0 2672 FC Bayern München WWWWW 5 \n", "1 2677 VfB Stuttgart WDWLW 5 \n", - "2 2671 1. FC Köln WWWDW 5 \n", + "2 2671 1. FC Köln WWDWW 5 \n", "3 2569 TSG Hoffenheim WLLDW 5 \n", - "4 2547 1. FC Union Berlin LLDWL 5 \n", + "4 2547 1. FC Union Berlin LDWLW 5 \n", "5 2674 Eintracht Frankfurt WWWLW 5 \n", - "6 2556 1. FSV Mainz 05 WWDWW 5 \n", - "7 2561 SC Paderborn 07 WLWWD 5 \n", + "6 2556 1. FSV Mainz 05 WDWWW 5 \n", + "7 2561 SC Paderborn 07 LWWDW 5 \n", "8 36360 RB Leipzig WWLLW 5 \n", "9 2527 Borussia M'gladbach WWWWW 5 \n", "10 2598 SV 07 Elversberg WWDWW 5 \n", "11 2681 Bayer 04 Leverkusen WWLWW 5 \n", "12 2673 Borussia Dortmund LWWDL 5 \n", - "13 2676 Hamburger SV LWLDW 5 \n", - "14 2538 SC Freiburg WLWWW 5 \n", - "15 2534 SV Werder Bremen WWDLW 5 \n", + "13 2676 Hamburger SV WLDWW 5 \n", + "14 2538 SC Freiburg LWWWW 5 \n", + "15 2534 SV Werder Bremen WDLWW 5 \n", "16 2600 FC Augsburg LWWLW 5 \n", - "17 2530 FC Schalke 04 WWWLL 5 \n", + "17 2530 FC Schalke 04 WWLLD 5 \n", "\n", " bundesliga_form bundesliga_match_count \n", "0 WWDWW 5 \n", @@ -1490,7 +1490,7 @@ "text": [ "\n", "1. FC Köln (team_id=2671)\n", - "Overall form: WWWDW\n" + "Overall form: WWDWW\n" ] }, { @@ -1529,19 +1529,6 @@ " \n", " \n", " 0\n", - " 2026-07-13T16:00:00+00:00\n", - " Club Friendly Games\n", - " SV Bergisch Gladbach 09\n", - " 1. FC Köln\n", - " 0\n", - " 8\n", - " W\n", - " 16400192\n", - " 1783958400\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-07-18T09:00:00+00:00\n", " Club Friendly Games\n", " 1. FC Köln\n", @@ -1554,7 +1541,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-07-23T16:15:00+00:00\n", " Club Friendly Games\n", " SV Bergisch Gladbach 09\n", @@ -1567,7 +1554,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-07-31T10:00:00+00:00\n", " Club Friendly Games\n", " 1. FC Köln\n", @@ -1580,7 +1567,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-08T13:30:00+00:00\n", " Club Friendly Games\n", " 1. FC Köln\n", @@ -1592,31 +1579,44 @@ " 1786195800\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-24T16:00:00+00:00\n", + " DFB Pokal\n", + " FC Würzburger Kickers\n", + " 1. FC Köln\n", + " 1\n", + " 2\n", + " W\n", + " 16287059\n", + " 1787587200\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ " date competition home_team \\\n", - "0 2026-07-13T16:00:00+00:00 Club Friendly Games SV Bergisch Gladbach 09 \n", - "1 2026-07-18T09:00:00+00:00 Club Friendly Games 1. FC Köln \n", - "2 2026-07-23T16:15:00+00:00 Club Friendly Games SV Bergisch Gladbach 09 \n", - "3 2026-07-31T10:00:00+00:00 Club Friendly Games 1. FC Köln \n", - "4 2026-08-08T13:30:00+00:00 Club Friendly Games 1. FC Köln \n", + "0 2026-07-18T09:00:00+00:00 Club Friendly Games 1. FC Köln \n", + "1 2026-07-23T16:15:00+00:00 Club Friendly Games SV Bergisch Gladbach 09 \n", + "2 2026-07-31T10:00:00+00:00 Club Friendly Games 1. FC Köln \n", + "3 2026-08-08T13:30:00+00:00 Club Friendly Games 1. FC Köln \n", + "4 2026-08-24T16:00:00+00:00 DFB Pokal FC Würzburger Kickers \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 1. FC Köln 0 8 W 16400192 1783958400 \n", - "1 FC Rheinsud Koln 5 0 W 16485214 1784365200 \n", - "2 1. FC Köln 0 8 W 16576563 1784823300 \n", - "3 Hertha BSC 2 2 D 16659200 1785492000 \n", - "4 Real Sociedad 2 1 W 16408303 1786195800 \n", + "0 FC Rheinsud Koln 5 0 W 16485214 1784365200 \n", + "1 1. FC Köln 0 8 W 16576563 1784823300 \n", + "2 Hertha BSC 2 2 D 16659200 1785492000 \n", + "3 Real Sociedad 2 1 W 16408303 1786195800 \n", + "4 1. FC Köln 1 2 W 16287059 1787587200 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -2038,7 +2038,7 @@ "text": [ "\n", "1. FC Union Berlin (team_id=2547)\n", - "Overall form: LLDWL\n" + "Overall form: LDWLW\n" ] }, { @@ -2077,19 +2077,6 @@ " \n", " \n", " 0\n", - " 2026-07-18T14:00:00+00:00\n", - " Club Friendly Games\n", - " FC Aarau\n", - " 1. FC Union Berlin\n", - " 2\n", - " 1\n", - " L\n", - " 16317789\n", - " 1784383200\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-08-01T12:00:00+00:00\n", " Club Friendly Games\n", " SG Dynamo Dresden\n", @@ -2102,7 +2089,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-02T12:00:00+00:00\n", " Club Friendly Games\n", " 1. FC Union Berlin\n", @@ -2115,7 +2102,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-09T13:30:00+00:00\n", " Club Friendly Games\n", " 1. FC Union Berlin\n", @@ -2128,7 +2115,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-15T13:30:00+00:00\n", " Club Friendly Games\n", " 1. FC Union Berlin\n", @@ -2140,31 +2127,44 @@ " 1786800600\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-23T13:30:00+00:00\n", + " DFB Pokal\n", + " Eintracht Braunschweig\n", + " 1. FC Union Berlin\n", + " 2\n", + " 4\n", + " W\n", + " 16287045\n", + " 1787491800\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ - " date competition home_team \\\n", - "0 2026-07-18T14:00:00+00:00 Club Friendly Games FC Aarau \n", - "1 2026-08-01T12:00:00+00:00 Club Friendly Games SG Dynamo Dresden \n", - "2 2026-08-02T12:00:00+00:00 Club Friendly Games 1. FC Union Berlin \n", - "3 2026-08-09T13:30:00+00:00 Club Friendly Games 1. FC Union Berlin \n", - "4 2026-08-15T13:30:00+00:00 Club Friendly Games 1. FC Union Berlin \n", + " date competition home_team \\\n", + "0 2026-08-01T12:00:00+00:00 Club Friendly Games SG Dynamo Dresden \n", + "1 2026-08-02T12:00:00+00:00 Club Friendly Games 1. FC Union Berlin \n", + "2 2026-08-09T13:30:00+00:00 Club Friendly Games 1. FC Union Berlin \n", + "3 2026-08-15T13:30:00+00:00 Club Friendly Games 1. FC Union Berlin \n", + "4 2026-08-23T13:30:00+00:00 DFB Pokal Eintracht Braunschweig \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 1. FC Union Berlin 2 1 L 16317789 1784383200 \n", - "1 1. FC Union Berlin 2 1 L 16303077 1785585600 \n", - "2 Cagliari 2 2 D 16363515 1785672000 \n", - "3 Aris Limassol 3 2 W 16739436 1786282200 \n", - "4 Ipswich Town 2 4 L 16404063 1786800600 \n", + "0 1. FC Union Berlin 2 1 L 16303077 1785585600 \n", + "1 Cagliari 2 2 D 16363515 1785672000 \n", + "2 Aris Limassol 3 2 W 16739436 1786282200 \n", + "3 Ipswich Town 2 4 L 16404063 1786800600 \n", + "4 1. FC Union Berlin 2 4 W 16287045 1787491800 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -2586,7 +2586,7 @@ "text": [ "\n", "1. FSV Mainz 05 (team_id=2556)\n", - "Overall form: WWDWW\n" + "Overall form: WDWWW\n" ] }, { @@ -2625,19 +2625,6 @@ " \n", " \n", " 0\n", - " 2026-07-25T13:00:00+00:00\n", - " Club Friendly Games\n", - " 1. FSV Mainz 05\n", - " Holstein Kiel\n", - " 3\n", - " 0\n", - " W\n", - " 16331086\n", - " 1784984400\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-07-31T14:00:00+00:00\n", " Club Friendly Games\n", " 1. FSV Mainz 05\n", @@ -2650,7 +2637,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-01T14:00:00+00:00\n", " Club Friendly Games\n", " 1. FSV Mainz 05\n", @@ -2663,7 +2650,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-08T15:00:00+00:00\n", " Club Friendly Games\n", " 1. FSV Mainz 05\n", @@ -2676,7 +2663,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-15T13:30:00+00:00\n", " Club Friendly Games\n", " 1. FSV Mainz 05\n", @@ -2688,31 +2675,44 @@ " 1786800600\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-23T13:30:00+00:00\n", + " DFB Pokal\n", + " VfB 1921 Krieschow\n", + " 1. FSV Mainz 05\n", + " 0\n", + " 9\n", + " W\n", + " 16287042\n", + " 1787491800\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ - " date competition home_team \\\n", - "0 2026-07-25T13:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", - "1 2026-07-31T14:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", - "2 2026-08-01T14:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", - "3 2026-08-08T15:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", - "4 2026-08-15T13:30:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", + " date competition home_team \\\n", + "0 2026-07-31T14:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", + "1 2026-08-01T14:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", + "2 2026-08-08T15:00:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", + "3 2026-08-15T13:30:00+00:00 Club Friendly Games 1. FSV Mainz 05 \n", + "4 2026-08-23T13:30:00+00:00 DFB Pokal VfB 1921 Krieschow \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 Holstein Kiel 3 0 W 16331086 1784984400 \n", - "1 Shabab Al-Ahli Dubai 1 0 W 16564738 1785506400 \n", - "2 Udinese 3 3 D 16568868 1785592800 \n", - "3 Paris FC 4 0 W 16739557 1786201200 \n", - "4 Bournemouth 2 1 W 16435459 1786800600 \n", + "0 Shabab Al-Ahli Dubai 1 0 W 16564738 1785506400 \n", + "1 Udinese 3 3 D 16568868 1785592800 \n", + "2 Paris FC 4 0 W 16739557 1786201200 \n", + "3 Bournemouth 2 1 W 16435459 1786800600 \n", + "4 1. FSV Mainz 05 0 9 W 16287042 1787491800 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -2860,7 +2860,7 @@ "text": [ "\n", "SC Paderborn 07 (team_id=2561)\n", - "Overall form: WLWWD\n" + "Overall form: LWWDW\n" ] }, { @@ -2899,19 +2899,6 @@ " \n", " \n", " 0\n", - " 2026-07-17T15:00:00+00:00\n", - " Club Friendly Games\n", - " SC Paderborn 07\n", - " Fagiano Okayama\n", - " 2\n", - " 1\n", - " W\n", - " 16485367\n", - " 1784300400\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-07-25T11:00:00+00:00\n", " Club Friendly Games\n", " SC Paderborn 07\n", @@ -2924,7 +2911,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-07-29T10:30:00+00:00\n", " Club Friendly Games\n", " SC Paderborn 07\n", @@ -2937,7 +2924,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-01T13:30:00+00:00\n", " Club Friendly Games\n", " VfL Osnabrück\n", @@ -2950,7 +2937,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-08T12:00:00+00:00\n", " Club Friendly Games\n", " SV Werder Bremen\n", @@ -2962,31 +2949,44 @@ " 1786190400\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-23T16:00:00+00:00\n", + " DFB Pokal\n", + " 1.FC Phönix Lübeck\n", + " SC Paderborn 07\n", + " 2\n", + " 4\n", + " W\n", + " 16287053\n", + " 1787500800\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ - " date competition home_team \\\n", - "0 2026-07-17T15:00:00+00:00 Club Friendly Games SC Paderborn 07 \n", - "1 2026-07-25T11:00:00+00:00 Club Friendly Games SC Paderborn 07 \n", - "2 2026-07-29T10:30:00+00:00 Club Friendly Games SC Paderborn 07 \n", - "3 2026-08-01T13:30:00+00:00 Club Friendly Games VfL Osnabrück \n", - "4 2026-08-08T12:00:00+00:00 Club Friendly Games SV Werder Bremen \n", + " date competition home_team \\\n", + "0 2026-07-25T11:00:00+00:00 Club Friendly Games SC Paderborn 07 \n", + "1 2026-07-29T10:30:00+00:00 Club Friendly Games SC Paderborn 07 \n", + "2 2026-08-01T13:30:00+00:00 Club Friendly Games VfL Osnabrück \n", + "3 2026-08-08T12:00:00+00:00 Club Friendly Games SV Werder Bremen \n", + "4 2026-08-23T16:00:00+00:00 DFB Pokal 1.FC Phönix Lübeck \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 Fagiano Okayama 2 1 W 16485367 1784300400 \n", - "1 1. FC Magdeburg 0 2 L 16400333 1784977200 \n", - "2 Southampton 2 1 W 16665883 1785321000 \n", - "3 SC Paderborn 07 0 2 W 16489897 1785591000 \n", - "4 SC Paderborn 07 2 2 D 16489645 1786190400 \n", + "0 1. FC Magdeburg 0 2 L 16400333 1784977200 \n", + "1 Southampton 2 1 W 16665883 1785321000 \n", + "2 SC Paderborn 07 0 2 W 16489897 1785591000 \n", + "3 SC Paderborn 07 2 2 D 16489645 1786190400 \n", + "4 SC Paderborn 07 2 4 W 16287053 1787500800 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -3399,19 +3399,6 @@ " \n", " \n", " 0\n", - " 2026-07-25T12:00:00+00:00\n", - " Club Friendly Games\n", - " Rot-Weiss Essen\n", - " Borussia M'gladbach\n", - " 1\n", - " 2\n", - " W\n", - " 16293553\n", - " 1784980800\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-08-01T12:00:00+00:00\n", " Club Friendly Games\n", " FC Hansa Rostock\n", @@ -3424,7 +3411,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-07T14:00:00+00:00\n", " Club Friendly Games\n", " TSG Hoffenheim\n", @@ -3437,7 +3424,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-12T16:00:00+00:00\n", " Club Friendly Games\n", " SSVg Velbert\n", @@ -3450,7 +3437,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-15T13:30:00+00:00\n", " Club Friendly Games\n", " Borussia M'gladbach\n", @@ -3462,31 +3449,44 @@ " 1786800600\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-23T13:30:00+00:00\n", + " DFB Pokal\n", + " TSV Schott Mainz\n", + " Borussia M'gladbach\n", + " 0\n", + " 5\n", + " W\n", + " 16287039\n", + " 1787491800\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ " date competition home_team \\\n", - "0 2026-07-25T12:00:00+00:00 Club Friendly Games Rot-Weiss Essen \n", - "1 2026-08-01T12:00:00+00:00 Club Friendly Games FC Hansa Rostock \n", - "2 2026-08-07T14:00:00+00:00 Club Friendly Games TSG Hoffenheim \n", - "3 2026-08-12T16:00:00+00:00 Club Friendly Games SSVg Velbert \n", - "4 2026-08-15T13:30:00+00:00 Club Friendly Games Borussia M'gladbach \n", + "0 2026-08-01T12:00:00+00:00 Club Friendly Games FC Hansa Rostock \n", + "1 2026-08-07T14:00:00+00:00 Club Friendly Games TSG Hoffenheim \n", + "2 2026-08-12T16:00:00+00:00 Club Friendly Games SSVg Velbert \n", + "3 2026-08-15T13:30:00+00:00 Club Friendly Games Borussia M'gladbach \n", + "4 2026-08-23T13:30:00+00:00 DFB Pokal TSV Schott Mainz \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 Borussia M'gladbach 1 2 W 16293553 1784980800 \n", - "1 Borussia M'gladbach 1 3 W 16293554 1785585600 \n", - "2 Borussia M'gladbach 1 4 W 16743431 1786111200 \n", - "3 Borussia M'gladbach 0 8 W 16569177 1786550400 \n", - "4 Aston Villa 2 1 W 16284993 1786800600 \n", + "0 Borussia M'gladbach 1 3 W 16293554 1785585600 \n", + "1 Borussia M'gladbach 1 4 W 16743431 1786111200 \n", + "2 Borussia M'gladbach 0 8 W 16569177 1786550400 \n", + "3 Aston Villa 2 1 W 16284993 1786800600 \n", + "4 Borussia M'gladbach 0 5 W 16287039 1787491800 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -4322,7 +4322,7 @@ "text": [ "\n", "Hamburger SV (team_id=2676)\n", - "Overall form: LWLDW\n" + "Overall form: WLDWW\n" ] }, { @@ -4361,19 +4361,6 @@ " \n", " \n", " 0\n", - " 2026-07-18T17:00:00+00:00\n", - " Club Friendly Games\n", - " SK Rapid Wien\n", - " Hamburger SV\n", - " 3\n", - " 2\n", - " L\n", - " 16363505\n", - " 1784394000\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-07-25T11:30:00+00:00\n", " Club Friendly Games\n", " Hamburger SV\n", @@ -4386,7 +4373,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-01T15:00:00+00:00\n", " Club Friendly Games\n", " Hamburger SV\n", @@ -4399,7 +4386,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-08T13:00:00+00:00\n", " Club Friendly Games\n", " Hamburger SV\n", @@ -4412,7 +4399,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-15T17:00:00+00:00\n", " Club Friendly Games\n", " Toulouse\n", @@ -4424,31 +4411,44 @@ " 1786813200\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-24T16:00:00+00:00\n", + " DFB Pokal\n", + " SC Verl\n", + " Hamburger SV\n", + " 0\n", + " 3\n", + " W\n", + " 16287050\n", + " 1787587200\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ - " date competition home_team \\\n", - "0 2026-07-18T17:00:00+00:00 Club Friendly Games SK Rapid Wien \n", - "1 2026-07-25T11:30:00+00:00 Club Friendly Games Hamburger SV \n", - "2 2026-08-01T15:00:00+00:00 Club Friendly Games Hamburger SV \n", - "3 2026-08-08T13:00:00+00:00 Club Friendly Games Hamburger SV \n", - "4 2026-08-15T17:00:00+00:00 Club Friendly Games Toulouse \n", + " date competition home_team \\\n", + "0 2026-07-25T11:30:00+00:00 Club Friendly Games Hamburger SV \n", + "1 2026-08-01T15:00:00+00:00 Club Friendly Games Hamburger SV \n", + "2 2026-08-08T13:00:00+00:00 Club Friendly Games Hamburger SV \n", + "3 2026-08-15T17:00:00+00:00 Club Friendly Games Toulouse \n", + "4 2026-08-24T16:00:00+00:00 DFB Pokal SC Verl \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 Hamburger SV 3 2 L 16363505 1784394000 \n", - "1 1. FC Heidenheim 3 1 W 16571364 1784979000 \n", - "2 Everton 1 2 L 16424189 1785596400 \n", - "3 Lille 2 2 D 16739388 1786194000 \n", - "4 Hamburger SV 1 2 W 16568546 1786813200 \n", + "0 1. FC Heidenheim 3 1 W 16571364 1784979000 \n", + "1 Everton 1 2 L 16424189 1785596400 \n", + "2 Lille 2 2 D 16739388 1786194000 \n", + "3 Hamburger SV 1 2 W 16568546 1786813200 \n", + "4 Hamburger SV 0 3 W 16287050 1787587200 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -4589,7 +4589,7 @@ "text": [ "\n", "SC Freiburg (team_id=2538)\n", - "Overall form: WLWWW\n" + "Overall form: LWWWW\n" ] }, { @@ -4628,19 +4628,6 @@ " \n", " \n", " 0\n", - " 2026-07-24T14:00:00+00:00\n", - " Club Friendly Games\n", - " Derby County\n", - " SC Freiburg\n", - " 1\n", - " 3\n", - " W\n", - " 16293523\n", - " 1784901600\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-07-31T12:00:00+00:00\n", " Club Friendly Games\n", " SpVgg Greuther Fürth\n", @@ -4653,7 +4640,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-08T13:30:00+00:00\n", " Club Friendly Games\n", " SC Freiburg\n", @@ -4666,7 +4653,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-15T12:00:00+00:00\n", " Club Friendly Games\n", " SC Freiburg\n", @@ -4679,7 +4666,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-20T18:30:00+00:00\n", " UEFA Europa Conference League, Qualification P...\n", " Motherwell\n", @@ -4691,38 +4678,51 @@ " 1787250600\n", " 17015\n", " \n", + " \n", + " 4\n", + " 2026-08-23T16:00:00+00:00\n", + " DFB Pokal\n", + " Fortuna Düsseldorf\n", + " SC Freiburg\n", + " 1\n", + " 5\n", + " W\n", + " 16287037\n", + " 1787500800\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ " date \\\n", - "0 2026-07-24T14:00:00+00:00 \n", - "1 2026-07-31T12:00:00+00:00 \n", - "2 2026-08-08T13:30:00+00:00 \n", - "3 2026-08-15T12:00:00+00:00 \n", - "4 2026-08-20T18:30:00+00:00 \n", + "0 2026-07-31T12:00:00+00:00 \n", + "1 2026-08-08T13:30:00+00:00 \n", + "2 2026-08-15T12:00:00+00:00 \n", + "3 2026-08-20T18:30:00+00:00 \n", + "4 2026-08-23T16:00:00+00:00 \n", "\n", " competition home_team \\\n", - "0 Club Friendly Games Derby County \n", - "1 Club Friendly Games SpVgg Greuther Fürth \n", + "0 Club Friendly Games SpVgg Greuther Fürth \n", + "1 Club Friendly Games SC Freiburg \n", "2 Club Friendly Games SC Freiburg \n", - "3 Club Friendly Games SC Freiburg \n", - "4 UEFA Europa Conference League, Qualification P... Motherwell \n", + "3 UEFA Europa Conference League, Qualification P... Motherwell \n", + "4 DFB Pokal Fortuna Düsseldorf \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 SC Freiburg 1 3 W 16293523 1784901600 \n", - "1 SC Freiburg 3 0 L 16408670 1785499200 \n", - "2 RC Strasbourg 2 0 W 16489899 1786195800 \n", - "3 Crystal Palace 2 0 W 16400328 1786795200 \n", - "4 SC Freiburg 1 3 W 16717090 1787250600 \n", + "0 SC Freiburg 3 0 L 16408670 1785499200 \n", + "1 RC Strasbourg 2 0 W 16489899 1786195800 \n", + "2 Crystal Palace 2 0 W 16400328 1786795200 \n", + "3 SC Freiburg 1 3 W 16717090 1787250600 \n", + "4 SC Freiburg 1 5 W 16287037 1787500800 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", - "3 853 \n", - "4 17015 " + "3 17015 \n", + "4 217 " ] }, "metadata": {}, @@ -4863,7 +4863,7 @@ "text": [ "\n", "SV Werder Bremen (team_id=2534)\n", - "Overall form: WWDLW\n" + "Overall form: WDLWW\n" ] }, { @@ -4902,19 +4902,6 @@ " \n", " \n", " 0\n", - " 2026-07-25T11:00:00+00:00\n", - " Club Friendly Games\n", - " SV Werder Bremen\n", - " VfL Bochum 1848\n", - " 2\n", - " 0\n", - " W\n", - " 16400336\n", - " 1784977200\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-08-01T13:00:00+00:00\n", " Club Friendly Games\n", " Energie Cottbus\n", @@ -4927,7 +4914,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-08T12:00:00+00:00\n", " Club Friendly Games\n", " SV Werder Bremen\n", @@ -4940,7 +4927,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-15T12:30:00+00:00\n", " Club Friendly Games\n", " SV Werder Bremen\n", @@ -4953,7 +4940,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-22T13:30:00+00:00\n", " DFB Pokal\n", " LSK Hansa Lüneburg\n", @@ -4965,31 +4952,44 @@ " 1787405400\n", " 217\n", " \n", + " \n", + " 4\n", + " 2026-08-23T10:00:00+00:00\n", + " Club Friendly Games\n", + " SV Werder Bremen\n", + " SV Meppen\n", + " 3\n", + " 1\n", + " W\n", + " 16899911\n", + " 1787479200\n", + " 853\n", + " \n", " \n", "\n", "" ], "text/plain": [ " date competition home_team \\\n", - "0 2026-07-25T11:00:00+00:00 Club Friendly Games SV Werder Bremen \n", - "1 2026-08-01T13:00:00+00:00 Club Friendly Games Energie Cottbus \n", - "2 2026-08-08T12:00:00+00:00 Club Friendly Games SV Werder Bremen \n", - "3 2026-08-15T12:30:00+00:00 Club Friendly Games SV Werder Bremen \n", - "4 2026-08-22T13:30:00+00:00 DFB Pokal LSK Hansa Lüneburg \n", + "0 2026-08-01T13:00:00+00:00 Club Friendly Games Energie Cottbus \n", + "1 2026-08-08T12:00:00+00:00 Club Friendly Games SV Werder Bremen \n", + "2 2026-08-15T12:30:00+00:00 Club Friendly Games SV Werder Bremen \n", + "3 2026-08-22T13:30:00+00:00 DFB Pokal LSK Hansa Lüneburg \n", + "4 2026-08-23T10:00:00+00:00 Club Friendly Games SV Werder Bremen \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 VfL Bochum 1848 2 0 W 16400336 1784977200 \n", - "1 SV Werder Bremen 2 4 W 16303194 1785589200 \n", - "2 SC Paderborn 07 2 2 D 16489645 1786190400 \n", - "3 Auxerre 0 1 L 16570791 1786797000 \n", - "4 SV Werder Bremen 0 3 W 16287052 1787405400 \n", + "0 SV Werder Bremen 2 4 W 16303194 1785589200 \n", + "1 SC Paderborn 07 2 2 D 16489645 1786190400 \n", + "2 Auxerre 0 1 L 16570791 1786797000 \n", + "3 SV Werder Bremen 0 3 W 16287052 1787405400 \n", + "4 SV Meppen 3 1 W 16899911 1787479200 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", - "3 853 \n", - "4 217 " + "3 217 \n", + "4 853 " ] }, "metadata": {}, @@ -5404,7 +5404,7 @@ "text": [ "\n", "FC Schalke 04 (team_id=2530)\n", - "Overall form: WWWLL\n" + "Overall form: WWLLD\n" ] }, { @@ -5443,19 +5443,6 @@ " \n", " \n", " 0\n", - " 2026-07-22T14:00:00+00:00\n", - " Club Friendly Games\n", - " FC Kharkiv\n", - " FC Schalke 04\n", - " 0\n", - " 2\n", - " W\n", - " 16485216\n", - " 1784728800\n", - " 853\n", - " \n", - " \n", - " 1\n", " 2026-07-25T14:00:00+00:00\n", " Club Friendly Games\n", " FC Schalke 04\n", @@ -5468,7 +5455,7 @@ " 853\n", " \n", " \n", - " 2\n", + " 1\n", " 2026-08-01T12:00:00+00:00\n", " Club Friendly Games\n", " KSV Hessen Kassel\n", @@ -5481,7 +5468,7 @@ " 853\n", " \n", " \n", - " 3\n", + " 2\n", " 2026-08-08T15:00:00+00:00\n", " Club Friendly Games\n", " FC Schalke 04\n", @@ -5494,7 +5481,7 @@ " 853\n", " \n", " \n", - " 4\n", + " 3\n", " 2026-08-16T15:00:00+00:00\n", " Club Friendly Games\n", " FC Schalke 04\n", @@ -5506,31 +5493,44 @@ " 1786892400\n", " 853\n", " \n", + " \n", + " 4\n", + " 2026-08-24T18:45:00+00:00\n", + " DFB Pokal\n", + " Hallescher FC\n", + " FC Schalke 04\n", + " 2\n", + " 2\n", + " D\n", + " 16287064\n", + " 1787597100\n", + " 217\n", + " \n", " \n", "\n", "" ], "text/plain": [ " date competition home_team \\\n", - "0 2026-07-22T14:00:00+00:00 Club Friendly Games FC Kharkiv \n", - "1 2026-07-25T14:00:00+00:00 Club Friendly Games FC Schalke 04 \n", - "2 2026-08-01T12:00:00+00:00 Club Friendly Games KSV Hessen Kassel \n", - "3 2026-08-08T15:00:00+00:00 Club Friendly Games FC Schalke 04 \n", - "4 2026-08-16T15:00:00+00:00 Club Friendly Games FC Schalke 04 \n", + "0 2026-07-25T14:00:00+00:00 Club Friendly Games FC Schalke 04 \n", + "1 2026-08-01T12:00:00+00:00 Club Friendly Games KSV Hessen Kassel \n", + "2 2026-08-08T15:00:00+00:00 Club Friendly Games FC Schalke 04 \n", + "3 2026-08-16T15:00:00+00:00 Club Friendly Games FC Schalke 04 \n", + "4 2026-08-24T18:45:00+00:00 DFB Pokal Hallescher FC \n", "\n", " away_team home_score away_score result match_id timestamp \\\n", - "0 FC Schalke 04 0 2 W 16485216 1784728800 \n", - "1 Fagiano Okayama 3 1 W 16485302 1784988000 \n", - "2 FC Schalke 04 0 5 W 16293563 1785585600 \n", - "3 Atalanta 0 3 L 16400194 1786201200 \n", - "4 Real Madrid 0 3 L 16672725 1786892400 \n", + "0 Fagiano Okayama 3 1 W 16485302 1784988000 \n", + "1 FC Schalke 04 0 5 W 16293563 1785585600 \n", + "2 Atalanta 0 3 L 16400194 1786201200 \n", + "3 Real Madrid 0 3 L 16672725 1786892400 \n", + "4 FC Schalke 04 2 2 D 16287064 1787597100 \n", "\n", " unique_tournament_id \n", "0 853 \n", "1 853 \n", "2 853 \n", "3 853 \n", - "4 853 " + "4 217 " ] }, "metadata": {}, @@ -5586,7 +5586,7 @@ "output_type": "stream", "text": [ "{\n", - " \"2026-08-23T00:46:27.454341+02:00\": {\n", + " \"2026-08-25T11:02:05.869307+02:00\": {\n", " \"2672\": {\n", " \"team\": \"FC Bayern München\",\n", " \"overall_form\": \"WWWWW\",\n", @@ -5887,24 +5887,10 @@ " },\n", " \"2671\": {\n", " \"team\": \"1. FC Köln\",\n", - " \"overall_form\": \"WWWDW\",\n", + " \"overall_form\": \"WWDWW\",\n", " \"bundesliga_form\": \"DLDLL\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16400192,\n", - " \"date\": \"2026-07-13T16:00:00+00:00\",\n", - " \"timestamp\": 1783958400,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"SV Bergisch Gladbach 09\",\n", - " \"home_team_id\": 6173,\n", - " \"away_team\": \"1. FC Köln\",\n", - " \"away_team_id\": 2671,\n", - " \"home_score\": 0,\n", - " \"away_score\": 8,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16485214,\n", " \"date\": \"2026-07-18T09:00:00+00:00\",\n", " \"timestamp\": 1784365200,\n", @@ -5959,6 +5945,20 @@ " \"home_score\": 2,\n", " \"away_score\": 1,\n", " \"result\": \"W\"\n", + " },\n", + " {\n", + " \"match_id\": 16287059,\n", + " \"date\": \"2026-08-24T16:00:00+00:00\",\n", + " \"timestamp\": 1787587200,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"FC Würzburger Kickers\",\n", + " \"home_team_id\": 23947,\n", + " \"away_team\": \"1. FC Köln\",\n", + " \"away_team_id\": 2671,\n", + " \"home_score\": 1,\n", + " \"away_score\": 2,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -6185,24 +6185,10 @@ " },\n", " \"2547\": {\n", " \"team\": \"1. FC Union Berlin\",\n", - " \"overall_form\": \"LLDWL\",\n", + " \"overall_form\": \"LDWLW\",\n", " \"bundesliga_form\": \"LLDWW\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16317789,\n", - " \"date\": \"2026-07-18T14:00:00+00:00\",\n", - " \"timestamp\": 1784383200,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"FC Aarau\",\n", - " \"home_team_id\": 2447,\n", - " \"away_team\": \"1. FC Union Berlin\",\n", - " \"away_team_id\": 2547,\n", - " \"home_score\": 2,\n", - " \"away_score\": 1,\n", - " \"result\": \"L\"\n", - " },\n", - " {\n", " \"match_id\": 16303077,\n", " \"date\": \"2026-08-01T12:00:00+00:00\",\n", " \"timestamp\": 1785585600,\n", @@ -6257,6 +6243,20 @@ " \"home_score\": 2,\n", " \"away_score\": 4,\n", " \"result\": \"L\"\n", + " },\n", + " {\n", + " \"match_id\": 16287045,\n", + " \"date\": \"2026-08-23T13:30:00+00:00\",\n", + " \"timestamp\": 1787491800,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"Eintracht Braunschweig\",\n", + " \"home_team_id\": 2557,\n", + " \"away_team\": \"1. FC Union Berlin\",\n", + " \"away_team_id\": 2547,\n", + " \"home_score\": 2,\n", + " \"away_score\": 4,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -6483,24 +6483,10 @@ " },\n", " \"2556\": {\n", " \"team\": \"1. FSV Mainz 05\",\n", - " \"overall_form\": \"WWDWW\",\n", + " \"overall_form\": \"WDWWW\",\n", " \"bundesliga_form\": \"DLWLW\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16331086,\n", - " \"date\": \"2026-07-25T13:00:00+00:00\",\n", - " \"timestamp\": 1784984400,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"1. FSV Mainz 05\",\n", - " \"home_team_id\": 2556,\n", - " \"away_team\": \"Holstein Kiel\",\n", - " \"away_team_id\": 2573,\n", - " \"home_score\": 3,\n", - " \"away_score\": 0,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16564738,\n", " \"date\": \"2026-07-31T14:00:00+00:00\",\n", " \"timestamp\": 1785506400,\n", @@ -6555,6 +6541,20 @@ " \"home_score\": 2,\n", " \"away_score\": 1,\n", " \"result\": \"W\"\n", + " },\n", + " {\n", + " \"match_id\": 16287042,\n", + " \"date\": \"2026-08-23T13:30:00+00:00\",\n", + " \"timestamp\": 1787491800,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"VfB 1921 Krieschow\",\n", + " \"home_team_id\": 258720,\n", + " \"away_team\": \"1. FSV Mainz 05\",\n", + " \"away_team_id\": 2556,\n", + " \"home_score\": 0,\n", + " \"away_score\": 9,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -6632,24 +6632,10 @@ " },\n", " \"2561\": {\n", " \"team\": \"SC Paderborn 07\",\n", - " \"overall_form\": \"WLWWD\",\n", + " \"overall_form\": \"LWWDW\",\n", " \"bundesliga_form\": \"DD\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16485367,\n", - " \"date\": \"2026-07-17T15:00:00+00:00\",\n", - " \"timestamp\": 1784300400,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"SC Paderborn 07\",\n", - " \"home_team_id\": 2561,\n", - " \"away_team\": \"Fagiano Okayama\",\n", - " \"away_team_id\": 34034,\n", - " \"home_score\": 2,\n", - " \"away_score\": 1,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16400333,\n", " \"date\": \"2026-07-25T11:00:00+00:00\",\n", " \"timestamp\": 1784977200,\n", @@ -6704,6 +6690,20 @@ " \"home_score\": 2,\n", " \"away_score\": 2,\n", " \"result\": \"D\"\n", + " },\n", + " {\n", + " \"match_id\": 16287053,\n", + " \"date\": \"2026-08-23T16:00:00+00:00\",\n", + " \"timestamp\": 1787500800,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"1.FC Phönix Lübeck\",\n", + " \"home_team_id\": 323848,\n", + " \"away_team\": \"SC Paderborn 07\",\n", + " \"away_team_id\": 2561,\n", + " \"home_score\": 2,\n", + " \"away_score\": 4,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -6892,20 +6892,6 @@ " \"bundesliga_form\": \"DDWLW\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16293553,\n", - " \"date\": \"2026-07-25T12:00:00+00:00\",\n", - " \"timestamp\": 1784980800,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"Rot-Weiss Essen\",\n", - " \"home_team_id\": 2562,\n", - " \"away_team\": \"Borussia M'gladbach\",\n", - " \"away_team_id\": 2527,\n", - " \"home_score\": 1,\n", - " \"away_score\": 2,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16293554,\n", " \"date\": \"2026-08-01T12:00:00+00:00\",\n", " \"timestamp\": 1785585600,\n", @@ -6960,6 +6946,20 @@ " \"home_score\": 2,\n", " \"away_score\": 1,\n", " \"result\": \"W\"\n", + " },\n", + " {\n", + " \"match_id\": 16287039,\n", + " \"date\": \"2026-08-23T13:30:00+00:00\",\n", + " \"timestamp\": 1787491800,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"TSV Schott Mainz\",\n", + " \"home_team_id\": 162354,\n", + " \"away_team\": \"Borussia M'gladbach\",\n", + " \"away_team_id\": 2527,\n", + " \"home_score\": 0,\n", + " \"away_score\": 5,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -7413,24 +7413,10 @@ " },\n", " \"2676\": {\n", " \"team\": \"Hamburger SV\",\n", - " \"overall_form\": \"LWLDW\",\n", + " \"overall_form\": \"WLDWW\",\n", " \"bundesliga_form\": \"LLWWD\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16363505,\n", - " \"date\": \"2026-07-18T17:00:00+00:00\",\n", - " \"timestamp\": 1784394000,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"SK Rapid Wien\",\n", - " \"home_team_id\": 2055,\n", - " \"away_team\": \"Hamburger SV\",\n", - " \"away_team_id\": 2676,\n", - " \"home_score\": 3,\n", - " \"away_score\": 2,\n", - " \"result\": \"L\"\n", - " },\n", - " {\n", " \"match_id\": 16571364,\n", " \"date\": \"2026-07-25T11:30:00+00:00\",\n", " \"timestamp\": 1784979000,\n", @@ -7485,6 +7471,20 @@ " \"home_score\": 1,\n", " \"away_score\": 2,\n", " \"result\": \"W\"\n", + " },\n", + " {\n", + " \"match_id\": 16287050,\n", + " \"date\": \"2026-08-24T16:00:00+00:00\",\n", + " \"timestamp\": 1787587200,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"SC Verl\",\n", + " \"home_team_id\": 2593,\n", + " \"away_team\": \"Hamburger SV\",\n", + " \"away_team_id\": 2676,\n", + " \"home_score\": 0,\n", + " \"away_score\": 3,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -7562,24 +7562,10 @@ " },\n", " \"2538\": {\n", " \"team\": \"SC Freiburg\",\n", - " \"overall_form\": \"WLWWW\",\n", + " \"overall_form\": \"LWWWW\",\n", " \"bundesliga_form\": \"WLDLW\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16293523,\n", - " \"date\": \"2026-07-24T14:00:00+00:00\",\n", - " \"timestamp\": 1784901600,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"Derby County\",\n", - " \"home_team_id\": 27,\n", - " \"away_team\": \"SC Freiburg\",\n", - " \"away_team_id\": 2538,\n", - " \"home_score\": 1,\n", - " \"away_score\": 3,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16408670,\n", " \"date\": \"2026-07-31T12:00:00+00:00\",\n", " \"timestamp\": 1785499200,\n", @@ -7634,6 +7620,20 @@ " \"home_score\": 1,\n", " \"away_score\": 3,\n", " \"result\": \"W\"\n", + " },\n", + " {\n", + " \"match_id\": 16287037,\n", + " \"date\": \"2026-08-23T16:00:00+00:00\",\n", + " \"timestamp\": 1787500800,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"Fortuna Düsseldorf\",\n", + " \"home_team_id\": 2588,\n", + " \"away_team\": \"SC Freiburg\",\n", + " \"away_team_id\": 2538,\n", + " \"home_score\": 1,\n", + " \"away_score\": 5,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -7711,24 +7711,10 @@ " },\n", " \"2534\": {\n", " \"team\": \"SV Werder Bremen\",\n", - " \"overall_form\": \"WWDLW\",\n", + " \"overall_form\": \"WDLWW\",\n", " \"bundesliga_form\": \"WDLLL\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16400336,\n", - " \"date\": \"2026-07-25T11:00:00+00:00\",\n", - " \"timestamp\": 1784977200,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"SV Werder Bremen\",\n", - " \"home_team_id\": 2534,\n", - " \"away_team\": \"VfL Bochum 1848\",\n", - " \"away_team_id\": 2542,\n", - " \"home_score\": 2,\n", - " \"away_score\": 0,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16303194,\n", " \"date\": \"2026-08-01T13:00:00+00:00\",\n", " \"timestamp\": 1785589200,\n", @@ -7783,6 +7769,20 @@ " \"home_score\": 0,\n", " \"away_score\": 3,\n", " \"result\": \"W\"\n", + " },\n", + " {\n", + " \"match_id\": 16899911,\n", + " \"date\": \"2026-08-23T10:00:00+00:00\",\n", + " \"timestamp\": 1787479200,\n", + " \"competition\": \"Club Friendly Games\",\n", + " \"unique_tournament_id\": 853,\n", + " \"home_team\": \"SV Werder Bremen\",\n", + " \"home_team_id\": 2534,\n", + " \"away_team\": \"SV Meppen\",\n", + " \"away_team_id\": 5804,\n", + " \"home_score\": 3,\n", + " \"away_score\": 1,\n", + " \"result\": \"W\"\n", " }\n", " ],\n", " \"bundesliga_matches\": [\n", @@ -8009,24 +8009,10 @@ " },\n", " \"2530\": {\n", " \"team\": \"FC Schalke 04\",\n", - " \"overall_form\": \"WWWLL\",\n", + " \"overall_form\": \"WWLLD\",\n", " \"bundesliga_form\": \"\",\n", " \"overall_matches\": [\n", " {\n", - " \"match_id\": 16485216,\n", - " \"date\": \"2026-07-22T14:00:00+00:00\",\n", - " \"timestamp\": 1784728800,\n", - " \"competition\": \"Club Friendly Games\",\n", - " \"unique_tournament_id\": 853,\n", - " \"home_team\": \"FC Kharkiv\",\n", - " \"home_team_id\": 266889,\n", - " \"away_team\": \"FC Schalke 04\",\n", - " \"away_team_id\": 2530,\n", - " \"home_score\": 0,\n", - " \"away_score\": 2,\n", - " \"result\": \"W\"\n", - " },\n", - " {\n", " \"match_id\": 16485302,\n", " \"date\": \"2026-07-25T14:00:00+00:00\",\n", " \"timestamp\": 1784988000,\n", @@ -8081,6 +8067,20 @@ " \"home_score\": 0,\n", " \"away_score\": 3,\n", " \"result\": \"L\"\n", + " },\n", + " {\n", + " \"match_id\": 16287064,\n", + " \"date\": \"2026-08-24T18:45:00+00:00\",\n", + " \"timestamp\": 1787597100,\n", + " \"competition\": \"DFB Pokal\",\n", + " \"unique_tournament_id\": 217,\n", + " \"home_team\": \"Hallescher FC\",\n", + " \"home_team_id\": 2582,\n", + " \"away_team\": \"FC Schalke 04\",\n", + " \"away_team_id\": 2530,\n", + " \"home_score\": 2,\n", + " \"away_score\": 2,\n", + " \"result\": \"D\"\n", " }\n", " ],\n", " \"bundesliga_matches\": []\n", @@ -8147,19 +8147,18 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "93f085ab-b641-4ca0-bd09-2d09da77fc3f", - "metadata": {}, - "outputs": [], - "source": [] - } - , - { - "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "prune-timestamped-outputs", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pruned 1 expired timestamped output(s).\n" + ] + } + ], "source": [ "from project_paths import prune_timestamped_outputs\n", "\n", diff --git a/notebooks/03_team_data/02_sofascore_team_stats.ipynb b/notebooks/03_team_data/02_sofascore_team_stats.ipynb index e7a9a82..38285c0 100644 --- a/notebooks/03_team_data/02_sofascore_team_stats.ipynb +++ b/notebooks/03_team_data/02_sofascore_team_stats.ipynb @@ -773,8 +773,8 @@ "Total requests: 18\n", "Successful requests: 15\n", "Failed requests: 3\n", - "JSON output: C:\\kickbase project\\outputs\\sofascore\\team_stats\\bundesliga_team_statistics_md_1_20260822T224652Z.json\n", - "CSV output: C:\\kickbase project\\outputs\\sofascore\\team_stats\\bundesliga_team_statistics_md_1_20260822T224652Z.csv\n", + "JSON output: C:\\kickbase project\\outputs\\sofascore\\team_stats\\bundesliga_team_statistics_md_1_20260825T090222Z.json\n", + "CSV output: C:\\kickbase project\\outputs\\sofascore\\team_stats\\bundesliga_team_statistics_md_1_20260825T090222Z.csv\n", "\n", "Failed request summary:\n", " team team_id season_label season_id error_type error\n", @@ -835,7 +835,7 @@ " previous_season\n", " 77333\n", " 1\n", - " 2026-08-22T22:46:56+00:00\n", + " 2026-08-25T09:02:26+00:00\n", " 115\n", " 21.217712\n", " 1755\n", @@ -859,7 +859,7 @@ " previous_season\n", " 77333\n", " 1\n", - " 2026-08-22T22:46:57+00:00\n", + " 2026-08-25T09:02:27+00:00\n", " 177\n", " 25.991189\n", " 2364\n", @@ -883,7 +883,7 @@ " previous_season\n", " 77333\n", " 1\n", - " 2026-08-22T22:46:58+00:00\n", + " 2026-08-25T09:02:28+00:00\n", " 175\n", " 27.301092\n", " 3130\n", @@ -907,7 +907,7 @@ " previous_season\n", " 77333\n", " 1\n", - " 2026-08-22T22:46:59+00:00\n", + " 2026-08-25T09:02:29+00:00\n", " 196\n", " 28.571429\n", " 2309\n", @@ -931,7 +931,7 @@ " previous_season\n", " 77333\n", " 1\n", - " 2026-08-22T22:47:00+00:00\n", + " 2026-08-25T09:02:30+00:00\n", " 200\n", " 29.498525\n", " 3038\n", @@ -962,11 +962,11 @@ "4 1. FC Union Berlin 2547 previous_season 77333 \n", "\n", " matchday_at_capture capture_timestamp accurateCrosses \\\n", - "0 1 2026-08-22T22:46:56+00:00 115 \n", - "1 1 2026-08-22T22:46:57+00:00 177 \n", - "2 1 2026-08-22T22:46:58+00:00 175 \n", - "3 1 2026-08-22T22:46:59+00:00 196 \n", - "4 1 2026-08-22T22:47:00+00:00 200 \n", + "0 1 2026-08-25T09:02:26+00:00 115 \n", + "1 1 2026-08-25T09:02:27+00:00 177 \n", + "2 1 2026-08-25T09:02:28+00:00 175 \n", + "3 1 2026-08-25T09:02:29+00:00 196 \n", + "4 1 2026-08-25T09:02:30+00:00 200 \n", "\n", " accurateCrossesPercentage accurateFinalThirdPassesAgainst \\\n", "0 21.217712 1755 \n", @@ -1026,14 +1026,21 @@ "\n", "team_statistics_df.head()\n" ] - } - , + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "prune-timestamped-outputs", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pruned 0 expired timestamped output(s).\n" + ] + } + ], "source": [ "from project_paths import prune_timestamped_outputs\n", "\n", diff --git a/notebooks/03_team_data/03_transfermarkt_squads.ipynb b/notebooks/03_team_data/03_transfermarkt_squads.ipynb index c8bfb52..430e87c 100644 --- a/notebooks/03_team_data/03_transfermarkt_squads.ipynb +++ b/notebooks/03_team_data/03_transfermarkt_squads.ipynb @@ -907,10 +907,10 @@ "Players with market values: 528\n", "\n", "JSON:\n", - "C:\\kickbase project\\outputs\\transfermarkt\\squads\\transfermarkt_bundesliga_squads_2026_20260823_004740.json\n", + "C:\\kickbase project\\outputs\\transfermarkt\\squads\\transfermarkt_bundesliga_squads_2026_20260823_175610.json\n", "\n", "CSV:\n", - "C:\\kickbase project\\outputs\\transfermarkt\\squads\\transfermarkt_bundesliga_squads_2026_20260823_004740.csv\n", + "C:\\kickbase project\\outputs\\transfermarkt\\squads\\transfermarkt_bundesliga_squads_2026_20260823_175610.csv\n", "\n", "First player rows:\n" ] @@ -1600,7 +1600,7 @@ "Configured percentile: 80\n", "Players exported: 118\n", "CSV:\n", - "C:\\kickbase project\\outputs\\transfermarkt\\squads\\transfermarkt_bundesliga_squads_2026_20260823_004740_team_market_value_p80.csv\n" + "C:\\kickbase project\\outputs\\transfermarkt\\squads\\transfermarkt_bundesliga_squads_2026_20260823_175610_team_market_value_p80.csv\n" ] }, { @@ -2003,14 +2003,21 @@ "metadata": {}, "outputs": [], "source": [] - } - , + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "prune-timestamped-outputs", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pruned 0 expired timestamped output(s).\n" + ] + } + ], "source": [ "from project_paths import prune_timestamped_outputs\n", "\n", diff --git a/notebooks/03_team_data/04_kbstats_players.ipynb b/notebooks/03_team_data/04_kbstats_players.ipynb index 779caa7..4b9564f 100644 --- a/notebooks/03_team_data/04_kbstats_players.ipynb +++ b/notebooks/03_team_data/04_kbstats_players.ipynb @@ -133,8 +133,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "JSON saved to: C:\\kickbase project\\outputs\\kbstats\\players\\kbstats_players_20260823_004913_+0200.json\n", - "CSV saved to: C:\\kickbase project\\outputs\\kbstats\\players\\kbstats_players_20260823_004913_+0200.csv\n" + "JSON saved to: C:\\kickbase project\\outputs\\kbstats\\players\\kbstats_players_20260823_175739_+0200.json\n", + "CSV saved to: C:\\kickbase project\\outputs\\kbstats\\players\\kbstats_players_20260823_175739_+0200.csv\n" ] } ], @@ -400,14 +400,21 @@ "display(players_df.head())\n", "print(f\"Rows: {len(players_df):,} | Columns: {len(players_df.columns):,}\")\n" ] - } - , + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "prune-timestamped-outputs", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pruned 0 expired timestamped output(s).\n" + ] + } + ], "source": [ "from project_paths import prune_timestamped_outputs\n", "\n", diff --git a/notebooks/03_team_data/05_sofascore_upcoming_matches.ipynb b/notebooks/03_team_data/05_sofascore_upcoming_matches.ipynb index 93396f8..724e47e 100644 --- a/notebooks/03_team_data/05_sofascore_upcoming_matches.ipynb +++ b/notebooks/03_team_data/05_sofascore_upcoming_matches.ipynb @@ -97,7 +97,7 @@ "Following Bundesliga matchday to check: 2\n", "Team input file: C:\\kickbase project\\outputs\\sofascore\\reference\\bundesliga_teams.json\n", "Match-ID validation file: C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_2.json\n", - "Snapshot output file: C:\\kickbase project\\outputs\\sofascore\\upcoming_matches\\upcoming_matches_md_2_2026-08-23_00-49-34_384394+0200.json\n" + "Snapshot output file: C:\\kickbase project\\outputs\\sofascore\\upcoming_matches\\upcoming_matches_md_2_2026-08-23_17-57-53_708387+0200.json\n" ] } ], @@ -568,6 +568,7 @@ " Warning: Bundesliga event 16434251 is not in the requested matchday 2 match-ID file; rejecting it.\n", " Warning: Bundesliga event 16434269 is not in the requested matchday 2 match-ID file; rejecting it.\n", " Warning: Bundesliga event 16434274 is not in the requested matchday 2 match-ID file; rejecting it.\n", + " Warning: Bundesliga event 16434282 is not in the requested matchday 2 match-ID file; rejecting it.\n", "[6/18] Eintracht Frankfurt (team_id=2674)\n", " Loading page 0: https://www.sofascore.com/api/v1/team/2674/events/next/0\n", " Warning: Bundesliga event 16434026 is not in the requested matchday 2 match-ID file; rejecting it.\n", @@ -629,6 +630,7 @@ " Warning: Bundesliga event 16434258 is not in the requested matchday 2 match-ID file; rejecting it.\n", " Warning: Bundesliga event 16434269 is not in the requested matchday 2 match-ID file; rejecting it.\n", " Warning: Bundesliga event 16434272 is not in the requested matchday 2 match-ID file; rejecting it.\n", + " Warning: Bundesliga event 16434280 is not in the requested matchday 2 match-ID file; rejecting it.\n", "[8/18] SC Paderborn 07 (team_id=2561)\n", " Loading page 0: https://www.sofascore.com/api/v1/team/2561/events/next/0\n", " Warning: Bundesliga event 16434044 is not in the requested matchday 2 match-ID file; rejecting it.\n", @@ -720,6 +722,7 @@ " Warning: Bundesliga event 16434266 is not in the requested matchday 2 match-ID file; rejecting it.\n", " Warning: Bundesliga event 16434268 is not in the requested matchday 2 match-ID file; rejecting it.\n", " Warning: Bundesliga event 16434275 is not in the requested matchday 2 match-ID file; rejecting it.\n", + " Warning: Bundesliga event 16434284 is not in the requested matchday 2 match-ID file; rejecting it.\n", "[11/18] SV 07 Elversberg (team_id=2598)\n", " Loading page 0: https://www.sofascore.com/api/v1/team/2598/events/next/0\n", " Warning: Bundesliga event 16434020 is not in the requested matchday 2 match-ID file; rejecting it.\n", @@ -1070,15 +1073,15 @@ " 4\n", " 2547\n", " 1. FC Union Berlin\n", - " DFB Pokal\n", - " Eintracht Braunschweig\n", - " 2026-08-23T13:30:00+00:00\n", - " away\n", + " Bundesliga\n", + " Eintracht Frankfurt\n", + " 2026-08-29T13:30:00+00:00\n", + " home\n", " Bundesliga\n", " Bayer 04 Leverkusen\n", " 2026-09-05T13:30:00+00:00\n", " away\n", - " 16287045\n", + " 16434026\n", " 16434042\n", " 2\n", " \n", @@ -1102,15 +1105,15 @@ " 6\n", " 2556\n", " 1. FSV Mainz 05\n", - " DFB Pokal\n", - " VfB 1921 Krieschow\n", - " 2026-08-23T13:30:00+00:00\n", - " away\n", + " Bundesliga\n", + " SC Paderborn 07\n", + " 2026-08-29T13:30:00+00:00\n", + " home\n", " Bundesliga\n", " Hamburger SV\n", " 2026-09-06T13:30:00+00:00\n", " away\n", - " 16287042\n", + " 16434044\n", " 16434030\n", " 2\n", " \n", @@ -1150,15 +1153,15 @@ " 9\n", " 2527\n", " Borussia M'gladbach\n", - " DFB Pokal\n", - " TSV Schott Mainz\n", - " 2026-08-23T13:30:00+00:00\n", + " Bundesliga\n", + " RB Leipzig\n", + " 2026-08-29T13:30:00+00:00\n", " away\n", " Bundesliga\n", " SV 07 Elversberg\n", " 2026-09-05T13:30:00+00:00\n", " home\n", - " 16287039\n", + " 16434023\n", " 16434028\n", " 2\n", " \n", @@ -1300,12 +1303,12 @@ "1 2677 VfB Stuttgart Bundesliga \n", "2 2671 1. FC Köln DFB Pokal \n", "3 2569 TSG Hoffenheim Bundesliga \n", - "4 2547 1. FC Union Berlin DFB Pokal \n", + "4 2547 1. FC Union Berlin Bundesliga \n", "5 2674 Eintracht Frankfurt Bundesliga \n", - "6 2556 1. FSV Mainz 05 DFB Pokal \n", + "6 2556 1. FSV Mainz 05 Bundesliga \n", "7 2561 SC Paderborn 07 DFB Pokal \n", "8 36360 RB Leipzig Bundesliga \n", - "9 2527 Borussia M'gladbach DFB Pokal \n", + "9 2527 Borussia M'gladbach Bundesliga \n", "10 2598 SV 07 Elversberg Bundesliga \n", "11 2681 Bayer 04 Leverkusen Bundesliga \n", "12 2673 Borussia Dortmund Bundesliga \n", @@ -1315,25 +1318,25 @@ "16 2600 FC Augsburg Bundesliga \n", "17 2530 FC Schalke 04 DFB Pokal \n", "\n", - " next_overall_opponent next_overall_date next_overall_venue \\\n", - "0 VfB Stuttgart 2026-08-28T18:30:00+00:00 home \n", - "1 FC Bayern München 2026-08-28T18:30:00+00:00 away \n", - "2 FC Würzburger Kickers 2026-08-24T16:00:00+00:00 away \n", - "3 1. FC Köln 2026-08-29T13:30:00+00:00 away \n", - "4 Eintracht Braunschweig 2026-08-23T13:30:00+00:00 away \n", - "5 1. FC Union Berlin 2026-08-29T13:30:00+00:00 away \n", - "6 VfB 1921 Krieschow 2026-08-23T13:30:00+00:00 away \n", - "7 1.FC Phönix Lübeck 2026-08-23T16:00:00+00:00 away \n", - "8 Borussia M'gladbach 2026-08-29T13:30:00+00:00 home \n", - "9 TSV Schott Mainz 2026-08-23T13:30:00+00:00 away \n", - "10 Bayer 04 Leverkusen 2026-08-29T13:30:00+00:00 home \n", - "11 SV 07 Elversberg 2026-08-29T13:30:00+00:00 away \n", - "12 Hamburger SV 2026-08-29T16:30:00+00:00 home \n", - "13 SC Verl 2026-08-24T16:00:00+00:00 away \n", - "14 Fortuna Düsseldorf 2026-08-23T16:00:00+00:00 away \n", - "15 SC Freiburg 2026-08-30T13:30:00+00:00 away \n", - "16 FC Schalke 04 2026-08-30T15:30:00+00:00 home \n", - "17 Hallescher FC 2026-08-24T18:45:00+00:00 away \n", + " next_overall_opponent next_overall_date next_overall_venue \\\n", + "0 VfB Stuttgart 2026-08-28T18:30:00+00:00 home \n", + "1 FC Bayern München 2026-08-28T18:30:00+00:00 away \n", + "2 FC Würzburger Kickers 2026-08-24T16:00:00+00:00 away \n", + "3 1. FC Köln 2026-08-29T13:30:00+00:00 away \n", + "4 Eintracht Frankfurt 2026-08-29T13:30:00+00:00 home \n", + "5 1. FC Union Berlin 2026-08-29T13:30:00+00:00 away \n", + "6 SC Paderborn 07 2026-08-29T13:30:00+00:00 home \n", + "7 1.FC Phönix Lübeck 2026-08-23T16:00:00+00:00 away \n", + "8 Borussia M'gladbach 2026-08-29T13:30:00+00:00 home \n", + "9 RB Leipzig 2026-08-29T13:30:00+00:00 away \n", + "10 Bayer 04 Leverkusen 2026-08-29T13:30:00+00:00 home \n", + "11 SV 07 Elversberg 2026-08-29T13:30:00+00:00 away \n", + "12 Hamburger SV 2026-08-29T16:30:00+00:00 home \n", + "13 SC Verl 2026-08-24T16:00:00+00:00 away \n", + "14 Fortuna Düsseldorf 2026-08-23T16:00:00+00:00 away \n", + "15 SC Freiburg 2026-08-30T13:30:00+00:00 away \n", + "16 FC Schalke 04 2026-08-30T15:30:00+00:00 home \n", + "17 Hallescher FC 2026-08-24T18:45:00+00:00 away \n", "\n", " following_bundesliga_competition following_bundesliga_opponent \\\n", "0 Bundesliga FC Schalke 04 \n", @@ -1360,12 +1363,12 @@ "1 2026-09-04T18:30:00+00:00 home 16434087 \n", "2 2026-09-04T18:30:00+00:00 away 16287059 \n", "3 2026-09-05T13:30:00+00:00 home 16434022 \n", - "4 2026-09-05T13:30:00+00:00 away 16287045 \n", + "4 2026-09-05T13:30:00+00:00 away 16434026 \n", "5 2026-09-06T15:30:00+00:00 home 16434026 \n", - "6 2026-09-06T13:30:00+00:00 away 16287042 \n", + "6 2026-09-06T13:30:00+00:00 away 16434044 \n", "7 2026-09-05T13:30:00+00:00 home 16287053 \n", "8 2026-09-05T13:30:00+00:00 away 16434023 \n", - "9 2026-09-05T13:30:00+00:00 home 16287039 \n", + "9 2026-09-05T13:30:00+00:00 home 16434023 \n", "10 2026-09-05T13:30:00+00:00 away 16434020 \n", "11 2026-09-05T13:30:00+00:00 home 16434020 \n", "12 2026-09-05T13:30:00+00:00 away 16434025 \n", @@ -1403,7 +1406,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Saved 18 team result(s) to C:\\kickbase project\\outputs\\sofascore\\upcoming_matches\\upcoming_matches_md_2_2026-08-23_00-49-34_384394+0200.json.\n", + "Saved 18 team result(s) to C:\\kickbase project\\outputs\\sofascore\\upcoming_matches\\upcoming_matches_md_2_2026-08-23_17-57-53_708387+0200.json.\n", "Chrome driver closed.\n" ] } @@ -1580,14 +1583,21 @@ " except Exception as exc:\n", " print(f'Chrome driver shutdown warning: {exc}')\n" ] - } - , + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "prune-timestamped-outputs", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pruned 0 expired timestamped output(s).\n" + ] + } + ], "source": [ "from project_paths import prune_timestamped_outputs\n", "\n", diff --git a/notebooks/04_derived_analysis/02_sofascore_high_rated_players.ipynb b/notebooks/04_derived_analysis/02_sofascore_high_rated_players.ipynb index ba0e969..eb9079a 100644 --- a/notebooks/04_derived_analysis/02_sofascore_high_rated_players.ipynb +++ b/notebooks/04_derived_analysis/02_sofascore_high_rated_players.ipynb @@ -24,7 +24,8 @@ "- One reusable browser is started with `uc.Chrome(version_main=150)` and the\n", " only SofaScore endpoint used is\n", " `https://www.sofascore.com/api/v1/event/{match_id}/lineups`.\n", - "- Enter the current Bundesliga matchday when prompted. On matchdays 1–3, a\n", + "- Enter the current Bundesliga matchday when prompted. On matchday 1, a player\n", + " needs at least one valid rating. On matchdays 2–3, a\n", " player is evaluated with ratings in at least two of the selected five matches,\n", " or in the immediately latest match. From matchday 4, they need ratings in at\n", " least three matches or in both of the two most recent available matches. They are\n", @@ -153,6 +154,7 @@ "# Set workflow configuration value: RATING_THRESHOLD.\n", "RATING_THRESHOLD = Decimal(\"7.00\")\n", "# Set workflow configuration value: EARLY_SEASON_MAX_MATCHDAY.\n", + "MATCHDAY_ONE_MINIMUM_RATED_MATCHES = 1\n", "EARLY_SEASON_MAX_MATCHDAY = 3\n", "# Set workflow configuration value: EARLY_SEASON_MINIMUM_RATED_MATCHES.\n", "EARLY_SEASON_MINIMUM_RATED_MATCHES = 2\n", @@ -179,6 +181,7 @@ " \"CHROME_MAJOR_VERSION\": CHROME_MAJOR_VERSION,\n", " \"PAGE_LOAD_TIMEOUT_SECONDS\": PAGE_LOAD_TIMEOUT_SECONDS,\n", " \"WAIT_TIMEOUT_SECONDS\": WAIT_TIMEOUT_SECONDS,\n", + " \"MATCHDAY_ONE_MINIMUM_RATED_MATCHES\": MATCHDAY_ONE_MINIMUM_RATED_MATCHES,\n", " \"EARLY_SEASON_MAX_MATCHDAY\": EARLY_SEASON_MAX_MATCHDAY,\n", " \"EARLY_SEASON_MINIMUM_RATED_MATCHES\": EARLY_SEASON_MINIMUM_RATED_MATCHES,\n", " \"MINIMUM_RATED_MATCHES\": MINIMUM_RATED_MATCHES,\n", @@ -918,8 +921,9 @@ "source": [ "## 8. Match ordering and player qualification\n", "\n", - "Each category is sorted oldest-to-newest. On matchdays 1–3, qualification uses\n", - "either two rated matches or the immediately newest match; from matchday 4, it\n", + "Each category is sorted oldest-to-newest. On matchday 1, qualification uses one\n", + "rated match. On matchdays 2–3, it uses either two rated matches or the immediately\n", + "newest match; from matchday 4, it\n", "uses either three rated matches or both specifically newest matches. This is\n", "followed by the unrounded average\n", "threshold. Output averages use decimal half-up rounding to two places.\n" @@ -959,11 +963,16 @@ " \"bundesliga_matchday\": matchday,\n", " \"early_season_max_matchday\": EARLY_SEASON_MAX_MATCHDAY,\n", " \"minimum_rated_matches\": (\n", + " MATCHDAY_ONE_MINIMUM_RATED_MATCHES\n", + " if matchday == MINIMUM_BUNDESLIGA_MATCHDAY\n", + " else\n", " EARLY_SEASON_MINIMUM_RATED_MATCHES\n", " if early_season\n", " else MINIMUM_RATED_MATCHES\n", " ),\n", - " \"last_match_exception\": early_season,\n", + " \"last_match_exception\": (\n", + " MINIMUM_BUNDESLIGA_MATCHDAY < matchday <= EARLY_SEASON_MAX_MATCHDAY\n", + " ),\n", " \"last_two_exception\": not early_season,\n", " }\n", "\n", @@ -974,6 +983,8 @@ " ordered_match_ids: list[int],\n", " matchday: int,\n", ") -> bool:\n", + " if matchday == MINIMUM_BUNDESLIGA_MATCHDAY:\n", + " return rating_count >= MATCHDAY_ONE_MINIMUM_RATED_MATCHES\n", " if matchday <= EARLY_SEASON_MAX_MATCHDAY:\n", " played_latest_match = (\n", " bool(ordered_match_ids)\n", @@ -995,6 +1006,8 @@ "\n", "\n", "def eligibility_rule_description(matchday: int) -> str:\n", + " if matchday == MINIMUM_BUNDESLIGA_MATCHDAY:\n", + " return f\"at least {MATCHDAY_ONE_MINIMUM_RATED_MATCHES} rated match\"\n", " if matchday <= EARLY_SEASON_MAX_MATCHDAY:\n", " return (\n", " f\"at least {EARLY_SEASON_MINIMUM_RATED_MATCHES} rated matches \"\n", diff --git a/notebooks/04_derived_analysis/05_sofascore_player_average_ratings.ipynb b/notebooks/04_derived_analysis/05_sofascore_player_average_ratings.ipynb index 1382fbe..0fb92b6 100644 --- a/notebooks/04_derived_analysis/05_sofascore_player_average_ratings.ipynb +++ b/notebooks/04_derived_analysis/05_sofascore_player_average_ratings.ipynb @@ -9,7 +9,7 @@ "\n", "This notebook calculates average SofaScore ratings for every player meeting the existing appearance rule in the recent **overall** and **Bundesliga** match windows. The categories are evaluated independently: ratings are never mixed between them.\n", "\n", - "Enter the current Bundesliga matchday when prompted. On matchdays 1–3, a player is included with valid ratings in at least two of the selected five matches, or with a valid rating in the immediately latest match. From matchday 4, the normal rule applies: at least three valid ratings, or valid ratings in both of the two most-recent available matches. Missing or non-numeric ratings are ignored. Unlike the high-rated-players notebook, no minimum average-rating threshold is applied.\n", + "Enter the current Bundesliga matchday when prompted. On matchday 1, a player is included with at least one valid rating. On matchdays 2–3, a player is included with valid ratings in at least two of the selected five matches, or with a valid rating in the immediately latest match. From matchday 4, the normal rule applies: at least three valid ratings, or valid ratings in both of the two most-recent available matches. Missing or non-numeric ratings are ignored. Unlike the high-rated-players notebook, no minimum average-rating threshold is applied.\n", "\n", "Outputs are timestamped JSON and CSV files in `outputs/sofascore/player_average_ratings`. JSON retains each player's per-match rating trail; CSV has one row per player and category.\n" ] @@ -80,6 +80,7 @@ "HEADLESS = False\n", "PAGE_LOAD_TIMEOUT_SECONDS = 30\n", "WAIT_TIMEOUT_SECONDS = 20\n", + "MATCHDAY_ONE_MINIMUM_RATED_MATCHES = 1\n", "EARLY_SEASON_MAX_MATCHDAY = 3\n", "EARLY_SEASON_MINIMUM_RATED_MATCHES = 2\n", "MINIMUM_RATED_MATCHES = 3\n", @@ -89,6 +90,7 @@ "TEAM_FORM_FILENAME_RE = re.compile(r'^team_form_(?P\\d{4}-\\d{2}-\\d{2})_(?P