vv
Deploy Iddaai Backend / build-and-deploy (push) Successful in 1m7s

This commit is contained in:
2026-06-02 03:37:00 +03:00
parent 671979b07d
commit 4e563e996e
10 changed files with 708 additions and 0 deletions
@@ -86,6 +86,28 @@ POST_CAL_TRUST: Dict[str, float] = {
class MarketBoardMixin:
def _league_confidence_for(self, league_id: Optional[str]) -> Optional[Dict[str, Any]]:
"""Return the backtest-derived confidence record for a league, or None.
Shape: {"label": high|medium|low, "bet_roi": float, "bet_n": int,
"hit": float}. None → league absent or too few bets ('unknown') → FE
shows no badge. Never raises (missing artifact = graceful None)."""
if not league_id:
return None
lookup = getattr(self, "league_confidence", None) or {}
info = lookup.get(str(league_id))
if not isinstance(info, dict):
return None
label = info.get("label")
if label in (None, "unknown"):
return None
return {
"label": label,
"bet_roi": info.get("bet_roi"),
"bet_n": info.get("bet_n"),
"hit": info.get("hit"),
}
def _build_prediction_package(
self,
data: MatchData,
@@ -320,6 +342,10 @@ class MarketBoardMixin:
"home_team": data.home_team_name,
"away_team": data.away_team_name,
"league": data.league_name,
"league_id": data.league_id,
# Backtest-derived per-league confidence (ROI + sample size).
# None when the league has too little data to judge → FE shows no badge.
"league_confidence": self._league_confidence_for(data.league_id),
"match_date_ms": data.match_date_ms,
"sport": data.sport,
# Live snapshot — match_commentary uses this to detect upset-in-progress
@@ -57,6 +57,7 @@ from services.v26_shadow_engine import V26ShadowEngine, get_v26_shadow_engine
from services.match_commentary import generate_match_commentary
from utils.top_leagues import load_top_league_ids
from utils.league_reliability import load_league_reliability
from utils.league_confidence import load_league_confidence
from config.config_loader import build_threshold_dict, get_threshold_default, get_config
from models.calibration import get_calibrator
@@ -171,6 +172,7 @@ class SingleMatchOrchestrator(
self.engine_mode = str(os.getenv("AI_ENGINE_MODE", "v28-pro-max")).strip().lower()
self.top_league_ids = load_top_league_ids()
self.league_reliability = load_league_reliability()
self.league_confidence = load_league_confidence()
self.enrichment = FeatureEnrichmentService()
self.odds_band_analyzer = OddsBandAnalyzer()
# ── Market Thresholds (loaded from config/market_thresholds.json) ──