Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ creating a timestamped history.
6. Run the required collectors in `notebooks/05_predicted_lineups`: RotoWire,
LigaInsider, Kicker, and/or the source-specific manual Kickbase workflow.
Their snapshots share the match/home/away/player envelope while retaining
source-specific details.
source-specific details. Default lineup-blend weights are LigaInsider 4,
Kickbase 3, Kicker 2, and RotoWire 1; only sources covering a team
contribute to that team's blend.
7. Create the required expected-points score file in
`notebooks/06_score_creation`.
8. Run an optimizer in `notebooks/07_squad_optimisation`, or run
Expand Down
16 changes: 16 additions & 0 deletions data/reference/kickbase_player_name_cross_references.csv
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,19 @@ 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
elversberg,Lasse Günther,La. Günther,2026-08-27T12:34:26+02:00
dortmund,Joey Veerman,J. Veerman,2026-08-27T12:34:28+02:00
union,Rani Khedira,R. Khedira,2026-08-27T12:34:31+02:00
mainz,Kaishu Sano,Kai. Sano,2026-08-27T12:34:33+02:00
koeln,Said El Mala,S. El Mala,2026-08-27T12:34:35+02:00
dortmund,Felix Nmecha,F. Nmecha,2026-08-27T12:34:41+02:00
freiburg,Yuito Suzuki,Y. Suzuki,2026-08-27T12:34:44+02:00
hoffenheim,Mats Rots,M. Rots,2026-08-27T12:34:46+02:00
leverkusen,Ezequiél Fernández,E. Fernandez,2026-08-27T12:34:57+02:00
frankfurt,Oscar Højlund,O. Höjlund,2026-08-27T12:34:59+02:00
leipzig,Ridle Baku,R. Baku,2026-08-27T12:35:05+02:00
frankfurt,Robin Koch,R. Koch,2026-08-27T12:35:09+02:00
freiburg,Maximilian Eggestein,M. Eggestein,2026-08-27T12:35:22+02:00
paderborn,Albert Frank Millgramm,A. Millgramm,2026-08-27T12:35:25+02:00
mainz,Jae-Sung Lee,J.-S. Lee,2026-08-27T12:35:29+02:00
mainz,Phillip Tietz,P. Tietz,2026-08-27T12:35:41+02:00
1 change: 1 addition & 0 deletions data/reference/player_name_cross_references.csv
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ 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
rotowire,hamburg,Shafiq Nandja,48225,Shafiq Bello Nandja,2026-08-27T12:47:28+02:00
10 changes: 8 additions & 2 deletions kbstats_points_odds_lineup_score.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
KB_TEAM_ID_TO_KEY,
LINEUP_OVERRIDE_COLUMNS,
LINEUP_SOURCES,
NAME_ONLY_LINEUP_SOURCE_KEYS,
KICKBASE_REFERENCE_COLUMNS,
_fuzzy_candidates,
_load_kickbase_lineup_overrides,
Expand Down Expand Up @@ -91,6 +92,7 @@ class MetricConfig:
"expected_match_points",
"ligainsider_starting_chance",
"kickbase_starting_chance",
"kicker_starting_chance",
"rotowire_starting_chance",
"questionable_injury_penalty",
"starting_chance",
Expand Down Expand Up @@ -249,7 +251,7 @@ def _resolve_lineups(
if chosen is not None:
resolution[(index, source.key)] = (chosen, "exact")
continue
if source.key == "kickbase":
if source.key in NAME_ONLY_LINEUP_SOURCE_KEYS:
override = kickbase_override_by_key.get((team_key, normalized))
if override is not None:
chosen = candidates.get(normalize_name(override["kickbase_displayed_name"]))
Expand Down Expand Up @@ -306,7 +308,7 @@ def _resolve_lineups(
resolution[(index, source.key)] = (None, "missing")
continue
resolution[(index, source.key)] = (chosen, "prompted")
if source.key == "kickbase":
if source.key in NAME_ONLY_LINEUP_SOURCE_KEYS:
new_kickbase_overrides.append(
{
"canonical_team": team_key,
Expand Down Expand Up @@ -404,6 +406,7 @@ def run_score_creation(
match_point_values: list[float] = []
ligainsider_chances: list[float] = []
kickbase_chances: list[float] = []
kicker_chances: list[float] = []
rotowire_chances: list[float] = []
injury_penalties: list[float] = []
starting_chances: list[float] = []
Expand Down Expand Up @@ -463,6 +466,7 @@ def run_score_creation(
match_point_values.append(match_points)
ligainsider_chances.append(source_chance_by_key["ligainsider"])
kickbase_chances.append(source_chance_by_key["kickbase"])
kicker_chances.append(source_chance_by_key["kicker"])
rotowire_chances.append(source_chance_by_key["rotowire"])
injury_penalties.append(injury_penalty)
starting_chances.append(starting_chance)
Expand All @@ -477,6 +481,7 @@ def run_score_creation(
"expected_match_points": match_points,
"ligainsider_starting_chance": source_chance_by_key["ligainsider"],
"kickbase_starting_chance": source_chance_by_key["kickbase"],
"kicker_starting_chance": source_chance_by_key["kicker"],
"rotowire_starting_chance": source_chance_by_key["rotowire"],
"questionable_injury_penalty": injury_penalty,
"starting_chance": starting_chance,
Expand All @@ -489,6 +494,7 @@ def run_score_creation(
scored["expected_match_points"] = match_point_values
scored["ligainsider_starting_chance"] = ligainsider_chances
scored["kickbase_starting_chance"] = kickbase_chances
scored["kicker_starting_chance"] = kicker_chances
scored["rotowire_starting_chance"] = rotowire_chances
scored["questionable_injury_penalty"] = injury_penalties
scored["starting_chance"] = starting_chances
Expand Down
22 changes: 11 additions & 11 deletions notebooks/02_odds/02_fotmob_match_odds.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -878,18 +878,18 @@
" 'away_team': 'Bayer Leverkusen',\n",
" 'bookmakers': [{'bookmaker': 'Tipico',\n",
" 'bookmaker_source_id': 171,\n",
" 'home_win': 5.2,\n",
" 'draw': 4.6,\n",
" 'home_win': 5.3,\n",
" 'draw': 4.5,\n",
" 'away_win': 1.55}],\n",
" 'issues': []},\n",
" {'match_id': 5881147,\n",
" 'home_team': '1. FC Köln',\n",
" 'away_team': 'Hoffenheim',\n",
" 'bookmakers': [{'bookmaker': 'Tipico',\n",
" 'bookmaker_source_id': 171,\n",
" 'home_win': 3.0,\n",
" 'home_win': 3.1,\n",
" 'draw': 3.6,\n",
" 'away_win': 2.25}],\n",
" 'away_win': 2.2}],\n",
" 'issues': []},\n",
" {'match_id': 5881149,\n",
" 'home_team': 'Mainz 05',\n",
Expand All @@ -906,17 +906,17 @@
" 'bookmakers': [{'bookmaker': 'Tipico',\n",
" 'bookmaker_source_id': 171,\n",
" 'home_win': 1.52,\n",
" 'draw': 4.8,\n",
" 'away_win': 5.3}],\n",
" 'draw': 4.6,\n",
" 'away_win': 5.5}],\n",
" 'issues': []},\n",
" {'match_id': 5881151,\n",
" 'home_team': 'Union Berlin',\n",
" 'away_team': 'Eintracht Frankfurt',\n",
" 'bookmakers': [{'bookmaker': 'Tipico',\n",
" 'bookmaker_source_id': 171,\n",
" 'home_win': 2.5,\n",
" 'draw': 3.7,\n",
" 'away_win': 2.6}],\n",
" 'draw': 3.5,\n",
" 'away_win': 2.7}],\n",
" 'issues': []},\n",
" {'match_id': 5881145,\n",
" 'home_team': 'Borussia Dortmund',\n",
Expand All @@ -932,9 +932,9 @@
" 'away_team': 'Werder Bremen',\n",
" 'bookmakers': [{'bookmaker': 'Tipico',\n",
" 'bookmaker_source_id': 171,\n",
" 'home_win': 2.0,\n",
" 'draw': 3.7,\n",
" 'away_win': 3.5}],\n",
" 'home_win': 1.97,\n",
" 'draw': 3.6,\n",
" 'away_win': 3.7}],\n",
" 'issues': []},\n",
" {'match_id': 5881144,\n",
" 'home_team': 'Augsburg',\n",
Expand Down
6 changes: 3 additions & 3 deletions notebooks/03_team_data/01_sofascore_recent_form.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Execution timestamp: 2026-08-25T11:02:05.869307+02:00\n",
"Execution timestamp: 2026-08-27T12:38:44.831736+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-25_11-02-05_869307+0200.json\n"
"Snapshot output file: C:\\kickbase project\\outputs\\sofascore\\team_form\\team_form_2026-08-27_12-38-44_831736+0200.json\n"
]
}
],
Expand Down Expand Up @@ -5586,7 +5586,7 @@
"output_type": "stream",
"text": [
"{\n",
" \"2026-08-25T11:02:05.869307+02:00\": {\n",
" \"2026-08-27T12:38:44.831736+02:00\": {\n",
" \"2672\": {\n",
" \"team\": \"FC Bayern München\",\n",
" \"overall_form\": \"WWWWW\",\n",
Expand Down
Loading
Loading