"""Roulette: losses per 1,000 spins by wheel, and betting systems vs a 100 USDT bankroll.""" import numpy as np from common import save SEED = 20261004 rng = np.random.default_rng(SEED) WHEELS = {"European (single zero)": 37, "American (double zero)": 38, "Triple zero": 39} # A. 1 USDT on red for 1,000 spins, 100,000 players per wheel P = 100_000 wheel_rows = [] for name, pockets in WHEELS.items(): p = 18 / pockets wins = rng.binomial(1000, p, P) net = 2 * wins - 1000 wheel_rows.append({"wheel": name, "pockets": pockets, "edge_pct": round((1 - 36 / pockets) * 100, 3), "expected_loss_1000": round(1000 * (1 - 36 / pockets), 1), "median_net": float(np.median(net)), "chance_ahead_pct": round((net > 0).mean() * 100, 2), "p5": float(np.percentile(net, 5)), "p95": float(np.percentile(net, 95))}) # B. Systems on red, European wheel. Bankroll 100, base 1, table max 100, stop at +50 or when next bet unaffordable, max 1000 spins S = 50_000 MAXSPINS, TABLE_MAX, START, GOAL = 1000, 100, 100.0, 150.0 def run(system, pockets=37): p = 18 / pockets bank = np.full(S, START) bet = np.ones(S) fib_i = np.zeros(S, int) fib = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377] alive = np.ones(S, bool) spins = np.zeros(S, int) total_wagered = np.zeros(S) for _ in range(MAXSPINS): if system == "Flat 1 USDT": bet[:] = 1 elif system == "Fibonacci": bet = np.array(fib)[np.minimum(fib_i, len(fib) - 1)].astype(float) bet = np.minimum(bet, TABLE_MAX) can = alive & (bet <= bank) alive &= can if not alive.any(): break win = rng.random(S) < p delta = np.where(win, bet, -bet) * alive bank += delta total_wagered += bet * alive spins += alive if system == "Martingale": bet = np.where(win, 1.0, bet * 2) elif system == "D'Alembert": bet = np.where(win, np.maximum(1.0, bet - 1), bet + 1) elif system == "Fibonacci": fib_i = np.where(win, np.maximum(0, fib_i - 2), fib_i + 1) alive &= bank < GOAL return {"system": system, "sessions": S, "reached_goal_pct": round((bank >= GOAL).mean() * 100, 2), "busted_or_stuck_pct": round(((bank < GOAL) & (spins < MAXSPINS)).mean() * 100, 2), "avg_final_bank": round(bank.mean(), 2), "avg_result": round(bank.mean() - START, 2), "median_spins": int(np.median(spins)), "avg_wagered": round(total_wagered.mean(), 1), "loss_per_100_wagered": round(-(bank.mean() - START) / total_wagered.mean() * 100, 3)} systems = [run(s) for s in ("Flat 1 USDT", "Martingale", "D'Alembert", "Fibonacci")] # C. Stop-loss / stop-win rules, flat 5 USDT on red, European def stop_rule(stop_loss, stop_win, spins_max=200, bet=5.0): p = 18 / 37 bank = np.zeros(S) alive = np.ones(S, bool) n = np.zeros(S, int) for _ in range(spins_max): win = rng.random(S) < p bank += np.where(win, bet, -bet) * alive n += alive alive &= (bank > -stop_loss) & (bank < stop_win) return {"stop_loss": stop_loss, "stop_win": stop_win, "bet": bet, "max_spins": spins_max, "hit_win_pct": round((bank >= stop_win).mean() * 100, 2), "hit_loss_pct": round((bank <= -stop_loss).mean() * 100, 2), "avg_result": round(bank.mean(), 2), "avg_spins": round(n.mean(), 1), "loss_per_100_wagered": round(-bank.mean() / (n.mean() * bet) * 100, 3)} stops = [stop_rule(*r) for r in ((50, 50), (50, 25), (100, 50), (25, 100), (1e9, 1e9))] # D. Exact bet table bets = [("Straight up", 1, 35), ("Split", 2, 17), ("Street", 3, 11), ("Corner", 4, 8), ("Six line", 6, 5), ("Dozen / column", 12, 2), ("Red/black, odd/even, high/low", 18, 1)] bet_rows = [] for name, nums, pay in bets: for wn, pk in WHEELS.items(): p = nums / pk bet_rows.append({"bet": name, "wheel": wn, "numbers": nums, "payout": f"{pay} to 1", "win_pct": round(p * 100, 3), "edge_pct": round((1 - p * (pay + 1)) * 100, 3)}) bet_rows.append({"bet": "Five-number (0,00,1,2,3)", "wheel": "American (double zero)", "numbers": 5, "payout": "6 to 1", "win_pct": round(5 / 38 * 100, 3), "edge_pct": round((1 - 5 / 38 * 7) * 100, 3)}) save("roulette", {"game": "Roulette", "players_per_wheel": P, "system_sessions": S, "seed": SEED, "system_rules": "bankroll 100 USDT, base 1, table max 100, stop at 150 or when next bet unaffordable, max 1000 spins, betting red", "script": "roulette_systems.py"}, {"wheels": wheel_rows, "systems": systems, "stops": stops, "bets": bet_rows}, [[s["system"], s["reached_goal_pct"], s["busted_or_stuck_pct"], s["avg_result"], s["loss_per_100_wagered"]] for s in systems], ["system", "reached_150_pct", "stopped_early_pct", "avg_result_usdt", "loss_per_100_wagered_usdt"])