Spaces:
Runtime error
Runtime error
File size: 10,292 Bytes
6f7e932 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | """
Confidence-Based Prediction Sections
Categorizes predictions by confidence level:
- Sure Win: 91%+ confidence (ultra-high probability picks)
- Strong Picks: 80-90% confidence (reliable selections)
- Value Hunters: 5%+ edge vs bookmaker odds
- Upset Watch: Underdog potential picks
- Daily Banker: Single safest pick of the day
"""
from dataclasses import dataclass, asdict
from typing import Dict, List, Optional, Tuple
from datetime import datetime
import json
@dataclass
class SectionConfig:
"""Configuration for a confidence section"""
name: str
description: str
icon: str
color: str
min_confidence: Optional[float] = None
max_confidence: Optional[float] = None
min_edge: Optional[float] = None
max_picks: Optional[int] = None
class ConfidenceSectionsManager:
"""
Categorize predictions into confidence-based sections.
Sections:
- Sure Win: 91%+ confidence picks (very rare, very reliable)
- Strong Picks: 80-90% confidence (solid selections)
- Value Hunters: Good edge vs market odds (5%+ value)
- Upset Watch: Underdog potential (25%+ probability)
- Daily Banker: Single highest confidence pick
"""
SECTIONS = {
'sure_win': SectionConfig(
name='🔒 Sure Win',
description='Ultra-high confidence picks (91%+ probability)',
icon='🔒',
color='#10B981', # Emerald green
min_confidence=0.91
),
'strong_picks': SectionConfig(
name='💪 Strong Picks',
description='High confidence selections (80-90%)',
icon='💪',
color='#3B82F6', # Blue
min_confidence=0.80,
max_confidence=0.90
),
'value_hunters': SectionConfig(
name='💎 Value Hunters',
description='Great edge vs bookmaker odds (5%+ value)',
icon='💎',
color='#8B5CF6', # Purple
min_edge=0.05
),
'upset_watch': SectionConfig(
name='⚡ Upset Watch',
description='Potential upsets worth watching',
icon='⚡',
color='#F59E0B', # Amber
),
'daily_banker': SectionConfig(
name='🎯 Daily Banker',
description='Single safest pick of the day',
icon='🎯',
color='#EF4444', # Red
max_picks=1
),
'risky_rewards': SectionConfig(
name='🎲 Risky Rewards',
description='Long shots with high potential returns',
icon='🎲',
color='#EC4899', # Pink
min_confidence=0.30,
max_confidence=0.50
)
}
def __init__(self):
self.prediction_history = []
def categorize(self, predictions: List[Dict]) -> Dict[str, List[Dict]]:
"""
Sort predictions into confidence-based sections.
Args:
predictions: List of prediction dicts with 'confidence', 'value_edge', etc.
Returns:
Dict mapping section name to list of predictions
"""
sections = {key: [] for key in self.SECTIONS}
if not predictions:
return sections
for pred in predictions:
confidence = pred.get('confidence', 0)
if isinstance(confidence, str):
confidence = float(confidence.replace('%', '')) / 100
elif confidence > 1:
confidence = confidence / 100
edge = pred.get('value_edge', 0) or 0
# Determine predicted outcome probabilities
home_prob = pred.get('home_win_prob', 0) or 0
draw_prob = pred.get('draw_prob', 0) or 0
away_prob = pred.get('away_win_prob', 0) or 0
# Normalize if needed
if home_prob > 1:
home_prob /= 100
if draw_prob > 1:
draw_prob /= 100
if away_prob > 1:
away_prob /= 100
max_prob = max(home_prob, draw_prob, away_prob)
# Sure Win: 91%+ confidence
if confidence >= 0.91 or max_prob >= 0.91:
sections['sure_win'].append(self._enrich_prediction(pred, 'sure_win'))
# Strong Picks: 80-90%
elif confidence >= 0.80 or max_prob >= 0.80:
sections['strong_picks'].append(self._enrich_prediction(pred, 'strong_picks'))
# Value Hunters: 5%+ edge
if edge >= 0.05:
sections['value_hunters'].append(self._enrich_prediction(pred, 'value_hunters'))
# Upset Watch: Underdog with reasonable probability
is_upset = self._is_upset_potential(pred)
if is_upset:
sections['upset_watch'].append(self._enrich_prediction(pred, 'upset_watch'))
# Risky Rewards: 30-50% confidence but good odds
if 0.30 <= confidence <= 0.50:
sections['risky_rewards'].append(self._enrich_prediction(pred, 'risky_rewards'))
# Daily Banker: Highest confidence pick
if predictions:
best = max(predictions, key=lambda x: self._get_confidence(x))
sections['daily_banker'] = [self._enrich_prediction(best, 'daily_banker')]
# Sort each section by confidence descending
for section_name in sections:
if section_name != 'daily_banker':
sections[section_name].sort(
key=lambda x: self._get_confidence(x),
reverse=True
)
return sections
def _get_confidence(self, pred: Dict) -> float:
"""Extract normalized confidence from prediction"""
confidence = pred.get('confidence', 0)
if isinstance(confidence, str):
confidence = float(confidence.replace('%', '')) / 100
elif confidence > 1:
confidence = confidence / 100
return confidence
def _is_upset_potential(self, pred: Dict) -> bool:
"""
Check if this is a potential upset.
Criteria:
- Lower-ranked team has 25%+ win probability
- OR home team expected to lose but has 30%+ probability
"""
home_prob = pred.get('home_win_prob', 0) or 0
away_prob = pred.get('away_win_prob', 0) or 0
if home_prob > 1:
home_prob /= 100
if away_prob > 1:
away_prob /= 100
# Check ELO difference if available
home_elo = pred.get('home_elo', 1500)
away_elo = pred.get('away_elo', 1500)
# Underdog is team with lower ELO
if home_elo < away_elo and home_prob >= 0.25:
return True
elif away_elo < home_elo and away_prob >= 0.25:
return True
# Also check if predicted outcome differs from ELO expectation
predicted = pred.get('predicted_outcome', '')
if home_elo > away_elo + 50 and predicted == 'Away':
return True
elif away_elo > home_elo + 50 and predicted == 'Home':
return True
return False
def _enrich_prediction(self, pred: Dict, section: str) -> Dict:
"""Add section metadata to prediction"""
enriched = pred.copy()
enriched['section'] = section
enriched['section_config'] = asdict(self.SECTIONS[section])
return enriched
def get_sure_wins(self, predictions: List[Dict]) -> List[Dict]:
"""Get only Sure Win picks (91%+ confidence)"""
return self.categorize(predictions)['sure_win']
def get_strong_picks(self, predictions: List[Dict]) -> List[Dict]:
"""Get Strong Picks (80-90% confidence)"""
return self.categorize(predictions)['strong_picks']
def get_value_bets(self, predictions: List[Dict]) -> List[Dict]:
"""Get Value Hunter picks (5%+ edge)"""
return self.categorize(predictions)['value_hunters']
def get_daily_banker(self, predictions: List[Dict]) -> Optional[Dict]:
"""Get the single Daily Banker pick"""
bankers = self.categorize(predictions)['daily_banker']
return bankers[0] if bankers else None
def get_section_stats(self, predictions: List[Dict]) -> Dict:
"""Get statistics about each section"""
sections = self.categorize(predictions)
stats = {}
for section_name, preds in sections.items():
if preds:
confidences = [self._get_confidence(p) for p in preds]
stats[section_name] = {
'count': len(preds),
'avg_confidence': round(sum(confidences) / len(confidences) * 100, 1),
'min_confidence': round(min(confidences) * 100, 1),
'max_confidence': round(max(confidences) * 100, 1),
'config': asdict(self.SECTIONS[section_name])
}
else:
stats[section_name] = {
'count': 0,
'avg_confidence': 0,
'min_confidence': 0,
'max_confidence': 0,
'config': asdict(self.SECTIONS[section_name])
}
return stats
def get_all_sections_config(self) -> Dict:
"""Get configuration for all sections"""
return {
name: asdict(config)
for name, config in self.SECTIONS.items()
}
# Global instance
confidence_manager = ConfidenceSectionsManager()
def get_confidence_sections(predictions: List[Dict]) -> Dict[str, List[Dict]]:
"""Get predictions organized by confidence sections"""
return confidence_manager.categorize(predictions)
def get_sure_wins(predictions: List[Dict]) -> List[Dict]:
"""Get 91%+ confidence predictions"""
return confidence_manager.get_sure_wins(predictions)
def get_daily_banker(predictions: List[Dict]) -> Optional[Dict]:
"""Get single safest pick"""
return confidence_manager.get_daily_banker(predictions)
|