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

65 lines
1.8 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.
"""凱利準則Kelly Criterion工具。"""
from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True)
class KellyResult:
"""凱利投注建議結果。"""
decimal_odds: float
win_probability: float
raw_kelly_fraction: float
fractional_kelly_factor: float
risk_tolerance_factor: float
final_fraction: float
stake_fraction: float
def calculate_kelly_fraction(
decimal_odds: float,
true_prob: float,
*,
bankroll: float,
fractional_kelly_factor: float = 1.0,
risk_tolerance_factor: float = 1.0,
) -> KellyResult:
"""依凱利準則估算下注比例與建議金額。
凱利公式:
f* = (b * p - q) / b
其中 b = odds - 1p 為勝率q = 1 - p。
"""
if decimal_odds <= 1:
raise ValueError('decimal_odds 必須大於 1')
if bankroll <= 0:
raise ValueError('bankroll 必須大於 0')
if not 0 <= true_prob <= 1:
raise ValueError('true_prob 需介於 0 到 1')
if not 0 <= fractional_kelly_factor <= 5:
raise ValueError('fractional_kelly_factor 須介於 0 到 5')
if not 0 <= risk_tolerance_factor <= 2:
raise ValueError('risk_tolerance_factor 須介於 0 到 2')
b = decimal_odds - 1
raw_kelly = (b * true_prob - (1 - true_prob)) / b
final_fraction = raw_kelly * fractional_kelly_factor * risk_tolerance_factor
# 保守處理避免負值與超過總資金比例100%)的極端輸出。
final_fraction = max(0.0, min(final_fraction, 1.0))
return KellyResult(
decimal_odds=decimal_odds,
win_probability=true_prob,
raw_kelly_fraction=raw_kelly,
fractional_kelly_factor=fractional_kelly_factor,
risk_tolerance_factor=risk_tolerance_factor,
final_fraction=final_fraction,
stake_fraction=final_fraction,
)
__all__ = ['KellyResult', 'calculate_kelly_fraction']