Skip to content

feat: B.League walk-forward — edge is NOT systematic (one-season artifact) - #13

Open
Manimall wants to merge 1 commit into
mainfrom
feature/bleague-walk-forward
Open

feat: B.League walk-forward — edge is NOT systematic (one-season artifact)#13
Manimall wants to merge 1 commit into
mainfrom
feature/bleague-walk-forward

Conversation

@Manimall

@Manimall Manimall commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Задача (Senior Quant)

Доказать, системная ли неэффективность букмекера эдж B.League (+19% ROI, CI95>0 на 142 внутрисезонных ставках) — или флуктуация одного сезона. Инструмент: строгий мульти-сезонный walk-forward.

Что сделано

  • Данные: добавлен архивный слаг B.League 24/25 (collector_config.py), собрано 736 матчей сезона 24/25 + odds-бэкфилл 100% (736/736). Подтверждено: Flashscore хранит исторические O/U (матч 2023 г. отдаёт handicap'ы).
  • scripts/walk_forward_bleague.py: строго хронологический expanding-window. V6, только BASE, порог 0.54, никаких подгонок. Обучение на всех прошлых сезонах → ставки на отложенный сезон; per-season + пул-агрегат bootstrap CI95.
  • Тест на season-bucketing (Aug rollover).

Результат: train 24/25 → test 25/26

Test сезон n_train Test AUC ROI % n ставок ROI CI95
2025/26 734 0.503 −5.00% 688 [−11.90%; +2.18%]
АГРЕГАТ −5.00% 688 [−11.90%; +2.18%]

❌ Вердикт: эдж НЕ системный

Грааль не пережил кросс-сезонный тест:

  • AUC 0.62 → 0.50 (внутри сезона → между сезонами).
  • ROI +19% → −5%.
  • CI95 [−11.9%; +2.2%] на 688 ставках (×5 к прежним 142) → надёжное «эджа нет».

Почему: прежний +19% использовал сплит ВНУТРИ одного сезона (те же команды, та же скоринговая среда) → модель ловила внутрисезонную структуру, которая не переносится на модель с прошлого сезона. Ранжирующая способность не генерализуется между сезонами — значит системного эджа нет.

Ценность

Walk-forward отловил ложное срабатывание на большой чистой выборке — уберёг от ставок на фантомный эдж. Тот же класс ошибки, что ловила слепая валидация, но теперь по объёму данных. Инструмент переиспользуемый (-- расширяется на N сезонов).

Гейт

ruff/mypy чисто · pytest зелёные · файлы ≤250 строк · строгая типизация · dataclass · без print/hardcode.

🤖 Generated with Claude Code

Verifies whether B.League's single-season +19% ROI (CI95>0 on 142 in-season
bets) is a real bookmaker inefficiency or a one-season fluke.

- collector_config.py: add BLeague_2425 archive slug (Flashscore keeps historical
  O/U odds — confirmed a 2023 match still serves handicaps).
- scripts/walk_forward_bleague.py: strict chronological expanding-window
  validation. Trains V6 (BASE, threshold 0.54, no tuning) on all prior seasons,
  bets the held-out season; per-season + pooled bootstrap-CI95 aggregate.
- tests/test_walk_forward_season.py: guards the Aug season-rollover bucketing.

Result (train 24/25 -> test 25/26, 688 bets): AUC 0.503, ROI -5.00%,
CI95 [-11.90%; +2.18%]. The edge did NOT survive: cross-season AUC collapses
0.62 -> 0.50, ROI +19% -> -5%. The single-season "edge" was a within-season
artifact (same teams/scoring environment), not a systematic inefficiency.
Walk-forward caught a false positive on a 5x larger, cleaner sample.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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