'use client'; import { FormEvent, useEffect, useMemo, useState } from 'react'; import { calculateKellyRecommendation } from '@/lib/betting-utils'; import { TW_DOLLAR } from '@/lib/betting-utils'; import { calculateKelly, type KellyResponse } from '@/lib/analytics-api'; export function BetSizingSlider() { const [bankroll, setBankroll] = useState(5000); const [odds, setOdds] = useState(2.4); const [probability, setProbability] = useState(0.55); const [fractional, setFractional] = useState(0.25); const [riskTolerance, setRiskTolerance] = useState(1); const [kellyProfile, setKellyProfile] = useState(null); const [isLoading, setIsLoading] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const profile = useMemo(() => { try { return calculateKellyRecommendation({ odds, trueProb: probability, bankroll, fractionalKelly: fractional, riskTolerance, }); } catch { return { recommendedStake: 0, recommendedFraction: 0, }; } }, [odds, probability, bankroll, fractional, riskTolerance]); const backendProfile = useMemo( () => ({ odds, true_prob: probability, bankroll, fractional_kelly_factor: fractional, risk_tolerance_factor: riskTolerance, }), [bankroll, fractional, odds, probability, riskTolerance], ); const showFractionPercent = kellyProfile ? kellyProfile.recommended_fraction : profile.recommendedFraction; const showStake = kellyProfile ? kellyProfile.recommended_stake : profile.recommendedStake; function onBankrollSubmit(event: FormEvent) { event.preventDefault(); } useEffect(() => { const handle = new AbortController(); setIsLoading(true); setErrorMessage(''); const runCalculation = async () => { try { const data = await calculateKelly(backendProfile); if (!handle.signal.aborted) { setKellyProfile(data); } } catch (error) { if (handle.signal.aborted) { return; } setErrorMessage(error instanceof Error ? error.message : '凱利計算暫時失敗,使用本機備援值'); } finally { if (!handle.signal.aborted) { setIsLoading(false); } } }; runCalculation(); return () => { handle.abort(); }; }, [backendProfile]); return (

凱利準則下注建議儀表板

建議下注金額

{TW_DOLLAR.format(profile.recommendedStake)}

建議投注比例:{showFractionPercent.toFixed(1)}%

建議下注金額:{TW_DOLLAR.format(showStake)}

{isLoading ?

重新計算下注建議中…

: null} {errorMessage ?

{errorMessage}

: null}
); }