""" Smart Bet Recommender ===================== Skor tahminine göre akıllı bahis önerileri yapan sistem. Örnek: Beşiktaş-Galatasaray için model 3-1 tahmin ediyor → DÜŞÜK RİSK: 1.5 Üst (yüksek ihtimal tutar) → ORTA RİSK: MS 1 + 2.5 Üst (orta ihtimal) → YÜKSEK RİSK: 3.5 Üst veya skor 3-1 (düşük ihtimal, yüksek kazanç) Ayrıca kombinasyonlar: - MS 1 + 1.5 Üst - MS 1 + KG Var - Her iki takım skor > 0.5 (her takım en az 1 gol atar) """ from dataclasses import dataclass from typing import Dict, List, Optional, Tuple from enum import Enum class RiskLevel(Enum): LOW = "LOW" # Yüksek olasılık, düşük oran (güvenli) MEDIUM = "MEDIUM" # Orta olasılık, orta oran HIGH = "HIGH" # Düşük olasılık, yüksek kazanç EXTREME = "EXTREME" # Çok düşük olasılık, çok yüksek kazanç @dataclass class BetRecommendation: """Tek bir bahis önerisi""" market: str # Piyasa adı (örn: "MS 1", "2.5 Üst") pick: str # Seçim (örn: "1", "OVER", "YES") odds: float # Oran probability: float # Model olasılığı (0-1) confidence: float # Güven seviyesi (0-100) risk_level: RiskLevel def to_dict(self) -> dict: return { "market": self.market, "pick": self.pick, "odds": self.odds, "probability": round(self.probability * 100, 1), "confidence": round(self.confidence, 1), "risk_level": self.risk_level.value } @dataclass class MatchPredictionSet: """Bir maç için tüm tahmin seti""" match_name: str predicted_score: Tuple[int, int] # (home, away) home_win_prob: float draw_prob: float away_win_prob: float over_15_prob: float over_25_prob: float over_35_prob: float btts_yes_prob: float # Öneriler low_risk_bets: List[BetRecommendation] medium_risk_bets: List[BetRecommendation] high_risk_bets: List[BetRecommendation] extreme_risk_bets: List[BetRecommendation] def to_dict(self) -> dict: return { "match_name": self.match_name, "predicted_score": f"{self.predicted_score[0]}-{self.predicted_score[1]}", "probs": { "home_win": round(self.home_win_prob * 100, 1), "draw": round(self.draw_prob * 100, 1), "away_win": round(self.away_win_prob * 100, 1), "over_15": round(self.over_15_prob * 100, 1), "over_25": round(self.over_25_prob * 100, 1), "over_35": round(self.over_35_prob * 100, 1), "btts": round(self.btts_yes_prob * 100, 1) }, "low_risk": [b.to_dict() for b in self.low_risk_bets], "medium_risk": [b.to_dict() for b in self.medium_risk_bets], "high_risk": [b.to_dict() for b in self.high_risk_bets], "extreme_risk": [b.to_dict() for b in self.extreme_risk_bets] } class SmartBetRecommender: """ Akıllı Bahis Öneri Sistemi Skor tahminine göre farklı risk seviyelerinde bahisler önerir. Mantık: 1. DÜŞÜK RİSK: Yüksek olasılıklı (>70%), düşük oranlı bahisler - 1.5 Üst - Double Chance - Favori takım gol atar 2. ORTA RİSK: Orta olasılıklı (50-70%), orta oranlı bahisler - MS favori - 2.5 Üst - KG Var/Var 3. YÜKSEK RİSK: Düşük olasılıklı (30-50%), yüksek oranlı bahisler - 3.5 Üst - Skor tahmini - Handikap 4. EXTREME RİSK: Çok düşük olasılıklı (<30%), çok yüksek oranlı - Tam skor - Uzunluklu kombinasyonlar """ # Olasılık eşikleri PROB_LOW_RISK = 0.70 # > %70 olasılık PROB_MEDIUM_RISK = 0.50 # %50-70 olasılık PROB_HIGH_RISK = 0.30 # %30-50 olasılık # < %30 = EXTREME def __init__(self): pass def _determine_risk(self, probability: float) -> RiskLevel: """Olasılığa göre risk seviyesi belirle""" if probability >= self.PROB_LOW_RISK: return RiskLevel.LOW elif probability >= self.PROB_MEDIUM_RISK: return RiskLevel.MEDIUM elif probability >= self.PROB_HIGH_RISK: return RiskLevel.HIGH else: return RiskLevel.EXTREME def _get_favorite(self, home_prob: float, draw_prob: float, away_prob: float) -> Tuple[str, float]: """Favori sonucu ve olasılığını döndür""" if home_prob >= draw_prob and home_prob >= away_prob: return "1", home_prob elif away_prob >= home_prob and away_prob >= draw_prob: return "2", away_prob else: return "X", draw_prob def _calculate_expected_goals(self, predicted_score: Tuple[int, int]) -> float: """Tahmin edilen skora göre beklenen gol sayısı""" return predicted_score[0] + predicted_score[1] def recommend( self, match_name: str, predicted_score: Tuple[int, int], probs: Dict[str, float], odds: Dict[str, float] ) -> MatchPredictionSet: """ Maç için tüm bahis önerilerini oluştur. Args: match_name: Maç adı predicted_score: (home_goals, away_goals) probs: {"home_win": 0.55, "draw": 0.25, "away_win": 0.20, "over_15": 0.85, "over_25": 0.65, "over_35": 0.35, "btts_yes": 0.55} odds: {"1": 1.80, "X": 3.50, "2": 4.20, "ou15_o": 1.25, "ou15_u": 3.80, "ou25_o": 1.90, "ou25_u": 1.85, "ou35_o": 3.20, "ou35_u": 1.30, "btts_y": 1.75, "btts_n": 2.00} Returns: MatchPredictionSet with all recommendations """ home_prob = probs.get("home_win", 0.33) draw_prob = probs.get("draw", 0.33) away_prob = probs.get("away_win", 0.33) over_15_prob = probs.get("over_15", 0.70) over_25_prob = probs.get("over_25", 0.50) over_35_prob = probs.get("over_35", 0.30) btts_prob = probs.get("btts_yes", 0.50) # Beklenen goller expected_goals = self._calculate_expected_goals(predicted_score) # Favori favorite, favorite_prob = self._get_favorite(home_prob, draw_prob, away_prob) # Önerileri oluştur low_risk = [] medium_risk = [] high_risk = [] extreme_risk = [] # ========== DÜŞÜK RİSK ÖNERİLERİ ========== # 1.5 Üst (en güvenli) if over_15_prob >= self.PROB_LOW_RISK: low_risk.append(BetRecommendation( market="1.5 Üst/Alt", pick="OVER", odds=odds.get("ou15_o", 1.25), probability=over_15_prob, confidence=over_15_prob * 100, risk_level=RiskLevel.LOW )) # Double Chance if home_prob > away_prob: dc_prob = home_prob + draw_prob if dc_prob >= self.PROB_LOW_RISK: low_risk.append(BetRecommendation( market="Double Chance", pick="1X", odds=odds.get("dc_1x", 1.30), probability=dc_prob, confidence=dc_prob * 100, risk_level=RiskLevel.LOW )) elif away_prob > home_prob: dc_prob = away_prob + draw_prob if dc_prob >= self.PROB_LOW_RISK: low_risk.append(BetRecommendation( market="Double Chance", pick="X2", odds=odds.get("dc_x2", 1.30), probability=dc_prob, confidence=dc_prob * 100, risk_level=RiskLevel.LOW )) # ========== ORTA RİSK ÖNERİLERİ ========== # MS Favori if self.PROB_MEDIUM_RISK <= favorite_prob < self.PROB_LOW_RISK: medium_risk.append(BetRecommendation( market="Maç Sonucu", pick=favorite, odds=odds.get(favorite, 2.00), probability=favorite_prob, confidence=favorite_prob * 100, risk_level=RiskLevel.MEDIUM )) # 2.5 Üst if self.PROB_MEDIUM_RISK <= over_25_prob < self.PROB_LOW_RISK: medium_risk.append(BetRecommendation( market="2.5 Üst/Alt", pick="OVER", odds=odds.get("ou25_o", 1.90), probability=over_25_prob, confidence=over_25_prob * 100, risk_level=RiskLevel.MEDIUM )) # KG Var if self.PROB_MEDIUM_RISK <= btts_prob < self.PROB_LOW_RISK: medium_risk.append(BetRecommendation( market="Karşılıklı Gol", pick="YES", odds=odds.get("btts_y", 1.75), probability=btts_prob, confidence=btts_prob * 100, risk_level=RiskLevel.MEDIUM )) # MS + 2.5 Üst kombinasyonu if favorite_prob >= 0.45 and over_25_prob >= 0.50: combo_prob = favorite_prob * over_25_prob # Basit çarpım combo_odds = odds.get(favorite, 2.00) * odds.get("ou25_o", 1.90) if combo_prob >= 0.30: # En az %30 olasılık medium_risk.append(BetRecommendation( market=f"MS {favorite} + 2.5 Üst", pick=f"{favorite} & OVER", odds=combo_odds, probability=combo_prob, confidence=combo_prob * 100, risk_level=RiskLevel.MEDIUM )) # ========== YÜKSEK RİSK ÖNERİLERİ ========== # 3.5 Üst if self.PROB_HIGH_RISK <= over_35_prob < self.PROB_MEDIUM_RISK: high_risk.append(BetRecommendation( market="3.5 Üst/Alt", pick="OVER", odds=odds.get("ou35_o", 3.20), probability=over_35_prob, confidence=over_35_prob * 100, risk_level=RiskLevel.HIGH )) # Skor tahmini (yüksek skorlu maçlar için) if expected_goals >= 3.5: score_str = f"{predicted_score[0]}-{predicted_score[1]}" # Skor olasılığı tahmini (basit model) score_prob = 0.15 if expected_goals <= 4 else 0.10 high_risk.append(BetRecommendation( market="Tam Skor", pick=score_str, odds=8.0, # Tahmini oran probability=score_prob, confidence=score_prob * 100, risk_level=RiskLevel.HIGH )) # MS + 3.5 Üst if favorite_prob >= 0.40 and over_35_prob >= 0.30: combo_prob = favorite_prob * over_35_prob combo_odds = odds.get(favorite, 2.00) * odds.get("ou35_o", 3.20) high_risk.append(BetRecommendation( market=f"MS {favorite} + 3.5 Üst", pick=f"{favorite} & OVER", odds=combo_odds, probability=combo_prob, confidence=combo_prob * 100, risk_level=RiskLevel.HIGH )) # ========== EXTREME RİSK ÖNERİLERİ ========== # Uzun kombinasyonlar if favorite_prob >= 0.50 and btts_prob >= 0.50 and over_25_prob >= 0.60: combo_prob = favorite_prob * btts_prob * over_25_prob combo_odds = odds.get(favorite, 2.00) * odds.get("btts_y", 1.75) * odds.get("ou25_o", 1.90) if combo_prob >= 0.15: # En az %15 olasılık extreme_risk.append(BetRecommendation( market=f"MS {favorite} + KG Var + 2.5 Üst", pick=f"{favorite} & BTTS & OVER", odds=combo_odds, probability=combo_prob, confidence=combo_prob * 100, risk_level=RiskLevel.EXTREME )) return MatchPredictionSet( match_name=match_name, predicted_score=predicted_score, home_win_prob=home_prob, draw_prob=draw_prob, away_win_prob=away_prob, over_15_prob=over_15_prob, over_25_prob=over_25_prob, over_35_prob=over_35_prob, btts_yes_prob=btts_prob, low_risk_bets=low_risk, medium_risk_bets=medium_risk, high_risk_bets=high_risk, extreme_risk_bets=extreme_risk ) # Singleton _recommender = None def get_smart_bet_recommender() -> SmartBetRecommender: global _recommender if _recommender is None: _recommender = SmartBetRecommender() return _recommender