175 lines
5.8 KiB
Python
175 lines
5.8 KiB
Python
"""
|
|
Add 100 spread bets to the Wake Forest vs MS State game
|
|
"""
|
|
import asyncio
|
|
import random
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
from sqlalchemy import select
|
|
|
|
from app.database import async_session
|
|
from app.models import User, Wallet, SportEvent, SpreadBet
|
|
from app.models.spread_bet import TeamSide, SpreadBetStatus
|
|
from app.utils.security import get_password_hash
|
|
|
|
|
|
# Fake names for generating users
|
|
FIRST_NAMES = [
|
|
"James", "Emma", "Liam", "Olivia", "Noah", "Ava", "Oliver", "Sophia",
|
|
"Elijah", "Isabella", "Lucas", "Mia", "Mason", "Charlotte", "Ethan",
|
|
"Amelia", "Logan", "Harper", "Aiden", "Evelyn", "Jackson", "Luna",
|
|
"Sebastian", "Camila", "Henry", "Gianna", "Alexander", "Abigail"
|
|
]
|
|
|
|
LAST_NAMES = [
|
|
"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller",
|
|
"Davis", "Rodriguez", "Martinez", "Wilson", "Anderson", "Taylor",
|
|
"Thomas", "Moore", "Jackson", "Martin", "Lee", "Thompson", "White"
|
|
]
|
|
|
|
|
|
async def create_users_if_needed(db, count: int) -> list[User]:
|
|
"""Create additional test users if needed"""
|
|
# Get existing users
|
|
result = await db.execute(select(User).where(User.is_admin == False))
|
|
existing_users = list(result.scalars().all())
|
|
|
|
if len(existing_users) >= count:
|
|
return existing_users[:count]
|
|
|
|
# Create more users
|
|
users_needed = count - len(existing_users)
|
|
print(f"Creating {users_needed} additional test users...")
|
|
|
|
new_users = []
|
|
for i in range(users_needed):
|
|
first = random.choice(FIRST_NAMES)
|
|
last = random.choice(LAST_NAMES)
|
|
username = f"{first.lower()}{last.lower()}{random.randint(1, 999)}"
|
|
email = f"{username}@example.com"
|
|
|
|
# Check if user exists
|
|
result = await db.execute(select(User).where(User.email == email))
|
|
if result.scalar_one_or_none():
|
|
continue
|
|
|
|
user = User(
|
|
email=email,
|
|
username=username,
|
|
password_hash=get_password_hash("password123"),
|
|
display_name=f"{first} {last}"
|
|
)
|
|
db.add(user)
|
|
await db.flush()
|
|
|
|
# Create wallet with random balance
|
|
wallet = Wallet(
|
|
user_id=user.id,
|
|
balance=Decimal(str(random.randint(500, 5000))),
|
|
escrow=Decimal("0.00")
|
|
)
|
|
db.add(wallet)
|
|
new_users.append(user)
|
|
|
|
await db.commit()
|
|
|
|
# Re-fetch all users
|
|
result = await db.execute(select(User).where(User.is_admin == False))
|
|
return list(result.scalars().all())
|
|
|
|
|
|
async def add_bets():
|
|
"""Add 100 spread bets to Wake Forest vs MS State game"""
|
|
async with async_session() as db:
|
|
# Find the Wake Forest vs MS State event
|
|
result = await db.execute(
|
|
select(SportEvent).where(
|
|
SportEvent.home_team == "Wake Forest",
|
|
SportEvent.away_team == "MS State"
|
|
)
|
|
)
|
|
event = result.scalar_one_or_none()
|
|
|
|
if not event:
|
|
print("Error: Wake Forest vs MS State event not found!")
|
|
print("Please run init_spread_betting.py first")
|
|
return
|
|
|
|
print(f"Found event: {event.home_team} vs {event.away_team} (ID: {event.id})")
|
|
print(f"Official spread: {event.official_spread}")
|
|
print(f"Spread range: {event.min_spread} to {event.max_spread}")
|
|
|
|
# Create/get test users (need at least 20 for variety)
|
|
users = await create_users_if_needed(db, 20)
|
|
print(f"Using {len(users)} users to create bets")
|
|
|
|
# Generate 100 bets
|
|
print("\nCreating 100 spread bets...")
|
|
|
|
# Spread range from -10 to +10 with 0.5 increments
|
|
spreads = [x / 2 for x in range(-20, 21)] # -10.0 to +10.0
|
|
|
|
# Stake amounts - realistic distribution
|
|
stakes = [25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, 1000]
|
|
|
|
bets_created = 0
|
|
for i in range(100):
|
|
creator = random.choice(users)
|
|
|
|
# Generate spread - cluster around the official spread with some outliers
|
|
if random.random() < 0.7:
|
|
# 70% of bets cluster around official spread (+/- 3 points)
|
|
spread = event.official_spread + random.choice([-3, -2.5, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3])
|
|
else:
|
|
# 30% are spread across the full range
|
|
spread = random.choice(spreads)
|
|
|
|
# Clamp to valid range
|
|
spread = max(event.min_spread, min(event.max_spread, spread))
|
|
|
|
# Random team side
|
|
team = random.choice([TeamSide.HOME, TeamSide.AWAY])
|
|
|
|
# Random stake - weighted toward smaller amounts
|
|
if random.random() < 0.6:
|
|
stake = random.choice(stakes[:6]) # 60% small bets
|
|
elif random.random() < 0.85:
|
|
stake = random.choice(stakes[6:10]) # 25% medium bets
|
|
else:
|
|
stake = random.choice(stakes[10:]) # 15% large bets
|
|
|
|
bet = SpreadBet(
|
|
event_id=event.id,
|
|
spread=spread,
|
|
team=team,
|
|
creator_id=creator.id,
|
|
stake_amount=Decimal(str(stake)),
|
|
house_commission_percent=Decimal("10.00"),
|
|
status=SpreadBetStatus.OPEN,
|
|
created_at=datetime.utcnow()
|
|
)
|
|
db.add(bet)
|
|
bets_created += 1
|
|
|
|
if (i + 1) % 20 == 0:
|
|
print(f" Created {i + 1} bets...")
|
|
|
|
await db.commit()
|
|
|
|
print(f"\n{'='*60}")
|
|
print(f"Successfully created {bets_created} spread bets!")
|
|
print(f"{'='*60}")
|
|
print(f"\nBet distribution:")
|
|
print(f" Event: {event.home_team} vs {event.away_team}")
|
|
print(f" Spreads: clustered around {event.official_spread}")
|
|
print(f" Stakes: $25 - $1000")
|
|
print(f" Teams: mixed HOME and AWAY")
|
|
|
|
|
|
async def main():
|
|
await add_bets()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|