Files
iddaai-be/ai-engine/BETTING_WORKFLOW.md
T
fahricansecer b5cb412236
Deploy Iddaai Backend / build-and-deploy (push) Successful in 1m6s
gg
2026-05-29 11:59:51 +03:00

314 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IDDAAI — Bahis Motoru Operasyon Workflow'u (V31d)
> Bu doküman, AI bahis tahmin motorunun **nasıl çalıştırılacağı, doğrulanacağı,
> izleneceği ve yeniden ayarlanacağına** dair operasyon kılavuzudur.
> Hedef: **hem hacim hem kâr** — gerçekçi beklenti **premium tier'da +%30 ROI**,
> daha geniş ağda +%515.
>
> Son güncelleme: 2026-05-29 · Judge sürümü: `judge-v31d-evidence-tiers`
>
> **V31d ne değiştirdi (hacim krizi çözümü):** V31c yalnızca **28 oynanabilir
> bahis / 10k maç** üretiyordu çünkü iki veto (`calibrated_confidence_too_low`,
> `play_score_too_low`) HER underdog'u reddediyordu — bunlar ">%45 model güveni
> iste" diyen FAVORİ-seçme kuralı. Ama kârlı bir 6.5 oran underdog'u zaten sadece
> ~%20 tutar; kâr oran priminden gelir. V31d, **MS değer-tier eşleşmelerinde** bu
> iki vetoyu kaldırır ve skoru tier kalitesinden üretir. Sonuç (60g doğrulama):
> **28 → 602 oynanabilir bahis (22x), 1.6u → +39.4u, ROI %28 → +%32.7.**
> Tüm zengin analiz çıktısı (market_board, v25/v27, triple_value, olasılıklar)
> **aynen korunur** — yalnızca `playable` bayrağı değişir.
---
## 0. TL;DR — En Önemli 5 Kural
1. **SADECE TEKLİ BAHİS OYNA. KOMBİNE YOK.** Matematiksel olarak kanıtlandı:
1-leg `+%3.4` → 2-leg `-%32` → 3-leg `-%67` → 4-leg `-%83`. Marjinal +EV bacakları
çarpmak kazancı yok eder.
2. **Asıl kâr MS (1X2) underdog bölgesinde.** Oran ≥ 6.0 + model_gap ≥ 0 = en yüksek ROI.
3. **Hiçbir market mute edilmez.** Tier sistemi filtreler; gerçek ROI'ler görünür kalır
(`MUTED_MARKETS = set()`).
4. **Kalibrasyon ≠ Bahis sinyali.** MS tier'ları ham model olasılığını kullanır
(`model_gap`, `ev_edge`). İzotonik kalibratörler sadece ekrandaki `calibrated_confidence`'i
etkiler (BTTS/OU25'te şişik — dikkat).
5. **Backtest'e körü körüne güvenme.** Model eğitim kesim tarihini bil; in-sample/out-of-sample
ayrımını her zaman yap (bkz. Bölüm 6).
---
## 1. Sistem Mimarisi (Pipeline)
```
Maç verisi (DB: matches, odds, elo, form, h2h…)
[V25 Ensemble] XGBoost + LightGBM + CatBoost → her market için ham olasılık
[V27 Dual-Engine] ikinci görüş / consensus (AGREE / DISAGREE)
[İzotonik Kalibrasyon] ham olasılık → calibrated_confidence (ekran için)
└─ kalibratörü OLMAYAN marketlerde hafif damping (×0.92)
[BettingBrain V31d — Deterministik Hâkim]
├─ ev_edge = calibrated_probability × oran 1 (ham-prob + market blend)
├─ model_gap = ham_model_olasılık implied_prob
├─ trap_market = market geçmiş banttan fazla fiyatlamış mı?
├─ odds_reliability = lig bazında geçmiş Brier skorundan
└─ MARKET_ODDS_TIERS → value_tier (premium/strong/standard) → bet_grade (A/B/C)
[Çıktı] bet_summary[] → playable, value_tier, stake_units, bet_grade
→ BE (smart-coupon) → FE / Mobile
```
**Anahtar dosyalar:**
- `services/betting_brain.py` — deterministik hâkim, tier tanımları (`MARKET_ODDS_TIERS`)
- `services/orchestrator/market_board.py` — ev_edge/model_gap/kalibrasyon hesapları
- `scripts/diagnostic_backtest_multi.py` — çok-pick backtest (maç başına TÜM marketler)
- `models/v25/`, `models/calibration/` — model ve kalibratör dosyaları
---
## 2. V31d — Kanıta Dayalı Kademeli Değer Sistemi (Evidence-Based Tiers)
Kullanıcı risk iştahına göre seçer. Her tier maç başına ayrı sinyal üretir.
**Sadece premium otomatik STAKE'lenir (BET); strong/standard WATCH** olarak görünür
(tam analiz gösterilir, oynanmaz) çünkü 60 günlük veri o bantların ~başabaş olduğunu
söylüyor.
| Tier | Grade | Oran bandı | Filtre | 60g ROI* | Aksiyon | Karakter |
|------|:----:|-----------|--------|:----:|:----:|----------|
| **premium** | A | **6.00 7.50** | model_gap ≥ 0, rel ≥ 0.30 | **+%32.7** | **BET** | Doğrulanmış edge; ~%20 hit, yüksek varyans |
| **strong** | B | 5.00 6.00 | model_gap ≥ 0, rel ≥ 0.30 | ~%1 (başabaş) | WATCH | Görünür, oynanmaz (kanıt yetersiz) |
| **standard** | C | 3.00 5.00 | model_gap ≥ 0, rel ≥ 0.30 | +%0.5 (başabaş) | WATCH | Hacim bölgesi, marj yok |
| info (—) | — | markete özel | ultrastrict (min_edge≥0.02, rel≥0.45-0.55, trap yok) | ~0 | REJECT/info | Bilgi amaçlı, nadiren geçer |
\* 60 günlük doğrulamadan (72.582 settled satır, 7.793 maç, 2026-04-17..05-28;
`ms_envelope.py` + `new_gate_sim.py`). premium: 602 bahis, +%32.7 ROI, +39.4u,
%20.6 hit, **6 haftanın 6'sı da pozitif**, OOS(>05-24) +%47.4.
**NEDEN 6.07.5 (V31c'deki 6.050.0 değil):** edge dar bir banda yoğunlaşmış.
`6.07.0 +%35` · `7.08.0 ~başabaş` · **`8.0+ NEGATİF`** (%10..26, longshot mezarlığı).
Eski geniş premium tier kaybeden longshot'ları içeri alıyordu. 7.5 üstünde modelin
edge'i buharlaşıyor.
**Tasarım mantığı:** premium = ROI **ve** hacim motoru (60g'de ~14 bahis/gün = bol hacim).
Bahisçi:
- **Düşük risk / yüksek kalite** istiyorsa → sadece **premium (A)** oyna (varsayılan).
- **Daha fazla hacim** istiyorsa → premium bandını 6.08.0'e genişlet (ROI +%32.7 → +%19,
hâlâ sağlam, +%44 hacim) — `MARKET_ODDS_TIERS["MS"]` premium `max_odds`'u değiştir.
**Non-MS marketler (DC, OU25, OU35, BTTS, HT, OU15, HTFT, OE, HT_OU05, HT_OU15, CARDS):**
hepsi `ultrastrict` tek-tier ile bilgi amaçlı. Geçmiş veride sistematik olarak kayıp
verdikleri için BET üretmeleri zorlaştırıldı (mute YOK — sadece sıkı eşik).
**Veto mantığı (V31d kritik):** value-tier eşleşmelerinde `calibrated_confidence_too_low`
ve `play_score_too_low` vetoları KALDIRILIR (bunlar favori-seçme kuralı). Ama gerçek
koruma vetoları AKTİF kalır: `extreme_negative_ev` (ev<0.20), `ev_edge_too_high_trap`
(ev≥0.30), `htft_reversal_risk_high`, `v25_v27_hard_disagreement`, `low_reliability_hard`.
60g'de premium tier-eşleşmelerinin ~%71'i oynanabilir oldu; kalan ~%29 bu koruma
vetolarıyla doğru şekilde reddedildi.
---
## 3. EN İYİ BAHİS DEĞERLERİ — Kesin Sıralama (Best Bet Values)
> "Multi bahislerde bütün bahis değerlerinin en iyisi" sorusunun cevabı.
> **Hepsi TEKLİ oynanır.** (Aşağıdaki ROI'ler 0.2u sabit stake simülasyonundan.)
### MS (1X2) underdog — ince oran-bandı haritası (60g, gap ≥ 0)
> "Hangi bahis hangi oranda tutuyor" sorusunun kesin cevabı. `ms_envelope.py`.
> drop-3/5 = en büyük 3/5 kazancı çıkarınca ROI (konsantrasyon/sağlamlık testi).
| Oran bandı | Bahis | Hit% | ROI | drop-3 ROI | Karar |
|-----------|------:|-----:|----:|-----:|:-----:|
| **6.0 6.5** | 469 | %22.0 | **+%37.7** | +%34.4 | ✅ elit |
| **6.0 7.0** | 492 | %21.5 | **+%35.2** | +%29.9 | ✅ elit, sağlam |
| **6.0 7.5** (premium) | 645 | %20.0 | **+%29.3** | +%24.4 | ✅ ÖNERİLEN |
| 6.0 8.0 | 928 | %17.7 | +%19.1 | +%15.5 | ✅ hacim opsiyonu |
| 7.5 8.0 | 283 | %12.4 | %4.0 | — | ❌ |
| 8.0 9.0 | 78 | %9.0 | %25.7 | — | ❌ longshot |
| 9.0+ | ~266 | <%10 | negatif | — | ❌ mezarlık |
| 5.0 6.0 (strong) | ~1000 | %18 | ~%1 | — | ⚠️ başabaş → WATCH |
| 3.0 5.0 (standard) | ~5745 | %27 | +%0.5 | — | ⚠️ başabaş → WATCH |
**Korumalı premium (htft/disagreement vetoları uygulanmış) = staked set:**
602 bahis · %20.6 hit · **+%32.7 ROI** · +39.4u · 6/6 hafta pozitif · OOS +%47.4.
**Okuma:** Edge tamamen **6.07.5** bandında. 8.0 üstü longshot'lar kaybeder
(eski 6.050.0 premium tier'ı bu yüzden sulandırıyordu). 5.0 altı başabaş.
Premium tek başına ~14 bahis/gün = hem hacim hem +%32.7 ROI.
### ❌ İşe YARAMAYAN yapılandırmalar
- **Kombine (parlay):** her ek bacak ROI'yi çökertir (yukarıdaki TL;DR).
- **MS 8.0+ longshot:** %10..26 ROI, model edge'i yok.
- **MS 5.06.0 / 3.05.0:** başabaş; WATCH olarak göster, stake'leme.
- **OU25 her konfigürasyon:** sistematik kayıp (60g'de OU25 %22.8, OU35 %17.2).
- **BTTS:** sadece çok yüksek reliability'de marjinal.
---
## 4. KRİTİK KURAL — Tekli Bahis, Kombine Yok
| Kupon tipi | Hit% | ROI | Sonuç |
|-----------|-----:|----:|:-----:|
| 1-leg (tekli) | ~%24 | **+%3.4** | ✅ |
| 2-leg | düşük | %32.4 | ❌ |
| 3-leg | çok düşük | %66.6 | ❌ |
| 4-leg | minimal | %83.0 | ❌ |
**Neden:** Tekil bacaklar yalnızca marjinal +EV. Kombine, kazanma olasılıklarını
çarparken (her biri <1) kayıp olasılığını üssel büyütür. Düz (flat) tekli stake
matematiksel olarak üstündür. **Ürün, kullanıcıyı kombineye teşvik etmemeli;**
"günün premium tekli değerleri" şeklinde sunmalı.
---
## 5. Önerilen Stake Politikası
- **Flat stake** (sabit birim) — Kelly değil. Marjinal edge'de Kelly varyansı patlatır.
- **premium (A): 0.5u sabit** (`VALUE_TIER_STAKE_UNITS`). ~%20 hit + uzun kayıp serileri
(60g'de en uzun 35 ardışık kayıp) nedeniyle KÜÇÜK tutulur — kâr **frekanstan** gelir,
bahis başı büyüklükten değil. Bankroll/risk iştahı izin veriyorsa artırılabilir.
- strong/standard WATCH = stake YOK (görünür ama oynanmaz).
- Günlük/maç başına 1 sinyal; aynı maça birden çok tier'dan bahis = korelasyon riski,
en yüksek value_tier'ı seç.
- **Drawdown uyarısı:** 0.5u'da en kötü tarihsel düşüş ≈ 34u; 35 ardışık kayıp mümkün.
Bu bir maraton stratejisidir — kısa vadeli sonuçlara göre stake değiştirme.
---
## 6. Backtest Metodolojisi & Leakage Disiplini ⚠️
**En kritik bölüm. Backtest sayıları yanlış yorumlanırsa sistem kârlı sanılıp kaybettirir.**
### 6.1 Komut
```bash
# Konteyner içinde:
python scripts/diagnostic_backtest_multi.py --days 60 --max-matches 10000 \
--progress-interval 100 --checkpoint-every 200
# Çıktı: reports/multi_backtest_YYYYMMDD.{csv,json,txt}
# Checkpoint'li → kesilirse kaldığı yerden devam eder.
```
### 6.2 Lookahead / Sızıntı (leakage) kontrolü — ZORUNLU
- **Feature lookahead:** ✅ temiz — feature'lar match_date ÖNCESİ veriden hesaplanıyor.
- **Model eğitim-seti üyeliği:** Bunu HER ZAMAN kontrol et. Kalibratörler
`models/calibration/*_metrics.json` içindeki `last_trained` tarihinde, son ~5000
maç üzerinde fit edilir. Backtest penceresi bu tarihle çakışırsa **calibrated_confidence
in-sample (şişik)** olur.
- **Pratik test (ucuz):** Backtest sonucunu eğitim kesim tarihine göre ikiye böl;
in-sample vs out-of-sample hit% karşılaştır. Tüm-market hit% **neredeyse aynıysa**
(örn. %49.7 vs %49.4) → temel modellerde anlamlı sızıntı YOK, edge gerçek.
Eski veride hit% **aniden yükseliyorsa** → o dönem eğitim setinde, ROI'yi yok say.
- Hazır script: `/tmp/leakage_split.py <csv>` (eğitim tarihine göre böler).
- **Geriye doğru ne kadar gidilebilir?** Modeller en son holdout penceresini (≈son
10k maç ≈ 60-70 gün) eğitimden hariç tutuyor. Bu yüzden **~60 gün geriye backtest
çoğunlukla temiz holdout'tur.** Daha geriye (90+ gün) gitmek eğitim setine girip
ROI'yi yapay iyi gösterebilir → kaçın.
### 6.3 Doğrulama scriptleri
- `/tmp/v31c_validation.py <csv>` — V31c tier dökümü (premium/strong/standard ROI).
- `/tmp/best_bet_values.py <csv>` — grid-search liderlik tablosu + portföy + kombine testi.
- `/tmp/leakage_split.py <csv>` — in/out-of-sample sızıntı probu.
### 6.4 Doğrulama eşiği (bir tier "kârlı" sayılmadan önce)
- n ≥ 50 bahis (tercihen ≥ 200), out-of-sample.
- ROI > 0 hem in- hem out-of-sample'da, ya da en azından OOS'ta çökmemiş.
- Kümülatif kâr eğrisi yukarı trend (tek bir şanslı güne bağlı değil).
---
## 7. Operasyonel Döngü (Cadence)
### Günlük
- Motor sağlık kontrolü (futbol pipeline çalışıyor mu; basketbol `readiness_summary`
hatası bilinen/zararsız).
- Günün sinyallerini üret; **premium (A) tekli** değerleri öne çıkar.
- Settle olan dünün bahislerini logla (gerçek hit/ROI takibi).
### Haftalık
- Son 7-14 günün gerçek sonuçlarını backtest tahminiyle karşılaştır (calibration drift).
- Tier bazında gerçekleşen ROI'yi izle; standard (C) sürekli negatifse eşik sıkılaştır.
### Aylık
- Modelleri yeniden eğit (Colab: `extract_training_data_v27.py` → eğitim → `fetch_xgb_models.sh`).
- **Yeniden eğitimden sonra MUTLAKA** 60 günlük backtest + leakage_split ile yeniden doğrula.
- Tier eşiklerini güncelle (Bölüm 8).
- `models/calibration/*_metrics.json` `last_trained` tarihini not et (bir sonraki
backtest'in OOS penceresini bilmek için).
---
## 8. Tier / Eşik Güncelleme Protokolü
1. Yeni backtest CSV'sini al → `v31c_validation.py` + `leakage_split.py` çalıştır.
2. Her tier için OOS ROI'ye bak:
- ROI sağlam pozitif + n yeterli → koru.
- ROI marjinal/negatif → oran bandını daralt veya min_reliability/min_model_gap yükselt.
- premium 6.0+ eşiği: OOS'ta hâlâ en iyi ROI mi? Değilse bandı kaydır (örn. 6.5+).
3. `betting_brain.py``MARKET_ODDS_TIERS` düzenle, **versiyon string'ini artır**
(`judge-v31c-…``judge-v31d-…`).
4. Lokal syntax kontrol → sunucuya deploy (Bölüm 9) → yeniden doğrula.
5. Tier'lar netleştikten SONRA `value_tier`'ı UI'a yay (BE smart-coupon → FE badge → mobil).
---
## 9. Deploy Prosedürü (AI Engine)
```bash
# 1. Lokal syntax kontrol
python3 -c "import ast; ast.parse(open('services/betting_brain.py').read())"
# 2. Sunucuya kopyala (SSH: port 2222, kullanıcı haruncan)
scp -P 2222 services/betting_brain.py haruncan@<host>:/tmp/betting_brain.py
# 3. Konteynere koy + import testi
docker cp /tmp/betting_brain.py iddaai-ai-engine:/app/services/betting_brain.py
docker exec iddaai-ai-engine python -c "from services.betting_brain import BettingBrain; print('OK')"
# 4. Yeniden başlat + doğrula
docker restart iddaai-ai-engine
docker exec iddaai-ai-engine python -c "from services.betting_brain import BettingBrain as B; \
print([t['value_tier'] for t in B().MARKET_ODDS_TIERS['MS']])"
```
> Not: Port 8000 host-localhost'a expose DEĞİL; sağlık testini konteyner içinden veya
> Docker network üzerinden yap. Basketbol `readiness_summary` hatası bilinen, bloklamıyor.
---
## 10. Bilinen Sınırlamalar & Uyarılar
- **Kalibrasyon şişmesi:** BTTS / OU25 izotonik kalibratörleri olasılığı %10-15 fazla
gösteriyor (overcalibrated). Bu marketlerde ekrandaki `calibrated_confidence`'e tam
güvenme; bahis kararı zaten ham-prob `model_gap`/`ev_edge` ile veriliyor.
- **Out-of-sample örneklem küçük:** Eğitim kesim tarihinden sonraki temiz pencere dar
olabilir (~200 MS bahsi). İstatistiksel kesinlik için ileriye doğru gerçek sonuç
biriktir (paper-trade) veya 60 günlük holdout backtest kullan.
- **standard (C) tier kırılgan:** in-sample +%0.4, küçük OOS örnekte negatife düşebiliyor.
Hacim için var; ROI garantisi değil.
- **Tek pencere overfit riski:** Tek bir sezon/dönem penceresine göre ayar yapma;
farklı lig/sezon çeşitliliği ara.
- **Basketbol:** `BasketballV25Predictor.readiness_summary` eksik — futbolu etkilemiyor,
ayrı düzeltilecek.
---
## 11. Hızlı Komut Referansı
```bash
# 60 günlük backtest (konteyner içi)
python scripts/diagnostic_backtest_multi.py --days 60 --max-matches 10000
# Doğrulama (CSV lokale çekildikten sonra)
python3 /tmp/v31c_validation.py reports/multi_backtest_YYYYMMDD.csv
python3 /tmp/best_bet_values.py reports/multi_backtest_YYYYMMDD.csv
python3 /tmp/leakage_split.py reports/multi_backtest_YYYYMMDD.csv
# Kalibratör eğitim tarihleri
grep -o '"last_trained":[^,]*' models/calibration/*.json
```