Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.2444,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.117788",
|
||||
"mean_predicted": 0.4015,
|
||||
"mean_actual": 0.5454
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.1852,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 4989,
|
||||
"last_trained": "2026-05-24T23:10:58.129841",
|
||||
"mean_predicted": 0.2305,
|
||||
"mean_actual": 0.263
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.2383,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 4989,
|
||||
"last_trained": "2026-05-24T23:10:58.142015",
|
||||
"mean_predicted": 0.4549,
|
||||
"mean_actual": 0.4001
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.2137,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 4989,
|
||||
"last_trained": "2026-05-24T23:10:58.153390",
|
||||
"mean_predicted": 0.3146,
|
||||
"mean_actual": 0.3369
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.1956,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.164629",
|
||||
"mean_predicted": 0.3215,
|
||||
"mean_actual": 0.3196
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.1816,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.175615",
|
||||
"mean_predicted": 0.2453,
|
||||
"mean_actual": 0.2426
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.2241,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.186473",
|
||||
"mean_predicted": 0.4332,
|
||||
"mean_actual": 0.4378
|
||||
}
|
||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.196,
|
||||
"brier_score": 0.1708,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 13,
|
||||
"last_trained": "2026-05-11T23:38:11.500966",
|
||||
"mean_predicted": 0.7239,
|
||||
"mean_actual": 0.6154
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.196981",
|
||||
"mean_predicted": 0.7586,
|
||||
"mean_actual": 0.7732
|
||||
}
|
||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.2222,
|
||||
"brier_score": 0.2386,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 18,
|
||||
"last_trained": "2026-05-11T23:38:11.508353",
|
||||
"mean_predicted": 0.6258,
|
||||
"mean_actual": 0.5
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.207151",
|
||||
"mean_predicted": 0.5013,
|
||||
"mean_actual": 0.5538
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"brier_score": 0.215,
|
||||
"calibration_error": 0.0,
|
||||
"sample_count": 5000,
|
||||
"last_trained": "2026-05-24T23:10:58.217663",
|
||||
"mean_predicted": 0.305,
|
||||
"mean_actual": 0.3408
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
@@ -312,6 +312,52 @@ class BettingBrain:
|
||||
if market in {"HT", "HTFT", "OE"} and score < 86.0:
|
||||
vetoes.append("volatile_market_requires_exceptional_evidence")
|
||||
|
||||
# Cross-market reversal risk for MS/DC picks.
|
||||
# If HTFT model says the *opposite* of our MS pick is likely (a
|
||||
# reversal scenario like 1/2 or 2/1), the MS pick is fragile even
|
||||
# when its own calibrated_confidence is high. The Manchester City
|
||||
# 1-0 → 1-2 case is exactly this: MS=1 looked solid but HTFT 1/2
|
||||
# carried real probability mass that the MS scorer ignored.
|
||||
if market == "MS" and pick in ("1", "2"):
|
||||
board = package.get("market_board") or {}
|
||||
htft_payload = board.get("HTFT") if isinstance(board, dict) else None
|
||||
htft_probs = (
|
||||
htft_payload.get("probs", {})
|
||||
if isinstance(htft_payload, dict) else {}
|
||||
)
|
||||
risk_payload = package.get("risk") or {}
|
||||
if not htft_probs and isinstance(risk_payload, dict):
|
||||
htft_probs = risk_payload.get("ht_ft_probs", {}) or {}
|
||||
# Reversal outcomes that would make this MS pick lose despite
|
||||
# the team leading at half-time / trailing at half-time.
|
||||
if pick == "1":
|
||||
# Picked home win. Threats: 1/2 (led, lost) and 1/X (led, drew).
|
||||
reversal_keys = ("1/2", "1/X")
|
||||
drift_keys = ("X/2",)
|
||||
else:
|
||||
# Picked away win. Threats: 2/1, 2/X. Drift: X/1.
|
||||
reversal_keys = ("2/1", "2/X")
|
||||
drift_keys = ("X/1",)
|
||||
reversal_prob = sum(
|
||||
self._safe_float(htft_probs.get(key), 0.0) or 0.0
|
||||
for key in reversal_keys
|
||||
)
|
||||
drift_prob = sum(
|
||||
self._safe_float(htft_probs.get(key), 0.0) or 0.0
|
||||
for key in drift_keys
|
||||
)
|
||||
combined_risk = reversal_prob + 0.5 * drift_prob
|
||||
if combined_risk >= 0.25:
|
||||
score -= 28.0
|
||||
vetoes.append("htft_reversal_risk_high")
|
||||
issues.append(f"htft_reversal_prob={combined_risk:.2f}")
|
||||
elif combined_risk >= 0.15:
|
||||
score -= 14.0
|
||||
issues.append(f"htft_reversal_prob_moderate={combined_risk:.2f}")
|
||||
elif combined_risk >= 0.10:
|
||||
score -= 6.0
|
||||
issues.append(f"htft_reversal_prob_minor={combined_risk:.2f}")
|
||||
|
||||
# Sniper override: bypass eligible vetoes when value sniper triggered
|
||||
sniper_bypassed: List[str] = []
|
||||
if is_value_sniper and vetoes:
|
||||
|
||||
Reference in New Issue
Block a user