gg
Deploy Iddaai Backend / build-and-deploy (push) Successful in 1m6s

This commit is contained in:
2026-05-29 11:59:51 +03:00
parent 659110c806
commit b5cb412236
4 changed files with 736 additions and 64 deletions
+313
View File
@@ -0,0 +1,313 @@
# 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
```