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,
|
"calibration_error": 0.0,
|
||||||
"sample_count": 13,
|
"sample_count": 5000,
|
||||||
"last_trained": "2026-05-11T23:38:11.500966",
|
"last_trained": "2026-05-24T23:10:58.196981",
|
||||||
"mean_predicted": 0.7239,
|
"mean_predicted": 0.7586,
|
||||||
"mean_actual": 0.6154
|
"mean_actual": 0.7732
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"brier_score": 0.2222,
|
"brier_score": 0.2386,
|
||||||
"calibration_error": 0.0,
|
"calibration_error": 0.0,
|
||||||
"sample_count": 18,
|
"sample_count": 5000,
|
||||||
"last_trained": "2026-05-11T23:38:11.508353",
|
"last_trained": "2026-05-24T23:10:58.207151",
|
||||||
"mean_predicted": 0.6258,
|
"mean_predicted": 0.5013,
|
||||||
"mean_actual": 0.5
|
"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:
|
if market in {"HT", "HTFT", "OE"} and score < 86.0:
|
||||||
vetoes.append("volatile_market_requires_exceptional_evidence")
|
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 override: bypass eligible vetoes when value sniper triggered
|
||||||
sniper_bypassed: List[str] = []
|
sniper_bypassed: List[str] = []
|
||||||
if is_value_sniper and vetoes:
|
if is_value_sniper and vetoes:
|
||||||
|
|||||||
Reference in New Issue
Block a user