Skip to content

feat: add VTB, Poland, and Lithuania leagues to parser - #9

Merged
Manimall merged 2 commits into
mainfrom
feature/add-vtb-plk-lkl
Jun 8, 2026
Merged

feat: add VTB, Poland, and Lithuania leagues to parser#9
Manimall merged 2 commits into
mainfrom
feature/add-vtb-plk-lkl

Conversation

@Manimall

@Manimall Manimall commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Что сделано

Расширение датасета тремя лигами (VTB, PLK, LKL, сезон 2025/2026): парсер, сбор матчей, маппинг на Sofascore ID, обогащение TEAM_ADV и сбор реальных коэффициентов (full-time total). Главный итог — честная валидация против реального рынка.


Часть 1. Лиги в парсер

Три лиги в COLLECTOR_LEAGUES, слаги проверены вживую (HTTP 200): VTB /basketball/russia/vtb-united-league/, PLK /basketball/poland/basket-liga/, LKL /basketball/lithuania/lkl/. Собрано 863 матча (VTB 437, PLK 266, LKL 160), все с Q1–Q4.

Часть 2. Маппинг Sofascore ID + TEAM_ADV

  • catalog.py: PLK (tournament 263), LKL (975) → sofascore_id_finder.py резолвит числовые ID.
  • norm.py: фикс нормализации — ł đ ø ı ß æ œ (NFKD их не раскладывает). PLK-матчинг 69%→100%, 163 теста зелёные.
  • Маппинг 425/426 (99.8%), Go-обогащение 419 матчей с box-score.

Часть 3. Реальные коэффициенты (full-time total)

Реверс-инжиниринг Flashscore Odds API (global.ds.lsapp.eu/odds/pq_graphql): параметры eventId, bookmakerId, betType=OVER_UNDER, betScope.

⚠️ Ключевая находка: 1H/1Q тоталов на Flashscore НЕ существует. Валидны только FULL_TIME_OVER_TIMEFULL_TIME без линии); FIRST_HALF, *_QUARTER → отбивка на уровне enum. Проверено на матче PLK и на топ-игре EuroLeague (Valencia–Real Madrid) — даже там агрегатор 20+ букмекеров не даёт период-тоталов. Это рыночная реальность: букмекеры не котируют квартальные/половинные тоталы на эти лиги. Источник total_line_1h/1q отсутствует → колонки/миграция не делались.

Бэкфилл full-time линий (odds_enricher_direct.py):

Лига С реальной линией
PLK 265 / 266 (99.6%)
LKL 158 / 160 (98.8%)
VTB 19 / 437 (рынка O/U почти нет)

🎯 Финал: честная валидация period=game против реального рынка

Раньше baseline считался на синтетической медиане (фиктивный ROI). Теперь — против настоящих закрывающих линий букмекеров:

PLK (n_train=212, n_test=53):

Комбо AUC ROI
BASE 0.403 −12.6%
BASE+FATIGUE 0.346 −16.4%
BASE+TEAM_ADV 0.404 −18.0%
BASE+FAT+TEAM_ADV 0.376 −16.9%

LKL (n_train=127, n_test=31):

Комбо AUC ROI
BASE 0.363 −19.6%
BASE+FATIGUE 0.388 −19.6%
BASE+TEAM_ADV 0.471 +5.6% (27 ст.)
BASE+FAT+TEAM_ADV 0.533 +4.8% (29 ст.)

VTB — пропущен (19 линий, ниже минимума train/test).

Вывод

Модель не бьёт рынок на этих лигах. AUC ≤ 0.50 (часто 0.36–0.40): против закрывающей линии модель анти-предсказательна — линия уже содержит всё, что «знает» модель. Два «плюса» LKL (+4.8/+5.6%) — на 27–29 ставках при AUC ~0.5, это шум. Закономерно: обыграть острую линию труднее, чем наивную медиану.

Это ценный честный отрицательный результат на реальных котировках вместо самообмана на синтетике. Знаменитая «EuroLeague 1H AUC 0.685» тоже была против синтетической медианы — и проверить её рынком нельзя, т.к. 1H/1Q рынка не существует.

Что НЕ сделано (обоснованно)

  • total_line_1h/1q + миграция — источник не отдаёт период-тоталы.
  • VTB game-валидация — недостаточно линий (рынок O/U по VTB на Flashscore почти пуст).

Данные/линии — в БД (.gitignore). Изменения кода: catalog.py + norm.py (коммит 2e090bf) + collector_config.py (59613dc).

🤖 Generated with Claude Code

Manimall and others added 2 commits June 7, 2026 18:01
Add three Flashscore-collected leagues for the 2025/2026 season to
COLLECTOR_LEAGUES (current season only, per scope):
  - VTB United League  /basketball/russia/vtb-united-league/
  - PLK (Basket Liga)  /basketball/poland/basket-liga/
  - LKL                /basketball/lithuania/lkl/

Slugs verified live on Flashscore (HTTP 200, populated results tables).
Also gitignore .gstack/ (gstack local browse-skill state, auto-created).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Enable box-score (TEAM_ADV) enrichment for the Flashscore-collected
Polish (PLK) and Lithuanian (LKL) leagues, which the Go scout skipped
because their external_id was a non-numeric Flashscore id (fs_...).

- catalog.py: add PLK (tournament 263, Orlen Basket Liga) and LKL
  (tournament 975, Betsson-LKL) so scripts/sofascore_id_finder.py can
  resolve their numeric Sofascore event IDs.
- norm.py: fold Latin letters NFKD leaves intact (ł, đ, ø, ı, ß, æ, œ)
  to ASCII before matching. Polish "Wrocław"/"Włocławek" now match
  "Wroclaw"/"Wloclawek"; PLK fuzzy-match jumped 69% -> 100% at the
  default 0.50 threshold. No feature/grid-search impact (norm is used
  only for name matching). 163 tests still pass.

Mapping result (date ±1d + team-name fuzzy): 425/426 matches resolved
(PLK 266/266, LKL 159/160; the 1 miss is a genuine fixture discrepancy).
Go scout then enriched 419 matches with ORtg/DRtg/Possessions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Manimall
Manimall merged commit 24699f7 into main Jun 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant