This commit is contained in:
@@ -139,7 +139,7 @@ class FullMatchPrediction:
|
||||
ht_confidence: float = 0.0
|
||||
|
||||
# === SKOR TAHMİNLERİ ===
|
||||
score: ScorePrediction = None
|
||||
score: Optional[ScorePrediction] = None
|
||||
predicted_ft_score: str = "1-1"
|
||||
predicted_ht_score: str = "0-0"
|
||||
ft_scores_top5: List[Dict] = field(default_factory=list)
|
||||
@@ -161,7 +161,13 @@ class FullMatchPrediction:
|
||||
upset_score: int = 0 # 0-100 arası sürpriz skoru
|
||||
upset_level: str = "LOW" # LOW, MEDIUM, HIGH, EXTREME
|
||||
upset_reasons: List[str] = field(default_factory=list)
|
||||
|
||||
|
||||
# === SÜRPRİZ PROFİLİ ===
|
||||
surprise_score: float = 0.0 # 0-100 overall surprise risk score
|
||||
surprise_comment: str = "" # Human-readable surprise commentary
|
||||
surprise_reasons: List[str] = field(default_factory=list) # Flagged risk reasons
|
||||
surprise_breakdown: List[Dict[str, Any]] = field(default_factory=list) # Per-factor {code, points, label}
|
||||
|
||||
# === ENGINE KATKILARI ===
|
||||
team_confidence: float = 0.0
|
||||
player_confidence: float = 0.0
|
||||
@@ -412,18 +418,19 @@ class V20EnsemblePredictor:
|
||||
|
||||
# Calculators
|
||||
print("⚙️ Loading market calculators...")
|
||||
self.match_result_calc = MatchResultCalculator(self.config)
|
||||
self.over_under_calc = OverUnderCalculator(self.config)
|
||||
self.half_time_calc = HalfTimeCalculator(self.config)
|
||||
self.score_calc = ScoreCalculator(self.config)
|
||||
cfg: Any = self.config
|
||||
self.match_result_calc = MatchResultCalculator(cfg)
|
||||
self.over_under_calc = OverUnderCalculator(cfg)
|
||||
self.half_time_calc = HalfTimeCalculator(cfg)
|
||||
self.score_calc = ScoreCalculator(cfg)
|
||||
print(" ✅ Score Calculator (XGBoost FT+HT) loaded")
|
||||
self.other_markets_calc = OtherMarketsCalculator(self.config)
|
||||
self.risk_assessor = RiskAssessor(self.config)
|
||||
self.bet_recommender = BetRecommender(self.config)
|
||||
self.other_markets_calc = OtherMarketsCalculator(cfg)
|
||||
self.risk_assessor = RiskAssessor(cfg)
|
||||
self.bet_recommender = BetRecommender(cfg)
|
||||
|
||||
# Expert Recommender (New Logic)
|
||||
from core.calculators.expert_recommender import ExpertRecommender
|
||||
self.expert_recommender = ExpertRecommender(self.config)
|
||||
self.expert_recommender = ExpertRecommender(cfg)
|
||||
|
||||
# XGBoost Integration
|
||||
print("🤖 Loading XGBoost models...")
|
||||
@@ -551,7 +558,7 @@ class V20EnsemblePredictor:
|
||||
features = features.copy()
|
||||
features[col] = 0.0
|
||||
|
||||
return features[expected]
|
||||
return features[expected] # type: ignore[return-value]
|
||||
|
||||
def _favorite_profile_from_odds(self, odds_data: Dict[str, float]) -> Tuple[str, float]:
|
||||
"""
|
||||
@@ -838,10 +845,10 @@ class V20EnsemblePredictor:
|
||||
home_team_name: str,
|
||||
away_team_name: str,
|
||||
match_date_ms: int,
|
||||
odds_data: Dict[str, float] = None,
|
||||
home_lineup: List[str] = None,
|
||||
away_lineup: List[str] = None,
|
||||
referee_name: str = None,
|
||||
odds_data: Optional[Dict[str, float]] = None,
|
||||
home_lineup: Optional[List[str]] = None,
|
||||
away_lineup: Optional[List[str]] = None,
|
||||
referee_name: Optional[str] = None,
|
||||
home_goals_avg: float = 1.5,
|
||||
home_conceded_avg: float = 1.2,
|
||||
away_goals_avg: float = 1.2,
|
||||
@@ -849,9 +856,9 @@ class V20EnsemblePredictor:
|
||||
home_position: int = 10,
|
||||
away_position: int = 10,
|
||||
league_name: str = "",
|
||||
league_id: str = None,
|
||||
league_id: Optional[str] = None,
|
||||
sport: str = "football",
|
||||
sidelined_data: Dict = None) -> FullMatchPrediction:
|
||||
sidelined_data: Optional[Dict] = None) -> FullMatchPrediction:
|
||||
"""
|
||||
Generate complete V20 ensemble prediction.
|
||||
|
||||
@@ -895,8 +902,8 @@ class V20EnsemblePredictor:
|
||||
|
||||
referee_pred = self.referee_engine.predict(
|
||||
match_id=match_id,
|
||||
referee_name=referee_name,
|
||||
league_id=league_id
|
||||
referee_name=referee_name or "",
|
||||
league_id=league_id or ""
|
||||
)
|
||||
|
||||
upset_factors = self.upset_engine.calculate_upset_potential(
|
||||
@@ -935,9 +942,9 @@ class V20EnsemblePredictor:
|
||||
away_position=away_position,
|
||||
match_date_ms=match_date_ms,
|
||||
odds_data=odds_data,
|
||||
referee_name=referee_name,
|
||||
home_form_score=team_pred.home_form_score if hasattr(team_pred, 'home_form_score') else 50.0,
|
||||
away_form_score=team_pred.away_form_score if hasattr(team_pred, 'away_form_score') else 50.0,
|
||||
referee_name=referee_name or "",
|
||||
home_form_score=getattr(team_pred, 'home_form_score', 50.0),
|
||||
away_form_score=getattr(team_pred, 'away_form_score', 50.0),
|
||||
favorite_side=favorite_side,
|
||||
favorite_odds=favorite_odds
|
||||
)
|
||||
@@ -1105,7 +1112,7 @@ class V20EnsemblePredictor:
|
||||
|
||||
best_bet = _map_dto(rec_result.best_bet)
|
||||
alt_bet = _map_dto(rec_result.alternative_bet)
|
||||
recommended = [_map_dto(r) for r in rec_result.recommended_bets]
|
||||
recommended = [m for m in (_map_dto(r) for r in rec_result.recommended_bets) if m is not None]
|
||||
|
||||
# Analysis Details
|
||||
analysis_details = {
|
||||
@@ -1187,13 +1194,13 @@ class V20EnsemblePredictor:
|
||||
|
||||
# Others
|
||||
total_corners_pred=other_result.total_corners_pred,
|
||||
corner_pick=other_result.corner_pick,
|
||||
corner_pick=other_result.corner_pick or "",
|
||||
total_cards_pred=other_result.total_cards_pred,
|
||||
card_pick=other_result.card_pick,
|
||||
card_pick=other_result.card_pick or "",
|
||||
cards_over_prob=other_result.cards_over_prob,
|
||||
cards_under_prob=other_result.cards_under_prob,
|
||||
cards_confidence=other_result.cards_confidence,
|
||||
handicap_pick=other_result.handicap_pick,
|
||||
handicap_pick=other_result.handicap_pick or "",
|
||||
handicap_home_prob=other_result.handicap_home_prob,
|
||||
handicap_draw_prob=other_result.handicap_draw_prob,
|
||||
handicap_away_prob=other_result.handicap_away_prob,
|
||||
|
||||
Reference in New Issue
Block a user