80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
from datetime import datetime, timedelta
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, func
|
|
from app.models.bet import Bet
|
|
from app.models.bankroll import Bankroll
|
|
|
|
async def calculate_risk_score(user_id, db: AsyncSession) -> dict:
|
|
score = 0
|
|
factors = []
|
|
now = datetime.utcnow()
|
|
|
|
# 1. Horário noturno (22h-5h) +15
|
|
hour = now.hour
|
|
if hour >= 22 or hour < 5:
|
|
score += 15
|
|
factors.append("Apostando em horário noturno")
|
|
|
|
# 2. Valor crescente +25
|
|
recent = await db.execute(
|
|
select(Bet).where(Bet.user_id == user_id).order_by(Bet.created_at.desc()).limit(5)
|
|
)
|
|
recent_bets = recent.scalars().all()
|
|
if len(recent_bets) >= 3:
|
|
amounts = [float(b.amount) for b in recent_bets[:3]]
|
|
if amounts[0] > amounts[1] > amounts[2]:
|
|
score += 25
|
|
factors.append("Valores de aposta crescentes")
|
|
|
|
# 3. Recuperação (aposta logo após loss) +30
|
|
if len(recent_bets) >= 2:
|
|
last = recent_bets[0]
|
|
prev = recent_bets[1]
|
|
if prev.result == "loss" and last.created_at and prev.created_at:
|
|
diff = (last.created_at - prev.created_at).total_seconds()
|
|
if diff < 1800: # 30 min
|
|
score += 30
|
|
factors.append("Tentativa de recuperação após perda")
|
|
|
|
# 4. Frequência alta (>5 apostas em 24h) +20
|
|
day_ago = now - timedelta(hours=24)
|
|
count_result = await db.execute(
|
|
select(func.count()).select_from(Bet).where(Bet.user_id == user_id, Bet.created_at >= day_ago)
|
|
)
|
|
bet_count = count_result.scalar() or 0
|
|
if bet_count > 5:
|
|
score += 20
|
|
factors.append(f"Alta frequência: {bet_count} apostas em 24h")
|
|
|
|
# 5. Limite estourado +25
|
|
br_result = await db.execute(select(Bankroll).where(Bankroll.user_id == user_id))
|
|
bankroll = br_result.scalar_one_or_none()
|
|
if bankroll and float(bankroll.month_spent) > float(bankroll.monthly_budget):
|
|
score += 25
|
|
factors.append("Limite mensal ultrapassado")
|
|
|
|
# 6. Emoção negativa +15
|
|
if recent_bets and recent_bets[0].emotion in ["😤", "😰", "tilt", "ansioso", "frustrado"]:
|
|
score += 15
|
|
factors.append("Emoção negativa detectada")
|
|
|
|
# 7. Sequência de perdas +20
|
|
loss_streak = 0
|
|
for b in recent_bets:
|
|
if b.result == "loss":
|
|
loss_streak += 1
|
|
else:
|
|
break
|
|
if loss_streak >= 3:
|
|
score += 20
|
|
factors.append(f"Sequência de {loss_streak} perdas consecutivas")
|
|
|
|
if score <= 30:
|
|
level = "green"
|
|
elif score <= 60:
|
|
level = "yellow"
|
|
else:
|
|
level = "red"
|
|
|
|
return {"score": score, "level": level, "factors": factors}
|