Files
2026FIFAWorldCup/platform/backend/app/analytics/rlm.py

71 lines
1.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""反向盤口移動RLM偵測模組。"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
@dataclass(frozen=True)
class ReverseLineMovementAlert:
match_id: str
market_type: str
selection: str
opening_odds: float
current_odds: float
ticket_pct: float
handle_pct: float
odds_change_pct: float
smart_money_to: str
is_triggered: bool
triggered_at: datetime
rationale: str
def evaluate_reverse_line_movement(
match_id: str,
market_type: str,
selection: str,
*,
opening_odds: float,
current_odds: float,
ticket_pct: float,
handle_pct: float,
ticket_threshold: float = 70.0,
odds_change_threshold: float = 0.05,
) -> ReverseLineMovementAlert:
"""依條件判斷是否出現反向盤口。"""
if opening_odds <= 0:
odds_pct = 0.0
else:
odds_pct = round((current_odds - opening_odds) / opening_odds, 6)
is_triggered = (
ticket_pct > ticket_threshold
and odds_pct > odds_change_threshold
and handle_pct < ticket_pct
)
smart_money_to = selection if handle_pct > ticket_pct else '對側'
rationale = (
f'散戶 {ticket_pct:.1f}% 追捧卻資金 {handle_pct:.1f}%\n'
f'盤口由 {opening_odds:.2f} 上升到 {current_odds:.2f}'
)
return ReverseLineMovementAlert(
match_id=match_id,
market_type=market_type,
selection=selection,
opening_odds=opening_odds,
current_odds=current_odds,
ticket_pct=ticket_pct,
handle_pct=handle_pct,
odds_change_pct=round(odds_pct * 100, 4),
smart_money_to=smart_money_to,
is_triggered=is_triggered,
triggered_at=datetime.utcnow(),
rationale=rationale,
)