diff --git a/notebooks/07_squad_optimisation/optimize_squad_all_limits_arena.ipynb b/notebooks/07_squad_optimisation/optimize_squad_all_limits_arena.ipynb
index e85135f..2661736 100644
--- a/notebooks/07_squad_optimisation/optimize_squad_all_limits_arena.ipynb
+++ b/notebooks/07_squad_optimisation/optimize_squad_all_limits_arena.ipynb
@@ -1402,10 +1402,10 @@
"output_type": "stream",
"text": [
"Selected score input:\n",
- " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- " Retrieval timestamp: 20260825_110735_+0200\n",
+ " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ " Retrieval timestamp: 20260827_124042_+0200\n",
" Method: sofascore_overall_rating_odds_lineup\n",
- " Metric-creation timestamp: 20260825_121320_+0200\n"
+ " Metric-creation timestamp: 20260827_124757_+0200\n"
]
},
{
@@ -1434,7 +1434,7 @@
" 16434029 SC Freiburg SC Freiburg (5) SV Werder Bremen SV Werder Bremen (10)\n",
" 16434039 FC Augsburg FC Augsburg (13) FC Schalke 04 FC Schalke 04 (8)\n",
"\n",
- "Validated 469 player rows once before formation solving.\n",
+ "Validated 468 player rows once before formation solving.\n",
"Detected market-value unit: euros; internal optimization unit: euros.\n",
"Solving formation 4-4-2 ...\n",
" Status: Optimal\n",
@@ -1492,71 +1492,71 @@
"
0 | \n",
" 4-4-2 | \n",
" Optimal | \n",
- " 170.5025 | \n",
- " €144,911,804 | \n",
+ " 164.322127 | \n",
+ " €149,469,775 | \n",
" \n",
" \n",
" | 1 | \n",
" 4-2-4 | \n",
" Optimal | \n",
- " 166.07502 | \n",
- " €148,233,738 | \n",
+ " 159.784339 | \n",
+ " €147,092,336 | \n",
"
\n",
" \n",
" | 2 | \n",
" 3-4-3 | \n",
" Optimal | \n",
- " 170.5025 | \n",
- " €146,394,057 | \n",
+ " 162.953419 | \n",
+ " €148,339,960 | \n",
"
\n",
" \n",
" | 3 | \n",
" 4-3-3 | \n",
" Optimal | \n",
- " 169.649688 | \n",
- " €149,503,459 | \n",
+ " 163.21241 | \n",
+ " €149,871,175 | \n",
"
\n",
" \n",
" | 4 | \n",
" 5-3-2 | \n",
" Optimal | \n",
- " 169.814048 | \n",
- " €149,964,323 | \n",
+ " 163.994477 | \n",
+ " €148,755,806 | \n",
"
\n",
" \n",
" | 5 | \n",
" 3-5-2 | \n",
" Optimal | \n",
- " 171.148234 | \n",
- " €143,718,582 | \n",
+ " 164.063136 | \n",
+ " €147,938,560 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5-4-1 | \n",
" Optimal | \n",
- " 170.355363 | \n",
- " €147,885,767 | \n",
+ " 164.628601 | \n",
+ " €145,992,472 | \n",
"
\n",
" \n",
" | 7 | \n",
" 4-5-1 | \n",
" Optimal | \n",
- " 170.463699 | \n",
- " €147,694,799 | \n",
+ " 165.354379 | \n",
+ " €149,925,126 | \n",
"
\n",
" \n",
" | 8 | \n",
" 3-6-1 | \n",
" Optimal | \n",
- " 170.620366 | \n",
- " €149,212,083 | \n",
+ " 164.766404 | \n",
+ " €149,621,689 | \n",
"
\n",
" \n",
" | 9 | \n",
" 5-2-3 | \n",
" Optimal | \n",
- " 166.915294 | \n",
- " €149,354,702 | \n",
+ " 161.203579 | \n",
+ " €149,013,901 | \n",
"
\n",
" \n",
"\n",
@@ -1564,16 +1564,16 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 4-4-2 Optimal 170.5025 €144,911,804\n",
- "1 4-2-4 Optimal 166.07502 €148,233,738\n",
- "2 3-4-3 Optimal 170.5025 €146,394,057\n",
- "3 4-3-3 Optimal 169.649688 €149,503,459\n",
- "4 5-3-2 Optimal 169.814048 €149,964,323\n",
- "5 3-5-2 Optimal 171.148234 €143,718,582\n",
- "6 5-4-1 Optimal 170.355363 €147,885,767\n",
- "7 4-5-1 Optimal 170.463699 €147,694,799\n",
- "8 3-6-1 Optimal 170.620366 €149,212,083\n",
- "9 5-2-3 Optimal 166.915294 €149,354,702"
+ "0 4-4-2 Optimal 164.322127 €149,469,775\n",
+ "1 4-2-4 Optimal 159.784339 €147,092,336\n",
+ "2 3-4-3 Optimal 162.953419 €148,339,960\n",
+ "3 4-3-3 Optimal 163.21241 €149,871,175\n",
+ "4 5-3-2 Optimal 163.994477 €148,755,806\n",
+ "5 3-5-2 Optimal 164.063136 €147,938,560\n",
+ "6 5-4-1 Optimal 164.628601 €145,992,472\n",
+ "7 4-5-1 Optimal 165.354379 €149,925,126\n",
+ "8 3-6-1 Optimal 164.766404 €149,621,689\n",
+ "9 5-2-3 Optimal 161.203579 €149,013,901"
]
},
"metadata": {},
@@ -1586,39 +1586,39 @@
"Independent post-solve verification passed.\n",
"\n",
"=== Input ===\n",
- "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- "Retrieval timestamp: 20260825_110735_+0200\n",
+ "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ "Retrieval timestamp: 20260827_124042_+0200\n",
"Score method: sofascore_overall_rating_odds_lineup\n",
- "Metric-creation timestamp: 20260825_121320_+0200\n",
+ "Metric-creation timestamp: 20260827_124757_+0200\n",
"Requested matchday: 1\n",
"Match JSON source used: SofaScore\n",
"Match JSON path: C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_1.json\n",
"Detected/used market-value unit: euros -> integer euros\n",
"\n",
"=== Optimization result ===\n",
- "Chosen formation: 3-5-2\n",
+ "Chosen formation: 4-5-1\n",
"Solver status: Optimal\n",
- "Total score (captain doubled): 171.148234\n",
- "Recommended captain: Phillip Tietz\n",
- "Total squad value: €143,718,582\n",
- "Remaining budget: €6,281,418\n",
+ "Total score (captain doubled): 165.354379\n",
+ "Recommended captain: Dominik Kohr\n",
+ "Total squad value: €149,925,126\n",
+ "Remaining budget: €74,874\n",
"\n",
"=== Selected players ===\n",
- " Full Name Position Club In-Game Value Score Captain\n",
- " Manuel Neuer GK FC Bayern München 13565866.0 16.507984 \n",
- " Julian Ryerson DEF Borussia Dortmund 26027952.0 17.286749 \n",
- "Zeno Van den Bosch DEF 1. FC Union Berlin 13456741.0 11.138947 \n",
- " Otávio DEF Eintracht Frankfurt 9374748.0 9.632982 \n",
- " Ezechiel Banzuzi MID RB Leipzig 8349668.0 15.312951 \n",
- " Malik Tillman MID Bayer 04 Leverkusen 13303012.0 14.082281 \n",
- " Han-Noah Massengo MID FC Augsburg 9899475.0 11.946075 \n",
- " Patrick Wimmer MID TSG Hoffenheim 7364887.0 11.405367 \n",
- " Ísak Jóhannesson MID 1. FC Köln 9418752.0 10.980463 \n",
- " Phillip Tietz FOR 1. FSV Mainz 05 13658389.0 19.802807 Yes\n",
- " Igor Matanović FOR SC Freiburg 19299092.0 13.248821 \n",
+ " Full Name Position Club In-Game Value Score Captain\n",
+ " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
+ " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 Yes\n",
+ " Miguel Gutiérrez DEF Bayer 04 Leverkusen 21033862.0 13.791336 \n",
+ " Zeno Van den Bosch DEF 1. FC Union Berlin 13151299.0 10.973146 \n",
+ " Otávio DEF Eintracht Frankfurt 10044435.0 9.787575 \n",
+ "Konstantinos Karetsas MID Borussia Dortmund 24574032.0 17.098594 \n",
+ " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
+ " Han-Noah Massengo MID FC Augsburg 10113144.0 11.731293 \n",
+ " Patrick Wimmer MID TSG Hoffenheim 8149700.0 11.405367 \n",
+ " Ísak Jóhannesson MID 1. FC Köln 9815158.0 10.980463 \n",
+ " Igor Matanović FOR SC Freiburg 19575194.0 13.304292 \n",
"\n",
"=== Output ===\n",
- "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_130825_+0200.csv\n"
+ "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131319_+0200.csv\n"
]
}
],
@@ -1768,14 +1768,14 @@
"name": "stdin",
"output_type": "stream",
"text": [
- "Select this lineup for All Limits Arena? [y/n]: y\n"
+ "Select this lineup for All Limits Arena? [y/n]: n\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Selected lineup saved to: C:\\kickbase project\\outputs\\selected_lineups\\all-limits-arena.json\n"
+ "Lineup was not selected; the existing selection is unchanged.\n"
]
}
],
diff --git a/notebooks/07_squad_optimisation/optimize_squad_insider_arena.ipynb b/notebooks/07_squad_optimisation/optimize_squad_insider_arena.ipynb
index 32bfd0c..6a957be 100644
--- a/notebooks/07_squad_optimisation/optimize_squad_insider_arena.ipynb
+++ b/notebooks/07_squad_optimisation/optimize_squad_insider_arena.ipynb
@@ -1397,10 +1397,10 @@
"output_type": "stream",
"text": [
"Selected score input:\n",
- " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- " Retrieval timestamp: 20260825_110735_+0200\n",
+ " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ " Retrieval timestamp: 20260827_124042_+0200\n",
" Method: sofascore_overall_rating_odds_lineup\n",
- " Metric-creation timestamp: 20260825_121320_+0200\n"
+ " Metric-creation timestamp: 20260827_124757_+0200\n"
]
},
{
@@ -1429,7 +1429,7 @@
" 16434029 SC Freiburg SC Freiburg (5) SV Werder Bremen SV Werder Bremen (10)\n",
" 16434039 FC Augsburg FC Augsburg (13) FC Schalke 04 FC Schalke 04 (8)\n",
"\n",
- "Validated 469 player rows once before formation solving.\n",
+ "Validated 468 player rows once before formation solving.\n",
"Detected market-value unit: euros; internal optimization unit: euros.\n",
"Solving formation 2-2-1 ...\n",
" Status: Optimal\n",
@@ -1473,22 +1473,22 @@
" 0 | \n",
" 2-2-1 | \n",
" Optimal | \n",
- " 119.196726 | \n",
- " €177,668,096 | \n",
+ " 118.132982 | \n",
+ " €163,815,383 | \n",
" \n",
" \n",
" | 1 | \n",
" 2-1-2 | \n",
" Optimal | \n",
- " 119.573845 | \n",
- " €170,724,854 | \n",
+ " 116.191979 | \n",
+ " €154,215,577 | \n",
"
\n",
" \n",
" | 2 | \n",
" 1-2-2 | \n",
" Optimal | \n",
- " 119.38569 | \n",
- " €168,759,799 | \n",
+ " 117.285143 | \n",
+ " €178,724,207 | \n",
"
\n",
" \n",
"\n",
@@ -1496,9 +1496,9 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 2-2-1 Optimal 119.196726 €177,668,096\n",
- "1 2-1-2 Optimal 119.573845 €170,724,854\n",
- "2 1-2-2 Optimal 119.38569 €168,759,799"
+ "0 2-2-1 Optimal 118.132982 €163,815,383\n",
+ "1 2-1-2 Optimal 116.191979 €154,215,577\n",
+ "2 1-2-2 Optimal 117.285143 €178,724,207"
]
},
"metadata": {},
@@ -1511,34 +1511,34 @@
"Independent post-solve verification passed.\n",
"\n",
"=== Input ===\n",
- "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- "Retrieval timestamp: 20260825_110735_+0200\n",
+ "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ "Retrieval timestamp: 20260827_124042_+0200\n",
"Score method: sofascore_overall_rating_odds_lineup\n",
- "Metric-creation timestamp: 20260825_121320_+0200\n",
+ "Metric-creation timestamp: 20260827_124757_+0200\n",
"Requested matchday: 1\n",
"Match JSON source used: SofaScore\n",
"Match JSON path: C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_1.json\n",
"Detected/used market-value unit: euros -> integer euros\n",
"\n",
"=== Optimization result ===\n",
- "Chosen formation: 2-1-2\n",
+ "Chosen formation: 2-2-1\n",
"Solver status: Optimal\n",
- "Total score (captain doubled): 119.573845\n",
- "Recommended captain: Phillip Tietz\n",
- "Total squad value: €170,724,854\n",
- "Remaining budget: €9,275,146\n",
+ "Total score (captain doubled): 118.132982\n",
+ "Recommended captain: Nadiem Amiri\n",
+ "Total squad value: €163,815,383\n",
+ "Remaining budget: €16,184,617\n",
"\n",
"=== Selected players ===\n",
" Full Name Position Club In-Game Value Score Captain\n",
- " Mark Flekken GK Bayer 04 Leverkusen 15527801.0 14.490463 \n",
- "Julian Ryerson DEF Borussia Dortmund 26027952.0 17.286749 \n",
- " Willi Orban DEF RB Leipzig 31396500.0 16.361783 \n",
- " Michael Olise MID FC Bayern München 64815120.0 18.580415 \n",
- " Phillip Tietz FOR 1. FSV Mainz 05 13658389.0 19.802807 Yes\n",
- "Igor Matanović FOR SC Freiburg 19299092.0 13.248821 \n",
+ " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
+ "Julian Ryerson DEF Borussia Dortmund 26105247.0 17.286749 \n",
+ " Willi Orban DEF RB Leipzig 31442247.0 16.167175 \n",
+ " Nadiem Amiri MID 1. FSV Mainz 05 33932022.0 19.563537 Yes\n",
+ " Aleix García MID Bayer 04 Leverkusen 38996349.0 15.528023 \n",
+ "Igor Matanović FOR SC Freiburg 19575194.0 13.304292 \n",
"\n",
"=== Output ===\n",
- "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_123428_+0200.csv\n"
+ "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131159_+0200.csv\n"
]
}
],
@@ -1688,14 +1688,28 @@
"name": "stdin",
"output_type": "stream",
"text": [
- "Select this lineup for Kickbase.insider Arena? [y/n]: n\n"
+ "Select this lineup for Kickbase.insider Arena? [y/n]: y\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Lineup was not selected; the existing selection is unchanged.\n"
+ "Current selected lineup for Kickbase.insider Arena: expected points=118.351453, players=[Mark Flekken, Julian Ryerson, Willi Orban, Michael Olise, Phillip Tietz, Igor Matanović]\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Replace the current selected lineup? [y/n]: y\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Selected lineup saved to: C:\\kickbase project\\outputs\\selected_lineups\\kickbase.insider-arena.json\n"
]
}
],
@@ -1729,7 +1743,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "Pruned 2 expired timestamped output(s).\n"
+ "Pruned 1 expired timestamped output(s).\n"
]
}
],
diff --git a/notebooks/07_squad_optimisation/optimize_squad_max_2_per_team.ipynb b/notebooks/07_squad_optimisation/optimize_squad_max_2_per_team.ipynb
index 6dc86ea..8aea57a 100644
--- a/notebooks/07_squad_optimisation/optimize_squad_max_2_per_team.ipynb
+++ b/notebooks/07_squad_optimisation/optimize_squad_max_2_per_team.ipynb
@@ -41,7 +41,7 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 1,
"id": "5e3ef4c5",
"metadata": {},
"outputs": [],
@@ -266,7 +266,7 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 2,
"id": "9b3c19b4",
"metadata": {},
"outputs": [],
@@ -619,7 +619,7 @@
},
{
"cell_type": "code",
- "execution_count": 13,
+ "execution_count": 3,
"id": "eb6fdda4",
"metadata": {},
"outputs": [],
@@ -811,7 +811,7 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 4,
"id": "39379a72",
"metadata": {},
"outputs": [],
@@ -1028,7 +1028,7 @@
},
{
"cell_type": "code",
- "execution_count": 15,
+ "execution_count": 5,
"id": "042c1a42",
"metadata": {},
"outputs": [],
@@ -1225,7 +1225,7 @@
},
{
"cell_type": "code",
- "execution_count": 16,
+ "execution_count": 6,
"id": "063f64a6",
"metadata": {},
"outputs": [],
@@ -1382,7 +1382,7 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": 7,
"id": "eedaa4d7",
"metadata": {},
"outputs": [
@@ -1391,10 +1391,10 @@
"output_type": "stream",
"text": [
"Selected score input:\n",
- " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- " Retrieval timestamp: 20260825_110735_+0200\n",
+ " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ " Retrieval timestamp: 20260827_124042_+0200\n",
" Method: sofascore_overall_rating_odds_lineup\n",
- " Metric-creation timestamp: 20260825_121320_+0200\n"
+ " Metric-creation timestamp: 20260827_124757_+0200\n"
]
},
{
@@ -1423,7 +1423,7 @@
" 16434029 SC Freiburg SC Freiburg (5) SV Werder Bremen SV Werder Bremen (10)\n",
" 16434039 FC Augsburg FC Augsburg (13) FC Schalke 04 FC Schalke 04 (8)\n",
"\n",
- "Validated 469 player rows once before formation solving.\n",
+ "Validated 468 player rows once before formation solving.\n",
"Detected market-value unit: euros; internal optimization unit: euros.\n",
"Solving formation 4-4-2 ...\n",
" Status: Optimal\n",
@@ -1481,71 +1481,71 @@
" 0 | \n",
" 4-4-2 | \n",
" Optimal | \n",
- " 185.287405 | \n",
- " €149,673,130 | \n",
+ " 176.83448 | \n",
+ " €148,575,397 | \n",
" \n",
" \n",
" | 1 | \n",
" 4-2-4 | \n",
" Optimal | \n",
- " 181.753169 | \n",
- " €148,280,784 | \n",
+ " 172.73198 | \n",
+ " €148,303,337 | \n",
"
\n",
" \n",
" | 2 | \n",
" 3-4-3 | \n",
" Optimal | \n",
- " 184.085256 | \n",
- " €148,980,848 | \n",
+ " 175.182403 | \n",
+ " €149,968,324 | \n",
"
\n",
" \n",
" | 3 | \n",
" 4-3-3 | \n",
" Optimal | \n",
- " 184.146848 | \n",
- " €149,933,961 | \n",
+ " 174.771193 | \n",
+ " €149,248,832 | \n",
"
\n",
" \n",
" | 4 | \n",
" 5-3-2 | \n",
" Optimal | \n",
- " 184.491639 | \n",
- " €149,557,996 | \n",
+ " 176.749196 | \n",
+ " €149,819,349 | \n",
"
\n",
" \n",
" | 5 | \n",
" 3-5-2 | \n",
" Optimal | \n",
- " 185.495014 | \n",
- " €148,553,836 | \n",
+ " 175.966194 | \n",
+ " €147,603,480 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5-4-1 | \n",
" Optimal | \n",
- " 185.621673 | \n",
- " €149,140,185 | \n",
+ " 178.132352 | \n",
+ " €149,705,212 | \n",
"
\n",
" \n",
" | 7 | \n",
" 4-5-1 | \n",
" Optimal | \n",
- " 186.315752 | \n",
- " €149,369,355 | \n",
+ " 177.944197 | \n",
+ " €148,173,997 | \n",
"
\n",
" \n",
" | 8 | \n",
" 3-6-1 | \n",
" Optimal | \n",
- " 186.908654 | \n",
- " €149,016,248 | \n",
+ " 176.111554 | \n",
+ " €146,134,960 | \n",
"
\n",
" \n",
" | 9 | \n",
" 5-2-3 | \n",
" Optimal | \n",
- " 182.425738 | \n",
- " €147,565,439 | \n",
+ " 174.186405 | \n",
+ " €147,722,777 | \n",
"
\n",
" \n",
"\n",
@@ -1553,16 +1553,16 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 4-4-2 Optimal 185.287405 €149,673,130\n",
- "1 4-2-4 Optimal 181.753169 €148,280,784\n",
- "2 3-4-3 Optimal 184.085256 €148,980,848\n",
- "3 4-3-3 Optimal 184.146848 €149,933,961\n",
- "4 5-3-2 Optimal 184.491639 €149,557,996\n",
- "5 3-5-2 Optimal 185.495014 €148,553,836\n",
- "6 5-4-1 Optimal 185.621673 €149,140,185\n",
- "7 4-5-1 Optimal 186.315752 €149,369,355\n",
- "8 3-6-1 Optimal 186.908654 €149,016,248\n",
- "9 5-2-3 Optimal 182.425738 €147,565,439"
+ "0 4-4-2 Optimal 176.83448 €148,575,397\n",
+ "1 4-2-4 Optimal 172.73198 €148,303,337\n",
+ "2 3-4-3 Optimal 175.182403 €149,968,324\n",
+ "3 4-3-3 Optimal 174.771193 €149,248,832\n",
+ "4 5-3-2 Optimal 176.749196 €149,819,349\n",
+ "5 3-5-2 Optimal 175.966194 €147,603,480\n",
+ "6 5-4-1 Optimal 178.132352 €149,705,212\n",
+ "7 4-5-1 Optimal 177.944197 €148,173,997\n",
+ "8 3-6-1 Optimal 176.111554 €146,134,960\n",
+ "9 5-2-3 Optimal 174.186405 €147,722,777"
]
},
"metadata": {},
@@ -1575,39 +1575,39 @@
"Independent post-solve verification passed.\n",
"\n",
"=== Input ===\n",
- "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- "Retrieval timestamp: 20260825_110735_+0200\n",
+ "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ "Retrieval timestamp: 20260827_124042_+0200\n",
"Score method: sofascore_overall_rating_odds_lineup\n",
- "Metric-creation timestamp: 20260825_121320_+0200\n",
+ "Metric-creation timestamp: 20260827_124757_+0200\n",
"Requested matchday: 1\n",
"Match JSON source used: SofaScore\n",
"Match JSON path: C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_1.json\n",
"Detected/used market-value unit: euros -> integer euros\n",
"\n",
"=== Optimization result ===\n",
- "Chosen formation: 3-6-1\n",
+ "Chosen formation: 5-4-1\n",
"Solver status: Optimal\n",
- "Total score (captain doubled): 186.908654\n",
- "Recommended captain: Phillip Tietz\n",
- "Total squad value: €149,016,248\n",
- "Remaining budget: €983,752\n",
+ "Total score (captain doubled): 178.132352\n",
+ "Recommended captain: Nathaniel Brown\n",
+ "Total squad value: €149,705,212\n",
+ "Remaining budget: €294,788\n",
"\n",
"=== Selected players ===\n",
- " Full Name Position Club In-Game Value Score Captain\n",
- " Manuel Neuer GK FC Bayern München 13565866.0 16.507984 \n",
- " Dominik Kohr DEF 1. FSV Mainz 05 10467001.0 17.426471 \n",
- " Julian Ryerson DEF Borussia Dortmund 26027952.0 17.286749 \n",
- " Ridle Baku DEF RB Leipzig 17851318.0 15.459788 \n",
- "Konstantinos Karetsas MID Borussia Dortmund 24062897.0 17.098594 \n",
- " Ezechiel Banzuzi MID RB Leipzig 8349668.0 15.312951 \n",
- " Malik Tillman MID Bayer 04 Leverkusen 13303012.0 14.082281 \n",
- " Yannik Engelhardt MID SC Freiburg 10779698.0 12.229681 \n",
- " Patrick Wimmer MID TSG Hoffenheim 7364887.0 11.405367 \n",
- " Marius Wolf MID FC Augsburg 3585560.0 10.493174 \n",
- " Phillip Tietz FOR 1. FSV Mainz 05 13658389.0 19.802807 Yes\n",
+ " Full Name Position Club In-Game Value Score Captain\n",
+ " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
+ " Nathaniel Brown DEF FC Bayern München 29629517.0 17.515843 Yes\n",
+ " Julian Ryerson DEF Borussia Dortmund 26105247.0 17.286749 \n",
+ " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 \n",
+ " Danny Da Costa DEF 1. FSV Mainz 05 9308429.0 15.846465 \n",
+ " Daniel Svensson DEF Borussia Dortmund 16621441.0 14.824107 \n",
+ " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
+ "Yannik Engelhardt MID SC Freiburg 10934988.0 12.280885 \n",
+ "Han-Noah Massengo MID FC Augsburg 10113144.0 11.731293 \n",
+ " Patrick Wimmer MID TSG Hoffenheim 8149700.0 11.405367 \n",
+ " Tidiam Gomis FOR RB Leipzig 5374444.0 10.6594 \n",
"\n",
"=== Output ===\n",
- "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125710_+0200.csv\n"
+ "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131000_+0200.csv\n"
]
}
],
@@ -1686,7 +1686,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": 8,
"id": "9e6563fe",
"metadata": {},
"outputs": [],
@@ -1748,7 +1748,7 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": 9,
"id": "a093bb20-eb9c-4365-9175-2c12be0c869a",
"metadata": {},
"outputs": [
@@ -1756,14 +1756,28 @@
"name": "stdin",
"output_type": "stream",
"text": [
- "Select this lineup for KickbaseKIS Arena? [y/n]: n\n"
+ "Select this lineup for KickbaseKIS Arena? [y/n]: y\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Lineup was not selected; the existing selection is unchanged.\n"
+ "Current selected lineup for KickbaseKIS Arena: expected points=178.538892, players=[Manuel Neuer, Julian Ryerson, Dominik Kohr, Ramy Bensebaini, Philipp Treu, Josip Juranović, Brajan Gruda, Yannik Engelhardt, Han-Noah Massengo, Ezechiel Banzuzi, Phillip Tietz]\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Replace the current selected lineup? [y/n]: y\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Selected lineup saved to: C:\\kickbase project\\outputs\\selected_lineups\\kickbasekis-arena.json\n"
]
}
],
@@ -1787,7 +1801,7 @@
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": 10,
"id": "prune-timestamped-outputs",
"metadata": {},
"outputs": [
diff --git a/notebooks/07_squad_optimisation/optimize_squad_three_teams_overlap_allowed.ipynb b/notebooks/07_squad_optimisation/optimize_squad_three_teams_overlap_allowed.ipynb
index b79e429..add45d8 100644
--- a/notebooks/07_squad_optimisation/optimize_squad_three_teams_overlap_allowed.ipynb
+++ b/notebooks/07_squad_optimisation/optimize_squad_three_teams_overlap_allowed.ipynb
@@ -1441,10 +1441,10 @@
"output_type": "stream",
"text": [
"Selected score input:\n",
- " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
- " Retrieval timestamp: 20260825_110735_+0200\n",
+ " File: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
+ " Retrieval timestamp: 20260827_124042_+0200\n",
" Method: sofascore_overall_rating_odds_lineup\n",
- " Metric-creation timestamp: 20260825_121320_+0200\n"
+ " Metric-creation timestamp: 20260827_124757_+0200\n"
]
},
{
@@ -1473,7 +1473,7 @@
" 16434029 SC Freiburg SC Freiburg (5) SV Werder Bremen SV Werder Bremen (10)\n",
" 16434039 FC Augsburg FC Augsburg (13) FC Schalke 04 FC Schalke 04 (8)\n",
"\n",
- "Validated 469 player rows once before formation solving.\n",
+ "Validated 468 player rows once before formation solving.\n",
"Detected market-value unit: euros; internal optimization unit: euros.\n",
"\n",
"=== Optimizing team 1 ===\n",
@@ -1580,71 +1580,71 @@
" 0 | \n",
" 4-4-2 | \n",
" Optimal | \n",
- " 208.075295 | \n",
- " €245,568,703 | \n",
+ " 201.988961 | \n",
+ " €248,804,872 | \n",
" \n",
" \n",
" | 1 | \n",
" 4-2-4 | \n",
" Optimal | \n",
- " 202.778716 | \n",
- " €247,029,332 | \n",
+ " 195.801314 | \n",
+ " €248,295,956 | \n",
"
\n",
" \n",
" | 2 | \n",
" 3-4-3 | \n",
" Optimal | \n",
- " 206.051029 | \n",
- " €245,508,950 | \n",
+ " 199.734814 | \n",
+ " €248,658,106 | \n",
"
\n",
" \n",
" | 3 | \n",
" 4-3-3 | \n",
" Optimal | \n",
- " 205.909158 | \n",
- " €249,942,411 | \n",
+ " 199.312979 | \n",
+ " €248,149,134 | \n",
"
\n",
" \n",
" | 4 | \n",
" 5-3-2 | \n",
" Optimal | \n",
- " 208.052109 | \n",
- " €249,432,702 | \n",
+ " 201.645538 | \n",
+ " €248,346,493 | \n",
"
\n",
" \n",
" | 5 | \n",
" 3-5-2 | \n",
" Optimal | \n",
- " 208.313505 | \n",
- " €240,972,953 | \n",
+ " 201.795313 | \n",
+ " €244,235,387 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5-4-1 | \n",
" Optimal | \n",
- " 209.460231 | \n",
- " €247,962,163 | \n",
+ " 203.706037 | \n",
+ " €243,923,774 | \n",
"
\n",
" \n",
" | 7 | \n",
" 4-5-1 | \n",
" Optimal | \n",
- " 209.199532 | \n",
- " €242,693,920 | \n",
+ " 203.947302 | \n",
+ " €239,496,775 | \n",
"
\n",
" \n",
" | 8 | \n",
" 3-6-1 | \n",
" Optimal | \n",
- " 208.783893 | \n",
- " €238,473,486 | \n",
+ " 202.46475 | \n",
+ " €248,151,751 | \n",
"
\n",
" \n",
" | 9 | \n",
" 5-2-3 | \n",
" Optimal | \n",
- " 205.568446 | \n",
- " €249,128,327 | \n",
+ " 198.207568 | \n",
+ " €248,669,050 | \n",
"
\n",
" \n",
"\n",
@@ -1652,16 +1652,16 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 4-4-2 Optimal 208.075295 €245,568,703\n",
- "1 4-2-4 Optimal 202.778716 €247,029,332\n",
- "2 3-4-3 Optimal 206.051029 €245,508,950\n",
- "3 4-3-3 Optimal 205.909158 €249,942,411\n",
- "4 5-3-2 Optimal 208.052109 €249,432,702\n",
- "5 3-5-2 Optimal 208.313505 €240,972,953\n",
- "6 5-4-1 Optimal 209.460231 €247,962,163\n",
- "7 4-5-1 Optimal 209.199532 €242,693,920\n",
- "8 3-6-1 Optimal 208.783893 €238,473,486\n",
- "9 5-2-3 Optimal 205.568446 €249,128,327"
+ "0 4-4-2 Optimal 201.988961 €248,804,872\n",
+ "1 4-2-4 Optimal 195.801314 €248,295,956\n",
+ "2 3-4-3 Optimal 199.734814 €248,658,106\n",
+ "3 4-3-3 Optimal 199.312979 €248,149,134\n",
+ "4 5-3-2 Optimal 201.645538 €248,346,493\n",
+ "5 3-5-2 Optimal 201.795313 €244,235,387\n",
+ "6 5-4-1 Optimal 203.706037 €243,923,774\n",
+ "7 4-5-1 Optimal 203.947302 €239,496,775\n",
+ "8 3-6-1 Optimal 202.46475 €248,151,751\n",
+ "9 5-2-3 Optimal 198.207568 €248,669,050"
]
},
"metadata": {},
@@ -1674,17 +1674,17 @@
"\n",
"=== Team 1: selected players ===\n",
" Full Name Position Club In-Game Value Score Captain\n",
- " Manuel Neuer GK FC Bayern München 13565866.0 16.507984 \n",
- " Dominik Kohr DEF 1. FSV Mainz 05 10467001.0 17.426471 \n",
- " Nathaniel Brown DEF FC Bayern München 29388219.0 17.294079 \n",
- " Julian Ryerson DEF Borussia Dortmund 26027952.0 17.286749 \n",
- " Willi Orban DEF RB Leipzig 31396500.0 16.361783 \n",
- " Joane Gadou DEF Borussia Dortmund 24871710.0 15.993183 \n",
- " Nadiem Amiri MID 1. FSV Mainz 05 33735560.0 19.802807 Yes\n",
- "Konstantinos Karetsas MID Borussia Dortmund 24062897.0 17.098594 \n",
- " Aleksandar Pavlović MID FC Bayern München 32438401.0 16.770016 \n",
- " Ezechiel Banzuzi MID RB Leipzig 8349668.0 15.312951 \n",
- " Phillip Tietz FOR 1. FSV Mainz 05 13658389.0 19.802807 \n",
+ " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
+ " Nathaniel Brown DEF FC Bayern München 29629517.0 17.515843 \n",
+ " Julian Ryerson DEF Borussia Dortmund 26105247.0 17.286749 \n",
+ " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 \n",
+ " Danny Da Costa DEF 1. FSV Mainz 05 9308429.0 15.846465 \n",
+ " Nadiem Amiri MID 1. FSV Mainz 05 33932022.0 19.563537 Yes\n",
+ "Konstantinos Karetsas MID Borussia Dortmund 24574032.0 17.098594 \n",
+ " Aleksandar Pavlović MID FC Bayern München 32570412.0 16.98506 \n",
+ " Brajan Gruda MID RB Leipzig 20088446.0 15.545361 \n",
+ " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
+ " Serhou Guirassy FOR Borussia Dortmund 29820368.0 15.475756 \n",
"\n",
"=== Team 2: formation comparison ===\n"
]
@@ -1721,71 +1721,71 @@
" 0 | \n",
" 4-4-2 | \n",
" Optimal | \n",
- " 205.733533 | \n",
- " €246,094,816 | \n",
+ " 199.39733 | \n",
+ " €248,793,683 | \n",
" \n",
" \n",
" | 1 | \n",
" 4-2-4 | \n",
" Optimal | \n",
- " 202.582126 | \n",
- " €248,988,513 | \n",
+ " 195.497271 | \n",
+ " €248,591,002 | \n",
"
\n",
" \n",
" | 2 | \n",
" 3-4-3 | \n",
" Optimal | \n",
- " 205.188301 | \n",
- " €249,770,747 | \n",
+ " 197.357243 | \n",
+ " €248,984,534 | \n",
"
\n",
" \n",
" | 3 | \n",
" 4-3-3 | \n",
" Optimal | \n",
- " 204.398061 | \n",
- " €249,821,598 | \n",
+ " 197.349203 | \n",
+ " €246,868,936 | \n",
"
\n",
" \n",
" | 4 | \n",
" 5-3-2 | \n",
" Optimal | \n",
- " 205.921688 | \n",
- " €248,059,871 | \n",
+ " 199.857524 | \n",
+ " €247,451,719 | \n",
"
\n",
" \n",
" | 5 | \n",
" 3-5-2 | \n",
" Optimal | \n",
- " 205.658689 | \n",
- " €247,271,280 | \n",
+ " 198.327693 | \n",
+ " €249,640,443 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5-4-1 | \n",
" Optimal | \n",
- " 206.392076 | \n",
- " €245,560,404 | \n",
+ " 200.917145 | \n",
+ " €245,839,930 | \n",
"
\n",
" \n",
" | 7 | \n",
" 4-5-1 | \n",
" Optimal | \n",
- " 206.501626 | \n",
- " €249,009,841 | \n",
+ " 200.386362 | \n",
+ " €248,780,825 | \n",
"
\n",
" \n",
" | 8 | \n",
" 3-6-1 | \n",
" Optimal | \n",
- " 205.916892 | \n",
- " €249,916,459 | \n",
+ " 199.316725 | \n",
+ " €249,627,585 | \n",
"
\n",
" \n",
" | 9 | \n",
" 5-2-3 | \n",
" Optimal | \n",
- " 204.793093 | \n",
- " €247,540,739 | \n",
+ " 197.537358 | \n",
+ " €248,400,151 | \n",
"
\n",
" \n",
"\n",
@@ -1793,16 +1793,16 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 4-4-2 Optimal 205.733533 €246,094,816\n",
- "1 4-2-4 Optimal 202.582126 €248,988,513\n",
- "2 3-4-3 Optimal 205.188301 €249,770,747\n",
- "3 4-3-3 Optimal 204.398061 €249,821,598\n",
- "4 5-3-2 Optimal 205.921688 €248,059,871\n",
- "5 3-5-2 Optimal 205.658689 €247,271,280\n",
- "6 5-4-1 Optimal 206.392076 €245,560,404\n",
- "7 4-5-1 Optimal 206.501626 €249,009,841\n",
- "8 3-6-1 Optimal 205.916892 €249,916,459\n",
- "9 5-2-3 Optimal 204.793093 €247,540,739"
+ "0 4-4-2 Optimal 199.39733 €248,793,683\n",
+ "1 4-2-4 Optimal 195.497271 €248,591,002\n",
+ "2 3-4-3 Optimal 197.357243 €248,984,534\n",
+ "3 4-3-3 Optimal 197.349203 €246,868,936\n",
+ "4 5-3-2 Optimal 199.857524 €247,451,719\n",
+ "5 3-5-2 Optimal 198.327693 €249,640,443\n",
+ "6 5-4-1 Optimal 200.917145 €245,839,930\n",
+ "7 4-5-1 Optimal 200.386362 €248,780,825\n",
+ "8 3-6-1 Optimal 199.316725 €249,627,585\n",
+ "9 5-2-3 Optimal 197.537358 €248,400,151"
]
},
"metadata": {},
@@ -1815,17 +1815,17 @@
"\n",
"=== Team 2: selected players ===\n",
" Full Name Position Club In-Game Value Score Captain\n",
- " Manuel Neuer GK FC Bayern München 13565866.0 16.507984 \n",
- " Dominik Kohr DEF 1. FSV Mainz 05 10467001.0 17.426471 \n",
- " Julian Ryerson DEF Borussia Dortmund 26027952.0 17.286749 \n",
- " Jonathan Tah DEF FC Bayern München 37034151.0 16.531806 \n",
- " Ridle Baku DEF RB Leipzig 17851318.0 15.459788 \n",
- " Nadiem Amiri MID 1. FSV Mainz 05 33735560.0 19.802807 \n",
- "Konstantinos Karetsas MID Borussia Dortmund 24062897.0 17.098594 \n",
- " Felix Nmecha MID Borussia Dortmund 27176066.0 15.946144 \n",
- " Brajan Gruda MID RB Leipzig 19603467.0 15.732484 \n",
- " Antonio Nusa MID RB Leipzig 25827174.0 15.103185 \n",
- " Phillip Tietz FOR 1. FSV Mainz 05 13658389.0 19.802807 Yes\n",
+ " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
+ " Nathaniel Brown DEF FC Bayern München 29629517.0 17.515843 \n",
+ " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 \n",
+ " Joane Gadou DEF Borussia Dortmund 25093948.0 15.993183 \n",
+ " Anthony Caci DEF 1. FSV Mainz 05 10976864.0 15.846465 \n",
+ " Daniel Svensson DEF Borussia Dortmund 16621441.0 14.824107 \n",
+ " Nadiem Amiri MID 1. FSV Mainz 05 33932022.0 19.563537 Yes\n",
+ "Konstantinos Karetsas MID Borussia Dortmund 24574032.0 17.098594 \n",
+ " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
+ " Nicolas Seiwald MID RB Leipzig 17963405.0 14.363913 \n",
+ " Luis Díaz FOR FC Bayern München 53580399.0 17.081566 \n",
"\n",
"=== Team 3: formation comparison ===\n"
]
@@ -1862,71 +1862,71 @@
" 0 | \n",
" 4-4-2 | \n",
" Optimal | \n",
- " 205.034911 | \n",
- " €249,552,688 | \n",
+ " 197.985407 | \n",
+ " €247,696,545 | \n",
" \n",
" \n",
" | 1 | \n",
" 4-2-4 | \n",
" Optimal | \n",
- " 202.582126 | \n",
- " €248,988,513 | \n",
+ " 194.627761 | \n",
+ " €248,569,980 | \n",
"
\n",
" \n",
" | 2 | \n",
" 3-4-3 | \n",
" Optimal | \n",
- " 203.992632 | \n",
- " €247,882,255 | \n",
+ " 195.829192 | \n",
+ " €249,029,239 | \n",
"
\n",
" \n",
" | 3 | \n",
" 4-3-3 | \n",
" Optimal | \n",
- " 203.926874 | \n",
- " €246,462,577 | \n",
+ " 196.670745 | \n",
+ " €248,950,565 | \n",
"
\n",
" \n",
" | 4 | \n",
" 5-3-2 | \n",
" Optimal | \n",
- " 204.746863 | \n",
- " €235,624,954 | \n",
+ " 198.747588 | \n",
+ " €247,928,387 | \n",
"
\n",
" \n",
" | 5 | \n",
" 3-5-2 | \n",
" Optimal | \n",
- " 204.819293 | \n",
- " €244,612,235 | \n",
+ " 197.284863 | \n",
+ " €248,036,643 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5-4-1 | \n",
" Optimal | \n",
- " 205.830602 | \n",
- " €246,196,292 | \n",
+ " 200.186272 | \n",
+ " €249,357,930 | \n",
"
\n",
" \n",
" | 7 | \n",
" 4-5-1 | \n",
" Optimal | \n",
- " 205.641596 | \n",
- " €248,094,331 | \n",
+ " 199.276426 | \n",
+ " €249,257,493 | \n",
"
\n",
" \n",
" | 8 | \n",
" 3-6-1 | \n",
" Optimal | \n",
- " 205.517271 | \n",
- " €248,037,164 | \n",
+ " 197.965721 | \n",
+ " €246,713,554 | \n",
"
\n",
" \n",
" | 9 | \n",
" 5-2-3 | \n",
" Optimal | \n",
- " 203.776039 | \n",
- " €248,041,526 | \n",
+ " 196.83812 | \n",
+ " €248,993,285 | \n",
"
\n",
" \n",
"\n",
@@ -1934,16 +1934,16 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 4-4-2 Optimal 205.034911 €249,552,688\n",
- "1 4-2-4 Optimal 202.582126 €248,988,513\n",
- "2 3-4-3 Optimal 203.992632 €247,882,255\n",
- "3 4-3-3 Optimal 203.926874 €246,462,577\n",
- "4 5-3-2 Optimal 204.746863 €235,624,954\n",
- "5 3-5-2 Optimal 204.819293 €244,612,235\n",
- "6 5-4-1 Optimal 205.830602 €246,196,292\n",
- "7 4-5-1 Optimal 205.641596 €248,094,331\n",
- "8 3-6-1 Optimal 205.517271 €248,037,164\n",
- "9 5-2-3 Optimal 203.776039 €248,041,526"
+ "0 4-4-2 Optimal 197.985407 €247,696,545\n",
+ "1 4-2-4 Optimal 194.627761 €248,569,980\n",
+ "2 3-4-3 Optimal 195.829192 €249,029,239\n",
+ "3 4-3-3 Optimal 196.670745 €248,950,565\n",
+ "4 5-3-2 Optimal 198.747588 €247,928,387\n",
+ "5 3-5-2 Optimal 197.284863 €248,036,643\n",
+ "6 5-4-1 Optimal 200.186272 €249,357,930\n",
+ "7 4-5-1 Optimal 199.276426 €249,257,493\n",
+ "8 3-6-1 Optimal 197.965721 €246,713,554\n",
+ "9 5-2-3 Optimal 196.83812 €248,993,285"
]
},
"metadata": {},
@@ -1956,20 +1956,20 @@
"\n",
"=== Team 3: selected players ===\n",
" Full Name Position Club In-Game Value Score Captain\n",
- " Gregor Kobel GK Borussia Dortmund 22268613.0 15.993183 \n",
- " Dominik Kohr DEF 1. FSV Mainz 05 10467001.0 17.426471 \n",
- " Nathaniel Brown DEF FC Bayern München 29388219.0 17.294079 \n",
- " Julian Ryerson DEF Borussia Dortmund 26027952.0 17.286749 \n",
- " Danny Da Costa DEF 1. FSV Mainz 05 9703648.0 16.040274 \n",
- " Ridle Baku DEF RB Leipzig 17851318.0 15.459788 \n",
- " Michael Olise MID FC Bayern München 64815120.0 18.580415 \n",
- "Konstantinos Karetsas MID Borussia Dortmund 24062897.0 17.098594 \n",
- " Brajan Gruda MID RB Leipzig 19603467.0 15.732484 \n",
- " Ezechiel Banzuzi MID RB Leipzig 8349668.0 15.312951 \n",
- " Phillip Tietz FOR 1. FSV Mainz 05 13658389.0 19.802807 Yes\n",
+ " Gregor Kobel GK Borussia Dortmund 21922957.0 15.993183 \n",
+ " Nathaniel Brown DEF FC Bayern München 29629517.0 17.515843 \n",
+ " Julian Ryerson DEF Borussia Dortmund 26105247.0 17.286749 \n",
+ " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 \n",
+ " Jonathan Tah DEF FC Bayern München 36997411.0 16.743795 \n",
+ " Anthony Caci DEF 1. FSV Mainz 05 10976864.0 15.846465 \n",
+ " Nadiem Amiri MID 1. FSV Mainz 05 33932022.0 19.563537 Yes\n",
+ "Konstantinos Karetsas MID Borussia Dortmund 24574032.0 17.098594 \n",
+ " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
+ " Antonio Nusa MID RB Leipzig 25940708.0 14.923546 \n",
+ " Igor Matanović FOR SC Freiburg 19575194.0 13.304292 \n",
"\n",
"=== Input ===\n",
- "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv\n",
+ "Score input file: C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv\n",
"Requested matchday: 1\n",
"Match JSON source used: SofaScore\n",
"Match JSON path: C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_1.json\n",
@@ -2010,36 +2010,36 @@
" \n",
" | 0 | \n",
" Team 1 | \n",
- " 5-4-1 | \n",
- " 209.460231 | \n",
- " €247,962,163 | \n",
+ " 4-5-1 | \n",
+ " 203.947302 | \n",
+ " €239,496,775 | \n",
" Nadiem Amiri | \n",
"
\n",
" \n",
" | 1 | \n",
" Team 2 | \n",
- " 4-5-1 | \n",
- " 206.501626 | \n",
- " €249,009,841 | \n",
- " Phillip Tietz | \n",
+ " 5-4-1 | \n",
+ " 200.917145 | \n",
+ " €245,839,930 | \n",
+ " Nadiem Amiri | \n",
"
\n",
" \n",
" | 2 | \n",
" Team 3 | \n",
" 5-4-1 | \n",
- " 205.830602 | \n",
- " €246,196,292 | \n",
- " Phillip Tietz | \n",
+ " 200.186272 | \n",
+ " €249,357,930 | \n",
+ " Nadiem Amiri | \n",
"
\n",
" \n",
"\n",
""
],
"text/plain": [
- " Team Formation Score (captain doubled) Squad Value Captain\n",
- "0 Team 1 5-4-1 209.460231 €247,962,163 Nadiem Amiri\n",
- "1 Team 2 4-5-1 206.501626 €249,009,841 Phillip Tietz\n",
- "2 Team 3 5-4-1 205.830602 €246,196,292 Phillip Tietz"
+ " Team Formation Score (captain doubled) Squad Value Captain\n",
+ "0 Team 1 4-5-1 203.947302 €239,496,775 Nadiem Amiri\n",
+ "1 Team 2 5-4-1 200.917145 €245,839,930 Nadiem Amiri\n",
+ "2 Team 3 5-4-1 200.186272 €249,357,930 Nadiem Amiri"
]
},
"metadata": {},
@@ -2051,9 +2051,9 @@
"text": [
"\n",
"=== Output ===\n",
- "Team 1 CSV: C:\\kickbase project\\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\n",
- "Team 2 CSV: C:\\kickbase project\\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\n",
- "Team 3 CSV: C:\\kickbase project\\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\n"
+ "Team 1 CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_three_teams_overlap_allowed_team_1_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv\n",
+ "Team 2 CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_three_teams_overlap_allowed_team_2_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv\n",
+ "Team 3 CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_three_teams_overlap_allowed_team_3_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv\n"
]
}
],
diff --git a/notebooks/07_squad_optimisation/optimize_squad_v1.ipynb b/notebooks/07_squad_optimisation/optimize_squad_v1.ipynb
index ae4685d..670b4f9 100644
--- a/notebooks/07_squad_optimisation/optimize_squad_v1.ipynb
+++ b/notebooks/07_squad_optimisation/optimize_squad_v1.ipynb
@@ -12,7 +12,7 @@
"## Inputs and selection rules\n",
"\n",
"- Score candidates are read from `C:\\kickbase project\\outputs\\expected_points\\expected_points_*.csv`. The filename is parsed as `expected_points_{retrieval_timestamp}_{method}_{metric_creation_timestamp}.csv`; timestamps use `YYYYMMDD_HHMMSS_+ZZZZ`. The valid file with the latest **metric-creation timestamp in its filename** is selected. Filesystem timestamps are never used, and methods may contain underscores.\n",
- "- The matchday is supplied interactively with `int(input(...))` and must be a positive integer.\n",
+ "- The matchday is supplied interactively with `int(input(...))` and must be a positive integer. After the player data is validated, the notebook prompts for the maximum number of players allowed per team (default 3), then for the minimum number of distinct teams. The latter defaults to 5 unless the selected team cap requires more teams for an 11-player squad.\n",
"- Match participants are loaded first from `outputs/sofascore/match_ids/match_ids_{matchday}.json`. If that file is missing or unusable, the notebook falls back to `outputs/fotmob/match_ids/match_ids_{matchday}_fotmob.json`. No website navigation, scraping, or API request occurs.\n",
"- The current score schema uses Kickbase team IDs while the match providers use different ID namespaces. A validated 18-club Kickbase mapping and exact provider-name aliases are embedded below. Unknown or ambiguous teams stop execution.\n",
"\n",
@@ -20,7 +20,7 @@
"\n",
"The model is a cardinality-constrained binary knapsack built with PuLP and solved by CBC. It creates selection and captain binary variables per player. Exactly one selected player is captain, so that player's score is counted once in the squad total and once again as the captain bonus. The primary objective maximizes this captain-doubled total. Among squads with exactly the same optimal captain-doubled total, a second solve minimizes total in-game value without sacrificing score.\n",
"\n",
- "Every squad must contain exactly 11 players, exactly 1 GK, the exact DEF/MID/FOR counts of its formation, cost no more than €250,000,000, use no more than 3 players from one club, and use no more than 4 players combined from the two clubs in any match. The ten evaluated formations, in deterministic tie order, are `4-4-2`, `4-2-4`, `3-4-3`, `4-3-3`, `5-3-2`, `3-5-2`, `5-4-1`, `4-5-1`, `3-6-1`, and `5-2-3`. Each formation includes one additional goalkeeper. The globally best feasible formation is chosen by score, then lower cost, then this list order.\n",
+ "Every squad must contain exactly 11 players, exactly 1 GK, the exact DEF/MID/FOR counts of its formation, cost no more than €250,000,000, use no more than the user-requested number of players from one club (three by default), include at least the user-requested number of distinct teams (five by default where feasible), and use no more than 4 players combined from the two clubs in any match. The ten evaluated formations, in deterministic tie order, are `4-4-2`, `4-2-4`, `3-4-3`, `4-3-3`, `5-3-2`, `3-5-2`, `5-4-1`, `4-5-1`, `3-6-1`, and `5-2-3`. Each formation includes one additional goalkeeper. The globally best feasible formation is chosen by score, then lower cost, then this list order.\n",
"\n",
"Market values are converted to an internal integer-euro representation after explicitly testing whether the source column is expressed in euros, thousands of euros, or millions of euros. Original CSV columns and values remain unchanged. Expected-point coefficients are also integerized exactly for reliable two-stage optimization.\n",
"\n",
@@ -41,7 +41,7 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 11,
"id": "5e3ef4c5",
"metadata": {},
"outputs": [],
@@ -267,7 +267,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 12,
"id": "9b3c19b4",
"metadata": {},
"outputs": [],
@@ -620,7 +620,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 13,
"id": "eb6fdda4",
"metadata": {},
"outputs": [],
@@ -660,6 +660,57 @@
" return parsed\n",
"\n",
"\n",
+ "# Request the maximum number of players permitted from one team.\n",
+ "def request_maximum_players_per_team(available_team_count: int) -> int:\n",
+ " raw_value = input(\n",
+ " 'Enter the maximum players allowed from one team (1-11; default 3): '\n",
+ " ).strip()\n",
+ " maximum_players_per_team = 3 if not raw_value else require_positive_integer(\n",
+ " raw_value, 'Maximum players per team'\n",
+ " )\n",
+ " # Validate the input before continuing with later processing.\n",
+ " if maximum_players_per_team > 11:\n",
+ " raise ValueError(\n",
+ " 'Maximum players per team cannot exceed the 11-player squad size; '\n",
+ " f'received {maximum_players_per_team}.'\n",
+ " )\n",
+ " if available_team_count * maximum_players_per_team < 11:\n",
+ " raise ValueError(\n",
+ " 'The selected per-team cap cannot fill an 11-player squad from the available teams: '\n",
+ " f'{available_team_count} teams x {maximum_players_per_team} players is fewer than 11.'\n",
+ " )\n",
+ " return maximum_players_per_team\n",
+ "\n",
+ "\n",
+ "# Request the required squad diversity for the current optimization.\n",
+ "def request_minimum_team_count(\n",
+ " available_team_count: int, maximum_players_per_team: int\n",
+ ") -> int:\n",
+ " minimum_viable_team_count = math.ceil(11 / maximum_players_per_team)\n",
+ " maximum_team_count = min(11, available_team_count)\n",
+ " # Validate the input before continuing with later processing.\n",
+ " if minimum_viable_team_count > maximum_team_count:\n",
+ " raise ValueError(\n",
+ " 'The selected per-team cap cannot fill an 11-player squad from the available teams: '\n",
+ " f'need at least {minimum_viable_team_count} teams, found {available_team_count}.'\n",
+ " )\n",
+ " default_minimum_team_count = max(5, minimum_viable_team_count)\n",
+ " raw_value = input(\n",
+ " f'Enter the minimum number of distinct teams in the squad '\n",
+ " f'({minimum_viable_team_count}-{maximum_team_count}; default {default_minimum_team_count}): '\n",
+ " ).strip()\n",
+ " minimum_team_count = default_minimum_team_count if not raw_value else require_positive_integer(\n",
+ " raw_value, 'Minimum distinct-team count'\n",
+ " )\n",
+ " # Validate the input before continuing with later processing.\n",
+ " if not minimum_viable_team_count <= minimum_team_count <= maximum_team_count:\n",
+ " raise ValueError(\n",
+ " f'Minimum distinct-team count must be between {minimum_viable_team_count} and '\n",
+ " f'{maximum_team_count}; received {minimum_team_count}.'\n",
+ " )\n",
+ " return minimum_team_count\n",
+ "\n",
+ "\n",
"# Handle field for reuse in the workflow.\n",
"def unique_field(record: dict[str, Any], aliases: tuple[str, ...], label: str) -> Any:\n",
" present = [(key, record[key]) for key in aliases if key in record and record[key] is not None]\n",
@@ -812,7 +863,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 14,
"id": "39379a72",
"metadata": {},
"outputs": [],
@@ -1029,7 +1080,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 15,
"id": "042c1a42",
"metadata": {},
"outputs": [],
@@ -1051,12 +1102,19 @@
" mapped_matches: list[MappedMatch],\n",
" formation: str,\n",
" counts: dict[str, int],\n",
+ " maximum_players_per_team: int,\n",
+ " minimum_team_count: int,\n",
" solver_msg: bool = False,\n",
") -> FormationResult:\n",
" model = LpProblem(f'Kickbase_Squad_{formation.replace(\"-\", \"_\")}', LpMaximize)\n",
" indices = [int(index) for index in prepared.df.index]\n",
" x = {index: LpVariable(f'x_{index}', cat='Binary') for index in indices}\n",
" captain = {index: LpVariable(f'captain_{index}', cat='Binary') for index in indices}\n",
+ " team_keys = sorted(prepared.team_keys.unique().tolist())\n",
+ " team_selected = {\n",
+ " team_key: LpVariable(f'team_selected_{team_key}', cat='Binary')\n",
+ " for team_key in team_keys\n",
+ " }\n",
"\n",
" squad_score_expression = lpSum(int(prepared.score_units.loc[index]) * x[index] for index in indices)\n",
" captain_bonus_expression = lpSum(int(prepared.score_units.loc[index]) * captain[index] for index in indices)\n",
@@ -1078,11 +1136,19 @@
" )\n",
"\n",
" # Process each available item while preserving the current workflow state.\n",
- " for team_key in sorted(prepared.team_keys.unique().tolist()):\n",
+ " for team_key in team_keys:\n",
+ " team_player_count = lpSum(\n",
+ " x[index] for index in indices if prepared.team_keys.loc[index] == team_key\n",
+ " )\n",
" model += (\n",
- " lpSum(x[index] for index in indices if prepared.team_keys.loc[index] == team_key) <= 3,\n",
+ " team_player_count <= maximum_players_per_team * team_selected[team_key],\n",
" f'Club_{team_key}',\n",
" )\n",
+ " model += team_selected[team_key] <= team_player_count, f'TeamSelected_{team_key}'\n",
+ " model += (\n",
+ " lpSum(team_selected[team_key] for team_key in team_keys) >= minimum_team_count,\n",
+ " 'MinimumDistinctTeams',\n",
+ " )\n",
"\n",
" # Process each available item while preserving the current workflow state.\n",
" for match in mapped_matches:\n",
@@ -1145,14 +1211,21 @@
"\n",
"# Handle all formations for reuse in the workflow.\n",
"def evaluate_all_formations(\n",
- " prepared: PreparedData, mapped_matches: list[MappedMatch], solver_msg: bool = False\n",
+ " prepared: PreparedData,\n",
+ " mapped_matches: list[MappedMatch],\n",
+ " maximum_players_per_team: int,\n",
+ " minimum_team_count: int,\n",
+ " solver_msg: bool = False,\n",
") -> list[FormationResult]:\n",
" ensure_cbc_available()\n",
" results: list[FormationResult] = []\n",
" # Process each available item while preserving the current workflow state.\n",
" for formation, counts in ALLOWED_FORMATIONS.items():\n",
" print(f'Solving formation {formation} ...')\n",
- " result = solve_formation(prepared, mapped_matches, formation, counts, solver_msg)\n",
+ " result = solve_formation(\n",
+ " prepared, mapped_matches, formation, counts, maximum_players_per_team,\n",
+ " minimum_team_count, solver_msg\n",
+ " )\n",
" print(f' Status: {result.status}')\n",
" results.append(result)\n",
" return results\n",
@@ -1226,14 +1299,18 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 16,
"id": "063f64a6",
"metadata": {},
"outputs": [],
"source": [
"# Handle winning solution for reuse in the workflow.\n",
"def verify_winning_solution(\n",
- " winner: FormationResult, prepared: PreparedData, mapped_matches: list[MappedMatch]\n",
+ " winner: FormationResult,\n",
+ " prepared: PreparedData,\n",
+ " mapped_matches: list[MappedMatch],\n",
+ " maximum_players_per_team: int,\n",
+ " minimum_team_count: int,\n",
") -> None:\n",
" selected = list(winner.chosen_indices)\n",
" failures: list[str] = []\n",
@@ -1264,9 +1341,15 @@
" )\n",
"\n",
" club_counts = prepared.team_keys.loc[selected].value_counts().to_dict()\n",
- " over_club_limit = {team: count for team, count in club_counts.items() if count > 3}\n",
+ " over_club_limit = {\n",
+ " team: count for team, count in club_counts.items() if count > maximum_players_per_team\n",
+ " }\n",
" if over_club_limit:\n",
" failures.append(f'club limit exceeded: {over_club_limit}')\n",
+ " if len(club_counts) < minimum_team_count:\n",
+ " failures.append(\n",
+ " f'expected at least {minimum_team_count} distinct teams, found {len(club_counts)}'\n",
+ " )\n",
"\n",
" # Process each available item while preserving the current workflow state.\n",
" for match in mapped_matches:\n",
@@ -1383,7 +1466,7 @@
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 17,
"id": "eedaa4d7",
"metadata": {},
"outputs": [
@@ -1410,7 +1493,21 @@
"output_type": "stream",
"text": [
"Match source used: SofaScore (C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_1.json)\n",
- "Club mapping mode: embedded Kickbase team-ID bridge\n",
+ "Club mapping mode: embedded Kickbase team-ID bridge\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the maximum players allowed from one team (1-11; default 3): 2\n",
+ "Enter the minimum number of distinct teams in the squad (6-11; default 6): \n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
"\n",
"Match-to-club mapping diagnostics:\n",
" Match ID JSON Home Team CSV Home Club JSON Away Team CSV Away Club\n",
@@ -1482,71 +1579,71 @@
" 0 | \n",
" 4-4-2 | \n",
" Optimal | \n",
- " 201.988961 | \n",
- " €248,804,872 | \n",
+ " 197.446407 | \n",
+ " €249,456,871 | \n",
" \n",
" \n",
" | 1 | \n",
" 4-2-4 | \n",
" Optimal | \n",
- " 195.801314 | \n",
- " €248,295,956 | \n",
+ " 192.627478 | \n",
+ " €246,245,918 | \n",
"
\n",
" \n",
" | 2 | \n",
" 3-4-3 | \n",
" Optimal | \n",
- " 199.734814 | \n",
- " €248,658,106 | \n",
+ " 196.016195 | \n",
+ " €241,280,468 | \n",
"
\n",
" \n",
" | 3 | \n",
" 4-3-3 | \n",
" Optimal | \n",
- " 199.312979 | \n",
- " €248,149,134 | \n",
+ " 195.721411 | \n",
+ " €249,817,829 | \n",
"
\n",
" \n",
" | 4 | \n",
" 5-3-2 | \n",
" Optimal | \n",
- " 201.645538 | \n",
- " €248,346,493 | \n",
+ " 196.944483 | \n",
+ " €249,156,966 | \n",
"
\n",
" \n",
" | 5 | \n",
" 3-5-2 | \n",
" Optimal | \n",
- " 201.795313 | \n",
- " €244,235,387 | \n",
+ " 197.201008 | \n",
+ " €246,310,326 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5-4-1 | \n",
" Optimal | \n",
- " 203.706037 | \n",
- " €243,923,774 | \n",
+ " 197.650723 | \n",
+ " €241,094,190 | \n",
"
\n",
" \n",
" | 7 | \n",
" 4-5-1 | \n",
" Optimal | \n",
- " 203.947302 | \n",
- " €239,496,775 | \n",
+ " 198.263672 | \n",
+ " €247,402,971 | \n",
"
\n",
" \n",
" | 8 | \n",
" 3-6-1 | \n",
" Optimal | \n",
- " 202.46475 | \n",
- " €248,151,751 | \n",
+ " 197.035949 | \n",
+ " €247,125,446 | \n",
"
\n",
" \n",
" | 9 | \n",
" 5-2-3 | \n",
" Optimal | \n",
- " 198.207568 | \n",
- " €248,669,050 | \n",
+ " 195.219487 | \n",
+ " €249,517,924 | \n",
"
\n",
" \n",
"\n",
@@ -1554,16 +1651,16 @@
],
"text/plain": [
" Formation Solver Status Total Score (captain doubled) Total Squad Value\n",
- "0 4-4-2 Optimal 201.988961 €248,804,872\n",
- "1 4-2-4 Optimal 195.801314 €248,295,956\n",
- "2 3-4-3 Optimal 199.734814 €248,658,106\n",
- "3 4-3-3 Optimal 199.312979 €248,149,134\n",
- "4 5-3-2 Optimal 201.645538 €248,346,493\n",
- "5 3-5-2 Optimal 201.795313 €244,235,387\n",
- "6 5-4-1 Optimal 203.706037 €243,923,774\n",
- "7 4-5-1 Optimal 203.947302 €239,496,775\n",
- "8 3-6-1 Optimal 202.46475 €248,151,751\n",
- "9 5-2-3 Optimal 198.207568 €248,669,050"
+ "0 4-4-2 Optimal 197.446407 €249,456,871\n",
+ "1 4-2-4 Optimal 192.627478 €246,245,918\n",
+ "2 3-4-3 Optimal 196.016195 €241,280,468\n",
+ "3 4-3-3 Optimal 195.721411 €249,817,829\n",
+ "4 5-3-2 Optimal 196.944483 €249,156,966\n",
+ "5 3-5-2 Optimal 197.201008 €246,310,326\n",
+ "6 5-4-1 Optimal 197.650723 €241,094,190\n",
+ "7 4-5-1 Optimal 198.263672 €247,402,971\n",
+ "8 3-6-1 Optimal 197.035949 €247,125,446\n",
+ "9 5-2-3 Optimal 195.219487 €249,517,924"
]
},
"metadata": {},
@@ -1581,6 +1678,8 @@
"Score method: sofascore_overall_rating_odds_lineup\n",
"Metric-creation timestamp: 20260827_124757_+0200\n",
"Requested matchday: 1\n",
+ "Maximum players per team requested: 2\n",
+ "Minimum distinct teams requested: 6\n",
"Match JSON source used: SofaScore\n",
"Match JSON path: C:\\kickbase project\\outputs\\sofascore\\match_ids\\match_ids_1.json\n",
"Detected/used market-value unit: euros -> integer euros\n",
@@ -1588,27 +1687,27 @@
"=== Optimization result ===\n",
"Chosen formation: 4-5-1\n",
"Solver status: Optimal\n",
- "Total score (captain doubled): 203.947302\n",
+ "Total score (captain doubled): 198.263672\n",
"Recommended captain: Nadiem Amiri\n",
- "Total squad value: €239,496,775\n",
- "Remaining budget: €10,503,225\n",
+ "Total squad value: €247,402,971\n",
+ "Remaining budget: €2,597,029\n",
"\n",
"=== Selected players ===\n",
- " Full Name Position Club In-Game Value Score Captain\n",
- " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
- " Nathaniel Brown DEF FC Bayern München 29629517.0 17.515843 \n",
- " Julian Ryerson DEF Borussia Dortmund 26105247.0 17.286749 \n",
- " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 \n",
- " Danny Da Costa DEF 1. FSV Mainz 05 9308429.0 15.846465 \n",
- " Nadiem Amiri MID 1. FSV Mainz 05 33932022.0 19.563537 Yes\n",
- "Konstantinos Karetsas MID Borussia Dortmund 24574032.0 17.098594 \n",
- " Aleksandar Pavlović MID FC Bayern München 32570412.0 16.98506 \n",
- " Brajan Gruda MID RB Leipzig 20088446.0 15.545361 \n",
- " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
- " Serhou Guirassy FOR Borussia Dortmund 29820368.0 15.475756 \n",
+ " Full Name Position Club In-Game Value Score Captain\n",
+ " Manuel Neuer GK FC Bayern München 13764324.0 16.719669 \n",
+ " Nathaniel Brown DEF FC Bayern München 29629517.0 17.515843 \n",
+ " Julian Ryerson DEF Borussia Dortmund 26105247.0 17.286749 \n",
+ " Dominik Kohr DEF 1. FSV Mainz 05 10652629.0 17.215913 \n",
+ " Miguel Gutiérrez DEF Bayer 04 Leverkusen 21033862.0 13.791336 \n",
+ " Nadiem Amiri MID 1. FSV Mainz 05 33932022.0 19.563537 Yes\n",
+ "Konstantinos Karetsas MID Borussia Dortmund 24574032.0 17.098594 \n",
+ " Brajan Gruda MID RB Leipzig 20088446.0 15.545361 \n",
+ " Aleix García MID Bayer 04 Leverkusen 38996349.0 15.528023 \n",
+ " Ezechiel Banzuzi MID RB Leipzig 9051349.0 15.130818 \n",
+ " Igor Matanović FOR SC Freiburg 19575194.0 13.304292 \n",
"\n",
"=== Output ===\n",
- "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_124906_+0200.csv\n"
+ "Optimized squad CSV: C:\\kickbase project\\outputs\\optimized_squad\\optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_164023_+0200.csv\n"
]
}
],
@@ -1623,19 +1722,28 @@
"matchday = request_matchday()\n",
"matches, match_source, match_path = load_matchday_matches(matchday)\n",
"prepared, mapped_matches, mapping_table = prepare_optimization_data(metadata.path, matches)\n",
+ "available_team_count = prepared.team_keys.nunique()\n",
+ "maximum_players_per_team = request_maximum_players_per_team(available_team_count)\n",
+ "minimum_team_count = request_minimum_team_count(\n",
+ " available_team_count, maximum_players_per_team\n",
+ ")\n",
"\n",
"print('\\nMatch-to-club mapping diagnostics:')\n",
"print(mapping_table.to_string(index=False))\n",
"print(f'\\nValidated {len(prepared.df):,} player rows once before formation solving.')\n",
"print(f'Detected market-value unit: {prepared.value_unit}; internal optimization unit: euros.')\n",
"\n",
- "formation_results = evaluate_all_formations(prepared, mapped_matches, solver_msg=False)\n",
+ "formation_results = evaluate_all_formations(\n",
+ " prepared, mapped_matches, maximum_players_per_team, minimum_team_count, solver_msg=False\n",
+ ")\n",
"comparison_table = formation_comparison(formation_results, prepared.score_scale)\n",
"print('\\nFormation comparison:')\n",
"display(comparison_table)\n",
"\n",
"winner = select_global_winner(formation_results)\n",
- "verify_winning_solution(winner, prepared, mapped_matches)\n",
+ "verify_winning_solution(\n",
+ " winner, prepared, mapped_matches, maximum_players_per_team, minimum_team_count\n",
+ ")\n",
"final_squad, sorted_indices = sort_final_squad(winner, prepared)\n",
"# Validate the input before continuing with later processing.\n",
"if list(final_squad.columns) != prepared.original_columns:\n",
@@ -1652,6 +1760,8 @@
"print(f'Score method: {metadata.method}')\n",
"print(f'Metric-creation timestamp: {metadata.metric_creation_timestamp}')\n",
"print(f'Requested matchday: {matchday}')\n",
+ "print(f'Maximum players per team requested: {maximum_players_per_team}')\n",
+ "print(f'Minimum distinct teams requested: {minimum_team_count}')\n",
"print(f'Match JSON source used: {match_source}')\n",
"print(f'Match JSON path: {match_path}')\n",
"print(f'Detected/used market-value unit: {prepared.value_unit} -> integer euros')\n",
@@ -1687,7 +1797,7 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 18,
"id": "d8ddd441",
"metadata": {},
"outputs": [],
@@ -1749,10 +1859,39 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 19,
"id": "a093bb20-eb9c-4365-9175-2c12be0c869a",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Select this lineup for Bundesliga Arena? [y/n]: y\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Current selected lineup for Bundesliga Arena: expected points=198.263672, players=[Manuel Neuer, Nathaniel Brown, Julian Ryerson, Dominik Kohr, Miguel Gutiérrez, Nadiem Amiri, Konstantinos Karetsas, Brajan Gruda, Aleix García, Ezechiel Banzuzi, Igor Matanović]\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Replace the current selected lineup? [y/n]: y\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Selected lineup saved to: C:\\kickbase project\\outputs\\selected_lineups\\bundesliga-arena.json\n"
+ ]
+ }
+ ],
"source": [
"\n",
"\n",
@@ -1773,10 +1912,18 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 20,
"id": "prune-timestamped-outputs",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Pruned 4 expired timestamped output(s).\n"
+ ]
+ }
+ ],
"source": [
"from project_paths import prune_timestamped_outputs\n",
"\n",
diff --git a/notebooks/08_visualisation/matchday_report.ipynb b/notebooks/08_visualisation/matchday_report.ipynb
new file mode 100644
index 0000000..e865ae7
--- /dev/null
+++ b/notebooks/08_visualisation/matchday_report.ipynb
@@ -0,0 +1,11956 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "8fd5bb47",
+ "metadata": {},
+ "source": [
+ "# Bundesliga matchday report\n",
+ "\n",
+ "This read-only notebook visualises existing project snapshots. It does not request live data, run collection notebooks, or write output files. Run the code cells from top to bottom and enter the matchday when prompted."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "58d13000",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Bundesliga matchday (1-34): 1\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Loaded 9 canonical fixtures for Matchday 1.\n"
+ ]
+ }
+ ],
+ "source": [
+ "import html\n",
+ "import json\n",
+ "import math\n",
+ "import re\n",
+ "import sys\n",
+ "import tempfile\n",
+ "import webbrowser\n",
+ "from pathlib import Path\n",
+ "from typing import Any\n",
+ "\n",
+ "import pandas as pd\n",
+ "import plotly.express as px\n",
+ "import plotly.io as pio\n",
+ "from IPython.display import Markdown, display\n",
+ "\n",
+ "\n",
+ "def locate_project_root() -> Path:\n",
+ " starts = []\n",
+ " notebook_path = globals().get('__vsc_ipynb_file__')\n",
+ " if isinstance(notebook_path, str) and notebook_path.strip():\n",
+ " starts.append(Path(notebook_path).resolve().parent)\n",
+ " starts.append(Path.cwd().resolve())\n",
+ " checked = set()\n",
+ " for start in starts:\n",
+ " for candidate in (start, *start.parents):\n",
+ " if candidate in checked:\n",
+ " continue\n",
+ " checked.add(candidate)\n",
+ " if (candidate / 'project_paths.py').is_file():\n",
+ " return candidate\n",
+ " raise FileNotFoundError('Could not locate project_paths.py. Open this notebook inside the Kickbase project.')\n",
+ "\n",
+ "\n",
+ "PROJECT_ROOT = locate_project_root()\n",
+ "if str(PROJECT_ROOT) not in sys.path:\n",
+ " sys.path.insert(0, str(PROJECT_ROOT))\n",
+ "\n",
+ "from project_paths import (\n",
+ " DERIVED_BUNDESLIGA_SNAPSHOTS_DIR, EXPECTED_POINTS_DIR, FOTMOB_ODDS_DIR,\n",
+ " KICKBASE_PREDICTED_LINEUPS_DIR, KICKER_PREDICTED_LINEUPS_DIR,\n",
+ " LIGAINSIDER_PREDICTED_LINEUPS_DIR, ROTOWIRE_PREDICTED_LINEUPS_DIR,\n",
+ " SOFASCORE_MATCH_IDS_DIR, SOFASCORE_ODDS_DIR, SOFASCORE_PLAYER_AVERAGE_RATINGS_DIR,\n",
+ " SOFASCORE_TEAM_FORM_DIR, SOFASCORE_UPCOMING_MATCHES_DIR,\n",
+ ")\n",
+ "from sofascore_rating_odds_lineup_score import KB_TEAM_ID_TO_KEY, canonical_team\n",
+ "\n",
+ "\n",
+ "LINEUP_SOURCES = (\n",
+ " ('LigaInsider', LIGAINSIDER_PREDICTED_LINEUPS_DIR, 'ligainsider_bundesliga_lineups_*.json'),\n",
+ " ('Kickbase', KICKBASE_PREDICTED_LINEUPS_DIR, 'kickbase_bundesliga_lineups_*.json'),\n",
+ " ('Kicker', KICKER_PREDICTED_LINEUPS_DIR, 'kicker_bundesliga_lineups_*.json'),\n",
+ " ('RotoWire', ROTOWIRE_PREDICTED_LINEUPS_DIR, 'rotowire_bundesliga_lineups_*.json'),\n",
+ ")\n",
+ "RESULT_COLOURS = {'W': '#2ca02c', 'D': '#f0ad4e', 'L': '#d9534f'}\n",
+ "BROWSER_REPORT_DIR = Path(tempfile.gettempdir()) / 'kickbase_matchday_reports'\n",
+ "\n",
+ "\n",
+ "def queue_figure(figure):\n",
+ " MATCH_FIGURES.append(figure)\n",
+ "\n",
+ "\n",
+ "def open_match_report(matchday: int, number: int, title: str, figures: list) -> Path | None:\n",
+ " if not figures:\n",
+ " return None\n",
+ " BROWSER_REPORT_DIR.mkdir(parents=True, exist_ok=True)\n",
+ " slug = re.sub('[^a-z0-9]+', '-', title.casefold()).strip('-')\n",
+ " report_path = BROWSER_REPORT_DIR / f'matchday_{matchday:02d}_{number:02d}_{slug}.html'\n",
+ " regular_fragments, formation_fragments = [], []\n",
+ " for index, figure in enumerate(figures):\n",
+ " fragment = pio.to_html(figure, full_html=False, include_plotlyjs=index == 0, config={'responsive': True})\n",
+ " if figure.layout.meta == {'report_kind': 'formation'}:\n",
+ " formation_fragments.append(f'{fragment}
')\n",
+ " else:\n",
+ " regular_fragments.append(fragment)\n",
+ " figures_html = '\\n'.join(regular_fragments)\n",
+ " formations_html = 'Formation comparison
' if formation_fragments else ''\n",
+ " document = f'{html.escape(title)}{html.escape(title)}
{figures_html}{formations_html}'\n",
+ " report_path.write_text(document, encoding='utf-8')\n",
+ " webbrowser.open_new_tab(report_path.as_uri())\n",
+ " return report_path\n",
+ "\n",
+ "\n",
+ "\n",
+ "def read_json(path: Path) -> Any:\n",
+ " try:\n",
+ " return json.loads(path.read_text(encoding='utf-8'))\n",
+ " except (OSError, UnicodeDecodeError, json.JSONDecodeError) as exc:\n",
+ " raise ValueError(f'Could not read {path}: {exc}') from exc\n",
+ "\n",
+ "\n",
+ "def ask_matchday() -> int:\n",
+ " value = input('Bundesliga matchday (1-34): ').strip()\n",
+ " try:\n",
+ " matchday = int(value)\n",
+ " except ValueError as exc:\n",
+ " raise ValueError('Matchday must be a whole number from 1 to 34.') from exc\n",
+ " if not 1 <= matchday <= 34:\n",
+ " raise ValueError('Matchday must be a whole number from 1 to 34.')\n",
+ " return matchday\n",
+ "\n",
+ "\n",
+ "def team_key(name: Any) -> str | None:\n",
+ " try:\n",
+ " return canonical_team(name)\n",
+ " except (TypeError, ValueError):\n",
+ " return None\n",
+ "\n",
+ "\n",
+ "def fixture_key(home: Any, away: Any) -> frozenset[str] | None:\n",
+ " home_key, away_key = team_key(home), team_key(away)\n",
+ " if home_key is None or away_key is None or home_key == away_key:\n",
+ " return None\n",
+ " return frozenset((home_key, away_key))\n",
+ "\n",
+ "\n",
+ "def snapshot_time(document: Any, path: Path) -> str:\n",
+ " if isinstance(document, dict):\n",
+ " metadata = document.get('metadata', {})\n",
+ " if isinstance(metadata, dict):\n",
+ " for key in ('captured_at', 'processed_at', 'capture_finished_at'):\n",
+ " if metadata.get(key):\n",
+ " return str(metadata[key])\n",
+ " for key in ('generated_at', 'execution_timestamp', 'captured_at'):\n",
+ " if document.get(key):\n",
+ " return str(document[key])\n",
+ " return path.name\n",
+ "\n",
+ "\n",
+ "def newest_json(directory: Path, pattern: str, predicate=None) -> tuple[Path | None, Any | None]:\n",
+ " candidates = []\n",
+ " for path in directory.glob(pattern):\n",
+ " try:\n",
+ " document = read_json(path)\n",
+ " except ValueError:\n",
+ " continue\n",
+ " if predicate is None or predicate(document, path):\n",
+ " candidates.append((snapshot_time(document, path), path, document))\n",
+ " if not candidates:\n",
+ " return None, None\n",
+ " _, path, document = max(candidates, key=lambda item: (item[0], item[1].name))\n",
+ " return path, document\n",
+ "\n",
+ "\n",
+ "def valid_bookmaker(value: Any) -> bool:\n",
+ " if not isinstance(value, dict):\n",
+ " return False\n",
+ " try:\n",
+ " odds = [float(value[key]) for key in ('home_win', 'draw', 'away_win')]\n",
+ " except (KeyError, TypeError, ValueError):\n",
+ " return False\n",
+ " return all(math.isfinite(odd) and odd > 1 for odd in odds)\n",
+ "\n",
+ "\n",
+ "def odds_record(document: Any, key: frozenset[str]) -> dict[str, Any] | None:\n",
+ " if not isinstance(document, list):\n",
+ " return None\n",
+ " for record in document:\n",
+ " if not isinstance(record, dict) or fixture_key(record.get('home_team'), record.get('away_team')) != key:\n",
+ " continue\n",
+ " bookmaker = next((item for item in record.get('bookmakers', []) if valid_bookmaker(item)), None)\n",
+ " if bookmaker is None:\n",
+ " return None\n",
+ " home_odd, draw_odd, away_odd = (float(bookmaker[name]) for name in ('home_win', 'draw', 'away_win'))\n",
+ " inverse = [1 / home_odd, 1 / draw_odd, 1 / away_odd]\n",
+ " total = sum(inverse)\n",
+ " return {\n",
+ " 'home_odd': home_odd, 'draw_odd': draw_odd, 'away_odd': away_odd,\n",
+ " 'home_points': 3 * inverse[0] / total + inverse[1] / total,\n",
+ " 'away_points': 3 * inverse[2] / total + inverse[1] / total,\n",
+ " 'bookmaker': bookmaker.get('bookmaker') or 'Unnamed bookmaker',\n",
+ " }\n",
+ " return None\n",
+ "\n",
+ "\n",
+ "def matches_from_snapshot(document: Any) -> dict[frozenset[str], dict[str, Any]]:\n",
+ " found = {}\n",
+ " if not isinstance(document, dict):\n",
+ " return found\n",
+ " for match in document.get('matches', []):\n",
+ " if not isinstance(match, dict):\n",
+ " continue\n",
+ " key = fixture_key(match.get('home', {}).get('team_name'), match.get('away', {}).get('team_name'))\n",
+ " if key is not None:\n",
+ " found[key] = match\n",
+ " return found\n",
+ "\n",
+ "\n",
+ "def matching_lineup_snapshot(directory: Path, pattern: str, requested: set[frozenset[str]], matchday: int) -> tuple[Path | None, Any | None, str]:\n",
+ " candidates = []\n",
+ " for path in directory.glob(pattern):\n",
+ " try:\n",
+ " document = read_json(path)\n",
+ " except ValueError:\n",
+ " continue\n",
+ " metadata = document.get('metadata', {}) if isinstance(document, dict) else {}\n",
+ " declared_matchday = metadata.get('matchday') if isinstance(metadata, dict) else None\n",
+ " coverage = set(matches_from_snapshot(document))\n",
+ " if declared_matchday is not None and declared_matchday != matchday:\n",
+ " continue\n",
+ " if coverage != requested:\n",
+ " continue\n",
+ " candidates.append((snapshot_time(document, path), path, document))\n",
+ " if not candidates:\n",
+ " return None, None, 'No snapshot exactly matches the requested fixture set.'\n",
+ " _, path, document = max(candidates, key=lambda item: (item[0], item[1].name))\n",
+ " return path, document, ''\n",
+ "\n",
+ "\n",
+ "def standings_rows(document: Any, keys: set[str]) -> list[dict[str, Any]]:\n",
+ " rows = []\n",
+ " if not isinstance(document, dict):\n",
+ " return rows\n",
+ " for team in document.get('teams', {}).values():\n",
+ " if not isinstance(team, dict) or team_key(team.get('team')) not in keys:\n",
+ " continue\n",
+ " rows.append({name: team.get(name) for name in ('team', 'position', 'matches', 'points', 'goal_difference')})\n",
+ " return sorted(rows, key=lambda row: (row['position'] is None, row['position']))\n",
+ "\n",
+ "\n",
+ "def form_rows(document: Any, key: str, category: str) -> list[dict[str, Any]]:\n",
+ " if not isinstance(document, dict) or not document:\n",
+ " return []\n",
+ " payload = next(iter(document.values()))\n",
+ " if not isinstance(payload, dict):\n",
+ " return []\n",
+ " entry = next((item for item in payload.values() if isinstance(item, dict) and team_key(item.get('team')) == key), None)\n",
+ " if entry is None:\n",
+ " return []\n",
+ " rows = []\n",
+ " for index, match in enumerate(entry.get(f'{category}_matches', [])):\n",
+ " if not isinstance(match, dict):\n",
+ " continue\n",
+ " is_home = team_key(match.get('home_team')) == key\n",
+ " opponent = match.get('away_team') if is_home else match.get('home_team')\n",
+ " home_score, away_score = match.get('home_score'), match.get('away_score')\n",
+ " score = f'{home_score}-{away_score}' if home_score is not None and away_score is not None else 'Score unavailable'\n",
+ " rows.append(dict(match, team=entry.get('team'), category=category, match_number=index + 1, opponent=opponent, score=score))\n",
+ " return rows\n",
+ "\n",
+ "\n",
+ "def upcoming_rows(document: Any, key: str) -> list[dict[str, Any]]:\n",
+ " if not isinstance(document, dict):\n",
+ " return []\n",
+ " entry = next((item for item in document.get('teams', {}).values() if isinstance(item, dict) and team_key(item.get('team')) == key), None)\n",
+ " if entry is None:\n",
+ " return []\n",
+ " rows = []\n",
+ " for category, field in (('Overall', 'next_match'), ('Bundesliga', 'next_bundesliga_match')):\n",
+ " match = entry.get(field)\n",
+ " if isinstance(match, dict):\n",
+ " rows.append({'category': category, 'team': entry.get('team'), 'date': match.get('date'), 'opponent': match.get('opponent'), 'venue': match.get('venue'), 'competition': match.get('competition')})\n",
+ " return rows\n",
+ "\n",
+ "\n",
+ "def rating_rows(document: Any, keys: set[str]) -> list[dict[str, Any]]:\n",
+ " rows = []\n",
+ " if not isinstance(document, dict):\n",
+ " return rows\n",
+ " for entry in document.get('teams', {}).values():\n",
+ " if not isinstance(entry, dict) or team_key(entry.get('team')) not in keys:\n",
+ " continue\n",
+ " for category in ('overall', 'bundesliga'):\n",
+ " players = entry.get(category, {}).get('players', []) if isinstance(entry.get(category), dict) else []\n",
+ " for player in players:\n",
+ " if isinstance(player, dict):\n",
+ " rows.append({'team': entry.get('team'), 'category': category.title(), **player})\n",
+ " return rows\n",
+ "\n",
+ "\n",
+ "def formation(players: list[dict[str, Any]]) -> str | None:\n",
+ " starters = [player for player in players if player.get('starting_probability_rank', 1) == 1 and player.get('formation_row') is not None]\n",
+ " counts = [len([player for player in starters if player.get('formation_row') == row]) for row in sorted({player['formation_row'] for player in starters})]\n",
+ " if not counts:\n",
+ " return None\n",
+ " return '-'.join(str(count) for count in (counts[1:] if counts[0] == 1 else counts))\n",
+ "\n",
+ "\n",
+ "def rotowire_coordinates(players: list[dict[str, Any]]) -> list[dict[str, Any]]:\n",
+ " line_order = ('Goalkeeper', 'Defence', 'Holding midfield', 'Midfield', 'Attacking midfield', 'Forward')\n",
+ " grouped = {line: [] for line in line_order}\n",
+ " for original_index, player in enumerate(players):\n",
+ " position = str(player.get('position') or '').upper()\n",
+ " if position == 'GK':\n",
+ " line = 'Goalkeeper'\n",
+ " elif position in {'DMC', 'DM', 'DML', 'DMR'}:\n",
+ " line = 'Holding midfield'\n",
+ " elif position in {'AML', 'AMC', 'AMR', 'AM'}:\n",
+ " line = 'Attacking midfield'\n",
+ " elif position in {'ML', 'MC', 'MR', 'M'}:\n",
+ " line = 'Midfield'\n",
+ " elif position in {'FW', 'ST', 'F'} or position.startswith('F'):\n",
+ " line = 'Forward'\n",
+ " elif position.startswith('D'):\n",
+ " line = 'Defence'\n",
+ " else:\n",
+ " line = 'Midfield'\n",
+ " side = 0 if position.endswith('L') else 2 if position.endswith('R') else 1\n",
+ " grouped[line].append((side, original_index, dict(player)))\n",
+ " positioned = []\n",
+ " for row_number, line in enumerate((line for line in line_order if grouped[line]), start=1):\n",
+ " for slot_index, (_, _, player) in enumerate(sorted(grouped[line]), start=1):\n",
+ " player['formation_row'] = row_number\n",
+ " player['slot_index'] = slot_index\n",
+ " positioned.append(player)\n",
+ " return positioned\n",
+ "\n",
+ "\n",
+ "def formation_figure(players: list[dict[str, Any]], source_name: str, label: str, side_rows: list[dict[str, Any]] | None = None):\n",
+ " frame = pd.DataFrame(players).copy()\n",
+ " frame['player'] = frame['displayed_name'].fillna(frame['full_name'])\n",
+ " frame['full_player_name'] = frame['full_name'].fillna(frame['displayed_name'])\n",
+ " frame['formation_row'] = pd.to_numeric(frame['formation_row'])\n",
+ " frame['slot_index'] = pd.to_numeric(frame['slot_index'])\n",
+ " frame['row_size'] = frame.groupby('formation_row')['formation_row'].transform('size')\n",
+ " frame['pitch_x'] = 100 * frame['slot_index'] / (frame['row_size'] + 1)\n",
+ " # LigaInsider and Kicker source rows use the opposite left/right orientation from the pitch view.\n",
+ " # Kickbase coordinates already match the pitch's left/right orientation.\n",
+ " if source_name in {'LigaInsider', 'Kicker'}:\n",
+ " frame['pitch_x'] = 100 - frame['pitch_x']\n",
+ " final_row = frame['formation_row'].max()\n",
+ " frame['pitch_y'] = 50 if final_row == 1 else 8 + 84 * (frame['formation_row'] - 1) / (final_row - 1)\n",
+ " figure = px.scatter(frame, x='pitch_x', y='pitch_y', hover_data={'full_player_name': True, 'position': True, 'injury_status': True, 'player': False}, title=f'{source_name}: {label} predicted starters')\n",
+ " figure.update_traces(marker={'size': 12, 'color': '#f8faf8', 'line': {'color': '#17202a', 'width': 1}})\n",
+ " has_side_rows = bool(side_rows)\n",
+ " figure.update_layout(showlegend=False, height=500, plot_bgcolor='#237a48', paper_bgcolor='white', margin={'l': 20, 'r': 135 if has_side_rows else 20, 't': 60, 'b': 20}, meta={'report_kind': 'formation'})\n",
+ " figure.update_xaxes(range=[0, 145] if has_side_rows else [0, 100], visible=False, fixedrange=True)\n",
+ " figure.update_yaxes(range=[0, 100], visible=False, fixedrange=True)\n",
+ " pitch_lines = [\n",
+ " {'type': 'rect', 'x0': 0, 'x1': 100, 'y0': 0, 'y1': 100},\n",
+ " {'type': 'line', 'x0': 0, 'x1': 100, 'y0': 50, 'y1': 50},\n",
+ " {'type': 'circle', 'x0': 42, 'x1': 58, 'y0': 42, 'y1': 58},\n",
+ " {'type': 'rect', 'x0': 25, 'x1': 75, 'y0': 0, 'y1': 18},\n",
+ " {'type': 'rect', 'x0': 25, 'x1': 75, 'y0': 82, 'y1': 100},\n",
+ " ]\n",
+ " for line in pitch_lines:\n",
+ " figure.add_shape(**line, line={'color': 'white', 'width': 2}, layer='below')\n",
+ " for player in frame.to_dict('records'):\n",
+ " figure.add_annotation(x=player['pitch_x'], y=player['pitch_y'], text=html.escape(str(player['player'])), showarrow=False, bgcolor='rgba(16,42,67,0.88)', bordercolor='rgba(255,255,255,0.5)', borderwidth=1, borderpad=4, font={'color': 'white', 'size': 11})\n",
+ " if has_side_rows:\n",
+ " figure.add_annotation(x=121, y=99, text='Alternatives / bench', showarrow=False, font={'color': '#102a43', 'size': 11})\n",
+ " step = 84 / max(1, len(side_rows) - 1)\n",
+ " for index, row in enumerate(side_rows):\n",
+ " relation = 'Bench' if row['type'] == 'Bench' else f'for {row[\"Alternative to\"]}'\n",
+ " text = f'{html.escape(str(row[\"player\"]))}
{html.escape(relation)}'\n",
+ " figure.add_annotation(x=121, y=90 - index * step, text=text, showarrow=False, align='center', bgcolor='rgba(255,255,255,0.96)', bordercolor='#102a43', borderwidth=1, borderpad=3, font={'color': '#102a43', 'size': 10})\n",
+ " return figure\n",
+ "\n",
+ "\n",
+ "matchday = ask_matchday()\n",
+ "fixtures_path = SOFASCORE_MATCH_IDS_DIR / f'match_ids_{matchday}.json'\n",
+ "if not fixtures_path.is_file():\n",
+ " raise FileNotFoundError(f'No canonical SofaScore fixtures exist for matchday {matchday}: {fixtures_path}')\n",
+ "fixtures = read_json(fixtures_path)\n",
+ "if not isinstance(fixtures, list) or not fixtures:\n",
+ " raise ValueError(f'Canonical fixture file is empty or invalid: {fixtures_path}')\n",
+ "fixture_keys = {fixture_key(item.get('home_team'), item.get('away_team')) for item in fixtures if isinstance(item, dict)}\n",
+ "if None in fixture_keys or len(fixture_keys) != len(fixtures):\n",
+ " raise ValueError('Canonical fixture file contains unknown or duplicate team pairs.')\n",
+ "print(f'Loaded {len(fixtures)} canonical fixtures for Matchday {matchday}.')\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "39844217",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/markdown": [
+ "## Matchday 1 overview"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " artifact | \n",
+ " selected_file | \n",
+ " state | \n",
+ " note | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Canonical fixtures | \n",
+ " match_ids_1.json | \n",
+ " Loaded | \n",
+ " 9 fixtures | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " FotMob odds | \n",
+ " matchday_1_odds_fotmob.json | \n",
+ " Loaded | \n",
+ " Primary 1X2 source | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " SofaScore odds | \n",
+ " matchday_1_odds.json | \n",
+ " Loaded | \n",
+ " Fallback 1X2 source | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " League table | \n",
+ " bundesliga_table_2026-08-23_00-49-56.json | \n",
+ " Loaded | \n",
+ " Latest league snapshot; it is not matchday-spe... | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Recent form | \n",
+ " team_form_2026-08-27_12-38-44_831736+0200.json | \n",
+ " Loaded | \n",
+ " Latest team-form snapshot; it is not matchday-... | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " Upcoming matches | \n",
+ " — | \n",
+ " Omitted | \n",
+ " Exact requested_matchday match required. | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " SofaScore player ratings | \n",
+ " team_player_average_ratings_2026-08-27_12-41-4... | \n",
+ " Loaded | \n",
+ " Must cite the selected form snapshot. | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " LigaInsider lineups | \n",
+ " ligainsider_bundesliga_lineups_20260827_124626... | \n",
+ " Loaded | \n",
+ " Exact fixture coverage. | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " Kickbase lineups | \n",
+ " kickbase_bundesliga_lineups_20260825_113858.json | \n",
+ " Loaded | \n",
+ " Exact fixture coverage. | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " Kicker lineups | \n",
+ " kicker_bundesliga_lineups_20260827_124652.json | \n",
+ " Loaded | \n",
+ " Exact fixture coverage. | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " RotoWire lineups | \n",
+ " rotowire_bundesliga_lineups_20260827_124203.json | \n",
+ " Loaded | \n",
+ " Exact fixture coverage. | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " Player expected points | \n",
+ " expected_points_20260827_124042_+0200_sofascor... | \n",
+ " Loaded | \n",
+ " Per-team expected-match points match selected ... | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " artifact \\\n",
+ "0 Canonical fixtures \n",
+ "1 FotMob odds \n",
+ "2 SofaScore odds \n",
+ "3 League table \n",
+ "4 Recent form \n",
+ "5 Upcoming matches \n",
+ "6 SofaScore player ratings \n",
+ "7 LigaInsider lineups \n",
+ "8 Kickbase lineups \n",
+ "9 Kicker lineups \n",
+ "10 RotoWire lineups \n",
+ "11 Player expected points \n",
+ "\n",
+ " selected_file state \\\n",
+ "0 match_ids_1.json Loaded \n",
+ "1 matchday_1_odds_fotmob.json Loaded \n",
+ "2 matchday_1_odds.json Loaded \n",
+ "3 bundesliga_table_2026-08-23_00-49-56.json Loaded \n",
+ "4 team_form_2026-08-27_12-38-44_831736+0200.json Loaded \n",
+ "5 — Omitted \n",
+ "6 team_player_average_ratings_2026-08-27_12-41-4... Loaded \n",
+ "7 ligainsider_bundesliga_lineups_20260827_124626... Loaded \n",
+ "8 kickbase_bundesliga_lineups_20260825_113858.json Loaded \n",
+ "9 kicker_bundesliga_lineups_20260827_124652.json Loaded \n",
+ "10 rotowire_bundesliga_lineups_20260827_124203.json Loaded \n",
+ "11 expected_points_20260827_124042_+0200_sofascor... Loaded \n",
+ "\n",
+ " note \n",
+ "0 9 fixtures \n",
+ "1 Primary 1X2 source \n",
+ "2 Fallback 1X2 source \n",
+ "3 Latest league snapshot; it is not matchday-spe... \n",
+ "4 Latest team-form snapshot; it is not matchday-... \n",
+ "5 Exact requested_matchday match required. \n",
+ "6 Must cite the selected form snapshot. \n",
+ "7 Exact fixture coverage. \n",
+ "8 Exact fixture coverage. \n",
+ "9 Exact fixture coverage. \n",
+ "10 Exact fixture coverage. \n",
+ "11 Per-team expected-match points match selected ... "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " fixture | \n",
+ " odds source | \n",
+ " home expected points | \n",
+ " away expected points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " FC Bayern München vs VfB Stuttgart | \n",
+ " FotMob | \n",
+ " 2.41 | \n",
+ " 0.45 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1. FC Köln vs TSG Hoffenheim | \n",
+ " FotMob | \n",
+ " 1.18 | \n",
+ " 1.56 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1. FC Union Berlin vs Eintracht Frankfurt | \n",
+ " FotMob | \n",
+ " 1.41 | \n",
+ " 1.32 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1. FSV Mainz 05 vs SC Paderborn 07 | \n",
+ " FotMob | \n",
+ " 1.96 | \n",
+ " 0.81 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " RB Leipzig vs Borussia M'gladbach | \n",
+ " FotMob | \n",
+ " 2.07 | \n",
+ " 0.72 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " SV 07 Elversberg vs Bayer 04 Leverkusen | \n",
+ " FotMob | \n",
+ " 0.75 | \n",
+ " 2.04 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " Borussia Dortmund vs Hamburger SV | \n",
+ " FotMob | \n",
+ " 2.35 | \n",
+ " 0.48 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " SC Freiburg vs SV Werder Bremen | \n",
+ " FotMob | \n",
+ " 1.71 | \n",
+ " 1.03 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " FC Augsburg vs FC Schalke 04 | \n",
+ " FotMob | \n",
+ " 1.59 | \n",
+ " 1.15 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " fixture odds source \\\n",
+ "0 FC Bayern München vs VfB Stuttgart FotMob \n",
+ "1 1. FC Köln vs TSG Hoffenheim FotMob \n",
+ "2 1. FC Union Berlin vs Eintracht Frankfurt FotMob \n",
+ "3 1. FSV Mainz 05 vs SC Paderborn 07 FotMob \n",
+ "4 RB Leipzig vs Borussia M'gladbach FotMob \n",
+ "5 SV 07 Elversberg vs Bayer 04 Leverkusen FotMob \n",
+ "6 Borussia Dortmund vs Hamburger SV FotMob \n",
+ "7 SC Freiburg vs SV Werder Bremen FotMob \n",
+ "8 FC Augsburg vs FC Schalke 04 FotMob \n",
+ "\n",
+ " home expected points away expected points \n",
+ "0 2.41 0.45 \n",
+ "1 1.18 1.56 \n",
+ "2 1.41 1.32 \n",
+ "3 1.96 0.81 \n",
+ "4 2.07 0.72 \n",
+ "5 0.75 2.04 \n",
+ "6 2.35 0.48 \n",
+ "7 1.71 1.03 \n",
+ "8 1.59 1.15 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.plotly.v1+json": {
+ "data": [
+ {
+ "hovertemplate": "fixture=FC Bayern München vs VfB Stuttgart
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "FC Bayern München vs VfB Stuttgart",
+ "marker": {
+ "color": "#636efa",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "FC Bayern München vs VfB Stuttgart",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "FC Bayern München",
+ "VfB Stuttgart"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "SOF6FK5HA0DNzMzMzMzcPw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=1. FC Köln vs TSG Hoffenheim
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "1. FC Köln vs TSG Hoffenheim",
+ "marker": {
+ "color": "#EF553B",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "1. FC Köln vs TSG Hoffenheim",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "1. FC Köln",
+ "TSG Hoffenheim"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "4XoUrkfh8j/2KFyPwvX4Pw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=1. FC Union Berlin vs Eintracht Frankfurt
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "1. FC Union Berlin vs Eintracht Frankfurt",
+ "marker": {
+ "color": "#00cc96",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "1. FC Union Berlin vs Eintracht Frankfurt",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "1. FC Union Berlin",
+ "Eintracht Frankfurt"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "j8L1KFyP9j8fhetRuB71Pw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=1. FSV Mainz 05 vs SC Paderborn 07
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "1. FSV Mainz 05 vs SC Paderborn 07",
+ "marker": {
+ "color": "#ab63fa",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "1. FSV Mainz 05 vs SC Paderborn 07",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "1. FSV Mainz 05",
+ "SC Paderborn 07"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "XI/C9Shc/z/sUbgehevpPw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=RB Leipzig vs Borussia M'gladbach
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "RB Leipzig vs Borussia M'gladbach",
+ "marker": {
+ "color": "#FFA15A",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "RB Leipzig vs Borussia M'gladbach",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "RB Leipzig",
+ "Borussia M'gladbach"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "j8L1KFyPAEAK16NwPQrnPw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=SV 07 Elversberg vs Bayer 04 Leverkusen
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "SV 07 Elversberg vs Bayer 04 Leverkusen",
+ "marker": {
+ "color": "#19d3f3",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "SV 07 Elversberg vs Bayer 04 Leverkusen",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "SV 07 Elversberg",
+ "Bayer 04 Leverkusen"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "AAAAAAAA6D9SuB6F61EAQA==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=Borussia Dortmund vs Hamburger SV
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "Borussia Dortmund vs Hamburger SV",
+ "marker": {
+ "color": "#FF6692",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "Borussia Dortmund vs Hamburger SV",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "Borussia Dortmund",
+ "Hamburger SV"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "zczMzMzMAkC4HoXrUbjePw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=SC Freiburg vs SV Werder Bremen
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "SC Freiburg vs SV Werder Bremen",
+ "marker": {
+ "color": "#B6E880",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "SC Freiburg vs SV Werder Bremen",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "SC Freiburg",
+ "SV Werder Bremen"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "XI/C9Shc+z97FK5H4XrwPw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ },
+ {
+ "hovertemplate": "fixture=FC Augsburg vs FC Schalke 04
team=%{x}
Expected match points=%{y}",
+ "legendgroup": "FC Augsburg vs FC Schalke 04",
+ "marker": {
+ "color": "#FF97FF",
+ "pattern": {
+ "shape": ""
+ }
+ },
+ "name": "FC Augsburg vs FC Schalke 04",
+ "orientation": "v",
+ "showlegend": true,
+ "textposition": "auto",
+ "type": "bar",
+ "x": [
+ "FC Augsburg",
+ "FC Schalke 04"
+ ],
+ "xaxis": "x",
+ "y": {
+ "bdata": "cT0K16Nw+T9mZmZmZmbyPw==",
+ "dtype": "f8"
+ },
+ "yaxis": "y"
+ }
+ ],
+ "layout": {
+ "barmode": "relative",
+ "legend": {
+ "title": {
+ "text": "fixture"
+ },
+ "tracegroupgap": 0
+ },
+ "template": {
+ "data": {
+ "bar": [
+ {
+ "error_x": {
+ "color": "#2a3f5f"
+ },
+ "error_y": {
+ "color": "#2a3f5f"
+ },
+ "marker": {
+ "line": {
+ "color": "#E5ECF6",
+ "width": 0.5
+ },
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "bar"
+ }
+ ],
+ "barpolar": [
+ {
+ "marker": {
+ "line": {
+ "color": "#E5ECF6",
+ "width": 0.5
+ },
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "barpolar"
+ }
+ ],
+ "carpet": [
+ {
+ "aaxis": {
+ "endlinecolor": "#2a3f5f",
+ "gridcolor": "white",
+ "linecolor": "white",
+ "minorgridcolor": "white",
+ "startlinecolor": "#2a3f5f"
+ },
+ "baxis": {
+ "endlinecolor": "#2a3f5f",
+ "gridcolor": "white",
+ "linecolor": "white",
+ "minorgridcolor": "white",
+ "startlinecolor": "#2a3f5f"
+ },
+ "type": "carpet"
+ }
+ ],
+ "choropleth": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "choropleth"
+ }
+ ],
+ "contour": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "contour"
+ }
+ ],
+ "contourcarpet": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "contourcarpet"
+ }
+ ],
+ "heatmap": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "heatmap"
+ }
+ ],
+ "histogram": [
+ {
+ "marker": {
+ "pattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ }
+ },
+ "type": "histogram"
+ }
+ ],
+ "histogram2d": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "histogram2d"
+ }
+ ],
+ "histogram2dcontour": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "histogram2dcontour"
+ }
+ ],
+ "mesh3d": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "type": "mesh3d"
+ }
+ ],
+ "parcoords": [
+ {
+ "line": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "parcoords"
+ }
+ ],
+ "pie": [
+ {
+ "automargin": true,
+ "type": "pie"
+ }
+ ],
+ "scatter": [
+ {
+ "fillpattern": {
+ "fillmode": "overlay",
+ "size": 10,
+ "solidity": 0.2
+ },
+ "type": "scatter"
+ }
+ ],
+ "scatter3d": [
+ {
+ "line": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatter3d"
+ }
+ ],
+ "scattercarpet": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattercarpet"
+ }
+ ],
+ "scattergeo": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattergeo"
+ }
+ ],
+ "scattergl": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattergl"
+ }
+ ],
+ "scattermap": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scattermap"
+ }
+ ],
+ "scatterpolar": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterpolar"
+ }
+ ],
+ "scatterpolargl": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterpolargl"
+ }
+ ],
+ "scatterternary": [
+ {
+ "marker": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "type": "scatterternary"
+ }
+ ],
+ "surface": [
+ {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ },
+ "colorscale": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "type": "surface"
+ }
+ ],
+ "table": [
+ {
+ "cells": {
+ "fill": {
+ "color": "#EBF0F8"
+ },
+ "line": {
+ "color": "white"
+ }
+ },
+ "header": {
+ "fill": {
+ "color": "#C8D4E3"
+ },
+ "line": {
+ "color": "white"
+ }
+ },
+ "type": "table"
+ }
+ ]
+ },
+ "layout": {
+ "annotationdefaults": {
+ "arrowcolor": "#2a3f5f",
+ "arrowhead": 0,
+ "arrowwidth": 1
+ },
+ "autotypenumbers": "strict",
+ "coloraxis": {
+ "colorbar": {
+ "outlinewidth": 0,
+ "ticks": ""
+ }
+ },
+ "colorscale": {
+ "diverging": [
+ [
+ 0,
+ "#8e0152"
+ ],
+ [
+ 0.1,
+ "#c51b7d"
+ ],
+ [
+ 0.2,
+ "#de77ae"
+ ],
+ [
+ 0.3,
+ "#f1b6da"
+ ],
+ [
+ 0.4,
+ "#fde0ef"
+ ],
+ [
+ 0.5,
+ "#f7f7f7"
+ ],
+ [
+ 0.6,
+ "#e6f5d0"
+ ],
+ [
+ 0.7,
+ "#b8e186"
+ ],
+ [
+ 0.8,
+ "#7fbc41"
+ ],
+ [
+ 0.9,
+ "#4d9221"
+ ],
+ [
+ 1,
+ "#276419"
+ ]
+ ],
+ "sequential": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ],
+ "sequentialminus": [
+ [
+ 0,
+ "#0d0887"
+ ],
+ [
+ 0.1111111111111111,
+ "#46039f"
+ ],
+ [
+ 0.2222222222222222,
+ "#7201a8"
+ ],
+ [
+ 0.3333333333333333,
+ "#9c179e"
+ ],
+ [
+ 0.4444444444444444,
+ "#bd3786"
+ ],
+ [
+ 0.5555555555555556,
+ "#d8576b"
+ ],
+ [
+ 0.6666666666666666,
+ "#ed7953"
+ ],
+ [
+ 0.7777777777777778,
+ "#fb9f3a"
+ ],
+ [
+ 0.8888888888888888,
+ "#fdca26"
+ ],
+ [
+ 1,
+ "#f0f921"
+ ]
+ ]
+ },
+ "colorway": [
+ "#636efa",
+ "#EF553B",
+ "#00cc96",
+ "#ab63fa",
+ "#FFA15A",
+ "#19d3f3",
+ "#FF6692",
+ "#B6E880",
+ "#FF97FF",
+ "#FECB52"
+ ],
+ "font": {
+ "color": "#2a3f5f"
+ },
+ "geo": {
+ "bgcolor": "white",
+ "lakecolor": "white",
+ "landcolor": "#E5ECF6",
+ "showlakes": true,
+ "showland": true,
+ "subunitcolor": "white"
+ },
+ "hoverlabel": {
+ "align": "left"
+ },
+ "hovermode": "closest",
+ "paper_bgcolor": "white",
+ "plot_bgcolor": "#E5ECF6",
+ "polar": {
+ "angularaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "bgcolor": "#E5ECF6",
+ "radialaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ }
+ },
+ "scene": {
+ "xaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ },
+ "yaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ },
+ "zaxis": {
+ "backgroundcolor": "#E5ECF6",
+ "gridcolor": "white",
+ "gridwidth": 2,
+ "linecolor": "white",
+ "showbackground": true,
+ "ticks": "",
+ "zerolinecolor": "white"
+ }
+ },
+ "shapedefaults": {
+ "line": {
+ "color": "#2a3f5f"
+ }
+ },
+ "ternary": {
+ "aaxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "baxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ },
+ "bgcolor": "#E5ECF6",
+ "caxis": {
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": ""
+ }
+ },
+ "title": {
+ "x": 0.05
+ },
+ "xaxis": {
+ "automargin": true,
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": "",
+ "title": {
+ "standoff": 15
+ },
+ "zerolinecolor": "white",
+ "zerolinewidth": 2
+ },
+ "yaxis": {
+ "automargin": true,
+ "gridcolor": "white",
+ "linecolor": "white",
+ "ticks": "",
+ "title": {
+ "standoff": 15
+ },
+ "zerolinecolor": "white",
+ "zerolinewidth": 2
+ }
+ }
+ },
+ "title": {
+ "text": "Odds-implied expected match points by team"
+ },
+ "xaxis": {
+ "anchor": "y",
+ "domain": [
+ 0,
+ 1
+ ],
+ "title": {
+ "text": "team"
+ }
+ },
+ "yaxis": {
+ "anchor": "x",
+ "domain": [
+ 0,
+ 1
+ ],
+ "title": {
+ "text": "Expected match points"
+ }
+ }
+ }
+ },
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAABEUAAAFoCAYAAACxEUX3AAAQAElEQVR4AeydCbxVU/vHn9M8U5GUKZkz5TXm9Ve85llCkrHUmyRCZMp0CRVJShmTKJlJovKSKW8hU0IZShrRqPG/v+ttHfuezrn33HvPOfece399eu7ee83ru9Y5Zz/PftbaFTbonwiIgAiIgAiIgAiIgAiIgAiIgAiIQFknoP7FIVDB9E8EREAEREAEREAEREAEREAEREAEyhQBdUYEkiMgo0hynJRKBERABERABERABERABERABLKTgFolAiJQbAIyihQbnTKKgAiIgAiIgAiIgAiIgAhkmoDqEwEREIFUEpBRJJU0VZYIiIAIiIAIiIAIiIAIpI6AShIBERABEUgzARlF0gxYxYuACIiACIiACIiACCRDQGlEQAREQAREIPMEZBTJPHPVKAIiIAIiIAIiUN4JqP8iIAIiIAIiIAJZQUBGkawYBjVCBERABERABMouAfVMBERABERABERABLKVgIwi2ToyapcIiIAIiEAuElCbRUAEREAEREAEREAEcoiAjCI5NFhqqgiIgAhkFwG1RgREQAREQAREQAREQARym4CMIrk9fmq9CIhApgioHhEQAREQAREQAREQAREQgTJHQEaRMjek6pAIlJyAShABERABERABERABERABERCB8kBARpHyMMrqY0EEFCcCIiACIiACIiACIiACIiACIlBOCcgoUq4GXp0VAREQAREQAREQAREQAREQAREQARHwBMquUcT3UEcREAEREAEREAEREAEREAEREAEREIGyS6AEPZNRpATwlFUEREAEREAEREAEREAEREAEREAEMklAdaWWgIwiqeWp0kRABERABERABERABERABERABFJDQKWIQNoJyCiSdsSqQAREQAREQAREQAREQAREQAQKI6B4ERCB0iAgo0hpUFedIiACIiACIiACIiACIlCeCajvIiACIpAlBGQUyZKBUDNEQAREQAREQAREQATKJgH1SgREQAREIHsJyCiSvWOjlomACIiACIiACIhArhFQe0VABERABEQgpwjIKJJTw6XGioAIiIAIiIAIZA8BtUQEREAEREAERCDXCcgokusjqPaLgAiIgAiIQCYIqA4REAEREAEREAERKIMEZBQpg4OqLomACIiACJSMgHKLgAiIgAiIgAiIgAiUDwIyipSPcVYvRUAERCARAYWLgAiIgAiIgAiIgAiIQLklIKNIuR16dVwEyiMB9VkEREAEREAEREAEREAEREAE/iYgo8jfLHQmAmWLgHojAiIgAiIgAiIgAiIgAiIgAiJQIAEZRQrEo8hcIaB2ioAIiIAIiIAIiIAIiIAIiIAIiEBRCcgoUlRipZ9eLRABERABERABERABERABERABERABEUgBgSw3iqSghypCBERABERABERABERABERABERABEQgywmUTvNkFCkd7qpVBERABERABERABERABERABESgvBJQv7OGgIwiWTMUaogIiIAIiIAIiIAIiIAIiIAIlD0C6pEIZDMBGUWyeXTUNhEQAREQAREQAREQAREQgVwioLaKgAjkGAEZRXJswNRcERABERABERABERABEcgOAmqFCIiACOQ+ARlFcn8M1QMREAEREAEREAEREIF0E1D5IiACIiACZZKAjCJlcljVKREQAREQAREQAREoPgHlFAEREAEREIHyQkBGkfIy0uqnCIiACIiACIhAPAIKEwEREAEREAERKMcEZBQpwuA/MvJ1O/aca2zBot8LzEU86UhfYMIcivR96nXn0LS2Gmawo760VlQOCv9yxmw75MQuNvH9aWWmt8wP+kTfykyn0tQRPqv6LKUJbk4Xq8aLgAiIgAiIgAiIgAiECZQbowhKFMpUs5YXmBeuCQ8DyeZzlJxsajPsaA/tymZu2dw2zxBlP5vbmaq2YexCUS9rc4b+8FlgPIvKirEvbt6i1pWO9PSZ9tOPdJRfojKVWQREQAREQAREQAREQAQKIVAujCIoLGd26m0d2p1oX056PCpcE058IZwULQIiIAJZTUCNEwEREAEREAEREAEREAERKDqBMm8UYenAS+Mm25WdzrSL2x6fjxDXA/MuN+Jz4Sln3nUd7YNXB1mzXXfI14/SuqAdtId2lVYbVG+5JJB1neYzwGeBz0TWNU4NEgEREAEREAEREAEREAERSEigTBtFVqxcZcNHv2kHNd/d2p56RFwIxCGTP55upPeJvJu/X2rDceyEj3x0viMGFeK9nNv1Dvvjz2X50nCBgcan8UfCiEtG8Ghh6QFtIz1Hrqkf8WVy5Jo05OHaiw8nDuEa1/ePp31jF13RJ7q0iHIpnzSJJJHbPBzDZVE39cSWQ/nUQ7yXRIxj8/pr+Pm8HCmP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E5BRpJxPAHVfBERABERABERABERABESgvBBQP0VABGIJyCgSS0TXIiACIiACIiACIiACIiACuU9APRABERCBJAjIKJIEJCURAREQAREQAREQAREQgWwmoLaJgAiIgAgUj4CMIsXjplwiIAIiIAIiIAIiIAKlQ0C1ioAIiIAIiEDKCMgokjKUKkgEREAEREAEREAEUk1A5YmACIiACIiACKSTgIwi6aSrskVABERABERABJInoJQiIAIiIAIiIAIikGECMopkGLiqEwEREAEREAEISERABERABERABERABEqfgIwipT8GaoEIiIAIlHUC6p8IiIAIiIAIiIAIiIAIZCUBGUWycljUKBEQgdwloJaLgAiIgAiIgAiIgAiIgAjkCgEZRXJlpNROEchGAmqTCIiACIiACIiACIiACIiACOQwARlFcnjw1PTMElBtIiACIiACIiACIiACIiACIiACZYuAjCJlazxT1RuVIwIiIAIiIAIiIAIiIAIiIAIiIAJlnoCMIlbmx1gdFAEREAEREAEREAEREAEREAEREAERsE0RyCiyKROFiIAIiIAIiIAIiIAIiIAIiIAIiEBuE1DrkyIgo0hSmJRIBERABERABERABERABERABEQgWwmoXSJQXAIyihSXnPKJgAiIgAiIgAiIgAiIgAiIQOYJqEYREIEUEpBRJIUwVZQIiIAIiIAIiIAIiIAIiEAqCagsERABEUgvARlF0stXpYuACIiACIiACIiACIhAcgSUSgREQAREIOMEZBTJOHJVKAIiIAIiIAIiIAIiIAIiIAIiIAIikA0EZBTJhlFQG0RABERABERABMoyAfVNBERABERABEQgSwnIKJKlA6NmiYAIiIAIiEBuElCrRUAEREAEREAERCB3CMgokjtjpZaKgAiIgAhkGwG1RwREQAREQAREQAREIKcJyCiS08OnxouACIhA5gioJhEQAREQAREQAREQAREoawRkFClrI6r+iIAIpIKAyhABERABERABERABERABESgHBGQUKQeDrC6KQMEEFCsCIiACIiACIiACIiACIiAC5ZOAjCLlc9zLb6/VcxEQAREQAREQAREQAREQAREQARHYSEBGkY0gyuJBfRIBERABERABERABERABERABERABEUhMoKwYRRL3UDEiIAIiIAIiIAIiIAIiIAIiIAIiIAJlhUBK+yGjSEpxqjAREAEREAEREAEREAEREAEREAERSBUBlZNuAjKKpJuwyhcBERABERABERABERABERABESicgFKIQCkQkFGkFKCrShEQAREQAREQAREQAREQgfJNQL0XARHIDgIyimTHOKgVIiACIiACIiACIiACIlBWCahfIiACIpC1BGQUydqhUcNEQAREQAREQAREQARyj4BaLAIiIAIikEsEcs4o0uvOoXbRFX1sxcpVTjhv1vICO+TELvbljNmmfyIgAiIgAiIgAiIgAhkioGpEQAREQAREIMcJ5JRRZMGi323q9JnWvs3RVqN6Nfto2tcO/5Sxgy2vV0frO/hZZyhxgfojAiIgAiIgAiIgAikkoKJEQAREQAREQATKHoGcMoqAv3atGtagfl1Obfw7n1jDBvWcgYSwpctX2vIVq1yc/oiACIiACIiACBSbgDKKgAiIgAiIgAiIQLkgkFNGkZo1qlntmtVt/qIl5r1Gjjp8fzdQhC1dtsKd648IiIAIiIAIJE9AKUVABERABERABERABMorgZwyirBkpkfns6xX3lBr2bq77bfXztaqRXNnIOkzcKS73rL+5uV1LNVvERABESicgFKIgAiIgAiIgAiIgAiIgAhECeSUUQTvkN59H7dhfa+xLyc9bnnXdXQdwRDSs2tbmzd/sfYUcUT0RwREAAISERABERABERABERABERABESiIQE4ZRQrqSGntKTJ30UqTiEEWzAHNQ30WNQc0BzQHNAc0BzQHkp4DBd1XK04EREAEyhOBMmMU+XDqV26/EfYdKU8DWD77ql6LgAiIgAiIgAiIgAiIgAiIgAiIQMkJ5IRR5MsZs+2QE7u4fUS++na2ndmptzVreUE+GTbiVWO/EfYdKTmWLCpBTREBERABERABERABERABERABERABEUgLgawyiiTqYbNdd7APXh1kk8bcZ3vssoONGtLb7Sny5aTHo0fiSZeoDIWLgAiIgAiIgAiIgAiIgAiIgAiIgAhkB4FsaUVOGEU8LDZUHf1wb5PxwxPRUQREQAREQAREQAREQAREQAREIMsJqHlZTCCnjCJZzFFNEwEREAEREAEREAEREAEREAERMCEQgdwikHNGkQWLfrdjz7km334ifn8RwokvrSHYUFoVq14REAEREAEREAEREAEREIHME1CNIiACOU8g54wi/R8ebfvttXN0L5Hw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0oWFMreot7lxhAHpOXJN+VxTZphduCzSbbdNQ6Ns+kF6hLzE+bqeG3qLS0Ne4jmSx8f7fnFESINQJuVQnr/2eWgnYWHx5ZIvHM45/YgdJ8qlfF9muJ2x6X1aXzb1k5dwXz5jQHxsHPGE+3oG3NbNMSeMOPqMcO6FcimfPLCibz4uncecMooACZcx3MQKczVKJ7Q0lq2iRUAEREAEREAEREAERKBMEahWoYJ1rbun3brFgUnJXtXrW0RvlitTc0CdEYFsJlCKRpHiYWHpzNczfzRcjnAhCksmXWyK13rlChPYsMEsMne2VfhmWsYl8t0Xpn8iIAIiIAIiIAIiIALpJ7BLrc3tym33sV7b7peUtN2qqVWsIKtI+kdGNYhAJglkb105ZRTBO0QbrWbvZCpqy3gCUHHOLKs6sFfGpcprT5ptWF/UJiu9CIiACIiACIiACJSAQPBEqAS5czkrRo5kpQI3ibncWbVdBEQgpwjklFFEG63m1NxKurGRdWst47J+XdLtU0IREAEREAEREAERSAWBSr9XtFozKlutbzIrNb6vZJFN94VMRZdUhgiYEIhArhPIKaOINlrN9emm9ouACIiACIiACIhA+SVQYa1Z7emVrE6GpdZ3lazCei1HScHMUxEiIAJlkEBOGUVqVK9m2mi1DM5CdUkEREAEREAEREAERCDLCKg5IiACIlA+COSUUWTBot9t9CuT7KNpX2uj1fIxP9VLERABERABERABEUg/AdUgAiIgAiJQbgnklFFky/qb2xtP321fTno8rhBHmnSM5pczZlubS3obhpl0lK8yRUAEREAEREAERCATBFSHCGSawIrl623ej2uSloVz11r53ZI206Oj+kRABHLKKFIaw4URhFf9ntmpty1dtqI0mqA6RUAEREAEREAEikdAuURABLKAwLLF623aY+vtw/4bkpIfP15v69bJLJLs0E18f5qhr6C3JJtH6VJP4JGRr9tFV/Qx3pha1NIZO8aQsSxqXqUvOQEZRQphiOcJHiijhvS22rVqFJJa0SIgAiIgAiJQWgRUrwhkngBqa2lJ5nurGktCYO3yiK1dlpxsWFOSmv7O2+vOoYai+ndI4WcotCi2zVpeYGGhLHJ75TUcR3rykQYhXVhog08TDuccJZiySMO1F67jhfv4TB19O2hLbB/oK+FhIX262xZb7yEndjG8+i30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dtNlg6B41lDCiCNNeR1M9VsEREAEREAEspaAGiYCIlBuCUQqVbKVOx1ry5udlZSsr7udRSLlFleBHcdrHs8ABM+X3j0uiO4TUmBGRaaUgMYhpThLvbCcMorgTlW7ZvXo+rMwPdaLEUeacLjORUAEREAERCDTBFSfCIiACIjA3wSq193KauxzjFVrflJSUmOnA61ihbJlFcFjAC8Bjn+TKfoZT/n90388D0paXtFboBwQ0DhAoexIThlFcOthmQxry1h754eBc8JYC0gaH66jCIiACIhA2gmoAhEQAREQAREolABGjmSlgtxECuWpBCIgAqkjkFNGEbrNuqdhfa8x3MVwG0PYSIfXLiVa80U+iQiIgAiUnIBKEAERKMsEKi3+wyr/+FvGpdIvC8oyVvVNBERABERABLKaQM4ZRaCJmxjuYt51jCPGEuIk8QlsiB+c/tANpVZz+vtW1mtQ/0RABESgnBGotOAP22LoaxmXzV77yCKr15Yz2uquCIiACIiACGQHgZw0imQHutxpBXaJL7+qYO9/mHn5blbFnAClRoqACIiACIgABCLr11vGZcN6qpaIgAiIgAiIgAiUAoGcM4rwyt2Lrujj3l3t39/twx4Z+XopIMz+KlmWOfO7iL3xZgUkozJ/vpl8RbJ/jqiFIiACIiACIiACIiACIiACIlAeCeScUeT2+4YbG6pOGTvYDmi+mxszNldlA9bJH083DCQu0P3RHxEQAREQAREQAREQAREQgdIksGT1epv+x2r7PEmZsWyNHqqV5oCpbhHIWQLFa3hOGUUWLPrdZs6aYwfvt8cmvW1Qv64tXb7Slq9YtUmcAkRABERABERABERABERABEqHwNxV6+2KX1fbOXOSk5d+X2Pr1pVPX+Nedw41JJMjRX1IJutUXSkgUEpFfDljth3T9mrjWEpNSHm1OWUUKaj38xctsdo1q1vNGtUKSqY4ERABERABERABERABERCBDBP4fb3Z4iRldQntIShrLLPnLZVevNLPEYntPsvwWaKfyOt84vvT3PJ9yjv2nGuMh7WUwZFrwsNCGHGkCQvlU084LeeJ0ofzlufzwvrO+MExLIQVli8T8bFjnqhdPh3zg/N4bWMeaq7EI1OysJwyimxZf3M7ttWB1nfws/k8QvjC6TNwpFtWw1KakiFRbhEQAREQAREQAREQAREQgVwkgF7Q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"
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "status_rows = [{'artifact': 'Canonical fixtures', 'selected_file': fixtures_path.name, 'state': 'Loaded', 'note': f'{len(fixtures)} fixtures'}]\n",
+ "\n",
+ "fotmob_path = FOTMOB_ODDS_DIR / f'matchday_{matchday}_odds_fotmob.json'\n",
+ "sofascore_odds_path = SOFASCORE_ODDS_DIR / f'matchday_{matchday}_odds.json'\n",
+ "fotmob_odds = read_json(fotmob_path) if fotmob_path.is_file() else []\n",
+ "sofascore_odds = read_json(sofascore_odds_path) if sofascore_odds_path.is_file() else []\n",
+ "status_rows.extend([\n",
+ " {'artifact': 'FotMob odds', 'selected_file': fotmob_path.name if fotmob_path.is_file() else '—', 'state': 'Loaded' if fotmob_path.is_file() else 'Missing', 'note': 'Primary 1X2 source'},\n",
+ " {'artifact': 'SofaScore odds', 'selected_file': sofascore_odds_path.name if sofascore_odds_path.is_file() else '—', 'state': 'Loaded' if sofascore_odds_path.is_file() else 'Missing', 'note': 'Fallback 1X2 source'},\n",
+ "])\n",
+ "\n",
+ "standings_path, standings = newest_json(DERIVED_BUNDESLIGA_SNAPSHOTS_DIR, 'bundesliga_table_*.json')\n",
+ "status_rows.append({'artifact': 'League table', 'selected_file': standings_path.name if standings_path else '—', 'state': 'Loaded' if standings_path else 'Missing', 'note': 'Latest league snapshot; it is not matchday-specific.'})\n",
+ "\n",
+ "form_path, form = newest_json(SOFASCORE_TEAM_FORM_DIR, 'team_form_*.json')\n",
+ "status_rows.append({'artifact': 'Recent form', 'selected_file': form_path.name if form_path else '—', 'state': 'Loaded' if form_path else 'Missing', 'note': 'Latest team-form snapshot; it is not matchday-specific.'})\n",
+ "\n",
+ "upcoming_path, upcoming = newest_json(SOFASCORE_UPCOMING_MATCHES_DIR, 'upcoming_matches_md_*.json', lambda document, _: isinstance(document, dict) and document.get('requested_matchday') == matchday)\n",
+ "status_rows.append({'artifact': 'Upcoming matches', 'selected_file': upcoming_path.name if upcoming_path else '—', 'state': 'Loaded' if upcoming_path else 'Omitted', 'note': 'Exact requested_matchday match required.'})\n",
+ "\n",
+ "ratings_path, ratings = newest_json(SOFASCORE_PLAYER_AVERAGE_RATINGS_DIR, 'team_player_average_ratings_*.json', lambda document, _: form_path is not None and isinstance(document, dict) and document.get('source_file') == form_path.name)\n",
+ "status_rows.append({'artifact': 'SofaScore player ratings', 'selected_file': ratings_path.name if ratings_path else '—', 'state': 'Loaded' if ratings_path else 'Omitted', 'note': 'Must cite the selected form snapshot.'})\n",
+ "\n",
+ "lineups = {}\n",
+ "for source_name, directory, pattern in LINEUP_SOURCES:\n",
+ " path, document, note = matching_lineup_snapshot(directory, pattern, fixture_keys, matchday)\n",
+ " lineups[source_name] = {'path': path, 'matches': matches_from_snapshot(document) if document else {}, 'note': note}\n",
+ " status_rows.append({'artifact': f'{source_name} lineups', 'selected_file': path.name if path else '—', 'state': 'Loaded' if path else 'Omitted', 'note': note or 'Exact fixture coverage.'})\n",
+ "\n",
+ "overview_rows, fixture_context = [], []\n",
+ "team_points = {}\n",
+ "for fixture in fixtures:\n",
+ " home, away = fixture['home_team'], fixture['away_team']\n",
+ " key = fixture_key(home, away)\n",
+ " selected, source = odds_record(fotmob_odds, key), 'FotMob'\n",
+ " if selected is None:\n",
+ " selected, source = odds_record(sofascore_odds, key), 'SofaScore fallback'\n",
+ " if selected is not None:\n",
+ " team_points[team_key(home)] = selected['home_points']\n",
+ " team_points[team_key(away)] = selected['away_points']\n",
+ " overview_rows.append({'fixture': f'{home} vs {away}', 'odds source': source if selected else 'Unavailable', 'home expected points': round(selected['home_points'], 2) if selected else None, 'away expected points': round(selected['away_points'], 2) if selected else None})\n",
+ " fixture_context.append({'fixture': fixture, 'key': key, 'odds': selected, 'odds_source': source if selected else 'Unavailable'})\n",
+ "\n",
+ "expected_path, expected_players, expected_note = None, None, 'No verified expected-points CSV is available.'\n",
+ "if len(team_points) == 18:\n",
+ " for candidate in sorted(EXPECTED_POINTS_DIR.glob('expected_points_*.csv'), reverse=True):\n",
+ " try:\n",
+ " frame = pd.read_csv(candidate)\n",
+ " actual = frame.groupby('teamId')['expected_match_points'].first().to_dict()\n",
+ " comparable = {KB_TEAM_ID_TO_KEY.get(int(team_id)): float(value) for team_id, value in actual.items() if pd.notna(value) and int(team_id) in KB_TEAM_ID_TO_KEY}\n",
+ " except (OSError, ValueError, KeyError, TypeError):\n",
+ " continue\n",
+ " if all(key in comparable and math.isclose(comparable[key], value, abs_tol=1e-6) for key, value in team_points.items()):\n",
+ " expected_path, expected_players, expected_note = candidate, frame, 'Per-team expected-match points match selected odds.'\n",
+ " break\n",
+ "status_rows.append({'artifact': 'Player expected points', 'selected_file': expected_path.name if expected_path else '—', 'state': 'Loaded' if expected_path else 'Omitted', 'note': expected_note})\n",
+ "\n",
+ "display(Markdown(f'## Matchday {matchday} overview'))\n",
+ "display(pd.DataFrame(status_rows))\n",
+ "overview = pd.DataFrame(overview_rows)\n",
+ "display(overview)\n",
+ "if overview['home expected points'].notna().any():\n",
+ " expected_overview = pd.concat([\n",
+ " overview.assign(team=overview['fixture'].str.split(' vs ').str[0], expected_points=overview['home expected points']),\n",
+ " overview.assign(team=overview['fixture'].str.split(' vs ').str[1], expected_points=overview['away expected points']),\n",
+ " ])\n",
+ " display(px.bar(expected_overview.dropna(subset=['expected_points']), x='team', y='expected_points', color='fixture', title='Odds-implied expected match points by team', labels={'expected_points': 'Expected match points'}))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "1ca7bbd1",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 1. FC Bayern München vs VfB Stuttgart"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " FC Bayern München | \n",
+ " 2.413 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " VfB Stuttgart | \n",
+ " 0.452 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 FC Bayern München 2.413\n",
+ "1 VfB Stuttgart 0.452"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " VfB Stuttgart | \n",
+ " 17 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 FC Bayern München 3 0 0 0\n",
+ "1 VfB Stuttgart 17 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 18 | \n",
+ " Michael Olise | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 2.412651 | \n",
+ " 1.000000 | \n",
+ " 18.818675 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " Joshua Kimmich | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 2.412651 | \n",
+ " 1.000000 | \n",
+ " 17.853614 | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " Nathaniel Brown | \n",
+ " FC Bayern München | \n",
+ " 2 | \n",
+ " 2.412651 | \n",
+ " 1.000000 | \n",
+ " 17.515843 | \n",
+ "
\n",
+ " \n",
+ " | 20 | \n",
+ " Luis Díaz | \n",
+ " FC Bayern München | \n",
+ " 4 | \n",
+ " 2.412651 | \n",
+ " 1.000000 | \n",
+ " 17.081566 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " Aleksandar Pavlović | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 2.412651 | \n",
+ " 1.000000 | \n",
+ " 16.985060 | \n",
+ "
\n",
+ " \n",
+ " | 31 | \n",
+ " Fabian Bredlow | \n",
+ " VfB Stuttgart | \n",
+ " 1 | \n",
+ " 0.451807 | \n",
+ " 1.000000 | \n",
+ " 4.111446 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " Dzenan Pejcinovic | \n",
+ " VfB Stuttgart | \n",
+ " 4 | \n",
+ " 0.451807 | \n",
+ " 0.906897 | \n",
+ " 3.892553 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " Tiago Tomás | \n",
+ " VfB Stuttgart | \n",
+ " 4 | \n",
+ " 0.451807 | \n",
+ " 1.000000 | \n",
+ " 3.659639 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " Jeff Chabot | \n",
+ " VfB Stuttgart | \n",
+ " 2 | \n",
+ " 0.451807 | \n",
+ " 1.000000 | \n",
+ " 3.569277 | \n",
+ "
\n",
+ " \n",
+ " | 33 | \n",
+ " Angelo Stiller | \n",
+ " VfB Stuttgart | \n",
+ " 3 | \n",
+ " 0.451807 | \n",
+ " 1.000000 | \n",
+ " 3.388554 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "18 Michael Olise FC Bayern München 3 2.412651 \n",
+ "3 Joshua Kimmich FC Bayern München 3 2.412651 \n",
+ "14 Nathaniel Brown FC Bayern München 2 2.412651 \n",
+ "20 Luis Díaz FC Bayern München 4 2.412651 \n",
+ "15 Aleksandar Pavlović FC Bayern München 3 2.412651 \n",
+ "31 Fabian Bredlow VfB Stuttgart 1 0.451807 \n",
+ "38 Dzenan Pejcinovic VfB Stuttgart 4 0.451807 \n",
+ "37 Tiago Tomás VfB Stuttgart 4 0.451807 \n",
+ "36 Jeff Chabot VfB Stuttgart 2 0.451807 \n",
+ "33 Angelo Stiller VfB Stuttgart 3 0.451807 \n",
+ "\n",
+ " starting_chance score \n",
+ "18 1.000000 18.818675 \n",
+ "3 1.000000 17.853614 \n",
+ "14 1.000000 17.515843 \n",
+ "20 1.000000 17.081566 \n",
+ "15 1.000000 16.985060 \n",
+ "31 1.000000 4.111446 \n",
+ "38 0.906897 3.892553 \n",
+ "37 1.000000 3.659639 \n",
+ "36 1.000000 3.569277 \n",
+ "33 1.000000 3.388554 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " FC Bayern München | \n",
+ " 2026-08-04T11:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Jeju SK | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " FC Bayern München | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " FC Bayern München | \n",
+ " 2026-08-07T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Aston Villa | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " FC Bayern München | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " FC Bayern München | \n",
+ " 2026-08-15T13:30:00+00:00 | \n",
+ " Telekom Cup | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " RB Leipzig | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " FC Bayern München | \n",
+ " 2026-08-18T16:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Heidenheim | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " FC Bayern München | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " FC Bayern München | \n",
+ " 2026-08-22T18:30:00+00:00 | \n",
+ " Supercup | \n",
+ " Borussia Dortmund | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " FC Bayern München | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " FC Bayern München | \n",
+ " 2026-04-19T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Bayern München | \n",
+ " 4 | \n",
+ " 2 | \n",
+ " VfB Stuttgart | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " FC Bayern München | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " FC Bayern München | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " FC Bayern München | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 3 | \n",
+ " 1. FC Heidenheim | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " FC Bayern München | \n",
+ " 2026-05-09T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " VfL Wolfsburg | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " FC Bayern München | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " FC Bayern München | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Bayern München | \n",
+ " 5 | \n",
+ " 1 | \n",
+ " 1. FC Köln | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " VfB Stuttgart | \n",
+ " 2026-07-29T16:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Kickers Offenbach | \n",
+ " 1 | \n",
+ " 8 | \n",
+ " VfB Stuttgart | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " VfB Stuttgart | \n",
+ " 2026-08-01T13:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Paris FC | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " VfB Stuttgart | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " VfB Stuttgart | \n",
+ " 2026-08-08T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " VfB Stuttgart | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Everton | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " VfB Stuttgart | \n",
+ " 2026-08-15T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Fulham | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " VfB Stuttgart | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " VfB Stuttgart | \n",
+ " 2026-08-21T18:45:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " FC Hansa Rostock | \n",
+ " 0 | \n",
+ " 4 | \n",
+ " VfB Stuttgart | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 2026-04-19T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Bayern München | \n",
+ " 4 | \n",
+ " 2 | \n",
+ " VfB Stuttgart | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 2026-04-26T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " SV Werder Bremen | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 3 | \n",
+ " 3 | \n",
+ " VfB Stuttgart | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " VfB Stuttgart | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall FC Bayern München 2026-08-04T11:00:00+00:00 \n",
+ "1 overall FC Bayern München 2026-08-07T12:00:00+00:00 \n",
+ "2 overall FC Bayern München 2026-08-15T13:30:00+00:00 \n",
+ "3 overall FC Bayern München 2026-08-18T16:00:00+00:00 \n",
+ "4 overall FC Bayern München 2026-08-22T18:30:00+00:00 \n",
+ "5 bundesliga FC Bayern München 2026-04-19T15:30:00+00:00 \n",
+ "6 bundesliga FC Bayern München 2026-04-25T13:30:00+00:00 \n",
+ "7 bundesliga FC Bayern München 2026-05-02T13:30:00+00:00 \n",
+ "8 bundesliga FC Bayern München 2026-05-09T16:30:00+00:00 \n",
+ "9 bundesliga FC Bayern München 2026-05-16T13:30:00+00:00 \n",
+ "10 overall VfB Stuttgart 2026-07-29T16:30:00+00:00 \n",
+ "11 overall VfB Stuttgart 2026-08-01T13:00:00+00:00 \n",
+ "12 overall VfB Stuttgart 2026-08-08T15:00:00+00:00 \n",
+ "13 overall VfB Stuttgart 2026-08-15T15:00:00+00:00 \n",
+ "14 overall VfB Stuttgart 2026-08-21T18:45:00+00:00 \n",
+ "15 bundesliga VfB Stuttgart 2026-04-19T15:30:00+00:00 \n",
+ "16 bundesliga VfB Stuttgart 2026-04-26T13:30:00+00:00 \n",
+ "17 bundesliga VfB Stuttgart 2026-05-02T13:30:00+00:00 \n",
+ "18 bundesliga VfB Stuttgart 2026-05-09T13:30:00+00:00 \n",
+ "19 bundesliga VfB Stuttgart 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team home_score away_score \\\n",
+ "0 Club Friendly Games Jeju SK 1 2 \n",
+ "1 Club Friendly Games Aston Villa 1 2 \n",
+ "2 Telekom Cup FC Bayern München 3 1 \n",
+ "3 Club Friendly Games 1. FC Heidenheim 2 4 \n",
+ "4 Supercup Borussia Dortmund 1 2 \n",
+ "5 Bundesliga FC Bayern München 4 2 \n",
+ "6 Bundesliga 1. FSV Mainz 05 3 4 \n",
+ "7 Bundesliga FC Bayern München 3 3 \n",
+ "8 Bundesliga VfL Wolfsburg 0 1 \n",
+ "9 Bundesliga FC Bayern München 5 1 \n",
+ "10 Club Friendly Games Kickers Offenbach 1 8 \n",
+ "11 Club Friendly Games Paris FC 2 2 \n",
+ "12 Club Friendly Games VfB Stuttgart 3 1 \n",
+ "13 Club Friendly Games Fulham 1 0 \n",
+ "14 DFB Pokal FC Hansa Rostock 0 4 \n",
+ "15 Bundesliga FC Bayern München 4 2 \n",
+ "16 Bundesliga VfB Stuttgart 1 1 \n",
+ "17 Bundesliga TSG Hoffenheim 3 3 \n",
+ "18 Bundesliga VfB Stuttgart 3 1 \n",
+ "19 Bundesliga Eintracht Frankfurt 2 2 \n",
+ "\n",
+ " away_team result \n",
+ "0 FC Bayern München W \n",
+ "1 FC Bayern München W \n",
+ "2 RB Leipzig W \n",
+ "3 FC Bayern München W \n",
+ "4 FC Bayern München W \n",
+ "5 VfB Stuttgart W \n",
+ "6 FC Bayern München W \n",
+ "7 1. FC Heidenheim D \n",
+ "8 FC Bayern München W \n",
+ "9 1. FC Köln W \n",
+ "10 VfB Stuttgart W \n",
+ "11 VfB Stuttgart D \n",
+ "12 Everton W \n",
+ "13 VfB Stuttgart L \n",
+ "14 VfB Stuttgart W \n",
+ "15 VfB Stuttgart L \n",
+ "16 SV Werder Bremen D \n",
+ "17 VfB Stuttgart D \n",
+ "18 Bayer 04 Leverkusen W \n",
+ "19 VfB Stuttgart D "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 31 | \n",
+ " FC Bayern München | \n",
+ " Bundesliga | \n",
+ " Michael Olise | \n",
+ " M | \n",
+ " 5 | \n",
+ " 8.34 | \n",
+ "
\n",
+ " \n",
+ " | 32 | \n",
+ " FC Bayern München | \n",
+ " Bundesliga | \n",
+ " Tom Bischof | \n",
+ " D | \n",
+ " 2 | \n",
+ " 8.00 | \n",
+ "
\n",
+ " \n",
+ " | 33 | \n",
+ " FC Bayern München | \n",
+ " Bundesliga | \n",
+ " Joshua Kimmich | \n",
+ " M | \n",
+ " 4 | \n",
+ " 7.85 | \n",
+ "
\n",
+ " \n",
+ " | 69 | \n",
+ " VfB Stuttgart | \n",
+ " Bundesliga | \n",
+ " Nikolas Nartey | \n",
+ " F | \n",
+ " 2 | \n",
+ " 7.75 | \n",
+ "
\n",
+ " \n",
+ " | 34 | \n",
+ " FC Bayern München | \n",
+ " Bundesliga | \n",
+ " Harry Kane | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.42 | \n",
+ "
\n",
+ " \n",
+ " | 70 | \n",
+ " VfB Stuttgart | \n",
+ " Bundesliga | \n",
+ " Chris Führich | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.38 | \n",
+ "
\n",
+ " \n",
+ " | 71 | \n",
+ " VfB Stuttgart | \n",
+ " Bundesliga | \n",
+ " Alexander Nübel | \n",
+ " G | \n",
+ " 5 | \n",
+ " 7.32 | \n",
+ "
\n",
+ " \n",
+ " | 35 | \n",
+ " FC Bayern München | \n",
+ " Bundesliga | \n",
+ " Dayot Upamecano | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 72 | \n",
+ " VfB Stuttgart | \n",
+ " Bundesliga | \n",
+ " Angelo Stiller | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 73 | \n",
+ " VfB Stuttgart | \n",
+ " Bundesliga | \n",
+ " Chema Andrés | \n",
+ " M | \n",
+ " 4 | \n",
+ " 7.23 | \n",
+ "
\n",
+ " \n",
+ " | 53 | \n",
+ " VfB Stuttgart | \n",
+ " Overall | \n",
+ " Dženan Pejčinović | \n",
+ " F | \n",
+ " 1 | \n",
+ " 9.50 | \n",
+ "
\n",
+ " \n",
+ " | 54 | \n",
+ " VfB Stuttgart | \n",
+ " Overall | \n",
+ " Fabian Bredlow | \n",
+ " G | \n",
+ " 1 | \n",
+ " 9.10 | \n",
+ "
\n",
+ " \n",
+ " | 55 | \n",
+ " VfB Stuttgart | \n",
+ " Overall | \n",
+ " Tiago Tomás | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.10 | \n",
+ "
\n",
+ " \n",
+ " | 56 | \n",
+ " VfB Stuttgart | \n",
+ " Overall | \n",
+ " Jeff Chabot | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.90 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " FC Bayern München | \n",
+ " Overall | \n",
+ " Michael Olise | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.80 | \n",
+ "
\n",
+ " \n",
+ " | 57 | \n",
+ " VfB Stuttgart | \n",
+ " Overall | \n",
+ " Angelo Stiller | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " FC Bayern München | \n",
+ " Overall | \n",
+ " Joshua Kimmich | \n",
+ " M | \n",
+ " 3 | \n",
+ " 7.40 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " FC Bayern München | \n",
+ " Overall | \n",
+ " Dayot Upamecano | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " FC Bayern München | \n",
+ " Overall | \n",
+ " Nathaniel Brown | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.26 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " FC Bayern München | \n",
+ " Overall | \n",
+ " Felipe Chávez | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.10 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position rating_count \\\n",
+ "31 FC Bayern München Bundesliga Michael Olise M 5 \n",
+ "32 FC Bayern München Bundesliga Tom Bischof D 2 \n",
+ "33 FC Bayern München Bundesliga Joshua Kimmich M 4 \n",
+ "69 VfB Stuttgart Bundesliga Nikolas Nartey F 2 \n",
+ "34 FC Bayern München Bundesliga Harry Kane F 5 \n",
+ "70 VfB Stuttgart Bundesliga Chris Führich M 5 \n",
+ "71 VfB Stuttgart Bundesliga Alexander Nübel G 5 \n",
+ "35 FC Bayern München Bundesliga Dayot Upamecano D 2 \n",
+ "72 VfB Stuttgart Bundesliga Angelo Stiller M 5 \n",
+ "73 VfB Stuttgart Bundesliga Chema Andrés M 4 \n",
+ "53 VfB Stuttgart Overall Dženan Pejčinović F 1 \n",
+ "54 VfB Stuttgart Overall Fabian Bredlow G 1 \n",
+ "55 VfB Stuttgart Overall Tiago Tomás M 1 \n",
+ "56 VfB Stuttgart Overall Jeff Chabot D 1 \n",
+ "0 FC Bayern München Overall Michael Olise M 2 \n",
+ "57 VfB Stuttgart Overall Angelo Stiller M 1 \n",
+ "1 FC Bayern München Overall Joshua Kimmich M 3 \n",
+ "2 FC Bayern München Overall Dayot Upamecano D 1 \n",
+ "3 FC Bayern München Overall Nathaniel Brown M 5 \n",
+ "4 FC Bayern München Overall Felipe Chávez M 2 \n",
+ "\n",
+ " average_rating \n",
+ "31 8.34 \n",
+ "32 8.00 \n",
+ "33 7.85 \n",
+ "69 7.75 \n",
+ "34 7.42 \n",
+ "70 7.38 \n",
+ "71 7.32 \n",
+ "35 7.30 \n",
+ "72 7.30 \n",
+ "73 7.23 \n",
+ "53 9.50 \n",
+ "54 9.10 \n",
+ "55 8.10 \n",
+ "56 7.90 \n",
+ "0 7.80 \n",
+ "57 7.50 \n",
+ "1 7.40 \n",
+ "2 7.30 \n",
+ "3 7.26 \n",
+ "4 7.10 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayern München** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**VfB Stuttgart** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Bayern München** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**VfB Stuttgart** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayern München** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**VfB Stuttgart** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayern Munich** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**VfB Stuttgart** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_01_fc-bayern-m-nchen-vs-vfb-stuttgart.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 2. 1. FC Köln vs TSG Hoffenheim"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1. FC Köln | \n",
+ " 1.181 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " TSG Hoffenheim | \n",
+ " 1.556 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 1. FC Köln 1.181\n",
+ "1 TSG Hoffenheim 1.556"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1. FC Köln | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " TSG Hoffenheim | \n",
+ " 15 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 1. FC Köln 1 0 0 0\n",
+ "1 TSG Hoffenheim 15 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 120 | \n",
+ " Ísak Jóhannesson | \n",
+ " 1. FC Köln | \n",
+ " 3 | \n",
+ " 1.180695 | \n",
+ " 1.0 | \n",
+ " 10.980463 | \n",
+ "
\n",
+ " \n",
+ " | 127 | \n",
+ " Alessio Castro-Montes | \n",
+ " 1. FC Köln | \n",
+ " 3 | \n",
+ " 1.180695 | \n",
+ " 1.0 | \n",
+ " 8.382934 | \n",
+ "
\n",
+ " \n",
+ " | 129 | \n",
+ " Gideon Mensah | \n",
+ " 1. FC Köln | \n",
+ " 2 | \n",
+ " 1.180695 | \n",
+ " 1.0 | \n",
+ " 8.146795 | \n",
+ "
\n",
+ " \n",
+ " | 128 | \n",
+ " Jahmai Simpson-Pusey | \n",
+ " 1. FC Köln | \n",
+ " 2 | \n",
+ " 1.180695 | \n",
+ " 1.0 | \n",
+ " 8.028726 | \n",
+ "
\n",
+ " \n",
+ " | 121 | \n",
+ " Luka Lochoshvili | \n",
+ " 1. FC Köln | \n",
+ " 2 | \n",
+ " 1.180695 | \n",
+ " 1.0 | \n",
+ " 7.910656 | \n",
+ "
\n",
+ " \n",
+ " | 144 | \n",
+ " Albian Hajdari | \n",
+ " TSG Hoffenheim | \n",
+ " 2 | \n",
+ " 1.555985 | \n",
+ " 1.0 | \n",
+ " 11.716564 | \n",
+ "
\n",
+ " \n",
+ " | 154 | \n",
+ " Wouter Burger | \n",
+ " TSG Hoffenheim | \n",
+ " 3 | \n",
+ " 1.555985 | \n",
+ " 1.0 | \n",
+ " 11.514286 | \n",
+ "
\n",
+ " \n",
+ " | 139 | \n",
+ " Patrick Wimmer | \n",
+ " TSG Hoffenheim | \n",
+ " 3 | \n",
+ " 1.555985 | \n",
+ " 1.0 | \n",
+ " 11.405367 | \n",
+ "
\n",
+ " \n",
+ " | 136 | \n",
+ " Ozan Kabak | \n",
+ " TSG Hoffenheim | \n",
+ " 2 | \n",
+ " 1.555985 | \n",
+ " 1.0 | \n",
+ " 10.814093 | \n",
+ "
\n",
+ " \n",
+ " | 152 | \n",
+ " Leon Avdullahu | \n",
+ " TSG Hoffenheim | \n",
+ " 3 | \n",
+ " 1.555985 | \n",
+ " 1.0 | \n",
+ " 10.736293 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "120 Ísak Jóhannesson 1. FC Köln 3 1.180695 \n",
+ "127 Alessio Castro-Montes 1. FC Köln 3 1.180695 \n",
+ "129 Gideon Mensah 1. FC Köln 2 1.180695 \n",
+ "128 Jahmai Simpson-Pusey 1. FC Köln 2 1.180695 \n",
+ "121 Luka Lochoshvili 1. FC Köln 2 1.180695 \n",
+ "144 Albian Hajdari TSG Hoffenheim 2 1.555985 \n",
+ "154 Wouter Burger TSG Hoffenheim 3 1.555985 \n",
+ "139 Patrick Wimmer TSG Hoffenheim 3 1.555985 \n",
+ "136 Ozan Kabak TSG Hoffenheim 2 1.555985 \n",
+ "152 Leon Avdullahu TSG Hoffenheim 3 1.555985 \n",
+ "\n",
+ " starting_chance score \n",
+ "120 1.0 10.980463 \n",
+ "127 1.0 8.382934 \n",
+ "129 1.0 8.146795 \n",
+ "128 1.0 8.028726 \n",
+ "121 1.0 7.910656 \n",
+ "144 1.0 11.716564 \n",
+ "154 1.0 11.514286 \n",
+ "139 1.0 11.405367 \n",
+ "136 1.0 10.814093 \n",
+ "152 1.0 10.736293 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " 1. FC Köln | \n",
+ " 2026-07-18T09:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Köln | \n",
+ " 5 | \n",
+ " 0 | \n",
+ " FC Rheinsud Koln | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " 1. FC Köln | \n",
+ " 2026-07-23T16:15:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV Bergisch Gladbach 09 | \n",
+ " 0 | \n",
+ " 8 | \n",
+ " 1. FC Köln | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " 1. FC Köln | \n",
+ " 2026-07-31T10:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Köln | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " Hertha BSC | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " 1. FC Köln | \n",
+ " 2026-08-08T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Köln | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Real Sociedad | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " 1. FC Köln | \n",
+ " 2026-08-24T16:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " FC Würzburger Kickers | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 1. FC Köln | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 2026-04-17T18:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC St. Pauli | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 1. FC Köln | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " 1. FC Köln | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 2026-05-10T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " 1. FC Heidenheim | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Bayern München | \n",
+ " 5 | \n",
+ " 1 | \n",
+ " 1. FC Köln | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-08-01T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " TSG Hoffenheim | \n",
+ " 3 | \n",
+ " 0 | \n",
+ " Karlsruher SC | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-08-07T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " TSG Hoffenheim | \n",
+ " 1 | \n",
+ " 4 | \n",
+ " Borussia M'gladbach | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-08-15T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Tottenham Hotspur | \n",
+ " 3 | \n",
+ " 0 | \n",
+ " TSG Hoffenheim | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-08-16T11:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Tottenham Hotspur | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " TSG Hoffenheim | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-08-22T13:30:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " Erzgebirge Aue | \n",
+ " 0 | \n",
+ " 4 | \n",
+ " TSG Hoffenheim | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Borussia Dortmund | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-04-25T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Hamburger SV | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " TSG Hoffenheim | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 3 | \n",
+ " 3 | \n",
+ " VfB Stuttgart | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " SV Werder Bremen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " TSG Hoffenheim | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall 1. FC Köln 2026-07-18T09:00:00+00:00 \n",
+ "1 overall 1. FC Köln 2026-07-23T16:15:00+00:00 \n",
+ "2 overall 1. FC Köln 2026-07-31T10:00:00+00:00 \n",
+ "3 overall 1. FC Köln 2026-08-08T13:30:00+00:00 \n",
+ "4 overall 1. FC Köln 2026-08-24T16:00:00+00:00 \n",
+ "5 bundesliga 1. FC Köln 2026-04-17T18:30:00+00:00 \n",
+ "6 bundesliga 1. FC Köln 2026-04-25T13:30:00+00:00 \n",
+ "7 bundesliga 1. FC Köln 2026-05-02T13:30:00+00:00 \n",
+ "8 bundesliga 1. FC Köln 2026-05-10T15:30:00+00:00 \n",
+ "9 bundesliga 1. FC Köln 2026-05-16T13:30:00+00:00 \n",
+ "10 overall TSG Hoffenheim 2026-08-01T13:30:00+00:00 \n",
+ "11 overall TSG Hoffenheim 2026-08-07T14:00:00+00:00 \n",
+ "12 overall TSG Hoffenheim 2026-08-15T14:00:00+00:00 \n",
+ "13 overall TSG Hoffenheim 2026-08-16T11:00:00+00:00 \n",
+ "14 overall TSG Hoffenheim 2026-08-22T13:30:00+00:00 \n",
+ "15 bundesliga TSG Hoffenheim 2026-04-18T13:30:00+00:00 \n",
+ "16 bundesliga TSG Hoffenheim 2026-04-25T16:30:00+00:00 \n",
+ "17 bundesliga TSG Hoffenheim 2026-05-02T13:30:00+00:00 \n",
+ "18 bundesliga TSG Hoffenheim 2026-05-09T13:30:00+00:00 \n",
+ "19 bundesliga TSG Hoffenheim 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team home_score away_score \\\n",
+ "0 Club Friendly Games 1. FC Köln 5 0 \n",
+ "1 Club Friendly Games SV Bergisch Gladbach 09 0 8 \n",
+ "2 Club Friendly Games 1. FC Köln 2 2 \n",
+ "3 Club Friendly Games 1. FC Köln 2 1 \n",
+ "4 DFB Pokal FC Würzburger Kickers 1 2 \n",
+ "5 Bundesliga FC St. Pauli 1 1 \n",
+ "6 Bundesliga 1. FC Köln 1 2 \n",
+ "7 Bundesliga 1. FC Union Berlin 2 2 \n",
+ "8 Bundesliga 1. FC Köln 1 3 \n",
+ "9 Bundesliga FC Bayern München 5 1 \n",
+ "10 Club Friendly Games TSG Hoffenheim 3 0 \n",
+ "11 Club Friendly Games TSG Hoffenheim 1 4 \n",
+ "12 Club Friendly Games Tottenham Hotspur 3 0 \n",
+ "13 Club Friendly Games Tottenham Hotspur 2 2 \n",
+ "14 DFB Pokal Erzgebirge Aue 0 4 \n",
+ "15 Bundesliga TSG Hoffenheim 2 1 \n",
+ "16 Bundesliga Hamburger SV 1 2 \n",
+ "17 Bundesliga TSG Hoffenheim 3 3 \n",
+ "18 Bundesliga TSG Hoffenheim 1 0 \n",
+ "19 Bundesliga Borussia M'gladbach 4 0 \n",
+ "\n",
+ " away_team result \n",
+ "0 FC Rheinsud Koln W \n",
+ "1 1. FC Köln W \n",
+ "2 Hertha BSC D \n",
+ "3 Real Sociedad W \n",
+ "4 1. FC Köln W \n",
+ "5 1. FC Köln D \n",
+ "6 Bayer 04 Leverkusen L \n",
+ "7 1. FC Köln D \n",
+ "8 1. FC Heidenheim L \n",
+ "9 1. FC Köln L \n",
+ "10 Karlsruher SC W \n",
+ "11 Borussia M'gladbach L \n",
+ "12 TSG Hoffenheim L \n",
+ "13 TSG Hoffenheim D \n",
+ "14 TSG Hoffenheim W \n",
+ "15 Borussia Dortmund W \n",
+ "16 TSG Hoffenheim W \n",
+ "17 VfB Stuttgart D \n",
+ "18 SV Werder Bremen W \n",
+ "19 TSG Hoffenheim L "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 61 | \n",
+ " TSG Hoffenheim | \n",
+ " Bundesliga | \n",
+ " Vladimír Coufal | \n",
+ " D | \n",
+ " 5 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 62 | \n",
+ " TSG Hoffenheim | \n",
+ " Bundesliga | \n",
+ " Leon Avdullahu | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.18 | \n",
+ "
\n",
+ " \n",
+ " | 63 | \n",
+ " TSG Hoffenheim | \n",
+ " Bundesliga | \n",
+ " Bazoumana Touré | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.14 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " 1. FC Köln | \n",
+ " Bundesliga | \n",
+ " Said El Mala | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.04 | \n",
+ "
\n",
+ " \n",
+ " | 64 | \n",
+ " TSG Hoffenheim | \n",
+ " Bundesliga | \n",
+ " Andrej Kramarić | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.04 | \n",
+ "
\n",
+ " \n",
+ " | 65 | \n",
+ " TSG Hoffenheim | \n",
+ " Bundesliga | \n",
+ " Wouter Burger | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.04 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " 1. FC Köln | \n",
+ " Bundesliga | \n",
+ " Luca Waldschmidt | \n",
+ " F | \n",
+ " 4 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " 1. FC Köln | \n",
+ " Bundesliga | \n",
+ " Tom Krauß | \n",
+ " M | \n",
+ " 2 | \n",
+ " 6.95 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " 1. FC Köln | \n",
+ " Bundesliga | \n",
+ " Marius Bülter | \n",
+ " F | \n",
+ " 5 | \n",
+ " 6.92 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " 1. FC Köln | \n",
+ " Bundesliga | \n",
+ " Eric Martel | \n",
+ " M | \n",
+ " 4 | \n",
+ " 6.83 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " 1. FC Köln | \n",
+ " Overall | \n",
+ " Ísak Bergmann Jóhannesson | \n",
+ " M | \n",
+ " 1 | \n",
+ " 9.30 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " TSG Hoffenheim | \n",
+ " Overall | \n",
+ " Albian Hajdari | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.53 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1. FC Köln | \n",
+ " Overall | \n",
+ " Tom Krauß | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " TSG Hoffenheim | \n",
+ " Overall | \n",
+ " Wouter Burger | \n",
+ " M | \n",
+ " 3 | \n",
+ " 7.40 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " TSG Hoffenheim | \n",
+ " Overall | \n",
+ " Patrick Wimmer | \n",
+ " M | \n",
+ " 3 | \n",
+ " 7.33 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1. FC Köln | \n",
+ " Overall | \n",
+ " Alessio Castro-Montes | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.10 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " TSG Hoffenheim | \n",
+ " Overall | \n",
+ " Valentin Gendrey | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.03 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1. FC Köln | \n",
+ " Overall | \n",
+ " Linton Maina | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ " | 40 | \n",
+ " TSG Hoffenheim | \n",
+ " Overall | \n",
+ " Alex Honajzer | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 1. FC Köln | \n",
+ " Overall | \n",
+ " Gideon Mensah | \n",
+ " D | \n",
+ " 1 | \n",
+ " 6.90 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position \\\n",
+ "61 TSG Hoffenheim Bundesliga Vladimír Coufal D \n",
+ "62 TSG Hoffenheim Bundesliga Leon Avdullahu M \n",
+ "63 TSG Hoffenheim Bundesliga Bazoumana Touré M \n",
+ "15 1. FC Köln Bundesliga Said El Mala F \n",
+ "64 TSG Hoffenheim Bundesliga Andrej Kramarić M \n",
+ "65 TSG Hoffenheim Bundesliga Wouter Burger M \n",
+ "16 1. FC Köln Bundesliga Luca Waldschmidt F \n",
+ "17 1. FC Köln Bundesliga Tom Krauß M \n",
+ "18 1. FC Köln Bundesliga Marius Bülter F \n",
+ "19 1. FC Köln Bundesliga Eric Martel M \n",
+ "0 1. FC Köln Overall Ísak Bergmann Jóhannesson M \n",
+ "36 TSG Hoffenheim Overall Albian Hajdari D \n",
+ "1 1. FC Köln Overall Tom Krauß M \n",
+ "37 TSG Hoffenheim Overall Wouter Burger M \n",
+ "38 TSG Hoffenheim Overall Patrick Wimmer M \n",
+ "2 1. FC Köln Overall Alessio Castro-Montes D \n",
+ "39 TSG Hoffenheim Overall Valentin Gendrey D \n",
+ "3 1. FC Köln Overall Linton Maina M \n",
+ "40 TSG Hoffenheim Overall Alex Honajzer M \n",
+ "4 1. FC Köln Overall Gideon Mensah D \n",
+ "\n",
+ " rating_count average_rating \n",
+ "61 5 7.30 \n",
+ "62 5 7.18 \n",
+ "63 5 7.14 \n",
+ "15 5 7.04 \n",
+ "64 5 7.04 \n",
+ "65 5 7.04 \n",
+ "16 4 7.00 \n",
+ "17 2 6.95 \n",
+ "18 5 6.92 \n",
+ "19 4 6.83 \n",
+ "0 1 9.30 \n",
+ "36 3 7.53 \n",
+ "1 1 7.50 \n",
+ "37 3 7.40 \n",
+ "38 3 7.33 \n",
+ "2 1 7.10 \n",
+ "39 3 7.03 \n",
+ "3 1 7.00 \n",
+ "40 1 7.00 \n",
+ "4 1 6.90 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Köln** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**TSG Hoffenheim** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Köln** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**TSG Hoffenheim** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Köln** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**TSG Hoffenheim** — formation **4-2-2-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Köln** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1899 Hoffenheim** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_02_1-fc-k-ln-vs-tsg-hoffenheim.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 3. 1. FC Union Berlin vs Eintracht Frankfurt"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1. FC Union Berlin | \n",
+ " 1.407 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Eintracht Frankfurt | \n",
+ " 1.323 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 1. FC Union Berlin 1.407\n",
+ "1 Eintracht Frankfurt 1.323"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Eintracht Frankfurt | \n",
+ " 6 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1. FC Union Berlin | \n",
+ " 16 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 Eintracht Frankfurt 6 0 0 0\n",
+ "1 1. FC Union Berlin 16 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 184 | \n",
+ " Zeno Van den Bosch | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 1.406814 | \n",
+ " 1.000000 | \n",
+ " 10.973146 | \n",
+ "
\n",
+ " \n",
+ " | 175 | \n",
+ " Josip Juranović | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 1.406814 | \n",
+ " 1.000000 | \n",
+ " 9.988377 | \n",
+ "
\n",
+ " \n",
+ " | 168 | \n",
+ " Tom Rothe | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 1.406814 | \n",
+ " 1.000000 | \n",
+ " 9.847695 | \n",
+ "
\n",
+ " \n",
+ " | 174 | \n",
+ " Aljoscha Kemlein | \n",
+ " 1. FC Union Berlin | \n",
+ " 3 | \n",
+ " 1.406814 | \n",
+ " 1.000000 | \n",
+ " 9.566333 | \n",
+ "
\n",
+ " \n",
+ " | 178 | \n",
+ " Leopold Querfeld | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 1.406814 | \n",
+ " 1.000000 | \n",
+ " 8.581563 | \n",
+ "
\n",
+ " \n",
+ " | 194 | \n",
+ " Can Uzun | \n",
+ " Eintracht Frankfurt | \n",
+ " 3 | \n",
+ " 1.322645 | \n",
+ " 1.000000 | \n",
+ " 10.647295 | \n",
+ "
\n",
+ " \n",
+ " | 209 | \n",
+ " Raphael Onyedika | \n",
+ " Eintracht Frankfurt | \n",
+ " 3 | \n",
+ " 1.322645 | \n",
+ " 1.000000 | \n",
+ " 10.184369 | \n",
+ "
\n",
+ " \n",
+ " | 208 | \n",
+ " Otávio | \n",
+ " Eintracht Frankfurt | \n",
+ " 2 | \n",
+ " 1.322645 | \n",
+ " 1.000000 | \n",
+ " 9.787575 | \n",
+ "
\n",
+ " \n",
+ " | 190 | \n",
+ " Jonathan Burkardt | \n",
+ " Eintracht Frankfurt | \n",
+ " 4 | \n",
+ " 1.322645 | \n",
+ " 0.838955 | \n",
+ " 9.265497 | \n",
+ "
\n",
+ " \n",
+ " | 204 | \n",
+ " Keita Kosugi | \n",
+ " Eintracht Frankfurt | \n",
+ " 2 | \n",
+ " 1.322645 | \n",
+ " 1.000000 | \n",
+ " 9.192385 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "184 Zeno Van den Bosch 1. FC Union Berlin 2 1.406814 \n",
+ "175 Josip Juranović 1. FC Union Berlin 2 1.406814 \n",
+ "168 Tom Rothe 1. FC Union Berlin 2 1.406814 \n",
+ "174 Aljoscha Kemlein 1. FC Union Berlin 3 1.406814 \n",
+ "178 Leopold Querfeld 1. FC Union Berlin 2 1.406814 \n",
+ "194 Can Uzun Eintracht Frankfurt 3 1.322645 \n",
+ "209 Raphael Onyedika Eintracht Frankfurt 3 1.322645 \n",
+ "208 Otávio Eintracht Frankfurt 2 1.322645 \n",
+ "190 Jonathan Burkardt Eintracht Frankfurt 4 1.322645 \n",
+ "204 Keita Kosugi Eintracht Frankfurt 2 1.322645 \n",
+ "\n",
+ " starting_chance score \n",
+ "184 1.000000 10.973146 \n",
+ "175 1.000000 9.988377 \n",
+ "168 1.000000 9.847695 \n",
+ "174 1.000000 9.566333 \n",
+ "178 1.000000 8.581563 \n",
+ "194 1.000000 10.647295 \n",
+ "209 1.000000 10.184369 \n",
+ "208 1.000000 9.787575 \n",
+ "190 0.838955 9.265497 \n",
+ "204 1.000000 9.192385 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-08-01T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SG Dynamo Dresden | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1. FC Union Berlin | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-08-02T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " Cagliari | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-08-09T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Union Berlin | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " Aris Limassol | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-08-15T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " Ipswich Town | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-08-23T13:30:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " Eintracht Braunschweig | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " 1. FC Union Berlin | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " VfL Wolfsburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-04-24T18:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " RB Leipzig | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " 1. FC Union Berlin | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " 1. FC Köln | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-05-10T17:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " 1. FC Union Berlin | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " FC Augsburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-08-01T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV Waldhof Mannheim | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " Eintracht Frankfurt | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-08-08T13:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Eintracht Frankfurt | \n",
+ " 2 | \n",
+ " 0 | \n",
+ " Hull City | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-08-12T16:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FSV Frankfurt | \n",
+ " 1 | \n",
+ " 5 | \n",
+ " Eintracht Frankfurt | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-08-15T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Brentford | \n",
+ " 7 | \n",
+ " 0 | \n",
+ " Eintracht Frankfurt | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-08-21T16:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " SC St Tönis 11/20 | \n",
+ " 0 | \n",
+ " 11 | \n",
+ " Eintracht Frankfurt | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-04-18T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " RB Leipzig | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Augsburg | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " Eintracht Frankfurt | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Hamburger SV | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-05-08T18:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " Eintracht Frankfurt | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " VfB Stuttgart | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall 1. FC Union Berlin 2026-08-01T12:00:00+00:00 \n",
+ "1 overall 1. FC Union Berlin 2026-08-02T12:00:00+00:00 \n",
+ "2 overall 1. FC Union Berlin 2026-08-09T13:30:00+00:00 \n",
+ "3 overall 1. FC Union Berlin 2026-08-15T13:30:00+00:00 \n",
+ "4 overall 1. FC Union Berlin 2026-08-23T13:30:00+00:00 \n",
+ "5 bundesliga 1. FC Union Berlin 2026-04-18T13:30:00+00:00 \n",
+ "6 bundesliga 1. FC Union Berlin 2026-04-24T18:30:00+00:00 \n",
+ "7 bundesliga 1. FC Union Berlin 2026-05-02T13:30:00+00:00 \n",
+ "8 bundesliga 1. FC Union Berlin 2026-05-10T17:30:00+00:00 \n",
+ "9 bundesliga 1. FC Union Berlin 2026-05-16T13:30:00+00:00 \n",
+ "10 overall Eintracht Frankfurt 2026-08-01T15:00:00+00:00 \n",
+ "11 overall Eintracht Frankfurt 2026-08-08T13:00:00+00:00 \n",
+ "12 overall Eintracht Frankfurt 2026-08-12T16:30:00+00:00 \n",
+ "13 overall Eintracht Frankfurt 2026-08-15T14:00:00+00:00 \n",
+ "14 overall Eintracht Frankfurt 2026-08-21T16:00:00+00:00 \n",
+ "15 bundesliga Eintracht Frankfurt 2026-04-18T16:30:00+00:00 \n",
+ "16 bundesliga Eintracht Frankfurt 2026-04-25T13:30:00+00:00 \n",
+ "17 bundesliga Eintracht Frankfurt 2026-05-02T13:30:00+00:00 \n",
+ "18 bundesliga Eintracht Frankfurt 2026-05-08T18:30:00+00:00 \n",
+ "19 bundesliga Eintracht Frankfurt 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team home_score away_score \\\n",
+ "0 Club Friendly Games SG Dynamo Dresden 2 1 \n",
+ "1 Club Friendly Games 1. FC Union Berlin 2 2 \n",
+ "2 Club Friendly Games 1. FC Union Berlin 3 2 \n",
+ "3 Club Friendly Games 1. FC Union Berlin 2 4 \n",
+ "4 DFB Pokal Eintracht Braunschweig 2 4 \n",
+ "5 Bundesliga 1. FC Union Berlin 1 2 \n",
+ "6 Bundesliga RB Leipzig 3 1 \n",
+ "7 Bundesliga 1. FC Union Berlin 2 2 \n",
+ "8 Bundesliga 1. FSV Mainz 05 1 3 \n",
+ "9 Bundesliga 1. FC Union Berlin 4 0 \n",
+ "10 Club Friendly Games SV Waldhof Mannheim 0 1 \n",
+ "11 Club Friendly Games Eintracht Frankfurt 2 0 \n",
+ "12 Club Friendly Games FSV Frankfurt 1 5 \n",
+ "13 Club Friendly Games Brentford 7 0 \n",
+ "14 DFB Pokal SC St Tönis 11/20 0 11 \n",
+ "15 Bundesliga Eintracht Frankfurt 1 3 \n",
+ "16 Bundesliga FC Augsburg 1 1 \n",
+ "17 Bundesliga Eintracht Frankfurt 1 2 \n",
+ "18 Bundesliga Borussia Dortmund 3 2 \n",
+ "19 Bundesliga Eintracht Frankfurt 2 2 \n",
+ "\n",
+ " away_team result \n",
+ "0 1. FC Union Berlin L \n",
+ "1 Cagliari D \n",
+ "2 Aris Limassol W \n",
+ "3 Ipswich Town L \n",
+ "4 1. FC Union Berlin W \n",
+ "5 VfL Wolfsburg L \n",
+ "6 1. FC Union Berlin L \n",
+ "7 1. FC Köln D \n",
+ "8 1. FC Union Berlin W \n",
+ "9 FC Augsburg W \n",
+ "10 Eintracht Frankfurt W \n",
+ "11 Hull City W \n",
+ "12 Eintracht Frankfurt W \n",
+ "13 Eintracht Frankfurt L \n",
+ "14 Eintracht Frankfurt W \n",
+ "15 RB Leipzig L \n",
+ "16 Eintracht Frankfurt D \n",
+ "17 Hamburger SV L \n",
+ "18 Eintracht Frankfurt L \n",
+ "19 VfB Stuttgart D "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 15 | \n",
+ " 1. FC Union Berlin | \n",
+ " Bundesliga | \n",
+ " Christopher Trimmel | \n",
+ " D | \n",
+ " 5 | \n",
+ " 7.80 | \n",
+ "
\n",
+ " \n",
+ " | 56 | \n",
+ " Eintracht Frankfurt | \n",
+ " Bundesliga | \n",
+ " Can Uzun | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.52 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " 1. FC Union Berlin | \n",
+ " Bundesliga | \n",
+ " András Schäfer | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " 1. FC Union Berlin | \n",
+ " Bundesliga | \n",
+ " Andrej Ilić | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.26 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " 1. FC Union Berlin | \n",
+ " Bundesliga | \n",
+ " Carl Klaus | \n",
+ " G | \n",
+ " 4 | \n",
+ " 7.23 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " 1. FC Union Berlin | \n",
+ " Bundesliga | \n",
+ " Leopold Querfeld | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 57 | \n",
+ " Eintracht Frankfurt | \n",
+ " Bundesliga | \n",
+ " Ellyes Skhiri | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.06 | \n",
+ "
\n",
+ " \n",
+ " | 58 | \n",
+ " Eintracht Frankfurt | \n",
+ " Bundesliga | \n",
+ " Timothy Chandler | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ " | 59 | \n",
+ " Eintracht Frankfurt | \n",
+ " Bundesliga | \n",
+ " Jonathan Burkardt | \n",
+ " F | \n",
+ " 4 | \n",
+ " 6.98 | \n",
+ "
\n",
+ " \n",
+ " | 60 | \n",
+ " Eintracht Frankfurt | \n",
+ " Bundesliga | \n",
+ " Hugo Larsson | \n",
+ " M | \n",
+ " 3 | \n",
+ " 6.83 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " 1. FC Union Berlin | \n",
+ " Overall | \n",
+ " Marin Ljubičić | \n",
+ " F | \n",
+ " 1 | \n",
+ " 8.60 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " Eintracht Frankfurt | \n",
+ " Overall | \n",
+ " Jonathan Burkardt | \n",
+ " F | \n",
+ " 2 | \n",
+ " 8.35 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " Eintracht Frankfurt | \n",
+ " Overall | \n",
+ " Can Uzun | \n",
+ " M | \n",
+ " 2 | \n",
+ " 8.05 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1. FC Union Berlin | \n",
+ " Overall | \n",
+ " Zeno Van Den Bosch | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.80 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " Eintracht Frankfurt | \n",
+ " Overall | \n",
+ " Raphael Onyedika | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.70 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " Eintracht Frankfurt | \n",
+ " Overall | \n",
+ " Robin Koch | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.55 | \n",
+ "
\n",
+ " \n",
+ " | 40 | \n",
+ " Eintracht Frankfurt | \n",
+ " Overall | \n",
+ " Mario Götze | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1. FC Union Berlin | \n",
+ " Overall | \n",
+ " Josip Juranović | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.10 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1. FC Union Berlin | \n",
+ " Overall | \n",
+ " András Schäfer | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 1. FC Union Berlin | \n",
+ " Overall | \n",
+ " Tom Alexander Rothe | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position \\\n",
+ "15 1. FC Union Berlin Bundesliga Christopher Trimmel D \n",
+ "56 Eintracht Frankfurt Bundesliga Can Uzun M \n",
+ "16 1. FC Union Berlin Bundesliga András Schäfer M \n",
+ "17 1. FC Union Berlin Bundesliga Andrej Ilić F \n",
+ "18 1. FC Union Berlin Bundesliga Carl Klaus G \n",
+ "19 1. FC Union Berlin Bundesliga Leopold Querfeld D \n",
+ "57 Eintracht Frankfurt Bundesliga Ellyes Skhiri M \n",
+ "58 Eintracht Frankfurt Bundesliga Timothy Chandler M \n",
+ "59 Eintracht Frankfurt Bundesliga Jonathan Burkardt F \n",
+ "60 Eintracht Frankfurt Bundesliga Hugo Larsson M \n",
+ "0 1. FC Union Berlin Overall Marin Ljubičić F \n",
+ "36 Eintracht Frankfurt Overall Jonathan Burkardt F \n",
+ "37 Eintracht Frankfurt Overall Can Uzun M \n",
+ "1 1. FC Union Berlin Overall Zeno Van Den Bosch D \n",
+ "38 Eintracht Frankfurt Overall Raphael Onyedika M \n",
+ "39 Eintracht Frankfurt Overall Robin Koch D \n",
+ "40 Eintracht Frankfurt Overall Mario Götze M \n",
+ "2 1. FC Union Berlin Overall Josip Juranović D \n",
+ "3 1. FC Union Berlin Overall András Schäfer M \n",
+ "4 1. FC Union Berlin Overall Tom Alexander Rothe D \n",
+ "\n",
+ " rating_count average_rating \n",
+ "15 5 7.80 \n",
+ "56 5 7.52 \n",
+ "16 5 7.30 \n",
+ "17 5 7.26 \n",
+ "18 4 7.23 \n",
+ "19 2 7.20 \n",
+ "57 5 7.06 \n",
+ "58 1 7.00 \n",
+ "59 4 6.98 \n",
+ "60 3 6.83 \n",
+ "0 1 8.60 \n",
+ "36 2 8.35 \n",
+ "37 2 8.05 \n",
+ "1 1 7.80 \n",
+ "38 2 7.70 \n",
+ "39 2 7.55 \n",
+ "40 1 7.50 \n",
+ "2 1 7.10 \n",
+ "3 1 7.00 \n",
+ "4 1 7.00 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Union Berlin** — formation **4-4-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Eintracht Frankfurt** — formation **4-4-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Union Berlin** — formation **4-2-2-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Eintracht Frankfurt** — formation **4-2-2-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FC Union Berlin** — formation **4-2-2-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Eintracht Frankfurt** — formation **4-2-2-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Union Berlin** — formation **4-4-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Eintracht Frankfurt** — formation **4-4-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_03_1-fc-union-berlin-vs-eintracht-frankfurt.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 4. 1. FSV Mainz 05 vs SC Paderborn 07"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 1.956 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SC Paderborn 07 | \n",
+ " 0.812 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 1. FSV Mainz 05 1.956\n",
+ "1 SC Paderborn 07 0.812"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 8 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SC Paderborn 07 | \n",
+ " 12 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 1. FSV Mainz 05 8 0 0 0\n",
+ "1 SC Paderborn 07 12 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 215 | \n",
+ " Nadiem Amiri | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 3 | \n",
+ " 1.956354 | \n",
+ " 1.000000 | \n",
+ " 19.563537 | \n",
+ "
\n",
+ " \n",
+ " | 210 | \n",
+ " Dominik Kohr | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2 | \n",
+ " 1.956354 | \n",
+ " 1.000000 | \n",
+ " 17.215913 | \n",
+ "
\n",
+ " \n",
+ " | 213 | \n",
+ " Danny Da Costa | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2 | \n",
+ " 1.956354 | \n",
+ " 1.000000 | \n",
+ " 15.846465 | \n",
+ "
\n",
+ " \n",
+ " | 227 | \n",
+ " Anthony Caci | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2 | \n",
+ " 1.956354 | \n",
+ " 1.000000 | \n",
+ " 15.846465 | \n",
+ "
\n",
+ " \n",
+ " | 214 | \n",
+ " Robin Zentner | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 1 | \n",
+ " 1.956354 | \n",
+ " 1.000000 | \n",
+ " 14.868288 | \n",
+ "
\n",
+ " \n",
+ " | 255 | \n",
+ " Santiago Castañeda | \n",
+ " SC Paderborn 07 | \n",
+ " 3 | \n",
+ " 0.812250 | \n",
+ " 1.000000 | \n",
+ " 6.904121 | \n",
+ "
\n",
+ " \n",
+ " | 249 | \n",
+ " Laurin Curda | \n",
+ " SC Paderborn 07 | \n",
+ " 2 | \n",
+ " 0.812250 | \n",
+ " 1.000000 | \n",
+ " 6.416772 | \n",
+ "
\n",
+ " \n",
+ " | 248 | \n",
+ " Laurin Ulrich | \n",
+ " SC Paderborn 07 | \n",
+ " 3 | \n",
+ " 0.812250 | \n",
+ " 1.000000 | \n",
+ " 5.685747 | \n",
+ "
\n",
+ " \n",
+ " | 253 | \n",
+ " Tjark Scheller | \n",
+ " SC Paderborn 07 | \n",
+ " 2 | \n",
+ " 0.812250 | \n",
+ " 1.000000 | \n",
+ " 5.685747 | \n",
+ "
\n",
+ " \n",
+ " | 244 | \n",
+ " Gabriel Vidović | \n",
+ " SC Paderborn 07 | \n",
+ " 3 | \n",
+ " 0.812250 | \n",
+ " 0.875862 | \n",
+ " 5.193356 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "215 Nadiem Amiri 1. FSV Mainz 05 3 1.956354 \n",
+ "210 Dominik Kohr 1. FSV Mainz 05 2 1.956354 \n",
+ "213 Danny Da Costa 1. FSV Mainz 05 2 1.956354 \n",
+ "227 Anthony Caci 1. FSV Mainz 05 2 1.956354 \n",
+ "214 Robin Zentner 1. FSV Mainz 05 1 1.956354 \n",
+ "255 Santiago Castañeda SC Paderborn 07 3 0.812250 \n",
+ "249 Laurin Curda SC Paderborn 07 2 0.812250 \n",
+ "248 Laurin Ulrich SC Paderborn 07 3 0.812250 \n",
+ "253 Tjark Scheller SC Paderborn 07 2 0.812250 \n",
+ "244 Gabriel Vidović SC Paderborn 07 3 0.812250 \n",
+ "\n",
+ " starting_chance score \n",
+ "215 1.000000 19.563537 \n",
+ "210 1.000000 17.215913 \n",
+ "213 1.000000 15.846465 \n",
+ "227 1.000000 15.846465 \n",
+ "214 1.000000 14.868288 \n",
+ "255 1.000000 6.904121 \n",
+ "249 1.000000 6.416772 \n",
+ "248 1.000000 5.685747 \n",
+ "253 1.000000 5.685747 \n",
+ "244 0.875862 5.193356 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-07-31T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " Shabab Al-Ahli Dubai | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-08-01T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 3 | \n",
+ " 3 | \n",
+ " Udinese | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-08-08T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " Paris FC | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-08-15T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Bournemouth | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-08-23T13:30:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " VfB 1921 Krieschow | \n",
+ " 0 | \n",
+ " 9 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-04-19T17:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " FC Bayern München | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-05-03T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC St. Pauli | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-05-10T17:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " 1. FC Union Berlin | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " 1. FSV Mainz 05 | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Heidenheim | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-07-25T11:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SC Paderborn 07 | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " 1. FC Magdeburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-07-29T10:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SC Paderborn 07 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Southampton | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-08-01T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " VfL Osnabrück | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " SC Paderborn 07 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-08-08T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV Werder Bremen | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " SC Paderborn 07 | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-08-23T16:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " 1.FC Phönix Lübeck | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " SC Paderborn 07 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-05-21T18:30:00+00:00 | \n",
+ " Bundesliga, Relegation/Promotion Playoffs | \n",
+ " VfL Wolfsburg | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " SC Paderborn 07 | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " SC Paderborn 07 | \n",
+ " 2026-05-25T18:30:00+00:00 | \n",
+ " Bundesliga, Relegation/Promotion Playoffs | \n",
+ " SC Paderborn 07 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " VfL Wolfsburg | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall 1. FSV Mainz 05 2026-07-31T14:00:00+00:00 \n",
+ "1 overall 1. FSV Mainz 05 2026-08-01T14:00:00+00:00 \n",
+ "2 overall 1. FSV Mainz 05 2026-08-08T15:00:00+00:00 \n",
+ "3 overall 1. FSV Mainz 05 2026-08-15T13:30:00+00:00 \n",
+ "4 overall 1. FSV Mainz 05 2026-08-23T13:30:00+00:00 \n",
+ "5 bundesliga 1. FSV Mainz 05 2026-04-19T17:30:00+00:00 \n",
+ "6 bundesliga 1. FSV Mainz 05 2026-04-25T13:30:00+00:00 \n",
+ "7 bundesliga 1. FSV Mainz 05 2026-05-03T13:30:00+00:00 \n",
+ "8 bundesliga 1. FSV Mainz 05 2026-05-10T17:30:00+00:00 \n",
+ "9 bundesliga 1. FSV Mainz 05 2026-05-16T13:30:00+00:00 \n",
+ "10 overall SC Paderborn 07 2026-07-25T11:00:00+00:00 \n",
+ "11 overall SC Paderborn 07 2026-07-29T10:30:00+00:00 \n",
+ "12 overall SC Paderborn 07 2026-08-01T13:30:00+00:00 \n",
+ "13 overall SC Paderborn 07 2026-08-08T12:00:00+00:00 \n",
+ "14 overall SC Paderborn 07 2026-08-23T16:00:00+00:00 \n",
+ "15 bundesliga SC Paderborn 07 2026-05-21T18:30:00+00:00 \n",
+ "16 bundesliga SC Paderborn 07 2026-05-25T18:30:00+00:00 \n",
+ "\n",
+ " competition home_team \\\n",
+ "0 Club Friendly Games 1. FSV Mainz 05 \n",
+ "1 Club Friendly Games 1. FSV Mainz 05 \n",
+ "2 Club Friendly Games 1. FSV Mainz 05 \n",
+ "3 Club Friendly Games 1. FSV Mainz 05 \n",
+ "4 DFB Pokal VfB 1921 Krieschow \n",
+ "5 Bundesliga Borussia M'gladbach \n",
+ "6 Bundesliga 1. FSV Mainz 05 \n",
+ "7 Bundesliga FC St. Pauli \n",
+ "8 Bundesliga 1. FSV Mainz 05 \n",
+ "9 Bundesliga 1. FC Heidenheim \n",
+ "10 Club Friendly Games SC Paderborn 07 \n",
+ "11 Club Friendly Games SC Paderborn 07 \n",
+ "12 Club Friendly Games VfL Osnabrück \n",
+ "13 Club Friendly Games SV Werder Bremen \n",
+ "14 DFB Pokal 1.FC Phönix Lübeck \n",
+ "15 Bundesliga, Relegation/Promotion Playoffs VfL Wolfsburg \n",
+ "16 Bundesliga, Relegation/Promotion Playoffs SC Paderborn 07 \n",
+ "\n",
+ " home_score away_score away_team result \n",
+ "0 1 0 Shabab Al-Ahli Dubai W \n",
+ "1 3 3 Udinese D \n",
+ "2 4 0 Paris FC W \n",
+ "3 2 1 Bournemouth W \n",
+ "4 0 9 1. FSV Mainz 05 W \n",
+ "5 1 1 1. FSV Mainz 05 D \n",
+ "6 3 4 FC Bayern München L \n",
+ "7 1 2 1. FSV Mainz 05 W \n",
+ "8 1 3 1. FC Union Berlin L \n",
+ "9 0 2 1. FSV Mainz 05 W \n",
+ "10 0 2 1. FC Magdeburg L \n",
+ "11 2 1 Southampton W \n",
+ "12 0 2 SC Paderborn 07 W \n",
+ "13 2 2 SC Paderborn 07 D \n",
+ "14 2 4 SC Paderborn 07 W \n",
+ "15 0 0 SC Paderborn 07 D \n",
+ "16 1 1 VfL Wolfsburg D "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 52 | \n",
+ " SC Paderborn 07 | \n",
+ " Bundesliga | \n",
+ " Dennis Seimen | \n",
+ " G | \n",
+ " 2 | \n",
+ " 8.35 | \n",
+ "
\n",
+ " \n",
+ " | 53 | \n",
+ " SC Paderborn 07 | \n",
+ " Bundesliga | \n",
+ " Calvin Brackelmann | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.75 | \n",
+ "
\n",
+ " \n",
+ " | 54 | \n",
+ " SC Paderborn 07 | \n",
+ " Bundesliga | \n",
+ " Laurin Curda | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.75 | \n",
+ "
\n",
+ " \n",
+ " | 55 | \n",
+ " SC Paderborn 07 | \n",
+ " Bundesliga | \n",
+ " Niklas Mohr | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Bundesliga | \n",
+ " Nadiem Amiri | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.52 | \n",
+ "
\n",
+ " \n",
+ " | 56 | \n",
+ " SC Paderborn 07 | \n",
+ " Bundesliga | \n",
+ " Santiago Castañeda | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Bundesliga | \n",
+ " Daniel Batz | \n",
+ " G | \n",
+ " 4 | \n",
+ " 7.38 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Bundesliga | \n",
+ " Phillipp Mwene | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Bundesliga | \n",
+ " Sheraldo Becker | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.06 | \n",
+ "
\n",
+ " \n",
+ " | 20 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Bundesliga | \n",
+ " Kacper Potulski | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.03 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Overall | \n",
+ " Nadiem Amiri | \n",
+ " M | \n",
+ " 1 | \n",
+ " 10.00 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Overall | \n",
+ " Phillip Tietz | \n",
+ " F | \n",
+ " 1 | \n",
+ " 10.00 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Overall | \n",
+ " Dominik Kohr | \n",
+ " D | \n",
+ " 1 | \n",
+ " 8.80 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " SC Paderborn 07 | \n",
+ " Overall | \n",
+ " Santiago Castañeda | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.50 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Overall | \n",
+ " Anthony Caci | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.10 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " Overall | \n",
+ " Danny da Costa | \n",
+ " D | \n",
+ " 1 | \n",
+ " 8.10 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " SC Paderborn 07 | \n",
+ " Overall | \n",
+ " Laurin Curda | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.90 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " SC Paderborn 07 | \n",
+ " Overall | \n",
+ " Mattes Hansen | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " SC Paderborn 07 | \n",
+ " Overall | \n",
+ " Gabriel Vidović | \n",
+ " F | \n",
+ " 1 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 40 | \n",
+ " SC Paderborn 07 | \n",
+ " Overall | \n",
+ " Jano Ter-Horst | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position rating_count \\\n",
+ "52 SC Paderborn 07 Bundesliga Dennis Seimen G 2 \n",
+ "53 SC Paderborn 07 Bundesliga Calvin Brackelmann D 2 \n",
+ "54 SC Paderborn 07 Bundesliga Laurin Curda M 2 \n",
+ "55 SC Paderborn 07 Bundesliga Niklas Mohr D 1 \n",
+ "16 1. FSV Mainz 05 Bundesliga Nadiem Amiri M 5 \n",
+ "56 SC Paderborn 07 Bundesliga Santiago Castañeda M 2 \n",
+ "17 1. FSV Mainz 05 Bundesliga Daniel Batz G 4 \n",
+ "18 1. FSV Mainz 05 Bundesliga Phillipp Mwene M 5 \n",
+ "19 1. FSV Mainz 05 Bundesliga Sheraldo Becker F 5 \n",
+ "20 1. FSV Mainz 05 Bundesliga Kacper Potulski D 3 \n",
+ "0 1. FSV Mainz 05 Overall Nadiem Amiri M 1 \n",
+ "1 1. FSV Mainz 05 Overall Phillip Tietz F 1 \n",
+ "2 1. FSV Mainz 05 Overall Dominik Kohr D 1 \n",
+ "36 SC Paderborn 07 Overall Santiago Castañeda M 1 \n",
+ "3 1. FSV Mainz 05 Overall Anthony Caci M 1 \n",
+ "4 1. FSV Mainz 05 Overall Danny da Costa D 1 \n",
+ "37 SC Paderborn 07 Overall Laurin Curda M 1 \n",
+ "38 SC Paderborn 07 Overall Mattes Hansen D 1 \n",
+ "39 SC Paderborn 07 Overall Gabriel Vidović F 1 \n",
+ "40 SC Paderborn 07 Overall Jano Ter-Horst D 1 \n",
+ "\n",
+ " average_rating \n",
+ "52 8.35 \n",
+ "53 7.75 \n",
+ "54 7.75 \n",
+ "55 7.60 \n",
+ "16 7.52 \n",
+ "56 7.50 \n",
+ "17 7.38 \n",
+ "18 7.30 \n",
+ "19 7.06 \n",
+ "20 7.03 \n",
+ "0 10.00 \n",
+ "1 10.00 \n",
+ "2 8.80 \n",
+ "36 8.50 \n",
+ "3 8.10 \n",
+ "4 8.10 \n",
+ "37 7.90 \n",
+ "38 7.60 \n",
+ "39 7.30 \n",
+ "40 7.30 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FSV Mainz 05** — formation **3-5-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Paderborn** — formation **3-4-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FSV Mainz 05** — formation **5-3-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Paderborn 07** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**1. FSV Mainz 05** — formation **3-3-2-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Paderborn 07** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FSV Mainz 05** — formation **3-5-2**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Paderborn** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_04_1-fsv-mainz-05-vs-sc-paderborn-07.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 5. RB Leipzig vs Borussia M'gladbach"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " RB Leipzig | \n",
+ " 2.073 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Borussia M'gladbach | \n",
+ " 0.722 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 RB Leipzig 2.073\n",
+ "1 Borussia M'gladbach 0.722"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Borussia M'gladbach | \n",
+ " 5 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " RB Leipzig | \n",
+ " 10 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 Borussia M'gladbach 5 0 0 0\n",
+ "1 RB Leipzig 10 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 312 | \n",
+ " Hugo Bolin | \n",
+ " Borussia M'gladbach | \n",
+ " 3 | \n",
+ " 0.721637 | \n",
+ " 1.0 | \n",
+ " 6.639063 | \n",
+ "
\n",
+ " \n",
+ " | 305 | \n",
+ " Lukas Ullrich | \n",
+ " Borussia M'gladbach | \n",
+ " 2 | \n",
+ " 0.721637 | \n",
+ " 1.0 | \n",
+ " 5.917426 | \n",
+ "
\n",
+ " \n",
+ " | 315 | \n",
+ " Daiki Hashioka | \n",
+ " Borussia M'gladbach | \n",
+ " 2 | \n",
+ " 0.721637 | \n",
+ " 1.0 | \n",
+ " 5.700935 | \n",
+ "
\n",
+ " \n",
+ " | 297 | \n",
+ " Philipp Sander | \n",
+ " Borussia M'gladbach | \n",
+ " 3 | \n",
+ " 0.721637 | \n",
+ " 1.0 | \n",
+ " 5.556607 | \n",
+ "
\n",
+ " \n",
+ " | 310 | \n",
+ " Kevin Diks | \n",
+ " Borussia M'gladbach | \n",
+ " 2 | \n",
+ " 0.721637 | \n",
+ " 1.0 | \n",
+ " 5.412280 | \n",
+ "
\n",
+ " \n",
+ " | 266 | \n",
+ " Willi Orban | \n",
+ " RB Leipzig | \n",
+ " 2 | \n",
+ " 2.072715 | \n",
+ " 1.0 | \n",
+ " 16.167175 | \n",
+ "
\n",
+ " \n",
+ " | 274 | \n",
+ " Brajan Gruda | \n",
+ " RB Leipzig | \n",
+ " 3 | \n",
+ " 2.072715 | \n",
+ " 1.0 | \n",
+ " 15.545361 | \n",
+ "
\n",
+ " \n",
+ " | 287 | \n",
+ " Ezechiel Banzuzi | \n",
+ " RB Leipzig | \n",
+ " 3 | \n",
+ " 2.072715 | \n",
+ " 1.0 | \n",
+ " 15.130818 | \n",
+ "
\n",
+ " \n",
+ " | 272 | \n",
+ " David Raum | \n",
+ " RB Leipzig | \n",
+ " 2 | \n",
+ " 2.072715 | \n",
+ " 1.0 | \n",
+ " 15.027182 | \n",
+ "
\n",
+ " \n",
+ " | 283 | \n",
+ " Antonio Nusa | \n",
+ " RB Leipzig | \n",
+ " 3 | \n",
+ " 2.072715 | \n",
+ " 1.0 | \n",
+ " 14.923546 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "312 Hugo Bolin Borussia M'gladbach 3 0.721637 \n",
+ "305 Lukas Ullrich Borussia M'gladbach 2 0.721637 \n",
+ "315 Daiki Hashioka Borussia M'gladbach 2 0.721637 \n",
+ "297 Philipp Sander Borussia M'gladbach 3 0.721637 \n",
+ "310 Kevin Diks Borussia M'gladbach 2 0.721637 \n",
+ "266 Willi Orban RB Leipzig 2 2.072715 \n",
+ "274 Brajan Gruda RB Leipzig 3 2.072715 \n",
+ "287 Ezechiel Banzuzi RB Leipzig 3 2.072715 \n",
+ "272 David Raum RB Leipzig 2 2.072715 \n",
+ "283 Antonio Nusa RB Leipzig 3 2.072715 \n",
+ "\n",
+ " starting_chance score \n",
+ "312 1.0 6.639063 \n",
+ "305 1.0 5.917426 \n",
+ "315 1.0 5.700935 \n",
+ "297 1.0 5.556607 \n",
+ "310 1.0 5.412280 \n",
+ "266 1.0 16.167175 \n",
+ "274 1.0 15.545361 \n",
+ "287 1.0 15.130818 \n",
+ "272 1.0 15.027182 \n",
+ "283 1.0 14.923546 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " RB Leipzig | \n",
+ " 2026-07-25T09:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " RB Leipzig | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " FC Ingolstadt 04 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " RB Leipzig | \n",
+ " 2026-08-01T09:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " RB Leipzig | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " SC Verl | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " RB Leipzig | \n",
+ " 2026-08-08T13:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Leeds United | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " RB Leipzig | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " RB Leipzig | \n",
+ " 2026-08-15T13:30:00+00:00 | \n",
+ " Telekom Cup | \n",
+ " FC Bayern München | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " RB Leipzig | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " RB Leipzig | \n",
+ " 2026-08-22T16:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " Eintracht Trier | \n",
+ " 0 | \n",
+ " 6 | \n",
+ " RB Leipzig | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " RB Leipzig | \n",
+ " 2026-04-18T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " RB Leipzig | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " RB Leipzig | \n",
+ " 2026-04-24T18:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " RB Leipzig | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " 1. FC Union Berlin | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " RB Leipzig | \n",
+ " 2026-05-02T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " RB Leipzig | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " RB Leipzig | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " RB Leipzig | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " FC St. Pauli | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " RB Leipzig | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SC Freiburg | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " RB Leipzig | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-08-01T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FC Hansa Rostock | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " Borussia M'gladbach | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-08-07T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " TSG Hoffenheim | \n",
+ " 1 | \n",
+ " 4 | \n",
+ " Borussia M'gladbach | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-08-12T16:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SSVg Velbert | \n",
+ " 0 | \n",
+ " 8 | \n",
+ " Borussia M'gladbach | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-08-15T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Borussia M'gladbach | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Aston Villa | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-08-23T13:30:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " TSV Schott Mainz | \n",
+ " 0 | \n",
+ " 5 | \n",
+ " Borussia M'gladbach | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-04-19T17:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 1. FSV Mainz 05 | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " VfL Wolfsburg | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " Borussia M'gladbach | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-05-03T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " Borussia Dortmund | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Augsburg | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Borussia M'gladbach | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " TSG Hoffenheim | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall RB Leipzig 2026-07-25T09:30:00+00:00 \n",
+ "1 overall RB Leipzig 2026-08-01T09:30:00+00:00 \n",
+ "2 overall RB Leipzig 2026-08-08T13:00:00+00:00 \n",
+ "3 overall RB Leipzig 2026-08-15T13:30:00+00:00 \n",
+ "4 overall RB Leipzig 2026-08-22T16:00:00+00:00 \n",
+ "5 bundesliga RB Leipzig 2026-04-18T16:30:00+00:00 \n",
+ "6 bundesliga RB Leipzig 2026-04-24T18:30:00+00:00 \n",
+ "7 bundesliga RB Leipzig 2026-05-02T16:30:00+00:00 \n",
+ "8 bundesliga RB Leipzig 2026-05-09T13:30:00+00:00 \n",
+ "9 bundesliga RB Leipzig 2026-05-16T13:30:00+00:00 \n",
+ "10 overall Borussia M'gladbach 2026-08-01T12:00:00+00:00 \n",
+ "11 overall Borussia M'gladbach 2026-08-07T14:00:00+00:00 \n",
+ "12 overall Borussia M'gladbach 2026-08-12T16:00:00+00:00 \n",
+ "13 overall Borussia M'gladbach 2026-08-15T13:30:00+00:00 \n",
+ "14 overall Borussia M'gladbach 2026-08-23T13:30:00+00:00 \n",
+ "15 bundesliga Borussia M'gladbach 2026-04-19T17:30:00+00:00 \n",
+ "16 bundesliga Borussia M'gladbach 2026-04-25T13:30:00+00:00 \n",
+ "17 bundesliga Borussia M'gladbach 2026-05-03T15:30:00+00:00 \n",
+ "18 bundesliga Borussia M'gladbach 2026-05-09T13:30:00+00:00 \n",
+ "19 bundesliga Borussia M'gladbach 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team home_score away_score \\\n",
+ "0 Club Friendly Games RB Leipzig 1 0 \n",
+ "1 Club Friendly Games RB Leipzig 4 0 \n",
+ "2 Club Friendly Games Leeds United 1 0 \n",
+ "3 Telekom Cup FC Bayern München 3 1 \n",
+ "4 DFB Pokal Eintracht Trier 0 6 \n",
+ "5 Bundesliga Eintracht Frankfurt 1 3 \n",
+ "6 Bundesliga RB Leipzig 3 1 \n",
+ "7 Bundesliga Bayer 04 Leverkusen 4 1 \n",
+ "8 Bundesliga RB Leipzig 2 1 \n",
+ "9 Bundesliga SC Freiburg 4 1 \n",
+ "10 Club Friendly Games FC Hansa Rostock 1 3 \n",
+ "11 Club Friendly Games TSG Hoffenheim 1 4 \n",
+ "12 Club Friendly Games SSVg Velbert 0 8 \n",
+ "13 Club Friendly Games Borussia M'gladbach 2 1 \n",
+ "14 DFB Pokal TSV Schott Mainz 0 5 \n",
+ "15 Bundesliga Borussia M'gladbach 1 1 \n",
+ "16 Bundesliga VfL Wolfsburg 0 0 \n",
+ "17 Bundesliga Borussia M'gladbach 1 0 \n",
+ "18 Bundesliga FC Augsburg 3 1 \n",
+ "19 Bundesliga Borussia M'gladbach 4 0 \n",
+ "\n",
+ " away_team result \n",
+ "0 FC Ingolstadt 04 W \n",
+ "1 SC Verl W \n",
+ "2 RB Leipzig L \n",
+ "3 RB Leipzig L \n",
+ "4 RB Leipzig W \n",
+ "5 RB Leipzig W \n",
+ "6 1. FC Union Berlin W \n",
+ "7 RB Leipzig L \n",
+ "8 FC St. Pauli W \n",
+ "9 RB Leipzig L \n",
+ "10 Borussia M'gladbach W \n",
+ "11 Borussia M'gladbach W \n",
+ "12 Borussia M'gladbach W \n",
+ "13 Aston Villa W \n",
+ "14 Borussia M'gladbach W \n",
+ "15 1. FSV Mainz 05 D \n",
+ "16 Borussia M'gladbach D \n",
+ "17 Borussia Dortmund W \n",
+ "18 Borussia M'gladbach L \n",
+ "19 TSG Hoffenheim W "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 62 | \n",
+ " Borussia M'gladbach | \n",
+ " Bundesliga | \n",
+ " Moritz Nicolas | \n",
+ " G | \n",
+ " 5 | \n",
+ " 7.54 | \n",
+ "
\n",
+ " \n",
+ " | 63 | \n",
+ " Borussia M'gladbach | \n",
+ " Bundesliga | \n",
+ " Rocco Reitz | \n",
+ " M | \n",
+ " 4 | \n",
+ " 7.53 | \n",
+ "
\n",
+ " \n",
+ " | 25 | \n",
+ " RB Leipzig | \n",
+ " Bundesliga | \n",
+ " Yan Diomande | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.46 | \n",
+ "
\n",
+ " \n",
+ " | 26 | \n",
+ " RB Leipzig | \n",
+ " Bundesliga | \n",
+ " Xaver Schlager | \n",
+ " M | \n",
+ " 3 | \n",
+ " 7.37 | \n",
+ "
\n",
+ " \n",
+ " | 27 | \n",
+ " RB Leipzig | \n",
+ " Bundesliga | \n",
+ " El Chadaille Bitshiabu | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.33 | \n",
+ "
\n",
+ " \n",
+ " | 64 | \n",
+ " Borussia M'gladbach | \n",
+ " Bundesliga | \n",
+ " Nico Elvedi | \n",
+ " D | \n",
+ " 4 | \n",
+ " 7.33 | \n",
+ "
\n",
+ " \n",
+ " | 65 | \n",
+ " Borussia M'gladbach | \n",
+ " Bundesliga | \n",
+ " Kevin Diks | \n",
+ " D | \n",
+ " 4 | \n",
+ " 7.25 | \n",
+ "
\n",
+ " \n",
+ " | 28 | \n",
+ " RB Leipzig | \n",
+ " Bundesliga | \n",
+ " Willi Orbán | \n",
+ " D | \n",
+ " 4 | \n",
+ " 7.23 | \n",
+ "
\n",
+ " \n",
+ " | 29 | \n",
+ " RB Leipzig | \n",
+ " Bundesliga | \n",
+ " Lukas Klostermann | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 66 | \n",
+ " Borussia M'gladbach | \n",
+ " Bundesliga | \n",
+ " Kevin Stöger | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.06 | \n",
+ "
\n",
+ " \n",
+ " | 46 | \n",
+ " Borussia M'gladbach | \n",
+ " Overall | \n",
+ " Hugo Bolin | \n",
+ " M | \n",
+ " 1 | \n",
+ " 9.20 | \n",
+ "
\n",
+ " \n",
+ " | 47 | \n",
+ " Borussia M'gladbach | \n",
+ " Overall | \n",
+ " Lukas Ullrich | \n",
+ " D | \n",
+ " 1 | \n",
+ " 8.20 | \n",
+ "
\n",
+ " \n",
+ " | 48 | \n",
+ " Borussia M'gladbach | \n",
+ " Overall | \n",
+ " Daiki Hashioka | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.90 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " RB Leipzig | \n",
+ " Overall | \n",
+ " Willi Orbán | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.80 | \n",
+ "
\n",
+ " \n",
+ " | 49 | \n",
+ " Borussia M'gladbach | \n",
+ " Overall | \n",
+ " Philipp Sander | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.70 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " RB Leipzig | \n",
+ " Overall | \n",
+ " Brajan Gruda | \n",
+ " F | \n",
+ " 3 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 50 | \n",
+ " Borussia M'gladbach | \n",
+ " Overall | \n",
+ " Kevin Diks | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " RB Leipzig | \n",
+ " Overall | \n",
+ " Ridle Baku | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.37 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " RB Leipzig | \n",
+ " Overall | \n",
+ " Ezechiel Banzuzi | \n",
+ " M | \n",
+ " 3 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " RB Leipzig | \n",
+ " Overall | \n",
+ " David Raum | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.25 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position \\\n",
+ "62 Borussia M'gladbach Bundesliga Moritz Nicolas G \n",
+ "63 Borussia M'gladbach Bundesliga Rocco Reitz M \n",
+ "25 RB Leipzig Bundesliga Yan Diomande F \n",
+ "26 RB Leipzig Bundesliga Xaver Schlager M \n",
+ "27 RB Leipzig Bundesliga El Chadaille Bitshiabu D \n",
+ "64 Borussia M'gladbach Bundesliga Nico Elvedi D \n",
+ "65 Borussia M'gladbach Bundesliga Kevin Diks D \n",
+ "28 RB Leipzig Bundesliga Willi Orbán D \n",
+ "29 RB Leipzig Bundesliga Lukas Klostermann D \n",
+ "66 Borussia M'gladbach Bundesliga Kevin Stöger M \n",
+ "46 Borussia M'gladbach Overall Hugo Bolin M \n",
+ "47 Borussia M'gladbach Overall Lukas Ullrich D \n",
+ "48 Borussia M'gladbach Overall Daiki Hashioka D \n",
+ "0 RB Leipzig Overall Willi Orbán D \n",
+ "49 Borussia M'gladbach Overall Philipp Sander M \n",
+ "1 RB Leipzig Overall Brajan Gruda F \n",
+ "50 Borussia M'gladbach Overall Kevin Diks D \n",
+ "2 RB Leipzig Overall Ridle Baku D \n",
+ "3 RB Leipzig Overall Ezechiel Banzuzi M \n",
+ "4 RB Leipzig Overall David Raum D \n",
+ "\n",
+ " rating_count average_rating \n",
+ "62 5 7.54 \n",
+ "63 4 7.53 \n",
+ "25 5 7.46 \n",
+ "26 3 7.37 \n",
+ "27 3 7.33 \n",
+ "64 4 7.33 \n",
+ "65 4 7.25 \n",
+ "28 4 7.23 \n",
+ "29 1 7.20 \n",
+ "66 5 7.06 \n",
+ "46 1 9.20 \n",
+ "47 1 8.20 \n",
+ "48 1 7.90 \n",
+ "0 3 7.80 \n",
+ "49 1 7.70 \n",
+ "1 3 7.50 \n",
+ "50 1 7.50 \n",
+ "2 3 7.37 \n",
+ "3 3 7.30 \n",
+ "4 2 7.25 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**RB Leipzig** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Borussia Mönchengladbach** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**RB Leipzig** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Borussia M'gladbach** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**RB Leipzig** — formation **4-1-2-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bor. Mönchengladbach** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**RB Leipzig** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Mönchengladbach** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_05_rb-leipzig-vs-borussia-m-gladbach.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 6. SV 07 Elversberg vs Bayer 04 Leverkusen"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " SV 07 Elversberg | \n",
+ " 0.746 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2.043 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 SV 07 Elversberg 0.746\n",
+ "1 Bayer 04 Leverkusen 2.043"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SV 07 Elversberg | \n",
+ " 14 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 Bayer 04 Leverkusen 2 0 0 0\n",
+ "1 SV 07 Elversberg 14 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 90 | \n",
+ " Aleix García | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 3 | \n",
+ " 2.043161 | \n",
+ " 1.0 | \n",
+ " 15.528023 | \n",
+ "
\n",
+ " \n",
+ " | 86 | \n",
+ " Edmond Tapsoba | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2 | \n",
+ " 2.043161 | \n",
+ " 1.0 | \n",
+ " 14.915074 | \n",
+ "
\n",
+ " \n",
+ " | 81 | \n",
+ " Mark Flekken | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 1 | \n",
+ " 2.043161 | \n",
+ " 1.0 | \n",
+ " 14.506442 | \n",
+ "
\n",
+ " \n",
+ " | 93 | \n",
+ " Ibrahim Maza | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 3 | \n",
+ " 2.043161 | \n",
+ " 1.0 | \n",
+ " 14.199968 | \n",
+ "
\n",
+ " \n",
+ " | 89 | \n",
+ " Miguel Gutiérrez | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2 | \n",
+ " 2.043161 | \n",
+ " 1.0 | \n",
+ " 13.791336 | \n",
+ "
\n",
+ " \n",
+ " | 61 | \n",
+ " Maximilian Rohr | \n",
+ " SV 07 Elversberg | \n",
+ " 2 | \n",
+ " 0.746414 | \n",
+ " 1.0 | \n",
+ " 5.448822 | \n",
+ "
\n",
+ " \n",
+ " | 69 | \n",
+ " Cole Campbell | \n",
+ " SV 07 Elversberg | \n",
+ " 3 | \n",
+ " 0.746414 | \n",
+ " 1.0 | \n",
+ " 5.150256 | \n",
+ "
\n",
+ " \n",
+ " | 66 | \n",
+ " Nicolas Kristof | \n",
+ " SV 07 Elversberg | \n",
+ " 1 | \n",
+ " 0.746414 | \n",
+ " 1.0 | \n",
+ " 5.075615 | \n",
+ "
\n",
+ " \n",
+ " | 68 | \n",
+ " Lukasz Poreba | \n",
+ " SV 07 Elversberg | \n",
+ " 3 | \n",
+ " 0.746414 | \n",
+ " 1.0 | \n",
+ " 5.075615 | \n",
+ "
\n",
+ " \n",
+ " | 62 | \n",
+ " Felix Keidel | \n",
+ " SV 07 Elversberg | \n",
+ " 2 | \n",
+ " 0.746414 | \n",
+ " 1.0 | \n",
+ " 4.926332 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "90 Aleix García Bayer 04 Leverkusen 3 2.043161 \n",
+ "86 Edmond Tapsoba Bayer 04 Leverkusen 2 2.043161 \n",
+ "81 Mark Flekken Bayer 04 Leverkusen 1 2.043161 \n",
+ "93 Ibrahim Maza Bayer 04 Leverkusen 3 2.043161 \n",
+ "89 Miguel Gutiérrez Bayer 04 Leverkusen 2 2.043161 \n",
+ "61 Maximilian Rohr SV 07 Elversberg 2 0.746414 \n",
+ "69 Cole Campbell SV 07 Elversberg 3 0.746414 \n",
+ "66 Nicolas Kristof SV 07 Elversberg 1 0.746414 \n",
+ "68 Lukasz Poreba SV 07 Elversberg 3 0.746414 \n",
+ "62 Felix Keidel SV 07 Elversberg 2 0.746414 \n",
+ "\n",
+ " starting_chance score \n",
+ "90 1.0 15.528023 \n",
+ "86 1.0 14.915074 \n",
+ "81 1.0 14.506442 \n",
+ "93 1.0 14.199968 \n",
+ "89 1.0 13.791336 \n",
+ "61 1.0 5.448822 \n",
+ "69 1.0 5.150256 \n",
+ "66 1.0 5.075615 \n",
+ "68 1.0 5.075615 \n",
+ "62 1.0 4.926332 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " SV 07 Elversberg | \n",
+ " 2026-07-25T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " NEC Nijmegen | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " SV 07 Elversberg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " SV 07 Elversberg | \n",
+ " 2026-08-04T16:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " RC Strasbourg | \n",
+ " 2 | \n",
+ " 5 | \n",
+ " SV 07 Elversberg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " SV 07 Elversberg | \n",
+ " 2026-08-08T19:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Mallorca | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " SV 07 Elversberg | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " SV 07 Elversberg | \n",
+ " 2026-08-15T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV 07 Elversberg | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " Lorient | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " SV 07 Elversberg | \n",
+ " 2026-08-22T13:30:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " MSV Duisburg | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " SV 07 Elversberg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " overall | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-08-01T09:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 3 | \n",
+ " 0 | \n",
+ " Rot-Weiss Essen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " overall | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-08-08T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Sevilla | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " overall | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-08-12T18:45:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Nottingham Forest | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " overall | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-08-15T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Newcastle United | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " overall | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-08-22T11:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " SV Wehen Wiesbaden | \n",
+ " 0 | \n",
+ " 4 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " FC Augsburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Köln | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-05-02T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " RB Leipzig | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " Hamburger SV | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall SV 07 Elversberg 2026-07-25T12:00:00+00:00 \n",
+ "1 overall SV 07 Elversberg 2026-08-04T16:00:00+00:00 \n",
+ "2 overall SV 07 Elversberg 2026-08-08T19:00:00+00:00 \n",
+ "3 overall SV 07 Elversberg 2026-08-15T13:30:00+00:00 \n",
+ "4 overall SV 07 Elversberg 2026-08-22T13:30:00+00:00 \n",
+ "5 overall Bayer 04 Leverkusen 2026-08-01T09:00:00+00:00 \n",
+ "6 overall Bayer 04 Leverkusen 2026-08-08T13:30:00+00:00 \n",
+ "7 overall Bayer 04 Leverkusen 2026-08-12T18:45:00+00:00 \n",
+ "8 overall Bayer 04 Leverkusen 2026-08-15T14:00:00+00:00 \n",
+ "9 overall Bayer 04 Leverkusen 2026-08-22T11:00:00+00:00 \n",
+ "10 bundesliga Bayer 04 Leverkusen 2026-04-18T13:30:00+00:00 \n",
+ "11 bundesliga Bayer 04 Leverkusen 2026-04-25T13:30:00+00:00 \n",
+ "12 bundesliga Bayer 04 Leverkusen 2026-05-02T16:30:00+00:00 \n",
+ "13 bundesliga Bayer 04 Leverkusen 2026-05-09T13:30:00+00:00 \n",
+ "14 bundesliga Bayer 04 Leverkusen 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team home_score away_score \\\n",
+ "0 Club Friendly Games NEC Nijmegen 0 1 \n",
+ "1 Club Friendly Games RC Strasbourg 2 5 \n",
+ "2 Club Friendly Games Mallorca 1 1 \n",
+ "3 Club Friendly Games SV 07 Elversberg 4 1 \n",
+ "4 DFB Pokal MSV Duisburg 1 3 \n",
+ "5 Club Friendly Games Bayer 04 Leverkusen 3 0 \n",
+ "6 Club Friendly Games Bayer 04 Leverkusen 2 1 \n",
+ "7 Club Friendly Games Nottingham Forest 2 1 \n",
+ "8 Club Friendly Games Newcastle United 1 2 \n",
+ "9 DFB Pokal SV Wehen Wiesbaden 0 4 \n",
+ "10 Bundesliga Bayer 04 Leverkusen 1 2 \n",
+ "11 Bundesliga 1. FC Köln 1 2 \n",
+ "12 Bundesliga Bayer 04 Leverkusen 4 1 \n",
+ "13 Bundesliga VfB Stuttgart 3 1 \n",
+ "14 Bundesliga Bayer 04 Leverkusen 1 1 \n",
+ "\n",
+ " away_team result \n",
+ "0 SV 07 Elversberg W \n",
+ "1 SV 07 Elversberg W \n",
+ "2 SV 07 Elversberg D \n",
+ "3 Lorient W \n",
+ "4 SV 07 Elversberg W \n",
+ "5 Rot-Weiss Essen W \n",
+ "6 Sevilla W \n",
+ "7 Bayer 04 Leverkusen L \n",
+ "8 Bayer 04 Leverkusen W \n",
+ "9 Bayer 04 Leverkusen W \n",
+ "10 FC Augsburg L \n",
+ "11 Bayer 04 Leverkusen W \n",
+ "12 RB Leipzig W \n",
+ "13 Bayer 04 Leverkusen L \n",
+ "14 Hamburger SV D "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 37 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Bundesliga | \n",
+ " Janis Blaswich | \n",
+ " G | \n",
+ " 1 | \n",
+ " 8.60 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Bundesliga | \n",
+ " Nathan Tella | \n",
+ " F | \n",
+ " 3 | \n",
+ " 7.97 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Bundesliga | \n",
+ " Aleix García | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.94 | \n",
+ "
\n",
+ " \n",
+ " | 40 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Bundesliga | \n",
+ " Alejandro Grimaldo | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.54 | \n",
+ "
\n",
+ " \n",
+ " | 41 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Bundesliga | \n",
+ " Patrik Schick | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.52 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " SV 07 Elversberg | \n",
+ " Overall | \n",
+ " Francis Onyeka | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.90 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Overall | \n",
+ " Aleix García | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Overall | \n",
+ " Victor Okoh Boniface | \n",
+ " F | \n",
+ " 1 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SV 07 Elversberg | \n",
+ " Overall | \n",
+ " Luca Schnellbacher | \n",
+ " F | \n",
+ " 1 | \n",
+ " 7.40 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " SV 07 Elversberg | \n",
+ " Overall | \n",
+ " Maximilian Rohr | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Overall | \n",
+ " Edmond Tapsoba | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Overall | \n",
+ " Janis Blaswich | \n",
+ " G | \n",
+ " 1 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " Bayer 04 Leverkusen | \n",
+ " Overall | \n",
+ " Mark Flekken | \n",
+ " G | \n",
+ " 1 | \n",
+ " 7.10 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " SV 07 Elversberg | \n",
+ " Overall | \n",
+ " Cole Campbell | \n",
+ " M | \n",
+ " 1 | \n",
+ " 6.90 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " SV 07 Elversberg | \n",
+ " Overall | \n",
+ " Florian Yves Le Joncour | \n",
+ " D | \n",
+ " 1 | \n",
+ " 6.80 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position \\\n",
+ "37 Bayer 04 Leverkusen Bundesliga Janis Blaswich G \n",
+ "38 Bayer 04 Leverkusen Bundesliga Nathan Tella F \n",
+ "39 Bayer 04 Leverkusen Bundesliga Aleix García M \n",
+ "40 Bayer 04 Leverkusen Bundesliga Alejandro Grimaldo M \n",
+ "41 Bayer 04 Leverkusen Bundesliga Patrik Schick F \n",
+ "0 SV 07 Elversberg Overall Francis Onyeka M \n",
+ "15 Bayer 04 Leverkusen Overall Aleix García M \n",
+ "16 Bayer 04 Leverkusen Overall Victor Okoh Boniface F \n",
+ "1 SV 07 Elversberg Overall Luca Schnellbacher F \n",
+ "2 SV 07 Elversberg Overall Maximilian Rohr D \n",
+ "17 Bayer 04 Leverkusen Overall Edmond Tapsoba D \n",
+ "18 Bayer 04 Leverkusen Overall Janis Blaswich G \n",
+ "19 Bayer 04 Leverkusen Overall Mark Flekken G \n",
+ "3 SV 07 Elversberg Overall Cole Campbell M \n",
+ "4 SV 07 Elversberg Overall Florian Yves Le Joncour D \n",
+ "\n",
+ " rating_count average_rating \n",
+ "37 1 8.60 \n",
+ "38 3 7.97 \n",
+ "39 5 7.94 \n",
+ "40 5 7.54 \n",
+ "41 5 7.52 \n",
+ "0 1 8.90 \n",
+ "15 2 7.60 \n",
+ "16 1 7.60 \n",
+ "1 1 7.40 \n",
+ "2 1 7.30 \n",
+ "17 2 7.30 \n",
+ "18 1 7.20 \n",
+ "19 1 7.10 \n",
+ "3 1 6.90 \n",
+ "4 1 6.80 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SV 07 Elversberg** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayer 04 Leverkusen** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SV 07 Elversberg** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayer 04 Leverkusen** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SV Elversberg** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayer 04 Leverkusen** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SV 07 Elversberg** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Bayer Leverkusen** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_06_sv-07-elversberg-vs-bayer-04-leverkusen.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 7. Borussia Dortmund vs Hamburger SV"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Borussia Dortmund | \n",
+ " 2.352 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Hamburger SV | \n",
+ " 0.482 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 Borussia Dortmund 2.352\n",
+ "1 Hamburger SV 0.482"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Borussia Dortmund | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Hamburger SV | \n",
+ " 9 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 Borussia Dortmund 4 0 0 0\n",
+ "1 Hamburger SV 9 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 324 | \n",
+ " Julian Ryerson | \n",
+ " Borussia Dortmund | \n",
+ " 2 | \n",
+ " 2.351939 | \n",
+ " 1.000000 | \n",
+ " 17.286749 | \n",
+ "
\n",
+ " \n",
+ " | 339 | \n",
+ " Konstantinos Karetsas | \n",
+ " Borussia Dortmund | \n",
+ " 3 | \n",
+ " 2.351939 | \n",
+ " 1.000000 | \n",
+ " 17.098594 | \n",
+ "
\n",
+ " \n",
+ " | 318 | \n",
+ " Waldemar Anton | \n",
+ " Borussia Dortmund | \n",
+ " 2 | \n",
+ " 2.351939 | \n",
+ " 1.000000 | \n",
+ " 16.228377 | \n",
+ "
\n",
+ " \n",
+ " | 320 | \n",
+ " Gregor Kobel | \n",
+ " Borussia Dortmund | \n",
+ " 1 | \n",
+ " 2.351939 | \n",
+ " 1.000000 | \n",
+ " 15.993183 | \n",
+ "
\n",
+ " \n",
+ " | 338 | \n",
+ " Joane Gadou | \n",
+ " Borussia Dortmund | \n",
+ " 2 | \n",
+ " 2.351939 | \n",
+ " 1.000000 | \n",
+ " 15.993183 | \n",
+ "
\n",
+ " \n",
+ " | 353 | \n",
+ " Albert Grønbæk | \n",
+ " Hamburger SV | \n",
+ " 3 | \n",
+ " 0.481892 | \n",
+ " 0.800000 | \n",
+ " 3.623826 | \n",
+ "
\n",
+ " \n",
+ " | 359 | \n",
+ " Louis Lemke | \n",
+ " Hamburger SV | \n",
+ " 2 | \n",
+ " 0.481892 | \n",
+ " 0.906897 | \n",
+ " 3.583613 | \n",
+ "
\n",
+ " \n",
+ " | 348 | \n",
+ " Nicolai Remberg | \n",
+ " Hamburger SV | \n",
+ " 3 | \n",
+ " 0.481892 | \n",
+ " 1.000000 | \n",
+ " 3.565999 | \n",
+ "
\n",
+ " \n",
+ " | 345 | \n",
+ " Sebastiaan Bornauw | \n",
+ " Hamburger SV | \n",
+ " 2 | \n",
+ " 0.481892 | \n",
+ " 1.000000 | \n",
+ " 3.469621 | \n",
+ "
\n",
+ " \n",
+ " | 361 | \n",
+ " Patson Daka | \n",
+ " Hamburger SV | \n",
+ " 4 | \n",
+ " 0.481892 | \n",
+ " 1.000000 | \n",
+ " 3.469621 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position \\\n",
+ "324 Julian Ryerson Borussia Dortmund 2 \n",
+ "339 Konstantinos Karetsas Borussia Dortmund 3 \n",
+ "318 Waldemar Anton Borussia Dortmund 2 \n",
+ "320 Gregor Kobel Borussia Dortmund 1 \n",
+ "338 Joane Gadou Borussia Dortmund 2 \n",
+ "353 Albert Grønbæk Hamburger SV 3 \n",
+ "359 Louis Lemke Hamburger SV 2 \n",
+ "348 Nicolai Remberg Hamburger SV 3 \n",
+ "345 Sebastiaan Bornauw Hamburger SV 2 \n",
+ "361 Patson Daka Hamburger SV 4 \n",
+ "\n",
+ " expected_match_points starting_chance score \n",
+ "324 2.351939 1.000000 17.286749 \n",
+ "339 2.351939 1.000000 17.098594 \n",
+ "318 2.351939 1.000000 16.228377 \n",
+ "320 2.351939 1.000000 15.993183 \n",
+ "338 2.351939 1.000000 15.993183 \n",
+ "353 0.481892 0.800000 3.623826 \n",
+ "359 0.481892 0.906897 3.583613 \n",
+ "348 0.481892 1.000000 3.565999 \n",
+ "345 0.481892 1.000000 3.469621 \n",
+ "361 0.481892 1.000000 3.469621 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " Borussia Dortmund | \n",
+ " 2026-07-29T10:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Cerezo Osaka | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " Borussia Dortmund | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " Borussia Dortmund | \n",
+ " 2026-08-01T10:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FC Tokyo | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " Borussia Dortmund | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " Borussia Dortmund | \n",
+ " 2026-08-09T13:00:00+00:00 | \n",
+ " Emirates Cup | \n",
+ " Arsenal | \n",
+ " 2 | \n",
+ " 3 | \n",
+ " Borussia Dortmund | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " Borussia Dortmund | \n",
+ " 2026-08-15T15:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Borussia Dortmund | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " AS Roma | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " Borussia Dortmund | \n",
+ " 2026-08-22T18:30:00+00:00 | \n",
+ " Supercup | \n",
+ " Borussia Dortmund | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " FC Bayern München | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " Borussia Dortmund | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 2026-04-26T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " SC Freiburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 2026-05-03T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia M'gladbach | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " Borussia Dortmund | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 2026-05-08T18:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " Eintracht Frankfurt | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " Borussia Dortmund | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " Hamburger SV | \n",
+ " 2026-07-25T11:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Hamburger SV | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " 1. FC Heidenheim | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " Hamburger SV | \n",
+ " 2026-08-01T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Hamburger SV | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Everton | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " Hamburger SV | \n",
+ " 2026-08-08T13:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Hamburger SV | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " Lille | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " Hamburger SV | \n",
+ " 2026-08-15T17:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Toulouse | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Hamburger SV | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " Hamburger SV | \n",
+ " 2026-08-24T16:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " SC Verl | \n",
+ " 0 | \n",
+ " 3 | \n",
+ " Hamburger SV | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " Hamburger SV | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Hamburger SV | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " Hamburger SV | \n",
+ " 2026-04-25T16:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Hamburger SV | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " TSG Hoffenheim | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " bundesliga | \n",
+ " Hamburger SV | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Eintracht Frankfurt | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Hamburger SV | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " bundesliga | \n",
+ " Hamburger SV | \n",
+ " 2026-05-10T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Hamburger SV | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " SC Freiburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " bundesliga | \n",
+ " Hamburger SV | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " Hamburger SV | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall Borussia Dortmund 2026-07-29T10:00:00+00:00 \n",
+ "1 overall Borussia Dortmund 2026-08-01T10:00:00+00:00 \n",
+ "2 overall Borussia Dortmund 2026-08-09T13:00:00+00:00 \n",
+ "3 overall Borussia Dortmund 2026-08-15T15:30:00+00:00 \n",
+ "4 overall Borussia Dortmund 2026-08-22T18:30:00+00:00 \n",
+ "5 bundesliga Borussia Dortmund 2026-04-18T13:30:00+00:00 \n",
+ "6 bundesliga Borussia Dortmund 2026-04-26T15:30:00+00:00 \n",
+ "7 bundesliga Borussia Dortmund 2026-05-03T15:30:00+00:00 \n",
+ "8 bundesliga Borussia Dortmund 2026-05-08T18:30:00+00:00 \n",
+ "9 bundesliga Borussia Dortmund 2026-05-16T13:30:00+00:00 \n",
+ "10 overall Hamburger SV 2026-07-25T11:30:00+00:00 \n",
+ "11 overall Hamburger SV 2026-08-01T15:00:00+00:00 \n",
+ "12 overall Hamburger SV 2026-08-08T13:00:00+00:00 \n",
+ "13 overall Hamburger SV 2026-08-15T17:00:00+00:00 \n",
+ "14 overall Hamburger SV 2026-08-24T16:00:00+00:00 \n",
+ "15 bundesliga Hamburger SV 2026-04-18T13:30:00+00:00 \n",
+ "16 bundesliga Hamburger SV 2026-04-25T16:30:00+00:00 \n",
+ "17 bundesliga Hamburger SV 2026-05-02T13:30:00+00:00 \n",
+ "18 bundesliga Hamburger SV 2026-05-10T13:30:00+00:00 \n",
+ "19 bundesliga Hamburger SV 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team home_score away_score \\\n",
+ "0 Club Friendly Games Cerezo Osaka 1 0 \n",
+ "1 Club Friendly Games FC Tokyo 0 1 \n",
+ "2 Emirates Cup Arsenal 2 3 \n",
+ "3 Club Friendly Games Borussia Dortmund 2 2 \n",
+ "4 Supercup Borussia Dortmund 1 2 \n",
+ "5 Bundesliga TSG Hoffenheim 2 1 \n",
+ "6 Bundesliga Borussia Dortmund 4 0 \n",
+ "7 Bundesliga Borussia M'gladbach 1 0 \n",
+ "8 Bundesliga Borussia Dortmund 3 2 \n",
+ "9 Bundesliga SV Werder Bremen 0 2 \n",
+ "10 Club Friendly Games Hamburger SV 3 1 \n",
+ "11 Club Friendly Games Hamburger SV 1 2 \n",
+ "12 Club Friendly Games Hamburger SV 2 2 \n",
+ "13 Club Friendly Games Toulouse 1 2 \n",
+ "14 DFB Pokal SC Verl 0 3 \n",
+ "15 Bundesliga SV Werder Bremen 3 1 \n",
+ "16 Bundesliga Hamburger SV 1 2 \n",
+ "17 Bundesliga Eintracht Frankfurt 1 2 \n",
+ "18 Bundesliga Hamburger SV 3 2 \n",
+ "19 Bundesliga Bayer 04 Leverkusen 1 1 \n",
+ "\n",
+ " away_team result \n",
+ "0 Borussia Dortmund L \n",
+ "1 Borussia Dortmund W \n",
+ "2 Borussia Dortmund W \n",
+ "3 AS Roma D \n",
+ "4 FC Bayern München L \n",
+ "5 Borussia Dortmund L \n",
+ "6 SC Freiburg W \n",
+ "7 Borussia Dortmund L \n",
+ "8 Eintracht Frankfurt W \n",
+ "9 Borussia Dortmund W \n",
+ "10 1. FC Heidenheim W \n",
+ "11 Everton L \n",
+ "12 Lille D \n",
+ "13 Hamburger SV W \n",
+ "14 Hamburger SV W \n",
+ "15 Hamburger SV L \n",
+ "16 TSG Hoffenheim L \n",
+ "17 Hamburger SV W \n",
+ "18 SC Freiburg W \n",
+ "19 Hamburger SV D "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 70 | \n",
+ " Hamburger SV | \n",
+ " Bundesliga | \n",
+ " Sander Tangvik | \n",
+ " G | \n",
+ " 1 | \n",
+ " 8.80 | \n",
+ "
\n",
+ " \n",
+ " | 35 | \n",
+ " Borussia Dortmund | \n",
+ " Bundesliga | \n",
+ " Ramy Bensebaini | \n",
+ " D | \n",
+ " 2 | \n",
+ " 8.20 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " Borussia Dortmund | \n",
+ " Bundesliga | \n",
+ " Nico Schlotterbeck | \n",
+ " D | \n",
+ " 5 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 71 | \n",
+ " Hamburger SV | \n",
+ " Bundesliga | \n",
+ " Fábio Vieira | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 72 | \n",
+ " Hamburger SV | \n",
+ " Bundesliga | \n",
+ " Robert Glatzel | \n",
+ " F | \n",
+ " 3 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 73 | \n",
+ " Hamburger SV | \n",
+ " Bundesliga | \n",
+ " Daniel Fernandes | \n",
+ " G | \n",
+ " 4 | \n",
+ " 7.48 | \n",
+ "
\n",
+ " \n",
+ " | 74 | \n",
+ " Hamburger SV | \n",
+ " Bundesliga | \n",
+ " Luka Vušković | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.47 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " Borussia Dortmund | \n",
+ " Bundesliga | \n",
+ " Gregor Kobel | \n",
+ " G | \n",
+ " 5 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " Borussia Dortmund | \n",
+ " Bundesliga | \n",
+ " Waldemar Anton | \n",
+ " D | \n",
+ " 5 | \n",
+ " 7.14 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " Borussia Dortmund | \n",
+ " Bundesliga | \n",
+ " Maximilian Beier | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.12 | \n",
+ "
\n",
+ " \n",
+ " | 55 | \n",
+ " Hamburger SV | \n",
+ " Overall | \n",
+ " Albert Grønbæk | \n",
+ " F | \n",
+ " 1 | \n",
+ " 9.40 | \n",
+ "
\n",
+ " \n",
+ " | 56 | \n",
+ " Hamburger SV | \n",
+ " Overall | \n",
+ " Louis Lemke | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.20 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " Borussia Dortmund | \n",
+ " Overall | \n",
+ " Patrick Drewes | \n",
+ " G | \n",
+ " 1 | \n",
+ " 7.70 | \n",
+ "
\n",
+ " \n",
+ " | 57 | \n",
+ " Hamburger SV | \n",
+ " Overall | \n",
+ " Sander Tangvik | \n",
+ " G | \n",
+ " 1 | \n",
+ " 7.70 | \n",
+ "
\n",
+ " \n",
+ " | 58 | \n",
+ " Hamburger SV | \n",
+ " Overall | \n",
+ " Nicolai Remberg | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.40 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Borussia Dortmund | \n",
+ " Overall | \n",
+ " Julian Ryerson | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.35 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " Borussia Dortmund | \n",
+ " Overall | \n",
+ " Giannis Konstantelias | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " Borussia Dortmund | \n",
+ " Overall | \n",
+ " Konstantinos Karetsas | \n",
+ " F | \n",
+ " 3 | \n",
+ " 7.27 | \n",
+ "
\n",
+ " \n",
+ " | 59 | \n",
+ " Hamburger SV | \n",
+ " Overall | \n",
+ " Patson Daka | \n",
+ " F | \n",
+ " 1 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Borussia Dortmund | \n",
+ " Overall | \n",
+ " Jan-Luca Riedl | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.10 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position \\\n",
+ "70 Hamburger SV Bundesliga Sander Tangvik G \n",
+ "35 Borussia Dortmund Bundesliga Ramy Bensebaini D \n",
+ "36 Borussia Dortmund Bundesliga Nico Schlotterbeck D \n",
+ "71 Hamburger SV Bundesliga Fábio Vieira F \n",
+ "72 Hamburger SV Bundesliga Robert Glatzel F \n",
+ "73 Hamburger SV Bundesliga Daniel Fernandes G \n",
+ "74 Hamburger SV Bundesliga Luka Vušković D \n",
+ "37 Borussia Dortmund Bundesliga Gregor Kobel G \n",
+ "38 Borussia Dortmund Bundesliga Waldemar Anton D \n",
+ "39 Borussia Dortmund Bundesliga Maximilian Beier F \n",
+ "55 Hamburger SV Overall Albert Grønbæk F \n",
+ "56 Hamburger SV Overall Louis Lemke M \n",
+ "0 Borussia Dortmund Overall Patrick Drewes G \n",
+ "57 Hamburger SV Overall Sander Tangvik G \n",
+ "58 Hamburger SV Overall Nicolai Remberg M \n",
+ "1 Borussia Dortmund Overall Julian Ryerson M \n",
+ "2 Borussia Dortmund Overall Giannis Konstantelias M \n",
+ "3 Borussia Dortmund Overall Konstantinos Karetsas F \n",
+ "59 Hamburger SV Overall Patson Daka F \n",
+ "4 Borussia Dortmund Overall Jan-Luca Riedl D \n",
+ "\n",
+ " rating_count average_rating \n",
+ "70 1 8.80 \n",
+ "35 2 8.20 \n",
+ "36 5 7.60 \n",
+ "71 5 7.60 \n",
+ "72 3 7.50 \n",
+ "73 4 7.48 \n",
+ "74 3 7.47 \n",
+ "37 5 7.30 \n",
+ "38 5 7.14 \n",
+ "39 5 7.12 \n",
+ "55 1 9.40 \n",
+ "56 1 8.20 \n",
+ "0 1 7.70 \n",
+ "57 1 7.70 \n",
+ "58 1 7.40 \n",
+ "1 2 7.35 \n",
+ "2 1 7.30 \n",
+ "3 3 7.27 \n",
+ "59 1 7.20 \n",
+ "4 2 7.10 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Borussia Dortmund** — formation **3-4-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Hamburger SV** — formation **3-4-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Borussia Dortmund** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Hamburger SV** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Borussia Dortmund** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Hamburger SV** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Borussia Dortmund** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Hamburger SV** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_07_borussia-dortmund-vs-hamburger-sv.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 8. SC Freiburg vs SV Werder Bremen"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " SC Freiburg | \n",
+ " 1.706 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SV Werder Bremen | \n",
+ " 1.031 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 SC Freiburg 1.706\n",
+ "1 SV Werder Bremen 1.031"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " SC Freiburg | \n",
+ " 11 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SV Werder Bremen | \n",
+ " 18 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 SC Freiburg 11 0 0 0\n",
+ "1 SV Werder Bremen 18 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 379 | \n",
+ " Igor Matanović | \n",
+ " SC Freiburg | \n",
+ " 4 | \n",
+ " 1.705678 | \n",
+ " 1.0 | \n",
+ " 13.304292 | \n",
+ "
\n",
+ " \n",
+ " | 364 | \n",
+ " Matthias Ginter | \n",
+ " SC Freiburg | \n",
+ " 2 | \n",
+ " 1.705678 | \n",
+ " 1.0 | \n",
+ " 12.963157 | \n",
+ "
\n",
+ " \n",
+ " | 377 | \n",
+ " Yannik Engelhardt | \n",
+ " SC Freiburg | \n",
+ " 3 | \n",
+ " 1.705678 | \n",
+ " 1.0 | \n",
+ " 12.280885 | \n",
+ "
\n",
+ " \n",
+ " | 381 | \n",
+ " Philipp Treu | \n",
+ " SC Freiburg | \n",
+ " 2 | \n",
+ " 1.705678 | \n",
+ " 1.0 | \n",
+ " 12.195601 | \n",
+ "
\n",
+ " \n",
+ " | 378 | \n",
+ " Mio Backhaus | \n",
+ " SC Freiburg | \n",
+ " 1 | \n",
+ " 1.705678 | \n",
+ " 1.0 | \n",
+ " 11.769182 | \n",
+ "
\n",
+ " \n",
+ " | 402 | \n",
+ " Jens Stage | \n",
+ " SV Werder Bremen | \n",
+ " 3 | \n",
+ " 1.031190 | \n",
+ " 1.0 | \n",
+ " 8.558879 | \n",
+ "
\n",
+ " \n",
+ " | 393 | \n",
+ " Marco Friedl | \n",
+ " SV Werder Bremen | \n",
+ " 2 | \n",
+ " 1.031190 | \n",
+ " 1.0 | \n",
+ " 8.249522 | \n",
+ "
\n",
+ " \n",
+ " | 394 | \n",
+ " Amos Pieper | \n",
+ " SV Werder Bremen | \n",
+ " 2 | \n",
+ " 1.031190 | \n",
+ " 1.0 | \n",
+ " 7.940165 | \n",
+ "
\n",
+ " \n",
+ " | 404 | \n",
+ " Olivier Deman | \n",
+ " SV Werder Bremen | \n",
+ " 2 | \n",
+ " 1.031190 | \n",
+ " 1.0 | \n",
+ " 7.527689 | \n",
+ "
\n",
+ " \n",
+ " | 413 | \n",
+ " Mick Schmetgens | \n",
+ " SV Werder Bremen | \n",
+ " 2 | \n",
+ " 1.031190 | \n",
+ " 1.0 | \n",
+ " 7.321450 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "379 Igor Matanović SC Freiburg 4 1.705678 \n",
+ "364 Matthias Ginter SC Freiburg 2 1.705678 \n",
+ "377 Yannik Engelhardt SC Freiburg 3 1.705678 \n",
+ "381 Philipp Treu SC Freiburg 2 1.705678 \n",
+ "378 Mio Backhaus SC Freiburg 1 1.705678 \n",
+ "402 Jens Stage SV Werder Bremen 3 1.031190 \n",
+ "393 Marco Friedl SV Werder Bremen 2 1.031190 \n",
+ "394 Amos Pieper SV Werder Bremen 2 1.031190 \n",
+ "404 Olivier Deman SV Werder Bremen 2 1.031190 \n",
+ "413 Mick Schmetgens SV Werder Bremen 2 1.031190 \n",
+ "\n",
+ " starting_chance score \n",
+ "379 1.0 13.304292 \n",
+ "364 1.0 12.963157 \n",
+ "377 1.0 12.280885 \n",
+ "381 1.0 12.195601 \n",
+ "378 1.0 11.769182 \n",
+ "402 1.0 8.558879 \n",
+ "393 1.0 8.249522 \n",
+ "394 1.0 7.940165 \n",
+ "404 1.0 7.527689 \n",
+ "413 1.0 7.321450 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " SC Freiburg | \n",
+ " 2026-07-31T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SpVgg Greuther Fürth | \n",
+ " 3 | \n",
+ " 0 | \n",
+ " SC Freiburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " SC Freiburg | \n",
+ " 2026-08-08T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SC Freiburg | \n",
+ " 2 | \n",
+ " 0 | \n",
+ " RC Strasbourg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " SC Freiburg | \n",
+ " 2026-08-15T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SC Freiburg | \n",
+ " 2 | \n",
+ " 0 | \n",
+ " Crystal Palace | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " SC Freiburg | \n",
+ " 2026-08-20T18:30:00+00:00 | \n",
+ " UEFA Europa Conference League, Qualification P... | \n",
+ " Motherwell | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " SC Freiburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " SC Freiburg | \n",
+ " 2026-08-23T16:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " Fortuna Düsseldorf | \n",
+ " 1 | \n",
+ " 5 | \n",
+ " SC Freiburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " SC Freiburg | \n",
+ " 2026-04-19T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SC Freiburg | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1. FC Heidenheim | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " SC Freiburg | \n",
+ " 2026-04-26T15:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Borussia Dortmund | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " SC Freiburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " SC Freiburg | \n",
+ " 2026-05-03T17:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SC Freiburg | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " VfL Wolfsburg | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " SC Freiburg | \n",
+ " 2026-05-10T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Hamburger SV | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " SC Freiburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " SC Freiburg | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SC Freiburg | \n",
+ " 4 | \n",
+ " 1 | \n",
+ " RB Leipzig | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " SV Werder Bremen | \n",
+ " 2026-08-01T13:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Energie Cottbus | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " SV Werder Bremen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " SV Werder Bremen | \n",
+ " 2026-08-08T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV Werder Bremen | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " SC Paderborn 07 | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " SV Werder Bremen | \n",
+ " 2026-08-15T12:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV Werder Bremen | \n",
+ " 0 | \n",
+ " 1 | \n",
+ " Auxerre | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " SV Werder Bremen | \n",
+ " 2026-08-22T13:30:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " LSK Hansa Lüneburg | \n",
+ " 0 | \n",
+ " 3 | \n",
+ " SV Werder Bremen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " SV Werder Bremen | \n",
+ " 2026-08-23T10:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SV Werder Bremen | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " SV Meppen | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Hamburger SV | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 2026-04-26T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " VfB Stuttgart | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " SV Werder Bremen | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " FC Augsburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " TSG Hoffenheim | \n",
+ " 1 | \n",
+ " 0 | \n",
+ " SV Werder Bremen | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 19 | \n",
+ " bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " Borussia Dortmund | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date \\\n",
+ "0 overall SC Freiburg 2026-07-31T12:00:00+00:00 \n",
+ "1 overall SC Freiburg 2026-08-08T13:30:00+00:00 \n",
+ "2 overall SC Freiburg 2026-08-15T12:00:00+00:00 \n",
+ "3 overall SC Freiburg 2026-08-20T18:30:00+00:00 \n",
+ "4 overall SC Freiburg 2026-08-23T16:00:00+00:00 \n",
+ "5 bundesliga SC Freiburg 2026-04-19T13:30:00+00:00 \n",
+ "6 bundesliga SC Freiburg 2026-04-26T15:30:00+00:00 \n",
+ "7 bundesliga SC Freiburg 2026-05-03T17:30:00+00:00 \n",
+ "8 bundesliga SC Freiburg 2026-05-10T13:30:00+00:00 \n",
+ "9 bundesliga SC Freiburg 2026-05-16T13:30:00+00:00 \n",
+ "10 overall SV Werder Bremen 2026-08-01T13:00:00+00:00 \n",
+ "11 overall SV Werder Bremen 2026-08-08T12:00:00+00:00 \n",
+ "12 overall SV Werder Bremen 2026-08-15T12:30:00+00:00 \n",
+ "13 overall SV Werder Bremen 2026-08-22T13:30:00+00:00 \n",
+ "14 overall SV Werder Bremen 2026-08-23T10:00:00+00:00 \n",
+ "15 bundesliga SV Werder Bremen 2026-04-18T13:30:00+00:00 \n",
+ "16 bundesliga SV Werder Bremen 2026-04-26T13:30:00+00:00 \n",
+ "17 bundesliga SV Werder Bremen 2026-05-02T13:30:00+00:00 \n",
+ "18 bundesliga SV Werder Bremen 2026-05-09T13:30:00+00:00 \n",
+ "19 bundesliga SV Werder Bremen 2026-05-16T13:30:00+00:00 \n",
+ "\n",
+ " competition home_team \\\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 UEFA Europa Conference League, Qualification P... Motherwell \n",
+ "4 DFB Pokal Fortuna Düsseldorf \n",
+ "5 Bundesliga SC Freiburg \n",
+ "6 Bundesliga Borussia Dortmund \n",
+ "7 Bundesliga SC Freiburg \n",
+ "8 Bundesliga Hamburger SV \n",
+ "9 Bundesliga SC Freiburg \n",
+ "10 Club Friendly Games Energie Cottbus \n",
+ "11 Club Friendly Games SV Werder Bremen \n",
+ "12 Club Friendly Games SV Werder Bremen \n",
+ "13 DFB Pokal LSK Hansa Lüneburg \n",
+ "14 Club Friendly Games SV Werder Bremen \n",
+ "15 Bundesliga SV Werder Bremen \n",
+ "16 Bundesliga VfB Stuttgart \n",
+ "17 Bundesliga SV Werder Bremen \n",
+ "18 Bundesliga TSG Hoffenheim \n",
+ "19 Bundesliga SV Werder Bremen \n",
+ "\n",
+ " home_score away_score away_team result \n",
+ "0 3 0 SC Freiburg L \n",
+ "1 2 0 RC Strasbourg W \n",
+ "2 2 0 Crystal Palace W \n",
+ "3 1 3 SC Freiburg W \n",
+ "4 1 5 SC Freiburg W \n",
+ "5 2 1 1. FC Heidenheim W \n",
+ "6 4 0 SC Freiburg L \n",
+ "7 1 1 VfL Wolfsburg D \n",
+ "8 3 2 SC Freiburg L \n",
+ "9 4 1 RB Leipzig W \n",
+ "10 2 4 SV Werder Bremen W \n",
+ "11 2 2 SC Paderborn 07 D \n",
+ "12 0 1 Auxerre L \n",
+ "13 0 3 SV Werder Bremen W \n",
+ "14 3 1 SV Meppen W \n",
+ "15 3 1 Hamburger SV W \n",
+ "16 1 1 SV Werder Bremen D \n",
+ "17 1 3 FC Augsburg L \n",
+ "18 1 0 SV Werder Bremen L \n",
+ "19 0 2 Borussia Dortmund L "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 59 | \n",
+ " SV Werder Bremen | \n",
+ " Bundesliga | \n",
+ " Mio Backhaus | \n",
+ " G | \n",
+ " 5 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 22 | \n",
+ " SC Freiburg | \n",
+ " Bundesliga | \n",
+ " Johan Manzambi | \n",
+ " M | \n",
+ " 4 | \n",
+ " 7.48 | \n",
+ "
\n",
+ " \n",
+ " | 60 | \n",
+ " SV Werder Bremen | \n",
+ " Bundesliga | \n",
+ " Romano Schmid | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.38 | \n",
+ "
\n",
+ " \n",
+ " | 23 | \n",
+ " SC Freiburg | \n",
+ " Bundesliga | \n",
+ " Matthias Ginter | \n",
+ " D | \n",
+ " 4 | \n",
+ " 7.35 | \n",
+ "
\n",
+ " \n",
+ " | 24 | \n",
+ " SC Freiburg | \n",
+ " Bundesliga | \n",
+ " Igor Matanović | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.26 | \n",
+ "
\n",
+ " \n",
+ " | 61 | \n",
+ " SV Werder Bremen | \n",
+ " Bundesliga | \n",
+ " Maximilian Wöber | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.25 | \n",
+ "
\n",
+ " \n",
+ " | 62 | \n",
+ " SV Werder Bremen | \n",
+ " Bundesliga | \n",
+ " Jens Stage | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.10 | \n",
+ "
\n",
+ " \n",
+ " | 63 | \n",
+ " SV Werder Bremen | \n",
+ " Bundesliga | \n",
+ " Olivier Deman | \n",
+ " D | \n",
+ " 5 | \n",
+ " 6.96 | \n",
+ "
\n",
+ " \n",
+ " | 25 | \n",
+ " SC Freiburg | \n",
+ " Bundesliga | \n",
+ " Philipp Lienhart | \n",
+ " D | \n",
+ " 5 | \n",
+ " 6.88 | \n",
+ "
\n",
+ " \n",
+ " | 26 | \n",
+ " SC Freiburg | \n",
+ " Bundesliga | \n",
+ " Vincenzo Grifo | \n",
+ " M | \n",
+ " 5 | \n",
+ " 6.82 | \n",
+ "
\n",
+ " \n",
+ " | 43 | \n",
+ " SV Werder Bremen | \n",
+ " Overall | \n",
+ " Jens Stage | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.30 | \n",
+ "
\n",
+ " \n",
+ " | 44 | \n",
+ " SV Werder Bremen | \n",
+ " Overall | \n",
+ " Ludovit Reis | \n",
+ " M | \n",
+ " 1 | \n",
+ " 8.00 | \n",
+ "
\n",
+ " \n",
+ " | 45 | \n",
+ " SV Werder Bremen | \n",
+ " Overall | \n",
+ " Marco Friedl | \n",
+ " D | \n",
+ " 1 | \n",
+ " 8.00 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " SC Freiburg | \n",
+ " Overall | \n",
+ " Igor Matanović | \n",
+ " F | \n",
+ " 3 | \n",
+ " 7.80 | \n",
+ "
\n",
+ " \n",
+ " | 46 | \n",
+ " SV Werder Bremen | \n",
+ " Overall | \n",
+ " Amos Pieper | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.70 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " SC Freiburg | \n",
+ " Overall | \n",
+ " Matthias Ginter | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.60 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " SC Freiburg | \n",
+ " Overall | \n",
+ " Derry Scherhant | \n",
+ " F | \n",
+ " 3 | \n",
+ " 7.53 | \n",
+ "
\n",
+ " \n",
+ " | 47 | \n",
+ " SV Werder Bremen | \n",
+ " Overall | \n",
+ " Paul Erevbenagie | \n",
+ " F | \n",
+ " 1 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " SC Freiburg | \n",
+ " Overall | \n",
+ " Lukas Kübler | \n",
+ " D | \n",
+ " 2 | \n",
+ " 7.45 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " SC Freiburg | \n",
+ " Overall | \n",
+ " Lucas Höler | \n",
+ " F | \n",
+ " 2 | \n",
+ " 7.30 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position rating_count \\\n",
+ "59 SV Werder Bremen Bundesliga Mio Backhaus G 5 \n",
+ "22 SC Freiburg Bundesliga Johan Manzambi M 4 \n",
+ "60 SV Werder Bremen Bundesliga Romano Schmid M 5 \n",
+ "23 SC Freiburg Bundesliga Matthias Ginter D 4 \n",
+ "24 SC Freiburg Bundesliga Igor Matanović F 5 \n",
+ "61 SV Werder Bremen Bundesliga Maximilian Wöber D 2 \n",
+ "62 SV Werder Bremen Bundesliga Jens Stage M 5 \n",
+ "63 SV Werder Bremen Bundesliga Olivier Deman D 5 \n",
+ "25 SC Freiburg Bundesliga Philipp Lienhart D 5 \n",
+ "26 SC Freiburg Bundesliga Vincenzo Grifo M 5 \n",
+ "43 SV Werder Bremen Overall Jens Stage M 1 \n",
+ "44 SV Werder Bremen Overall Ludovit Reis M 1 \n",
+ "45 SV Werder Bremen Overall Marco Friedl D 1 \n",
+ "0 SC Freiburg Overall Igor Matanović F 3 \n",
+ "46 SV Werder Bremen Overall Amos Pieper D 1 \n",
+ "1 SC Freiburg Overall Matthias Ginter D 3 \n",
+ "2 SC Freiburg Overall Derry Scherhant F 3 \n",
+ "47 SV Werder Bremen Overall Paul Erevbenagie F 1 \n",
+ "3 SC Freiburg Overall Lukas Kübler D 2 \n",
+ "4 SC Freiburg Overall Lucas Höler F 2 \n",
+ "\n",
+ " average_rating \n",
+ "59 7.60 \n",
+ "22 7.48 \n",
+ "60 7.38 \n",
+ "23 7.35 \n",
+ "24 7.26 \n",
+ "61 7.25 \n",
+ "62 7.10 \n",
+ "63 6.96 \n",
+ "25 6.88 \n",
+ "26 6.82 \n",
+ "43 8.30 \n",
+ "44 8.00 \n",
+ "45 8.00 \n",
+ "0 7.80 \n",
+ "46 7.70 \n",
+ "1 7.60 \n",
+ "2 7.53 \n",
+ "47 7.50 \n",
+ "3 7.45 \n",
+ "4 7.30 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Freiburg** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SV Werder Bremen** — formation **4-3-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Freiburg** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SV Werder Bremen** — formation **4-3-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Freiburg** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Werder Bremen** — formation **4-1-2-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**SC Freiburg** — formation **4-2-3-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Werder Bremen** — formation **4-1-2-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_08_sc-freiburg-vs-sv-werder-bremen.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "---\n",
+ "## 9. FC Augsburg vs FC Schalke 04"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### 1X2 odds and team expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Source:** FotMob — Tipico"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " expected match points | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " FC Augsburg | \n",
+ " 1.585 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " FC Schalke 04 | \n",
+ " 1.151 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team expected match points\n",
+ "0 FC Augsburg 1.585\n",
+ "1 FC Schalke 04 1.151"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### League position"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " position | \n",
+ " matches | \n",
+ " points | \n",
+ " goal_difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " FC Augsburg | \n",
+ " 7 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " FC Schalke 04 | \n",
+ " 13 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team position matches points goal_difference\n",
+ "0 FC Augsburg 7 0 0 0\n",
+ "1 FC Schalke 04 13 0 0 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Player expected points"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " name | \n",
+ " team_display | \n",
+ " position | \n",
+ " expected_match_points | \n",
+ " starting_chance | \n",
+ " score | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 422 | \n",
+ " Finn Dahmen | \n",
+ " FC Augsburg | \n",
+ " 1 | \n",
+ " 1.585310 | \n",
+ " 1.0 | \n",
+ " 12.523948 | \n",
+ "
\n",
+ " \n",
+ " | 438 | \n",
+ " Han-Noah Massengo | \n",
+ " FC Augsburg | \n",
+ " 3 | \n",
+ " 1.585310 | \n",
+ " 1.0 | \n",
+ " 11.731293 | \n",
+ "
\n",
+ " \n",
+ " | 426 | \n",
+ " Anton Kade | \n",
+ " FC Augsburg | \n",
+ " 4 | \n",
+ " 1.585310 | \n",
+ " 1.0 | \n",
+ " 11.097169 | \n",
+ "
\n",
+ " \n",
+ " | 434 | \n",
+ " Chrislain Matsima | \n",
+ " FC Augsburg | \n",
+ " 2 | \n",
+ " 1.585310 | \n",
+ " 1.0 | \n",
+ " 11.097169 | \n",
+ "
\n",
+ " \n",
+ " | 437 | \n",
+ " Hennes Behrens | \n",
+ " FC Augsburg | \n",
+ " 2 | \n",
+ " 1.585310 | \n",
+ " 1.0 | \n",
+ " 11.097169 | \n",
+ "
\n",
+ " \n",
+ " | 449 | \n",
+ " Soufiane El-Faouzi | \n",
+ " FC Schalke 04 | \n",
+ " 3 | \n",
+ " 1.151492 | \n",
+ " 1.0 | \n",
+ " 8.290742 | \n",
+ "
\n",
+ " \n",
+ " | 453 | \n",
+ " Hasan Kuruçay | \n",
+ " FC Schalke 04 | \n",
+ " 2 | \n",
+ " 1.151492 | \n",
+ " 1.0 | \n",
+ " 7.887720 | \n",
+ "
\n",
+ " \n",
+ " | 462 | \n",
+ " Nikola Katic | \n",
+ " FC Schalke 04 | \n",
+ " 2 | \n",
+ " 1.151492 | \n",
+ " 1.0 | \n",
+ " 7.887720 | \n",
+ "
\n",
+ " \n",
+ " | 447 | \n",
+ " Timo Becker | \n",
+ " FC Schalke 04 | \n",
+ " 2 | \n",
+ " 1.151492 | \n",
+ " 1.0 | \n",
+ " 7.772571 | \n",
+ "
\n",
+ " \n",
+ " | 441 | \n",
+ " Loris Karius | \n",
+ " FC Schalke 04 | \n",
+ " 1 | \n",
+ " 1.151492 | \n",
+ " 1.0 | \n",
+ " 7.599847 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " name team_display position expected_match_points \\\n",
+ "422 Finn Dahmen FC Augsburg 1 1.585310 \n",
+ "438 Han-Noah Massengo FC Augsburg 3 1.585310 \n",
+ "426 Anton Kade FC Augsburg 4 1.585310 \n",
+ "434 Chrislain Matsima FC Augsburg 2 1.585310 \n",
+ "437 Hennes Behrens FC Augsburg 2 1.585310 \n",
+ "449 Soufiane El-Faouzi FC Schalke 04 3 1.151492 \n",
+ "453 Hasan Kuruçay FC Schalke 04 2 1.151492 \n",
+ "462 Nikola Katic FC Schalke 04 2 1.151492 \n",
+ "447 Timo Becker FC Schalke 04 2 1.151492 \n",
+ "441 Loris Karius FC Schalke 04 1 1.151492 \n",
+ "\n",
+ " starting_chance score \n",
+ "422 1.0 12.523948 \n",
+ "438 1.0 11.731293 \n",
+ "426 1.0 11.097169 \n",
+ "434 1.0 11.097169 \n",
+ "437 1.0 11.097169 \n",
+ "449 1.0 8.290742 \n",
+ "453 1.0 7.887720 \n",
+ "462 1.0 7.887720 \n",
+ "447 1.0 7.772571 \n",
+ "441 1.0 7.599847 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Recent form and last-five match data"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " category | \n",
+ " team | \n",
+ " date | \n",
+ " competition | \n",
+ " home_team | \n",
+ " home_score | \n",
+ " away_score | \n",
+ " away_team | \n",
+ " result | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " overall | \n",
+ " FC Augsburg | \n",
+ " 2026-07-30T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Bournemouth | \n",
+ " 5 | \n",
+ " 2 | \n",
+ " FC Augsburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " overall | \n",
+ " FC Augsburg | \n",
+ " 2026-08-05T17:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " SC Schwaz | \n",
+ " 0 | \n",
+ " 15 | \n",
+ " FC Augsburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " overall | \n",
+ " FC Augsburg | \n",
+ " 2026-08-08T13:30:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FC Augsburg | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " Sassuolo | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " overall | \n",
+ " FC Augsburg | \n",
+ " 2026-08-15T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " Leeds United | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " FC Augsburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " overall | \n",
+ " FC Augsburg | \n",
+ " 2026-08-22T11:00:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " Energie Cottbus | \n",
+ " 0 | \n",
+ " 2 | \n",
+ " FC Augsburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " bundesliga | \n",
+ " FC Augsburg | \n",
+ " 2026-04-18T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " Bayer 04 Leverkusen | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " FC Augsburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " bundesliga | \n",
+ " FC Augsburg | \n",
+ " 2026-04-25T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Augsburg | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " Eintracht Frankfurt | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " bundesliga | \n",
+ " FC Augsburg | \n",
+ " 2026-05-02T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " SV Werder Bremen | \n",
+ " 1 | \n",
+ " 3 | \n",
+ " FC Augsburg | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " bundesliga | \n",
+ " FC Augsburg | \n",
+ " 2026-05-09T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " FC Augsburg | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Borussia M'gladbach | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " bundesliga | \n",
+ " FC Augsburg | \n",
+ " 2026-05-16T13:30:00+00:00 | \n",
+ " Bundesliga | \n",
+ " 1. FC Union Berlin | \n",
+ " 4 | \n",
+ " 0 | \n",
+ " FC Augsburg | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 10 | \n",
+ " overall | \n",
+ " FC Schalke 04 | \n",
+ " 2026-07-25T14:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FC Schalke 04 | \n",
+ " 3 | \n",
+ " 1 | \n",
+ " Fagiano Okayama | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 11 | \n",
+ " overall | \n",
+ " FC Schalke 04 | \n",
+ " 2026-08-01T12:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " KSV Hessen Kassel | \n",
+ " 0 | \n",
+ " 5 | \n",
+ " FC Schalke 04 | \n",
+ " W | \n",
+ "
\n",
+ " \n",
+ " | 12 | \n",
+ " overall | \n",
+ " FC Schalke 04 | \n",
+ " 2026-08-08T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FC Schalke 04 | \n",
+ " 0 | \n",
+ " 3 | \n",
+ " Atalanta | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 13 | \n",
+ " overall | \n",
+ " FC Schalke 04 | \n",
+ " 2026-08-16T15:00:00+00:00 | \n",
+ " Club Friendly Games | \n",
+ " FC Schalke 04 | \n",
+ " 0 | \n",
+ " 3 | \n",
+ " Real Madrid | \n",
+ " L | \n",
+ "
\n",
+ " \n",
+ " | 14 | \n",
+ " overall | \n",
+ " FC Schalke 04 | \n",
+ " 2026-08-24T18:45:00+00:00 | \n",
+ " DFB Pokal | \n",
+ " Hallescher FC | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " FC Schalke 04 | \n",
+ " D | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " category team date competition \\\n",
+ "0 overall FC Augsburg 2026-07-30T14:00:00+00:00 Club Friendly Games \n",
+ "1 overall FC Augsburg 2026-08-05T17:00:00+00:00 Club Friendly Games \n",
+ "2 overall FC Augsburg 2026-08-08T13:30:00+00:00 Club Friendly Games \n",
+ "3 overall FC Augsburg 2026-08-15T14:00:00+00:00 Club Friendly Games \n",
+ "4 overall FC Augsburg 2026-08-22T11:00:00+00:00 DFB Pokal \n",
+ "5 bundesliga FC Augsburg 2026-04-18T13:30:00+00:00 Bundesliga \n",
+ "6 bundesliga FC Augsburg 2026-04-25T13:30:00+00:00 Bundesliga \n",
+ "7 bundesliga FC Augsburg 2026-05-02T13:30:00+00:00 Bundesliga \n",
+ "8 bundesliga FC Augsburg 2026-05-09T13:30:00+00:00 Bundesliga \n",
+ "9 bundesliga FC Augsburg 2026-05-16T13:30:00+00:00 Bundesliga \n",
+ "10 overall FC Schalke 04 2026-07-25T14:00:00+00:00 Club Friendly Games \n",
+ "11 overall FC Schalke 04 2026-08-01T12:00:00+00:00 Club Friendly Games \n",
+ "12 overall FC Schalke 04 2026-08-08T15:00:00+00:00 Club Friendly Games \n",
+ "13 overall FC Schalke 04 2026-08-16T15:00:00+00:00 Club Friendly Games \n",
+ "14 overall FC Schalke 04 2026-08-24T18:45:00+00:00 DFB Pokal \n",
+ "\n",
+ " home_team home_score away_score away_team result \n",
+ "0 Bournemouth 5 2 FC Augsburg L \n",
+ "1 SC Schwaz 0 15 FC Augsburg W \n",
+ "2 FC Augsburg 3 2 Sassuolo W \n",
+ "3 Leeds United 4 0 FC Augsburg L \n",
+ "4 Energie Cottbus 0 2 FC Augsburg W \n",
+ "5 Bayer 04 Leverkusen 1 2 FC Augsburg W \n",
+ "6 FC Augsburg 1 1 Eintracht Frankfurt D \n",
+ "7 SV Werder Bremen 1 3 FC Augsburg W \n",
+ "8 FC Augsburg 3 1 Borussia M'gladbach W \n",
+ "9 1. FC Union Berlin 4 0 FC Augsburg L \n",
+ "10 FC Schalke 04 3 1 Fagiano Okayama W \n",
+ "11 KSV Hessen Kassel 0 5 FC Schalke 04 W \n",
+ "12 FC Schalke 04 0 3 Atalanta L \n",
+ "13 FC Schalke 04 0 3 Real Madrid L \n",
+ "14 Hallescher FC 2 2 FC Schalke 04 D "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Upcoming fixtures"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "> No saved upcoming-match snapshot exactly matches this requested matchday."
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Best recent SofaScore form"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " team | \n",
+ " category | \n",
+ " player_name | \n",
+ " position | \n",
+ " rating_count | \n",
+ " average_rating | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 14 | \n",
+ " FC Augsburg | \n",
+ " Bundesliga | \n",
+ " Fabian Rieder | \n",
+ " M | \n",
+ " 5 | \n",
+ " 7.52 | \n",
+ "
\n",
+ " \n",
+ " | 15 | \n",
+ " FC Augsburg | \n",
+ " Bundesliga | \n",
+ " Anton Kade | \n",
+ " F | \n",
+ " 5 | \n",
+ " 7.46 | \n",
+ "
\n",
+ " \n",
+ " | 16 | \n",
+ " FC Augsburg | \n",
+ " Bundesliga | \n",
+ " Finn Dahmen | \n",
+ " G | \n",
+ " 5 | \n",
+ " 7.44 | \n",
+ "
\n",
+ " \n",
+ " | 17 | \n",
+ " FC Augsburg | \n",
+ " Bundesliga | \n",
+ " Noahkai Banks | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.40 | \n",
+ "
\n",
+ " \n",
+ " | 18 | \n",
+ " FC Augsburg | \n",
+ " Bundesliga | \n",
+ " Arthur Chaves | \n",
+ " D | \n",
+ " 3 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 0 | \n",
+ " FC Augsburg | \n",
+ " Overall | \n",
+ " Finn Dahmen | \n",
+ " G | \n",
+ " 1 | \n",
+ " 7.90 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " FC Augsburg | \n",
+ " Overall | \n",
+ " Kristijan Jakić | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.70 | \n",
+ "
\n",
+ " \n",
+ " | 36 | \n",
+ " FC Schalke 04 | \n",
+ " Overall | \n",
+ " Edin Džeko | \n",
+ " F | \n",
+ " 2 | \n",
+ " 7.65 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " FC Augsburg | \n",
+ " Overall | \n",
+ " Noahkai Banks | \n",
+ " D | \n",
+ " 1 | \n",
+ " 7.50 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " FC Augsburg | \n",
+ " Overall | \n",
+ " Han-Noah Massengo | \n",
+ " M | \n",
+ " 1 | \n",
+ " 7.40 | \n",
+ "
\n",
+ " \n",
+ " | 37 | \n",
+ " FC Schalke 04 | \n",
+ " Overall | \n",
+ " Dejan Ljubičić | \n",
+ " F | \n",
+ " 2 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 38 | \n",
+ " FC Schalke 04 | \n",
+ " Overall | \n",
+ " Moussa Sylla | \n",
+ " F | \n",
+ " 2 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 39 | \n",
+ " FC Schalke 04 | \n",
+ " Overall | \n",
+ " Soufiane El-Faouzi | \n",
+ " M | \n",
+ " 2 | \n",
+ " 7.20 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " FC Augsburg | \n",
+ " Overall | \n",
+ " Anton Kade | \n",
+ " F | \n",
+ " 1 | \n",
+ " 7.00 | \n",
+ "
\n",
+ " \n",
+ " | 40 | \n",
+ " FC Schalke 04 | \n",
+ " Overall | \n",
+ " Hasan Kuruçay | \n",
+ " D | \n",
+ " 2 | \n",
+ " 6.85 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " team category player_name position rating_count \\\n",
+ "14 FC Augsburg Bundesliga Fabian Rieder M 5 \n",
+ "15 FC Augsburg Bundesliga Anton Kade F 5 \n",
+ "16 FC Augsburg Bundesliga Finn Dahmen G 5 \n",
+ "17 FC Augsburg Bundesliga Noahkai Banks D 1 \n",
+ "18 FC Augsburg Bundesliga Arthur Chaves D 3 \n",
+ "0 FC Augsburg Overall Finn Dahmen G 1 \n",
+ "1 FC Augsburg Overall Kristijan Jakić M 1 \n",
+ "36 FC Schalke 04 Overall Edin Džeko F 2 \n",
+ "2 FC Augsburg Overall Noahkai Banks D 1 \n",
+ "3 FC Augsburg Overall Han-Noah Massengo M 1 \n",
+ "37 FC Schalke 04 Overall Dejan Ljubičić F 2 \n",
+ "38 FC Schalke 04 Overall Moussa Sylla F 2 \n",
+ "39 FC Schalke 04 Overall Soufiane El-Faouzi M 2 \n",
+ "4 FC Augsburg Overall Anton Kade F 1 \n",
+ "40 FC Schalke 04 Overall Hasan Kuruçay D 2 \n",
+ "\n",
+ " average_rating \n",
+ "14 7.52 \n",
+ "15 7.46 \n",
+ "16 7.44 \n",
+ "17 7.40 \n",
+ "18 7.20 \n",
+ "0 7.90 \n",
+ "1 7.70 \n",
+ "36 7.65 \n",
+ "2 7.50 \n",
+ "3 7.40 \n",
+ "37 7.20 \n",
+ "38 7.20 \n",
+ "39 7.20 \n",
+ "4 7.00 \n",
+ "40 6.85 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "### Predicted lineups"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### LigaInsider"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Augsburg** — formation **3-4-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**Schalke 04** — formation **3-4-3**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kickbase"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Augsburg** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Schalke 04** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### Kicker"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Augsburg** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Schalke 04** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "#### RotoWire"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Augsburg** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "**FC Schalke 04** — formation **3-4-2-1**"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/markdown": [
+ "Charts opened in one browser tab: `C:\\Users\\sidth\\AppData\\Local\\Temp\\kickbase_matchday_reports\\matchday_01_09_fc-augsburg-vs-fc-schalke-04.html`"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "for number, context in enumerate(fixture_context, start=1):\n",
+ " MATCH_FIGURES = []\n",
+ " fixture, key, odds = context['fixture'], context['key'], context['odds']\n",
+ " home, away = fixture['home_team'], fixture['away_team']\n",
+ " keys = {team_key(home), team_key(away)}\n",
+ " display(Markdown(f'---\\n## {number}. {home} vs {away}'))\n",
+ "\n",
+ " display(Markdown('### 1X2 odds and team expected points'))\n",
+ " if odds is None:\n",
+ " display(Markdown('> **Odds unavailable:** no valid FotMob market and no valid SofaScore fallback were saved for this fixture.'))\n",
+ " else:\n",
+ " odds_chart = pd.DataFrame([\n",
+ " {'outcome': home, 'decimal_odds': odds['home_odd']}, {'outcome': 'Draw', 'decimal_odds': odds['draw_odd']}, {'outcome': away, 'decimal_odds': odds['away_odd']},\n",
+ " ])\n",
+ " odds_chart['implied_chance'] = 1 / odds_chart['decimal_odds']\n",
+ " display(Markdown('**Source:** {} — {}'.format(context['odds_source'], odds['bookmaker'])))\n",
+ " queue_figure(px.bar(odds_chart, x='outcome', y='implied_chance', text='decimal_odds', hover_data={'decimal_odds': ':.2f'}, title='1X2 implied chance (higher means lower odds)', labels={'implied_chance': 'Implied chance', 'decimal_odds': 'Decimal odds'}).update_yaxes(tickformat='.0%'))\n",
+ " display(pd.DataFrame([{'team': home, 'expected match points': round(odds['home_points'], 3)}, {'team': away, 'expected match points': round(odds['away_points'], 3)}]))\n",
+ "\n",
+ " display(Markdown('### League position'))\n",
+ " position_rows = standings_rows(standings, keys)\n",
+ " if position_rows:\n",
+ " positions = pd.DataFrame(position_rows)\n",
+ " display(positions)\n",
+ " else:\n",
+ " display(Markdown('> League-position snapshot is unavailable for one or both teams.'))\n",
+ "\n",
+ " display(Markdown('### Player expected points'))\n",
+ " if expected_players is None:\n",
+ " display(Markdown(f'> **Omitted:** {expected_note}'))\n",
+ " else:\n",
+ " player_rows = expected_players[expected_players['teamId'].map(lambda value: KB_TEAM_ID_TO_KEY.get(int(value)) if pd.notna(value) else None).isin(keys)].copy()\n",
+ " player_rows['team'] = player_rows['teamId'].map(lambda value: KB_TEAM_ID_TO_KEY.get(int(value)) if pd.notna(value) else None)\n",
+ " team_labels = {team_key(home): home, team_key(away): away}\n",
+ " player_rows['team_display'] = player_rows['team'].map(team_labels)\n",
+ " player_rows = player_rows.sort_values(['team_display', 'score'], ascending=[True, False]).groupby('team_display', group_keys=False).head(5)\n",
+ " queue_figure(px.bar(player_rows.sort_values('score'), x='score', y='name', color='team_display', facet_col='team_display', orientation='h', title='Top five generated player scores for each team', labels={'score': 'Expected-points score', 'team_display': 'Team'}))\n",
+ " display(player_rows[['name', 'team_display', 'position', 'expected_match_points', 'starting_chance', 'score']])\n",
+ "\n",
+ " display(Markdown('### Recent form and last-five match data'))\n",
+ " all_form = []\n",
+ " for name, key_value in ((home, team_key(home)), (away, team_key(away))):\n",
+ " for category in ('overall', 'bundesliga'):\n",
+ " all_form.extend(form_rows(form, key_value, category))\n",
+ " if all_form:\n",
+ " form_frame = pd.DataFrame(all_form)\n",
+ " queue_figure(px.scatter(form_frame, x='match_number', y='category', color='result', text='result', facet_row='team', category_orders={'category': ['overall', 'bundesliga']}, color_discrete_map=RESULT_COLOURS, hover_data={'opponent': True, 'score': True, 'date': True, 'competition': True, 'home_team': False, 'away_team': False, 'home_score': False, 'away_score': False}, title='Last five results (oldest to newest)', labels={'match_number': 'Match order', 'category': 'Competition scope', 'opponent': 'Opponent', 'score': 'Score'}, height=420).update_traces(marker_size=18).update_xaxes(dtick=1))\n",
+ " display(form_frame[['category', 'team', 'date', 'competition', 'home_team', 'home_score', 'away_score', 'away_team', 'result']])\n",
+ " else:\n",
+ " display(Markdown('> Recent-form snapshot is unavailable for one or both teams.'))\n",
+ "\n",
+ " display(Markdown('### Upcoming fixtures'))\n",
+ " next_rows = upcoming_rows(upcoming, team_key(home)) + upcoming_rows(upcoming, team_key(away))\n",
+ " if next_rows:\n",
+ " display(pd.DataFrame(next_rows))\n",
+ " else:\n",
+ " display(Markdown('> No saved upcoming-match snapshot exactly matches this requested matchday.'))\n",
+ "\n",
+ " display(Markdown('### Best recent SofaScore form'))\n",
+ " ratings_frame = pd.DataFrame(rating_rows(ratings, keys))\n",
+ " if not ratings_frame.empty:\n",
+ " ratings_frame = ratings_frame.sort_values(['category', 'average_rating'], ascending=[True, False]).groupby(['team', 'category'], group_keys=False).head(5)\n",
+ " ratings_frame['player_label'] = ratings_frame['player_name'] + ' — ' + ratings_frame['category']\n",
+ " rating_figure = px.bar(ratings_frame.sort_values('average_rating'), x='average_rating', y='player_label', color='category', facet_row='team', orientation='h', hover_data=['position', 'rating_count'], title='Top SofaScore average ratings by team', labels={'average_rating': 'Average rating', 'player_label': 'Player and scope', 'category': 'Scope'}, height=620)\n",
+ " rating_figure.update_yaxes(showticklabels=True)\n",
+ " queue_figure(rating_figure)\n",
+ " display(ratings_frame[['team', 'category', 'player_name', 'position', 'rating_count', 'average_rating']])\n",
+ " else:\n",
+ " display(Markdown('> No player-rating snapshot is compatible with the selected form snapshot.'))\n",
+ "\n",
+ " display(Markdown('### Predicted lineups'))\n",
+ " for source_name, _, _ in LINEUP_SOURCES:\n",
+ " match = lineups[source_name]['matches'].get(key)\n",
+ " display(Markdown(f'#### {source_name}'))\n",
+ " if match is None:\n",
+ " display(Markdown('> **Omitted:** {}'.format(lineups[source_name]['note'])))\n",
+ " continue\n",
+ " for side in ('home', 'away'):\n",
+ " team = match.get(side, {})\n",
+ " players = team.get('players', []) if isinstance(team, dict) else []\n",
+ " starters = [player for player in players if isinstance(player, dict) and player.get('starting_probability_rank', 1) == 1]\n",
+ " if source_name == 'RotoWire':\n",
+ " starters = rotowire_coordinates(starters)\n",
+ " kicker_bench = []\n",
+ " if source_name == 'Kicker' and isinstance(team, dict):\n",
+ " raw_bench = team.get('kicker_details', {}).get('bench', {}).get('players', [])\n",
+ " kicker_bench = [player for player in raw_bench if isinstance(player, dict)] if isinstance(raw_bench, list) else []\n",
+ " backups = [player for player in players if isinstance(player, dict) and player.get('starting_probability_rank', 1) > 1]\n",
+ " label = team.get('team_name', side.title()) if isinstance(team, dict) else side.title()\n",
+ " shape = formation(starters)\n",
+ " display(Markdown(f'**{label}**' + (f' — formation **{shape}**' if shape else ' — formation not provided')))\n",
+ " starter_frame = pd.DataFrame(starters)\n",
+ " has_formation_coordinates = not starter_frame.empty and {'formation_row', 'slot_index'}.issubset(starter_frame.columns) and starter_frame['formation_row'].notna().all() and starter_frame['slot_index'].notna().all()\n",
+ " if has_formation_coordinates:\n",
+ " pass\n",
+ " elif not starter_frame.empty:\n",
+ " display(starter_frame[[column for column in ('displayed_name', 'full_name', 'position', 'injury_status') if column in starter_frame.columns]])\n",
+ " display(Markdown('> This provider does not expose formation coordinates.'))\n",
+ " else:\n",
+ " display(Markdown('> No predicted starters were saved.'))\n",
+ " primary_by_slot = {(player.get('formation_row'), player.get('slot_index')): player.get('displayed_name') or player.get('full_name') for player in starters}\n",
+ " backup_rows = []\n",
+ " for player in backups:\n",
+ " alternative_to = primary_by_slot.get((player.get('formation_row'), player.get('slot_index')))\n",
+ " backup_rows.append({'type': 'Alternative', 'player': player.get('displayed_name') or player.get('full_name'), 'Alternative to': alternative_to or 'Unspecified starter', 'position': player.get('position'), 'injury_status': player.get('injury_status')})\n",
+ " if source_name == 'Kicker':\n",
+ " for player in kicker_bench:\n",
+ " if isinstance(player, dict):\n",
+ " backup_rows.append({'type': 'Bench', 'player': player.get('displayed_name') or player.get('full_name'), 'Alternative to': '—', 'position': player.get('position'), 'injury_status': player.get('injury_status')})\n",
+ " if has_formation_coordinates:\n",
+ " queue_figure(formation_figure(starters, source_name, label, backup_rows))\n",
+ " report_path = open_match_report(matchday, number, f'{home} vs {away}', MATCH_FIGURES)\n",
+ " if report_path is not None:\n",
+ " display(Markdown(f'Charts opened in one browser tab: `{report_path}`'))\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.14.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_124739_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_124739_+0200.csv
deleted file mode 100644
index 1f489e0..0000000
--- a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_124739_+0200.csv
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-60,18,Dominik,Kohr,10467001.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,197.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,125782.0,125782.0,154324.0,228965.0,1377128.0,4045683.0,8.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,17.426471
-3543,2,Nathaniel,Brown,29388219.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,118968.0,118968.0,107021.0,65342.0,615612.0,2280283.0,7.26,2.382104545335327,1.0,1.0,1.0,0.0,1.0,17.294079
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-1246,43,Willi,Orban,31396500.0,131.0,33.0,33.0,33.0,193712.0,4323.0,0,2,https://kickbase.b-cdn.net/content/file/1f7999ae3a674c74ac9b8d4f00ed1028.png,4.0,1,137.0,,"[{""hasPlayed"": true, ""points"": 110}, {""hasPlayed"": true, ""points"": 313}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 131}, {""hasPlayed"": false, ""points"": null}]",2,Willi Orban,35234.0,35234.0,40210.0,40817.0,314744.0,1806852.0,7.8,2.097664543524416,1.0,1.0,1.0,0.0,1.0,16.361783
-15211,3,Joane,Gadou,24871710.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/48c386df17604a3cbfeaffff6bdffae7.png,22.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Joane Gadou,148351.0,148351.0,137140.0,137321.0,1127556.0,5088177.0,6.8,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.993183
-1639,18,Nadiem,Amiri,33735560.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,103.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,95594.0,95594.0,95066.0,95109.0,726550.0,2898080.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-6080,2,Aleksandar,Pavlović,32438401.0,119.0,24.0,24.0,16.0,98316.0,2844.0,0,3,https://kickbase.b-cdn.net/content/file/958c27ad7cf943a8b9e380f72fdc5b4f.png,45.0,1,87.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 43}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": false, ""points"": null}]",1,Aleksandar Pavlović,76709.0,76709.0,76063.0,69311.0,567395.0,2728865.0,7.04,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.770016
-11008,43,Ezechiel,Banzuzi,8349668.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,104.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,323577.0,323577.0,328182.0,302789.0,2211617.0,3836539.0,7.3,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.312951
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125445_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125445_+0200.csv
deleted file mode 100644
index 9477cde..0000000
--- a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125445_+0200.csv
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-3543,2,Nathaniel,Brown,29388219.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,118968.0,118968.0,107021.0,65342.0,615612.0,2280283.0,7.26,2.382104545335327,1.0,1.0,1.0,0.0,1.0,17.294079
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-2141,43,Ridle ,Baku,17851318.0,102.0,32.0,32.0,28.0,162435.0,3278.0,0,2,https://kickbase.b-cdn.net/content/file/938a124759354a928af165b155e6925a.png,17.0,2,183.0,,"[{""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 224}, {""hasPlayed"": true, ""points"": 124}]",2,Ridle Baku,15978.0,15978.0,-97332.0,-162153.0,-790053.0,280167.0,7.37,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.459788
-1639,18,Nadiem,Amiri,33735560.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,103.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,95594.0,95594.0,95066.0,95109.0,726550.0,2898080.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-4596,43,Brajan,Gruda,19603467.0,98.0,13.0,13.0,8.0,49007.0,1270.0,0,3,https://kickbase.b-cdn.net/content/file/fc98ceda9d134bd09d5526a600465611.png,10.0,1,64.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": true, ""points"": 89}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 48}]",1,Brajan Gruda,255323.0,255323.0,258092.0,255016.0,1840150.0,7292323.0,7.5,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.732484
-4199,7,Aleix,García,38852734.0,142.0,33.0,33.0,31.0,175200.0,4684.0,0,3,https://kickbase.b-cdn.net/content/file/3de0ab19c54f4523a5bf21f686259db0.png,24.0,1,120.0,,"[{""hasPlayed"": true, ""points"": 229}, {""hasPlayed"": true, ""points"": 121}, {""hasPlayed"": true, ""points"": 214}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 181}]",1,Aleix García,75157.0,75157.0,82462.0,80667.0,645449.0,3079625.0,7.6,2.040910253132191,1.0,1.0,1.0,0.0,1.0,15.510918
-2846,7,Malik,Tillman,13303012.0,82.0,29.0,29.0,18.0,111183.0,2380.0,0,3,https://kickbase.b-cdn.net/content/file/04966a0af0e2477db734c91fdd98d4e1.png,10.0,1,178.0,,"[{""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": 6}, {""hasPlayed"": true, ""points"": 16}, {""hasPlayed"": true, ""points"": 4}, {""hasPlayed"": true, ""points"": -13}]",2,Malik Tillman,255041.0,255041.0,232278.0,165460.0,541453.0,-2088500.0,6.9,2.040910253132191,1.0,1.0,1.0,0.0,1.0,14.082281
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-3304,5,Igor,Matanović,19299092.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,108.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,146084.0,146084.0,138732.0,159425.0,1129848.0,4911359.0,7.8,1.6985668387422834,1.0,1.0,1.0,0.0,1.0,13.248821
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125710_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125710_+0200.csv
deleted file mode 100644
index 9536c9e..0000000
--- a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_125710_+0200.csv
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-60,18,Dominik,Kohr,10467001.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,197.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,125782.0,125782.0,154324.0,228965.0,1377128.0,4045683.0,8.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,17.426471
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-2141,43,Ridle ,Baku,17851318.0,102.0,32.0,32.0,28.0,162435.0,3278.0,0,2,https://kickbase.b-cdn.net/content/file/938a124759354a928af165b155e6925a.png,17.0,2,183.0,,"[{""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 224}, {""hasPlayed"": true, ""points"": 124}]",2,Ridle Baku,15978.0,15978.0,-97332.0,-162153.0,-790053.0,280167.0,7.37,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.459788
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-11008,43,Ezechiel,Banzuzi,8349668.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,104.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,323577.0,323577.0,328182.0,302789.0,2211617.0,3836539.0,7.3,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.312951
-2846,7,Malik,Tillman,13303012.0,82.0,29.0,29.0,18.0,111183.0,2380.0,0,3,https://kickbase.b-cdn.net/content/file/04966a0af0e2477db734c91fdd98d4e1.png,10.0,1,178.0,,"[{""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": 6}, {""hasPlayed"": true, ""points"": 16}, {""hasPlayed"": true, ""points"": 4}, {""hasPlayed"": true, ""points"": -13}]",2,Malik Tillman,255041.0,255041.0,232278.0,165460.0,541453.0,-2088500.0,6.9,2.040910253132191,1.0,1.0,1.0,0.0,1.0,14.082281
-3209,5,Yannik,Engelhardt,10779698.0,64.0,31.0,31.0,29.0,162513.0,1970.0,0,3,https://kickbase.b-cdn.net/content/file/026c80a428ef428ba28a09167853739e.png,16.0,1,182.0,,"[{""hasPlayed"": true, ""points"": 135}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 86}, {""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": -10}]",2,Yannik Engelhardt,104591.0,104591.0,121682.0,133085.0,1337247.0,7033262.0,7.2,1.6985668387422834,1.0,1.0,1.0,0.0,1.0,12.229681
-3124,14,Patrick,Wimmer,7364887.0,59.0,25.0,25.0,21.0,105411.0,1466.0,0,3,https://kickbase.b-cdn.net/content/file/1ffbdbd2f14848519596bb5fc54bbec5.png,8.0,1,199.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 73}, {""hasPlayed"": true, ""points"": 55}, {""hasPlayed"": true, ""points"": 204}]",2,Patrick Wimmer,386961.0,386961.0,263235.0,-47320.0,-107951.0,204559.0,7.33,1.555984555984556,1.0,1.0,1.0,0.0,1.0,11.405367
-1809,13,Marius,Wolf,3585560.0,24.0,29.0,29.0,12.0,69269.0,686.0,0,3,https://kickbase.b-cdn.net/content/file/a1f80afaec424464a483185498e81a2e.png,27.0,1,191.0,,"[{""hasPlayed"": true, ""points"": 8}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 94}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 15}]",2,Marius Wolf,416041.0,416041.0,403685.0,380241.0,2727007.0,1350012.0,6.5,1.614334470989761,1.0,1.0,1.0,0.0,1.0,10.493174
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_130825_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_130825_+0200.csv
deleted file mode 100644
index 7a78faa..0000000
--- a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_130825_+0200.csv
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-14917,40,Zeno,Van den Bosch,13456741.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/f19174a181cb4b18a6fb28116d085029.png,4.0,2,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Zeno Van den Bosch,-37997.0,-37997.0,-14365.0,19756.0,362825.0,3021875.0,7.8,1.4280701754385965,1.0,1.0,1.0,0.0,1.0,11.138947
-15589,4,,Otávio,9374748.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/29d28defc06541cdb2d6e020dc443ca1.png,5.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Otávio,344646.0,344646.0,350148.0,300724.0,2022899.0,9374748.0,7.4,1.3017543859649123,1.0,1.0,1.0,0.0,1.0,9.632982
-11008,43,Ezechiel,Banzuzi,8349668.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,104.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,323577.0,323577.0,328182.0,302789.0,2211617.0,3836539.0,7.3,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.312951
-2846,7,Malik,Tillman,13303012.0,82.0,29.0,29.0,18.0,111183.0,2380.0,0,3,https://kickbase.b-cdn.net/content/file/04966a0af0e2477db734c91fdd98d4e1.png,10.0,1,178.0,,"[{""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": 6}, {""hasPlayed"": true, ""points"": 16}, {""hasPlayed"": true, ""points"": 4}, {""hasPlayed"": true, ""points"": -13}]",2,Malik Tillman,255041.0,255041.0,232278.0,165460.0,541453.0,-2088500.0,6.9,2.040910253132191,1.0,1.0,1.0,0.0,1.0,14.082281
-11556,13,Han-Noah,Massengo,9899475.0,59.0,33.0,33.0,29.0,158322.0,1949.0,0,3,https://kickbase.b-cdn.net/content/file/d5c086e505984d7ba4c7e0af23d1a901.png,4.0,1,196.0,,"[{""hasPlayed"": true, ""points"": -5}, {""hasPlayed"": true, ""points"": 22}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 64}, {""hasPlayed"": true, ""points"": 107}]",1,Han-Noah Massengo,43223.0,43223.0,21108.0,21730.0,353467.0,4423333.0,7.4,1.614334470989761,1.0,1.0,1.0,0.0,1.0,11.946075
-3124,14,Patrick,Wimmer,7364887.0,59.0,25.0,25.0,21.0,105411.0,1466.0,0,3,https://kickbase.b-cdn.net/content/file/1ffbdbd2f14848519596bb5fc54bbec5.png,8.0,1,199.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 73}, {""hasPlayed"": true, ""points"": 55}, {""hasPlayed"": true, ""points"": 204}]",2,Patrick Wimmer,386961.0,386961.0,263235.0,-47320.0,-107951.0,204559.0,7.33,1.555984555984556,1.0,1.0,1.0,0.0,1.0,11.405367
-7219,28,Ísak,Jóhannesson,9418752.0,48.0,31.0,31.0,21.0,119771.0,1473.0,0,3,https://kickbase.b-cdn.net/content/file/2922eb48335343ccb79b49b03af03818.png,8.0,1,156.0,,"[{""hasPlayed"": true, ""points"": -10}, {""hasPlayed"": true, ""points"": 59}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 7}, {""hasPlayed"": true, ""points"": 55}]",1,Ísak Jóhannesson,116882.0,116882.0,115820.0,125035.0,987615.0,4191768.0,9.3,1.1806949806949807,1.0,1.0,1.0,0.0,1.0,10.980463
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-3304,5,Igor,Matanović,19299092.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,108.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,146084.0,146084.0,138732.0,159425.0,1129848.0,4911359.0,7.8,1.6985668387422834,1.0,1.0,1.0,0.0,1.0,13.248821
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190737_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190737_+0200.csv
deleted file mode 100644
index 1f489e0..0000000
--- a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260825_110735_+0200_20260825_121320_+0200_20260825_190737_+0200.csv
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-60,18,Dominik,Kohr,10467001.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,197.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,125782.0,125782.0,154324.0,228965.0,1377128.0,4045683.0,8.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,17.426471
-3543,2,Nathaniel,Brown,29388219.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,118968.0,118968.0,107021.0,65342.0,615612.0,2280283.0,7.26,2.382104545335327,1.0,1.0,1.0,0.0,1.0,17.294079
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-1246,43,Willi,Orban,31396500.0,131.0,33.0,33.0,33.0,193712.0,4323.0,0,2,https://kickbase.b-cdn.net/content/file/1f7999ae3a674c74ac9b8d4f00ed1028.png,4.0,1,137.0,,"[{""hasPlayed"": true, ""points"": 110}, {""hasPlayed"": true, ""points"": 313}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 131}, {""hasPlayed"": false, ""points"": null}]",2,Willi Orban,35234.0,35234.0,40210.0,40817.0,314744.0,1806852.0,7.8,2.097664543524416,1.0,1.0,1.0,0.0,1.0,16.361783
-15211,3,Joane,Gadou,24871710.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/48c386df17604a3cbfeaffff6bdffae7.png,22.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Joane Gadou,148351.0,148351.0,137140.0,137321.0,1127556.0,5088177.0,6.8,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.993183
-1639,18,Nadiem,Amiri,33735560.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,103.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,95594.0,95594.0,95066.0,95109.0,726550.0,2898080.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-6080,2,Aleksandar,Pavlović,32438401.0,119.0,24.0,24.0,16.0,98316.0,2844.0,0,3,https://kickbase.b-cdn.net/content/file/958c27ad7cf943a8b9e380f72fdc5b4f.png,45.0,1,87.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 43}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": false, ""points"": null}]",1,Aleksandar Pavlović,76709.0,76709.0,76063.0,69311.0,567395.0,2728865.0,7.04,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.770016
-11008,43,Ezechiel,Banzuzi,8349668.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,104.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,323577.0,323577.0,328182.0,302789.0,2211617.0,3836539.0,7.3,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.312951
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130344_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130344_+0200.csv
new file mode 100644
index 0000000..a98a9d7
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130344_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+1540,18,Danny,Da Costa,9308429.0,73.0,34.0,34.0,30.0,178678.0,2498.0,0,2,https://kickbase.b-cdn.net/content/file/d7479cd684eb4636932e2e5651e92411.png,21.0,2,268.0,,"[{""hasPlayed"": true, ""points"": 72}, {""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 91}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 86}]",3,Danny Da Costa,-194065.0,-194065.0,-201154.0,-175018.0,-277047.0,2530127.0,8.1,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,15.846465
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+6080,2,Aleksandar,Pavlović,32570412.0,119.0,24.0,24.0,16.0,98316.0,2844.0,0,3,https://kickbase.b-cdn.net/content/file/958c27ad7cf943a8b9e380f72fdc5b4f.png,45.0,1,87.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 43}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": false, ""points"": null}]",1,Aleksandar Pavlović,62471.0,62471.0,69540.0,76709.0,507935.0,2716561.0,7.04,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.98506
+4199,7,Aleix,García,38996349.0,142.0,33.0,33.0,31.0,175200.0,4684.0,0,3,https://kickbase.b-cdn.net/content/file/3de0ab19c54f4523a5bf21f686259db0.png,24.0,1,120.0,,"[{""hasPlayed"": true, ""points"": 229}, {""hasPlayed"": true, ""points"": 121}, {""hasPlayed"": true, ""points"": 214}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 181}]",1,Aleix García,67853.0,67853.0,75762.0,75157.0,573849.0,3063032.0,7.6,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,15.528023
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130434_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130434_+0200.csv
new file mode 100644
index 0000000..6e33284
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130434_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+6080,2,Aleksandar,Pavlović,32570412.0,119.0,24.0,24.0,16.0,98316.0,2844.0,0,3,https://kickbase.b-cdn.net/content/file/958c27ad7cf943a8b9e380f72fdc5b4f.png,45.0,1,87.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 43}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": false, ""points"": null}]",1,Aleksandar Pavlović,62471.0,62471.0,69540.0,76709.0,507935.0,2716561.0,7.04,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.98506
+4199,7,Aleix,García,38996349.0,142.0,33.0,33.0,31.0,175200.0,4684.0,0,3,https://kickbase.b-cdn.net/content/file/3de0ab19c54f4523a5bf21f686259db0.png,24.0,1,120.0,,"[{""hasPlayed"": true, ""points"": 229}, {""hasPlayed"": true, ""points"": 121}, {""hasPlayed"": true, ""points"": 214}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 181}]",1,Aleix García,67853.0,67853.0,75762.0,75157.0,573849.0,3063032.0,7.6,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,15.528023
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+11556,13,Han-Noah,Massengo,10113144.0,59.0,33.0,33.0,29.0,158322.0,1949.0,0,3,https://kickbase.b-cdn.net/content/file/d5c086e505984d7ba4c7e0af23d1a901.png,4.0,1,192.0,,"[{""hasPlayed"": true, ""points"": -5}, {""hasPlayed"": true, ""points"": 22}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 64}, {""hasPlayed"": true, ""points"": 107}]",1,Han-Noah Massengo,115014.0,115014.0,98655.0,43223.0,397063.0,4290345.0,7.4,1.58530986993114,1.0,1.0,1.0,1.0,0.0,1.0,11.731293
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130827_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130827_+0200.csv
new file mode 100644
index 0000000..0955679
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_130827_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+3759,7,Miguel,Gutiérrez,21033862.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/86a6415d0ab240d780a37de359f3d327.png,3.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Miguel Gutiérrez,142459.0,142459.0,169109.0,169235.0,1140738.0,21033862.0,6.75,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,13.791336
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+4596,43,Brajan,Gruda,20088446.0,98.0,13.0,13.0,8.0,49007.0,1270.0,0,3,https://kickbase.b-cdn.net/content/file/fc98ceda9d134bd09d5526a600465611.png,10.0,1,63.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": true, ""points"": 89}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 48}]",1,Brajan Gruda,238580.0,238580.0,246399.0,255323.0,1783007.0,7373780.0,7.5,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.545361
+4199,7,Aleix,García,38996349.0,142.0,33.0,33.0,31.0,175200.0,4684.0,0,3,https://kickbase.b-cdn.net/content/file/3de0ab19c54f4523a5bf21f686259db0.png,24.0,1,120.0,,"[{""hasPlayed"": true, ""points"": 229}, {""hasPlayed"": true, ""points"": 121}, {""hasPlayed"": true, ""points"": 214}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 181}]",1,Aleix García,67853.0,67853.0,75762.0,75157.0,573849.0,3063032.0,7.6,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,15.528023
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131000_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131000_+0200.csv
new file mode 100644
index 0000000..b876bdd
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131000_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+1540,18,Danny,Da Costa,9308429.0,73.0,34.0,34.0,30.0,178678.0,2498.0,0,2,https://kickbase.b-cdn.net/content/file/d7479cd684eb4636932e2e5651e92411.png,21.0,2,268.0,,"[{""hasPlayed"": true, ""points"": 72}, {""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 91}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 86}]",3,Danny Da Costa,-194065.0,-194065.0,-201154.0,-175018.0,-277047.0,2530127.0,8.1,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,15.846465
+10115,3,Daniel,Svensson,16621441.0,82.0,33.0,33.0,27.0,162894.0,2705.0,0,2,https://kickbase.b-cdn.net/content/file/da063055c5d14c798dd8d7427fb2a48f.png,24.0,2,162.0,,"[{""hasPlayed"": true, ""points"": 151}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": -11}, {""hasPlayed"": true, ""points"": 27}, {""hasPlayed"": true, ""points"": 34}]",3,Daniel Svensson,23469.0,23469.0,-33135.0,-104336.0,-1274385.0,-2044044.0,6.95,2.3519386450788238,1.0,0.6896551724137931,1.0,1.0,0.0,0.9068965517241379,14.824107
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+3209,5,Yannik,Engelhardt,10934988.0,64.0,31.0,31.0,29.0,162513.0,1970.0,0,3,https://kickbase.b-cdn.net/content/file/026c80a428ef428ba28a09167853739e.png,16.0,1,180.0,,"[{""hasPlayed"": true, ""points"": 135}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 86}, {""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": -10}]",1,Yannik Engelhardt,61755.0,61755.0,93535.0,104591.0,952037.0,6725553.0,7.2,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,12.280885
+11556,13,Han-Noah,Massengo,10113144.0,59.0,33.0,33.0,29.0,158322.0,1949.0,0,3,https://kickbase.b-cdn.net/content/file/d5c086e505984d7ba4c7e0af23d1a901.png,4.0,1,192.0,,"[{""hasPlayed"": true, ""points"": -5}, {""hasPlayed"": true, ""points"": 22}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 64}, {""hasPlayed"": true, ""points"": 107}]",1,Han-Noah Massengo,115014.0,115014.0,98655.0,43223.0,397063.0,4290345.0,7.4,1.58530986993114,1.0,1.0,1.0,1.0,0.0,1.0,11.731293
+3124,14,Patrick,Wimmer,8149700.0,59.0,25.0,25.0,21.0,105411.0,1466.0,0,3,https://kickbase.b-cdn.net/content/file/a1e6985ea5b8487ca2db9c16a66eafe7.png,8.0,1,179.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 73}, {""hasPlayed"": true, ""points"": 55}, {""hasPlayed"": true, ""points"": 204}]",2,Patrick Wimmer,390379.0,390379.0,394434.0,386961.0,1010228.0,619632.0,7.33,1.555984555984556,1.0,1.0,1.0,1.0,0.0,1.0,11.405367
+10113,43,Tidiam,Gomis,5374444.0,23.0,18.0,18.0,2.0,25742.0,405.0,0,4,https://kickbase.b-cdn.net/content/file/6fdc632f20f64bac905749a9c2b23a86.png,27.0,1,75.0,,"[{""hasPlayed"": true, ""points"": -18}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 58}, {""hasPlayed"": false, ""points"": null}]",3,Tidiam Gomis,375324.0,375324.0,359219.0,304573.0,1170065.0,3173172.0,6.57,2.0727147495818166,0.6896551724137931,0.6896551724137931,1.0,1.0,0.0,0.7827586206896552,10.6594
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131159_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131159_+0200.csv
new file mode 100644
index 0000000..0b775b0
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131159_+0200.csv
@@ -0,0 +1,7 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+1246,43,Willi,Orban,31442247.0,131.0,33.0,33.0,33.0,193712.0,4323.0,0,2,https://kickbase.b-cdn.net/content/file/1f7999ae3a674c74ac9b8d4f00ed1028.png,4.0,1,137.0,,"[{""hasPlayed"": true, ""points"": 110}, {""hasPlayed"": true, ""points"": 313}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 131}, {""hasPlayed"": false, ""points"": null}]",2,Willi Orban,17884.0,17884.0,27863.0,35234.0,247509.0,1760857.0,7.8,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,16.167175
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+4199,7,Aleix,García,38996349.0,142.0,33.0,33.0,31.0,175200.0,4684.0,0,3,https://kickbase.b-cdn.net/content/file/3de0ab19c54f4523a5bf21f686259db0.png,24.0,1,120.0,,"[{""hasPlayed"": true, ""points"": 229}, {""hasPlayed"": true, ""points"": 121}, {""hasPlayed"": true, ""points"": 214}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 181}]",1,Aleix García,67853.0,67853.0,75762.0,75157.0,573849.0,3063032.0,7.6,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,15.528023
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131319_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131319_+0200.csv
new file mode 100644
index 0000000..05455bd
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_131319_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+3759,7,Miguel,Gutiérrez,21033862.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/86a6415d0ab240d780a37de359f3d327.png,3.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Miguel Gutiérrez,142459.0,142459.0,169109.0,169235.0,1140738.0,21033862.0,6.75,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,13.791336
+14917,40,Zeno,Van den Bosch,13151299.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/f19174a181cb4b18a6fb28116d085029.png,4.0,2,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Zeno Van den Bosch,-207126.0,-207126.0,-98316.0,-37997.0,-183712.0,2531514.0,7.8,1.4068136272545089,1.0,1.0,1.0,1.0,0.0,1.0,10.973146
+15589,4,,Otávio,10044435.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/29d28defc06541cdb2d6e020dc443ca1.png,5.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Otávio,328220.0,328220.0,341467.0,344646.0,2173007.0,10044435.0,7.4,1.322645290581162,1.0,1.0,1.0,1.0,0.0,1.0,9.787575
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+11556,13,Han-Noah,Massengo,10113144.0,59.0,33.0,33.0,29.0,158322.0,1949.0,0,3,https://kickbase.b-cdn.net/content/file/d5c086e505984d7ba4c7e0af23d1a901.png,4.0,1,192.0,,"[{""hasPlayed"": true, ""points"": -5}, {""hasPlayed"": true, ""points"": 22}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 64}, {""hasPlayed"": true, ""points"": 107}]",1,Han-Noah Massengo,115014.0,115014.0,98655.0,43223.0,397063.0,4290345.0,7.4,1.58530986993114,1.0,1.0,1.0,1.0,0.0,1.0,11.731293
+3124,14,Patrick,Wimmer,8149700.0,59.0,25.0,25.0,21.0,105411.0,1466.0,0,3,https://kickbase.b-cdn.net/content/file/a1e6985ea5b8487ca2db9c16a66eafe7.png,8.0,1,179.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 73}, {""hasPlayed"": true, ""points"": 55}, {""hasPlayed"": true, ""points"": 204}]",2,Patrick Wimmer,390379.0,390379.0,394434.0,386961.0,1010228.0,619632.0,7.33,1.555984555984556,1.0,1.0,1.0,1.0,0.0,1.0,11.405367
+7219,28,Ísak,Jóhannesson,9815158.0,48.0,31.0,31.0,21.0,119771.0,1473.0,0,3,https://kickbase.b-cdn.net/content/file/2922eb48335343ccb79b49b03af03818.png,8.0,1,150.0,,"[{""hasPlayed"": true, ""points"": -10}, {""hasPlayed"": true, ""points"": 59}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 7}, {""hasPlayed"": true, ""points"": 55}]",1,Ísak Jóhannesson,202458.0,202458.0,193948.0,116882.0,1068841.0,4831094.0,9.3,1.1806949806949807,1.0,1.0,1.0,1.0,0.0,1.0,10.980463
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_164023_+0200.csv b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_164023_+0200.csv
new file mode 100644
index 0000000..0955679
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_164023_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+3759,7,Miguel,Gutiérrez,21033862.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/86a6415d0ab240d780a37de359f3d327.png,3.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Miguel Gutiérrez,142459.0,142459.0,169109.0,169235.0,1140738.0,21033862.0,6.75,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,13.791336
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+4596,43,Brajan,Gruda,20088446.0,98.0,13.0,13.0,8.0,49007.0,1270.0,0,3,https://kickbase.b-cdn.net/content/file/fc98ceda9d134bd09d5526a600465611.png,10.0,1,63.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": true, ""points"": 89}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 48}]",1,Brajan Gruda,238580.0,238580.0,246399.0,255323.0,1783007.0,7373780.0,7.5,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.545361
+4199,7,Aleix,García,38996349.0,142.0,33.0,33.0,31.0,175200.0,4684.0,0,3,https://kickbase.b-cdn.net/content/file/3de0ab19c54f4523a5bf21f686259db0.png,24.0,1,120.0,,"[{""hasPlayed"": true, ""points"": 229}, {""hasPlayed"": true, ""points"": 121}, {""hasPlayed"": true, ""points"": 214}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 181}]",1,Aleix García,67853.0,67853.0,75762.0,75157.0,573849.0,3063032.0,7.6,2.0431608606557377,1.0,1.0,1.0,1.0,0.0,1.0,15.528023
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/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 b/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
deleted file mode 100644
index 1977295..0000000
--- a/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
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-1873,3,Gregor,Kobel,22268613.0,104.0,34.0,34.0,34.0,202740.0,3530.0,0,1,https://kickbase.b-cdn.net/content/file/f2d4753d2676442bb38580d0b59a6293.png,1.0,2,158.0,,"[{""hasPlayed"": true, ""points"": 154}, {""hasPlayed"": true, ""points"": 81}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 160}, {""hasPlayed"": true, ""points"": 65}]",1,Gregor Kobel,-153643.0,-153643.0,-160305.0,-158176.0,-715804.0,442252.0,6.8,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.993183
-3470,18,Anthony,Caci,10696369.0,54.0,10.0,10.0,6.0,35021.0,535.0,0,2,https://kickbase.b-cdn.net/content/file/5bb349b2622049a7aa73a59edcec1781.png,19.0,1,50.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 56}, {""hasPlayed"": true, ""points"": 25}, {""hasPlayed"": true, ""points"": -1}, {""hasPlayed"": true, ""points"": 112}]",1,Anthony Caci,141481.0,141481.0,138792.0,161073.0,1660781.0,5799043.0,8.1,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,16.040274
-1540,18,Danny,Da Costa,9703648.0,73.0,34.0,34.0,30.0,178678.0,2498.0,0,2,https://kickbase.b-cdn.net/content/file/d7479cd684eb4636932e2e5651e92411.png,21.0,2,257.0,,"[{""hasPlayed"": true, ""points"": 72}, {""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 91}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 86}]",3,Danny Da Costa,-175018.0,-175018.0,-10292.0,69860.0,406067.0,2788317.0,8.1,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,16.040274
-2141,43,Ridle ,Baku,17851318.0,102.0,32.0,32.0,28.0,162435.0,3278.0,0,2,https://kickbase.b-cdn.net/content/file/938a124759354a928af165b155e6925a.png,17.0,2,183.0,,"[{""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 224}, {""hasPlayed"": true, ""points"": 124}]",2,Ridle Baku,15978.0,15978.0,-97332.0,-162153.0,-790053.0,280167.0,7.37,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.459788
-2232,18,Philipp,Mwene,8581551.0,49.0,29.0,29.0,24.0,136771.0,1428.0,0,2,https://kickbase.b-cdn.net/content/file/275de3be8348462b85588eaa3c89e4b3.png,2.0,1,166.0,,"[{""hasPlayed"": true, ""points"": 181}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 233}, {""hasPlayed"": true, ""points"": 16}, {""hasPlayed"": true, ""points"": 57}]",1,Philipp Mwene,267335.0,267335.0,254531.0,227042.0,1024355.0,2883341.0,7.2,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,14.258021
-8329,2,Michael,Olise,64815120.0,225.0,32.0,32.0,23.0,154488.0,7185.0,0,3,https://kickbase.b-cdn.net/content/file/2d1bffc491014bb582c5d1c622b0ee37.png,17.0,1,110.0,,"[{""hasPlayed"": true, ""points"": 81}, {""hasPlayed"": true, ""points"": 334}, {""hasPlayed"": true, ""points"": 290}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 152}]",1,Michael Olise,23531.0,23531.0,26008.0,26065.0,193889.0,1061959.0,7.8,2.382104545335327,1.0,1.0,1.0,0.0,1.0,18.580415
-3069,3,Felix,Nmecha,27176066.0,94.0,29.0,29.0,25.0,141393.0,2730.0,0,3,https://kickbase.b-cdn.net/content/file/f83b3a24df594aaf81be1d58da773656.png,8.0,1,100.0,,"[{""hasPlayed"": true, ""points"": 126}, {""hasPlayed"": true, ""points"": 14}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Felix Nmecha,100847.0,100847.0,104846.0,112371.0,823568.0,5282545.0,6.78,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.946144
-4596,43,Brajan,Gruda,19603467.0,98.0,13.0,13.0,8.0,49007.0,1270.0,0,3,https://kickbase.b-cdn.net/content/file/fc98ceda9d134bd09d5526a600465611.png,10.0,1,64.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": true, ""points"": 89}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 48}]",1,Brajan Gruda,255323.0,255323.0,258092.0,255016.0,1840150.0,7292323.0,7.5,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.732484
-9507,43,Antonio,Nusa,25827174.0,91.0,31.0,31.0,24.0,129764.0,2835.0,0,3,https://kickbase.b-cdn.net/content/file/9a7ea9c911e04f9e9cf0fa6c4b57ca54.png,7.0,1,109.0,,"[{""hasPlayed"": true, ""points"": 20}, {""hasPlayed"": true, ""points"": 42}, {""hasPlayed"": true, ""points"": 25}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 265}]",1,Antonio Nusa,61396.0,61396.0,65803.0,69215.0,494974.0,3823836.0,7.2,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.103185
-2846,7,Malik,Tillman,13303012.0,82.0,29.0,29.0,18.0,111183.0,2380.0,0,3,https://kickbase.b-cdn.net/content/file/04966a0af0e2477db734c91fdd98d4e1.png,10.0,1,178.0,,"[{""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": 6}, {""hasPlayed"": true, ""points"": 16}, {""hasPlayed"": true, ""points"": 4}, {""hasPlayed"": true, ""points"": -13}]",2,Malik Tillman,255041.0,255041.0,232278.0,165460.0,541453.0,-2088500.0,6.9,2.040910253132191,1.0,1.0,1.0,0.0,1.0,14.082281
-1920,3,Serhou,Guirassy,29675533.0,102.0,33.0,33.0,27.0,151810.0,3356.0,0,4,https://kickbase.b-cdn.net/content/file/f60de765e2e34fce8747b78399dca305.png,9.0,1,113.0,,"[{""hasPlayed"": true, ""points"": 155}, {""hasPlayed"": true, ""points"": 134}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 187}, {""hasPlayed"": true, ""points"": 101}]",2,Serhou Guirassy,80352.0,80352.0,81761.0,93874.0,715153.0,3159986.0,6.58,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.475756
diff --git a/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 b/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
deleted file mode 100644
index 5432929..0000000
--- a/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
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-8227,43,Maarten,Vandevoordt,16440159.0,109.0,12.0,12.0,11.0,69295.0,1313.0,0,1,https://kickbase.b-cdn.net/content/file/1aa808600ddb4c5b9883e7caedba5966.png,26.0,1,79.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 77}, {""hasPlayed"": true, ""points"": 87}, {""hasPlayed"": true, ""points"": 96}, {""hasPlayed"": true, ""points"": 135}]",1,Maarten Vandevoordt,116643.0,116643.0,131229.0,133397.0,993559.0,4597617.0,7.03,2.097664543524416,1.0,1.0,1.0,0.0,1.0,14.746582
-173,2,Jonathan,Tah,37034151.0,127.0,28.0,28.0,23.0,135209.0,3559.0,0,2,https://kickbase.b-cdn.net/content/file/cd9c5cb89a074d1ea56f7d952e5074e4.png,4.0,1,96.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 53}, {""hasPlayed"": true, ""points"": 84}, {""hasPlayed"": true, ""points"": 59}, {""hasPlayed"": false, ""points"": null}]",1,Jonathan Tah,2336.0,2336.0,5474.0,10622.0,192144.0,1626924.0,6.94,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.531806
-1704,3,Waldemar,Anton,34065334.0,126.0,32.0,32.0,32.0,190794.0,4034.0,0,2,https://kickbase.b-cdn.net/content/file/5cbbbb34725b43dba3f7f4f6835b98f0.png,3.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 156}, {""hasPlayed"": true, ""points"": 123}, {""hasPlayed"": true, ""points"": 40}, {""hasPlayed"": true, ""points"": 153}, {""hasPlayed"": true, ""points"": 133}]",1,Waldemar Anton,23629.0,23629.0,28474.0,33240.0,274482.0,1839566.0,6.9,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,16.228377
-10115,3,Daniel,Svensson,16631107.0,82.0,33.0,33.0,27.0,162894.0,2705.0,0,2,https://kickbase.b-cdn.net/content/file/da063055c5d14c798dd8d7427fb2a48f.png,24.0,2,162.0,,"[{""hasPlayed"": true, ""points"": 151}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": -11}, {""hasPlayed"": true, ""points"": 27}, {""hasPlayed"": true, ""points"": 34}]",3,Daniel Svensson,-104336.0,-104336.0,-178990.0,-378731.0,-1699875.0,-1932221.0,6.95,2.3519386450788238,1.0,0.6896551724137931,1.0,0.0,0.8836206896551724,14.44364
-3759,7,Miguel,Gutiérrez,20722294.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/86a6415d0ab240d780a37de359f3d327.png,3.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Miguel Gutiérrez,169235.0,169235.0,167272.0,162520.0,1198179.0,20722294.0,6.75,2.040910253132191,1.0,1.0,1.0,0.0,1.0,13.776144
-1685,2,Joshua,Kimmich,59848908.0,186.0,29.0,29.0,24.0,151968.0,5391.0,0,3,https://kickbase.b-cdn.net/content/file/b41a70e2188a4c72aa165cfc7606c3e9.png,6.0,1,90.0,,"[{""hasPlayed"": true, ""points"": 317}, {""hasPlayed"": true, ""points"": 238}, {""hasPlayed"": true, ""points"": 83}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 215}]",1,Joshua Kimmich,15371.0,15371.0,16698.0,18958.0,145262.0,832489.0,7.4,2.382104545335327,1.0,1.0,1.0,0.0,1.0,17.627574
-8307,18,Kaishu,Sano,16097155.0,83.0,34.0,34.0,34.0,203515.0,2817.0,0,3,https://kickbase.b-cdn.net/content/file/5d056e6175064f30b16047761d382a84.png,6.0,1,174.0,,"[{""hasPlayed"": true, ""points"": 115}, {""hasPlayed"": true, ""points"": 55}, {""hasPlayed"": true, ""points"": 88}, {""hasPlayed"": true, ""points"": 149}, {""hasPlayed"": true, ""points"": 90}]",1,Kaishu Sano,151515.0,151515.0,153266.0,166542.0,1209726.0,4117899.0,7.4,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,14.654078
-6176,43,Nicolas,Seiwald,17714975.0,86.0,33.0,33.0,31.0,174575.0,2839.0,0,3,https://kickbase.b-cdn.net/content/file/5320dfb79fb348369e61599e552840b0.png,13.0,1,160.0,,"[{""hasPlayed"": true, ""points"": 44}, {""hasPlayed"": true, ""points"": 20}, {""hasPlayed"": true, ""points"": 60}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 115}]",1,Nicolas Seiwald,137375.0,137375.0,129121.0,129352.0,1062795.0,4890341.0,6.93,2.097664543524416,1.0,1.0,1.0,0.0,1.0,14.536815
-2476,18,Jae-Sung,Lee,11268142.0,65.0,28.0,28.0,26.0,141332.0,1824.0,0,3,https://kickbase.b-cdn.net/content/file/4958ca742c82430a89447e10efb492a9.png,7.0,1,161.0,,"[{""hasPlayed"": true, ""points"": 43}, {""hasPlayed"": true, ""points"": -22}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Jae-Sung Lee,179661.0,179661.0,175756.0,177547.0,1468438.0,5088882.0,6.7,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,13.267881
-2646,18,Sheraldo,Becker,14656968.0,76.0,14.0,14.0,11.0,61084.0,1065.0,0,4,https://kickbase.b-cdn.net/content/file/e279d94dff1f46ea8a7f16ea6656528c.png,23.0,1,72.0,,"[{""hasPlayed"": true, ""points"": 115}, {""hasPlayed"": true, ""points"": 114}, {""hasPlayed"": true, ""points"": 120}, {""hasPlayed"": true, ""points"": 136}, {""hasPlayed"": true, ""points"": 20}]",2,Sheraldo Becker,146998.0,146998.0,144072.0,150914.0,1168168.0,4533463.0,6.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,13.465909
-10113,43,Tidiam,Gomis,4639901.0,23.0,18.0,18.0,2.0,25742.0,405.0,0,4,https://kickbase.b-cdn.net/content/file/6fdc632f20f64bac905749a9c2b23a86.png,27.0,1,87.0,,"[{""hasPlayed"": true, ""points"": -18}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 58}, {""hasPlayed"": false, ""points"": null}]",3,Tidiam Gomis,304573.0,304573.0,180176.0,69949.0,302482.0,2953977.0,6.57,2.097664543524416,0.8113590263691683,0.6896551724137931,1.0,0.0,0.7893002028397567,10.877864
diff --git a/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 b/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
deleted file mode 100644
index 1f489e0..0000000
--- a/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
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-60,18,Dominik,Kohr,10467001.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,197.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,125782.0,125782.0,154324.0,228965.0,1377128.0,4045683.0,8.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,17.426471
-3543,2,Nathaniel,Brown,29388219.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,118968.0,118968.0,107021.0,65342.0,615612.0,2280283.0,7.26,2.382104545335327,1.0,1.0,1.0,0.0,1.0,17.294079
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-1246,43,Willi,Orban,31396500.0,131.0,33.0,33.0,33.0,193712.0,4323.0,0,2,https://kickbase.b-cdn.net/content/file/1f7999ae3a674c74ac9b8d4f00ed1028.png,4.0,1,137.0,,"[{""hasPlayed"": true, ""points"": 110}, {""hasPlayed"": true, ""points"": 313}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 131}, {""hasPlayed"": false, ""points"": null}]",2,Willi Orban,35234.0,35234.0,40210.0,40817.0,314744.0,1806852.0,7.8,2.097664543524416,1.0,1.0,1.0,0.0,1.0,16.361783
-15211,3,Joane,Gadou,24871710.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/48c386df17604a3cbfeaffff6bdffae7.png,22.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Joane Gadou,148351.0,148351.0,137140.0,137321.0,1127556.0,5088177.0,6.8,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.993183
-1639,18,Nadiem,Amiri,33735560.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,103.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,95594.0,95594.0,95066.0,95109.0,726550.0,2898080.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-6080,2,Aleksandar,Pavlović,32438401.0,119.0,24.0,24.0,16.0,98316.0,2844.0,0,3,https://kickbase.b-cdn.net/content/file/958c27ad7cf943a8b9e380f72fdc5b4f.png,45.0,1,87.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 43}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": false, ""points"": null}]",1,Aleksandar Pavlović,76709.0,76709.0,76063.0,69311.0,567395.0,2728865.0,7.04,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.770016
-11008,43,Ezechiel,Banzuzi,8349668.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,104.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,323577.0,323577.0,328182.0,302789.0,2211617.0,3836539.0,7.3,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.312951
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
diff --git a/outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_124906_+0200.csv b/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_1_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv
similarity index 100%
rename from outputs/optimized_squad/optimized_squad_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_124906_+0200.csv
rename to outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_1_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv
diff --git a/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 b/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
deleted file mode 100644
index 4915bba..0000000
--- a/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
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-237,2,Manuel,Neuer,13565866.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,153.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,92933.0,92933.0,83089.0,76563.0,705494.0,1850928.0,6.93,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.507984
-60,18,Dominik,Kohr,10467001.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,197.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,125782.0,125782.0,154324.0,228965.0,1377128.0,4045683.0,8.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,17.426471
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-173,2,Jonathan,Tah,37034151.0,127.0,28.0,28.0,23.0,135209.0,3559.0,0,2,https://kickbase.b-cdn.net/content/file/cd9c5cb89a074d1ea56f7d952e5074e4.png,4.0,1,96.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 53}, {""hasPlayed"": true, ""points"": 84}, {""hasPlayed"": true, ""points"": 59}, {""hasPlayed"": false, ""points"": null}]",1,Jonathan Tah,2336.0,2336.0,5474.0,10622.0,192144.0,1626924.0,6.94,2.382104545335327,1.0,1.0,1.0,0.0,1.0,16.531806
-2141,43,Ridle ,Baku,17851318.0,102.0,32.0,32.0,28.0,162435.0,3278.0,0,2,https://kickbase.b-cdn.net/content/file/938a124759354a928af165b155e6925a.png,17.0,2,183.0,,"[{""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 224}, {""hasPlayed"": true, ""points"": 124}]",2,Ridle Baku,15978.0,15978.0,-97332.0,-162153.0,-790053.0,280167.0,7.37,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.459788
-1639,18,Nadiem,Amiri,33735560.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,103.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,95594.0,95594.0,95066.0,95109.0,726550.0,2898080.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-3069,3,Felix,Nmecha,27176066.0,94.0,29.0,29.0,25.0,141393.0,2730.0,0,3,https://kickbase.b-cdn.net/content/file/f83b3a24df594aaf81be1d58da773656.png,8.0,1,100.0,,"[{""hasPlayed"": true, ""points"": 126}, {""hasPlayed"": true, ""points"": 14}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Felix Nmecha,100847.0,100847.0,104846.0,112371.0,823568.0,5282545.0,6.78,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.946144
-4596,43,Brajan,Gruda,19603467.0,98.0,13.0,13.0,8.0,49007.0,1270.0,0,3,https://kickbase.b-cdn.net/content/file/fc98ceda9d134bd09d5526a600465611.png,10.0,1,64.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": true, ""points"": 89}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 48}]",1,Brajan Gruda,255323.0,255323.0,258092.0,255016.0,1840150.0,7292323.0,7.5,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.732484
-9507,43,Antonio,Nusa,25827174.0,91.0,31.0,31.0,24.0,129764.0,2835.0,0,3,https://kickbase.b-cdn.net/content/file/9a7ea9c911e04f9e9cf0fa6c4b57ca54.png,7.0,1,109.0,,"[{""hasPlayed"": true, ""points"": 20}, {""hasPlayed"": true, ""points"": 42}, {""hasPlayed"": true, ""points"": 25}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 265}]",1,Antonio Nusa,61396.0,61396.0,65803.0,69215.0,494974.0,3823836.0,7.2,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.103185
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
diff --git a/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_2_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv b/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_2_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv
new file mode 100644
index 0000000..2a5eb03
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_2_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+237,2,Manuel,Neuer,13764324.0,95.0,22.0,22.0,22.0,124205.0,2083.0,0,1,https://kickbase.b-cdn.net/content/file/bf993bb6d6914136b11177795c5f77a9.png,1.0,1,151.0,,"[{""hasPlayed"": true, ""points"": 45}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Manuel Neuer,96741.0,96741.0,101717.0,92933.0,666678.0,1965781.0,6.93,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.719669
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+15211,3,Joane,Gadou,25093948.0,,,,,,,0,2,https://kickbase.b-cdn.net/content/file/48c386df17604a3cbfeaffff6bdffae7.png,22.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Joane Gadou,74761.0,74761.0,147477.0,148351.0,977173.0,4955201.0,6.8,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,15.993183
+3470,18,Anthony,Caci,10976864.0,54.0,10.0,10.0,6.0,35021.0,535.0,0,2,https://kickbase.b-cdn.net/content/file/5bb349b2622049a7aa73a59edcec1781.png,19.0,1,48.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 56}, {""hasPlayed"": true, ""points"": 25}, {""hasPlayed"": true, ""points"": -1}, {""hasPlayed"": true, ""points"": 112}]",1,Anthony Caci,136630.0,136630.0,143865.0,141481.0,1298438.0,5953497.0,8.1,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,15.846465
+10115,3,Daniel,Svensson,16621441.0,82.0,33.0,33.0,27.0,162894.0,2705.0,0,2,https://kickbase.b-cdn.net/content/file/da063055c5d14c798dd8d7427fb2a48f.png,24.0,2,162.0,,"[{""hasPlayed"": true, ""points"": 151}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": -11}, {""hasPlayed"": true, ""points"": 27}, {""hasPlayed"": true, ""points"": 34}]",3,Daniel Svensson,23469.0,23469.0,-33135.0,-104336.0,-1274385.0,-2044044.0,6.95,2.3519386450788238,1.0,0.6896551724137931,1.0,1.0,0.0,0.9068965517241379,14.824107
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+6176,43,Nicolas,Seiwald,17963405.0,86.0,33.0,33.0,31.0,174575.0,2839.0,0,3,https://kickbase.b-cdn.net/content/file/5320dfb79fb348369e61599e552840b0.png,13.0,1,158.0,,"[{""hasPlayed"": true, ""points"": 44}, {""hasPlayed"": true, ""points"": 20}, {""hasPlayed"": true, ""points"": 60}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": true, ""points"": 115}]",1,Nicolas Seiwald,120444.0,120444.0,127986.0,137375.0,954275.0,4921218.0,6.93,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,14.363913
+11675,2,Luis,Díaz,53580399.0,178.0,32.0,32.0,27.0,163321.0,5698.0,0,4,https://kickbase.b-cdn.net/content/file/43b93afe59614450a4de3fd8e08c486b.png,14.0,1,106.0,,"[{""hasPlayed"": true, ""points"": 205}, {""hasPlayed"": true, ""points"": 50}, {""hasPlayed"": true, ""points"": 54}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 225}]",1,Luis Díaz,19646.0,19646.0,24304.0,25001.0,177035.0,1040626.0,7.08,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.081566
diff --git a/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 b/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
deleted file mode 100644
index 28dd64a..0000000
--- a/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
+++ /dev/null
@@ -1,12 +0,0 @@
-id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
-1873,3,Gregor,Kobel,22268613.0,104.0,34.0,34.0,34.0,202740.0,3530.0,0,1,https://kickbase.b-cdn.net/content/file/f2d4753d2676442bb38580d0b59a6293.png,1.0,2,158.0,,"[{""hasPlayed"": true, ""points"": 154}, {""hasPlayed"": true, ""points"": 81}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 160}, {""hasPlayed"": true, ""points"": 65}]",1,Gregor Kobel,-153643.0,-153643.0,-160305.0,-158176.0,-715804.0,442252.0,6.8,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,15.993183
-60,18,Dominik,Kohr,10467001.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,197.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,125782.0,125782.0,154324.0,228965.0,1377128.0,4045683.0,8.8,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,17.426471
-3543,2,Nathaniel,Brown,29388219.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,118968.0,118968.0,107021.0,65342.0,615612.0,2280283.0,7.26,2.382104545335327,1.0,1.0,1.0,0.0,1.0,17.294079
-2395,3,Julian,Ryerson,26027952.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,52289.0,52289.0,48888.0,53404.0,408044.0,1281425.0,7.35,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.286749
-1540,18,Danny,Da Costa,9703648.0,73.0,34.0,34.0,30.0,178678.0,2498.0,0,2,https://kickbase.b-cdn.net/content/file/d7479cd684eb4636932e2e5651e92411.png,21.0,2,257.0,,"[{""hasPlayed"": true, ""points"": 72}, {""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 91}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 86}]",3,Danny Da Costa,-175018.0,-175018.0,-10292.0,69860.0,406067.0,2788317.0,8.1,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,16.040274
-2141,43,Ridle ,Baku,17851318.0,102.0,32.0,32.0,28.0,162435.0,3278.0,0,2,https://kickbase.b-cdn.net/content/file/938a124759354a928af165b155e6925a.png,17.0,2,183.0,,"[{""hasPlayed"": true, ""points"": -4}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 224}, {""hasPlayed"": true, ""points"": 124}]",2,Ridle Baku,15978.0,15978.0,-97332.0,-162153.0,-790053.0,280167.0,7.37,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.459788
-8329,2,Michael,Olise,64815120.0,225.0,32.0,32.0,23.0,154488.0,7185.0,0,3,https://kickbase.b-cdn.net/content/file/2d1bffc491014bb582c5d1c622b0ee37.png,17.0,1,110.0,,"[{""hasPlayed"": true, ""points"": 81}, {""hasPlayed"": true, ""points"": 334}, {""hasPlayed"": true, ""points"": 290}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 152}]",1,Michael Olise,23531.0,23531.0,26008.0,26065.0,193889.0,1061959.0,7.8,2.382104545335327,1.0,1.0,1.0,0.0,1.0,18.580415
-16378,3,Konstantinos,Karetsas,24062897.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,261715.0,261715.0,263110.0,275497.0,1944706.0,24062897.0,7.27,2.3519386450788238,1.0,1.0,1.0,0.0,1.0,17.098594
-4596,43,Brajan,Gruda,19603467.0,98.0,13.0,13.0,8.0,49007.0,1270.0,0,3,https://kickbase.b-cdn.net/content/file/fc98ceda9d134bd09d5526a600465611.png,10.0,1,64.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 68}, {""hasPlayed"": true, ""points"": 89}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 48}]",1,Brajan Gruda,255323.0,255323.0,258092.0,255016.0,1840150.0,7292323.0,7.5,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.732484
-11008,43,Ezechiel,Banzuzi,8349668.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,104.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,323577.0,323577.0,328182.0,302789.0,2211617.0,3836539.0,7.3,2.097664543524416,1.0,1.0,1.0,0.0,1.0,15.312951
-2030,18,Phillip,Tietz,13658389.0,56.0,29.0,29.0,19.0,120672.0,1612.0,0,4,https://kickbase.b-cdn.net/content/file/2acf94096d5443fcb6d70524c93fb74e.png,20.0,1,118.0,,"[{""hasPlayed"": true, ""points"": 240}, {""hasPlayed"": true, ""points"": 30}, {""hasPlayed"": true, ""points"": 198}, {""hasPlayed"": true, ""points"": 35}, {""hasPlayed"": true, ""points"": 49}]",1,Phillip Tietz,196077.0,196077.0,163403.0,171227.0,1282291.0,5671372.0,10.0,1.9802807486631018,1.0,1.0,1.0,0.0,1.0,19.802807
diff --git a/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_3_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv b/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_3_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv
new file mode 100644
index 0000000..e1ee4d1
--- /dev/null
+++ b/outputs/optimized_squad/optimized_squad_three_teams_overlap_allowed_team_3_sofascore_overall_rating_odds_lineup_20260827_124042_+0200_20260827_124757_+0200_20260827_163856_+0200.csv
@@ -0,0 +1,12 @@
+id,teamId,firstName,lastName,marketValue,averagePoints,games,gamesPlayed,start11,totalPlaytimeS,totalPoints,status,position,playerImage,number,trend,pointsPerValue,pointsStdDev,history,startProbability,name,marketChangeToday,marketChange.today,marketChange.yesterday,marketChange.twoDays,marketChange.sevenDaysAvg,marketChange.thirtyDaysAvg,sofascore_average_rating,expected_match_points,ligainsider_starting_chance,kickbase_starting_chance,kicker_starting_chance,rotowire_starting_chance,questionable_injury_penalty,starting_chance,score
+1873,3,Gregor,Kobel,21922957.0,104.0,34.0,34.0,34.0,202740.0,3530.0,0,1,https://kickbase.b-cdn.net/content/file/f2d4753d2676442bb38580d0b59a6293.png,1.0,2,161.0,,"[{""hasPlayed"": true, ""points"": 154}, {""hasPlayed"": true, ""points"": 81}, {""hasPlayed"": true, ""points"": 82}, {""hasPlayed"": true, ""points"": 160}, {""hasPlayed"": true, ""points"": 65}]",1,Gregor Kobel,-170082.0,-170082.0,-175574.0,-153643.0,-933458.0,-50314.0,6.8,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,15.993183
+3543,2,Nathaniel,Brown,29629517.0,83.0,33.0,33.0,29.0,176484.0,2726.0,0,2,https://kickbase.b-cdn.net/content/file/4dd49322843644839bb43182b3a8b68b.png,11.0,1,92.0,,"[{""hasPlayed"": true, ""points"": 70}, {""hasPlayed"": true, ""points"": 26}, {""hasPlayed"": true, ""points"": 38}, {""hasPlayed"": true, ""points"": 166}, {""hasPlayed"": true, ""points"": 31}]",2,Nathaniel Brown,117449.0,117449.0,123849.0,118968.0,691722.0,2404395.0,7.26,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,17.515843
+2395,3,Julian,Ryerson,26105247.0,105.0,31.0,31.0,26.0,148097.0,3246.0,0,2,https://kickbase.b-cdn.net/content/file/2998191f5e674fecb9ddf7762821ebc5.png,26.0,1,124.0,,"[{""hasPlayed"": true, ""points"": 141}, {""hasPlayed"": true, ""points"": 127}, {""hasPlayed"": true, ""points"": 41}, {""hasPlayed"": true, ""points"": 171}, {""hasPlayed"": true, ""points"": 3}]",1,Julian Ryerson,29647.0,29647.0,47648.0,52289.0,350103.0,1224103.0,7.35,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.286749
+60,18,Dominik,Kohr,10652629.0,71.0,29.0,29.0,28.0,153973.0,2070.0,0,2,https://kickbase.b-cdn.net/content/file/fc6cb9d67771484baa8cd7547280f6cd.png,31.0,1,194.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 24}, {""hasPlayed"": true, ""points"": 148}, {""hasPlayed"": true, ""points"": 112}]",2,Dominik Kohr,85097.0,85097.0,100531.0,125782.0,1173795.0,4346822.0,8.8,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,17.215913
+173,2,Jonathan,Tah,36997411.0,127.0,28.0,28.0,23.0,135209.0,3559.0,0,2,https://kickbase.b-cdn.net/content/file/cd9c5cb89a074d1ea56f7d952e5074e4.png,4.0,2,96.0,,"[{""hasPlayed"": true, ""points"": 146}, {""hasPlayed"": true, ""points"": 53}, {""hasPlayed"": true, ""points"": 84}, {""hasPlayed"": true, ""points"": 59}, {""hasPlayed"": false, ""points"": null}]",1,Jonathan Tah,-31217.0,-31217.0,-5523.0,2336.0,53043.0,1493674.0,6.94,2.4126506024096384,1.0,1.0,1.0,1.0,0.0,1.0,16.743795
+3470,18,Anthony,Caci,10976864.0,54.0,10.0,10.0,6.0,35021.0,535.0,0,2,https://kickbase.b-cdn.net/content/file/5bb349b2622049a7aa73a59edcec1781.png,19.0,1,48.0,,"[{""hasPlayed"": true, ""points"": 28}, {""hasPlayed"": true, ""points"": 56}, {""hasPlayed"": true, ""points"": 25}, {""hasPlayed"": true, ""points"": -1}, {""hasPlayed"": true, ""points"": 112}]",1,Anthony Caci,136630.0,136630.0,143865.0,141481.0,1298438.0,5953497.0,8.1,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,15.846465
+1639,18,Nadiem,Amiri,33932022.0,134.0,26.0,26.0,24.0,136794.0,3493.0,0,3,https://kickbase.b-cdn.net/content/file/fee710e358914669ab855823274a461e.png,10.0,1,102.0,,"[{""hasPlayed"": true, ""points"": 254}, {""hasPlayed"": true, ""points"": 98}, {""hasPlayed"": true, ""points"": 168}, {""hasPlayed"": true, ""points"": 93}, {""hasPlayed"": true, ""points"": 229}]",1,Nadiem Amiri,96057.0,96057.0,100405.0,95594.0,690099.0,3002667.0,10.0,1.956353749284488,1.0,1.0,1.0,1.0,0.0,1.0,19.563537
+16378,3,Konstantinos,Karetsas,24574032.0,,,,,,,0,3,https://kickbase.b-cdn.net/content/file/f4e89a3523cb47e09c5be6702baec885.png,19.0,1,,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",1,Konstantinos Karetsas,246470.0,246470.0,264665.0,261715.0,1873469.0,24574032.0,7.27,2.3519386450788238,1.0,1.0,1.0,1.0,0.0,1.0,17.098594
+11008,43,Ezechiel,Banzuzi,9051349.0,36.0,24.0,24.0,2.0,43182.0,871.0,0,3,https://kickbase.b-cdn.net/content/file/a9c36464a61049d0b9acd73d6c4e9c96.png,6.0,1,96.0,,"[{""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}, {""hasPlayed"": false, ""points"": null}]",2,Ezechiel Banzuzi,353269.0,353269.0,348412.0,323577.0,2266803.0,4737544.0,7.3,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,15.130818
+9507,43,Antonio,Nusa,25940708.0,91.0,31.0,31.0,24.0,129764.0,2835.0,0,3,https://kickbase.b-cdn.net/content/file/9a7ea9c911e04f9e9cf0fa6c4b57ca54.png,7.0,1,109.0,,"[{""hasPlayed"": true, ""points"": 20}, {""hasPlayed"": true, ""points"": 42}, {""hasPlayed"": true, ""points"": 25}, {""hasPlayed"": true, ""points"": 95}, {""hasPlayed"": true, ""points"": 265}]",1,Antonio Nusa,56019.0,56019.0,57515.0,61396.0,456293.0,3689179.0,7.2,2.0727147495818166,1.0,1.0,1.0,1.0,0.0,1.0,14.923546
+3304,5,Igor,Matanović,19575194.0,68.0,31.0,31.0,14.0,106505.0,2099.0,0,4,https://kickbase.b-cdn.net/content/file/6bb42fe3c2da4e1e9f8ad8dc25f1cc85.png,31.0,1,107.0,,"[{""hasPlayed"": true, ""points"": 265}, {""hasPlayed"": true, ""points"": 207}, {""hasPlayed"": true, ""points"": 17}, {""hasPlayed"": true, ""points"": 5}, {""hasPlayed"": true, ""points"": 37}]",1,Igor Matanović,126494.0,126494.0,149608.0,146084.0,1048492.0,4973610.0,7.8,1.705678495361178,1.0,1.0,1.0,1.0,0.0,1.0,13.304292
diff --git a/outputs/selected_lineups/bundesliga-arena.json b/outputs/selected_lineups/bundesliga-arena.json
index 5c465a3..1779f60 100644
--- a/outputs/selected_lineups/bundesliga-arena.json
+++ b/outputs/selected_lineups/bundesliga-arena.json
@@ -1,10 +1,10 @@
{
"schema_version": 1,
"league": "Bundesliga Arena",
- "selected_at": "2026-08-25T10:59:41.968496+00:00",
- "source": "manual",
+ "selected_at": "2026-08-27T14:40:23.085261+00:00",
+ "source": "optimizer_v1",
"expected_points": {
- "value": "201.630119",
+ "value": "198.263672",
"label": "Total expected points (captain doubled)",
"includes_captain_bonus": true
},
@@ -14,58 +14,68 @@
"id": "237",
"name": "Manuel Neuer",
"position": "GK",
- "market_value": "13565866.0",
- "market_value_eur": 13565866,
+ "market_value": "13764324.0",
+ "market_value_eur": 13764324,
"club": "FC Bayern München",
- "expected_points": "16.507984",
+ "expected_points": "16.719669",
"captain": false
},
{
"id": "3543",
"name": "Nathaniel Brown",
"position": "DEF",
- "market_value": "29388219.0",
- "market_value_eur": 29388219,
+ "market_value": "29629517.0",
+ "market_value_eur": 29629517,
"club": "FC Bayern München",
- "expected_points": "17.294079",
+ "expected_points": "17.515843",
"captain": false
},
{
"id": "2395",
"name": "Julian Ryerson",
"position": "DEF",
- "market_value": "26027952.0",
- "market_value_eur": 26027952,
+ "market_value": "26105247.0",
+ "market_value_eur": 26105247,
"club": "Borussia Dortmund",
"expected_points": "17.286749",
"captain": false
},
{
- "id": "2141",
- "name": "Ridle Baku",
+ "id": "60",
+ "name": "Dominik Kohr",
"position": "DEF",
- "market_value": "17851318.0",
- "market_value_eur": 17851318,
- "club": "RB Leipzig",
- "expected_points": "15.459788",
+ "market_value": "10652629.0",
+ "market_value_eur": 10652629,
+ "club": "1. FSV Mainz 05",
+ "expected_points": "17.215913",
+ "captain": false
+ },
+ {
+ "id": "3759",
+ "name": "Miguel Gutiérrez",
+ "position": "DEF",
+ "market_value": "21033862.0",
+ "market_value_eur": 21033862,
+ "club": "Bayer 04 Leverkusen",
+ "expected_points": "13.791336",
"captain": false
},
{
"id": "1639",
"name": "Nadiem Amiri",
"position": "MID",
- "market_value": "33735560.0",
- "market_value_eur": 33735560,
+ "market_value": "33932022.0",
+ "market_value_eur": 33932022,
"club": "1. FSV Mainz 05",
- "expected_points": "19.802807",
+ "expected_points": "19.563537",
"captain": true
},
{
"id": "16378",
"name": "Konstantinos Karetsas",
"position": "MID",
- "market_value": "24062897.0",
- "market_value_eur": 24062897,
+ "market_value": "24574032.0",
+ "market_value_eur": 24574032,
"club": "Borussia Dortmund",
"expected_points": "17.098594",
"captain": false
@@ -74,61 +84,48 @@
"id": "4596",
"name": "Brajan Gruda",
"position": "MID",
- "market_value": "19603467.0",
- "market_value_eur": 19603467,
+ "market_value": "20088446.0",
+ "market_value_eur": 20088446,
"club": "RB Leipzig",
- "expected_points": "15.732484",
+ "expected_points": "15.545361",
"captain": false
},
{
"id": "4199",
"name": "Aleix García",
"position": "MID",
- "market_value": "38852734.0",
- "market_value_eur": 38852734,
+ "market_value": "38996349.0",
+ "market_value_eur": 38996349,
"club": "Bayer 04 Leverkusen",
- "expected_points": "15.510918",
+ "expected_points": "15.528023",
"captain": false
},
{
- "id": "2846",
- "name": "Malik Tillman",
+ "id": "11008",
+ "name": "Ezechiel Banzuzi",
"position": "MID",
- "market_value": "13303012.0",
- "market_value_eur": 13303012,
- "club": "Bayer 04 Leverkusen",
- "expected_points": "14.082281",
- "captain": false
- },
- {
- "id": "2030",
- "name": "Phillip Tietz",
- "position": "FOR",
- "market_value": "13658389.0",
- "market_value_eur": 13658389,
- "club": "1. FSV Mainz 05",
- "expected_points": "19.802807",
+ "market_value": "9051349.0",
+ "market_value_eur": 9051349,
+ "club": "RB Leipzig",
+ "expected_points": "15.130818",
"captain": false
},
{
"id": "3304",
"name": "Igor Matanović",
"position": "FOR",
- "market_value": "19299092.0",
- "market_value_eur": 19299092,
+ "market_value": "19575194.0",
+ "market_value_eur": 19575194,
"club": "SC Freiburg",
- "expected_points": "13.248821",
+ "expected_points": "13.304292",
"captain": false
}
],
"metadata": {
- "score_input_file": "C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv",
+ "score_input_file": "C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv",
"score_method": "sofascore_overall_rating_odds_lineup",
- "metric_creation_timestamp": "20260825_121320_+0200",
+ "metric_creation_timestamp": "20260827_124757_+0200",
"matchday": 1,
- "formation": "3-5-2",
- "budget_override_used": false,
- "nominal_budget_eur": 250000000,
- "total_value_eur": 249348506
+ "formation": "4-5-1"
}
}
diff --git a/outputs/selected_lineups/kickbase.insider-arena.json b/outputs/selected_lineups/kickbase.insider-arena.json
index 65e9f77..1ec18bb 100644
--- a/outputs/selected_lineups/kickbase.insider-arena.json
+++ b/outputs/selected_lineups/kickbase.insider-arena.json
@@ -1,31 +1,31 @@
{
"schema_version": 1,
"league": "Kickbase.insider Arena",
- "selected_at": "2026-08-25T10:38:37.097567+00:00",
- "source": "manual",
+ "selected_at": "2026-08-27T11:11:59.883409+00:00",
+ "source": "optimizer_insider_arena",
"expected_points": {
- "value": "118.351453",
+ "value": "118.132982",
"label": "Total expected points (captain doubled)",
"includes_captain_bonus": true
},
"player_count": 6,
"players": [
{
- "id": "72",
- "name": "Mark Flekken",
+ "id": "237",
+ "name": "Manuel Neuer",
"position": "GK",
- "market_value": "15527801.0",
- "market_value_eur": 15527801,
- "club": "Bayer 04 Leverkusen",
- "expected_points": "14.490463",
+ "market_value": "13764324.0",
+ "market_value_eur": 13764324,
+ "club": "FC Bayern München",
+ "expected_points": "16.719669",
"captain": false
},
{
"id": "2395",
"name": "Julian Ryerson",
"position": "DEF",
- "market_value": "26027952.0",
- "market_value_eur": 26027952,
+ "market_value": "26105247.0",
+ "market_value_eur": 26105247,
"club": "Borussia Dortmund",
"expected_points": "17.286749",
"captain": false
@@ -34,51 +34,48 @@
"id": "1246",
"name": "Willi Orban",
"position": "DEF",
- "market_value": "31396500.0",
- "market_value_eur": 31396500,
+ "market_value": "31442247.0",
+ "market_value_eur": 31442247,
"club": "RB Leipzig",
- "expected_points": "16.361783",
+ "expected_points": "16.167175",
"captain": false
},
{
- "id": "8329",
- "name": "Michael Olise",
+ "id": "1639",
+ "name": "Nadiem Amiri",
"position": "MID",
- "market_value": "64815120.0",
- "market_value_eur": 64815120,
- "club": "FC Bayern München",
- "expected_points": "18.580415",
+ "market_value": "33932022.0",
+ "market_value_eur": 33932022,
+ "club": "1. FSV Mainz 05",
+ "expected_points": "19.563537",
"captain": true
},
{
- "id": "2030",
- "name": "Phillip Tietz",
- "position": "FOR",
- "market_value": "13658389.0",
- "market_value_eur": 13658389,
- "club": "1. FSV Mainz 05",
- "expected_points": "19.802807",
+ "id": "4199",
+ "name": "Aleix García",
+ "position": "MID",
+ "market_value": "38996349.0",
+ "market_value_eur": 38996349,
+ "club": "Bayer 04 Leverkusen",
+ "expected_points": "15.528023",
"captain": false
},
{
"id": "3304",
"name": "Igor Matanović",
"position": "FOR",
- "market_value": "19299092.0",
- "market_value_eur": 19299092,
+ "market_value": "19575194.0",
+ "market_value_eur": 19575194,
"club": "SC Freiburg",
- "expected_points": "13.248821",
+ "expected_points": "13.304292",
"captain": false
}
],
"metadata": {
- "score_input_file": "C:\\kickbase project\\outputs\\expected_points\\expected_points_20260825_110735_+0200_sofascore_overall_rating_odds_lineup_20260825_121320_+0200.csv",
+ "score_input_file": "C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv",
"score_method": "sofascore_overall_rating_odds_lineup",
- "metric_creation_timestamp": "20260825_121320_+0200",
+ "metric_creation_timestamp": "20260827_124757_+0200",
"matchday": 1,
- "formation": "2-1-2",
- "budget_override_used": false,
- "nominal_budget_eur": 180000000,
- "total_value_eur": 170724854
+ "formation": "2-2-1"
}
}
diff --git a/outputs/selected_lineups/kickbasekis-arena.json b/outputs/selected_lineups/kickbasekis-arena.json
index e7dcba7..1a52a31 100644
--- a/outputs/selected_lineups/kickbasekis-arena.json
+++ b/outputs/selected_lineups/kickbasekis-arena.json
@@ -1,30 +1,41 @@
{
"schema_version": 1,
"league": "KickbaseKIS Arena",
- "selected_at": "2026-08-23T16:04:17.164856+00:00",
+ "selected_at": "2026-08-27T11:10:00.803866+00:00",
"source": "optimizer_v2_per_match",
"expected_points": {
- "value": "178.538892",
+ "value": "178.132352",
"label": "Total expected points (captain doubled)",
"includes_captain_bonus": true
},
+ "player_count": 11,
"players": [
{
"id": "237",
"name": "Manuel Neuer",
"position": "GK",
- "market_value": "13389844.0",
- "market_value_eur": 13389844,
+ "market_value": "13764324.0",
+ "market_value_eur": 13764324,
"club": "FC Bayern München",
"expected_points": "16.719669",
"captain": false
},
+ {
+ "id": "3543",
+ "name": "Nathaniel Brown",
+ "position": "DEF",
+ "market_value": "29629517.0",
+ "market_value_eur": 29629517,
+ "club": "FC Bayern München",
+ "expected_points": "17.515843",
+ "captain": true
+ },
{
"id": "2395",
"name": "Julian Ryerson",
"position": "DEF",
- "market_value": "25926775.0",
- "market_value_eur": 25926775,
+ "market_value": "26105247.0",
+ "market_value_eur": 26105247,
"club": "Borussia Dortmund",
"expected_points": "17.286749",
"captain": false
@@ -33,97 +44,87 @@
"id": "60",
"name": "Dominik Kohr",
"position": "DEF",
- "market_value": "10186895.0",
- "market_value_eur": 10186895,
+ "market_value": "10652629.0",
+ "market_value_eur": 10652629,
"club": "1. FSV Mainz 05",
"expected_points": "17.215913",
"captain": false
},
{
- "id": "2736",
- "name": "Ramy Bensebaini",
+ "id": "1540",
+ "name": "Danny Da Costa",
"position": "DEF",
- "market_value": "21726972.0",
- "market_value_eur": 21726972,
- "club": "Borussia Dortmund",
- "expected_points": "15.993183",
- "captain": false
- },
- {
- "id": "6209",
- "name": "Philipp Treu",
- "position": "DEF",
- "market_value": "11814328.0",
- "market_value_eur": 11814328,
- "club": "SC Freiburg",
- "expected_points": "11.98638",
+ "market_value": "9308429.0",
+ "market_value_eur": 9308429,
+ "club": "1. FSV Mainz 05",
+ "expected_points": "15.846465",
"captain": false
},
{
- "id": "4598",
- "name": "Josip Juranović",
+ "id": "10115",
+ "name": "Daniel Svensson",
"position": "DEF",
- "market_value": "6443857.0",
- "market_value_eur": 6443857,
- "club": "1. FC Union Berlin",
- "expected_points": "9.895782",
+ "market_value": "16621441.0",
+ "market_value_eur": 16621441,
+ "club": "Borussia Dortmund",
+ "expected_points": "14.824107",
"captain": false
},
{
- "id": "4596",
- "name": "Brajan Gruda",
+ "id": "11008",
+ "name": "Ezechiel Banzuzi",
"position": "MID",
- "market_value": "19090052.0",
- "market_value_eur": 19090052,
+ "market_value": "9051349.0",
+ "market_value_eur": 9051349,
"club": "RB Leipzig",
- "expected_points": "15.513336",
+ "expected_points": "15.130818",
"captain": false
},
{
"id": "3209",
"name": "Yannik Engelhardt",
"position": "MID",
- "market_value": "10553425.0",
- "market_value_eur": 10553425,
+ "market_value": "10934988.0",
+ "market_value_eur": 10934988,
"club": "SC Freiburg",
- "expected_points": "12.070201",
+ "expected_points": "12.280885",
"captain": false
},
{
"id": "11556",
"name": "Han-Noah Massengo",
"position": "MID",
- "market_value": "9835144.0",
- "market_value_eur": 9835144,
+ "market_value": "10113144.0",
+ "market_value_eur": 10113144,
"club": "FC Augsburg",
"expected_points": "11.731293",
"captain": false
},
{
- "id": "11008",
- "name": "Ezechiel Banzuzi",
+ "id": "3124",
+ "name": "Patrick Wimmer",
"position": "MID",
- "market_value": "7697909.0",
- "market_value_eur": 7697909,
- "club": "RB Leipzig",
- "expected_points": "10.999312",
+ "market_value": "8149700.0",
+ "market_value_eur": 8149700,
+ "club": "TSG Hoffenheim",
+ "expected_points": "11.405367",
"captain": false
},
{
- "id": "2030",
- "name": "Phillip Tietz",
+ "id": "10113",
+ "name": "Tidiam Gomis",
"position": "FOR",
- "market_value": "13298909.0",
- "market_value_eur": 13298909,
- "club": "1. FSV Mainz 05",
- "expected_points": "19.563537",
- "captain": true
+ "market_value": "5374444.0",
+ "market_value_eur": 5374444,
+ "club": "RB Leipzig",
+ "expected_points": "10.6594",
+ "captain": false
}
],
"metadata": {
- "score_input_file": "C:\\kickbase project\\outputs\\expected_points\\expected_points_20260823_175739_+0200_sofascore_overall_rating_odds_lineup_20260823_180205_+0200.csv",
+ "score_input_file": "C:\\kickbase project\\outputs\\expected_points\\expected_points_20260827_124042_+0200_sofascore_overall_rating_odds_lineup_20260827_124757_+0200.csv",
"score_method": "sofascore_overall_rating_odds_lineup",
- "metric_creation_timestamp": "20260823_180205_+0200",
+ "metric_creation_timestamp": "20260827_124757_+0200",
"matchday": 1,
"formation": "5-4-1"
}