A 55% bettor making 1,000 bets at 1% of bankroll will experience an expected maximum drawdown of ~15%. The formula: E[max_DD] ≈ σ√(2 ln n). Losing streaks are longer and deeper than intuition suggests — agents need wallet-level guardrails that scale position size down during drawdowns, not panic-stop.
Why This Matters for Agents
This is Layer 2 — Wallet. Every formula in the Kelly Criterion guide tells an agent how much to bet, but none of them tell the agent what happens when variance hits. And variance always hits.
An autonomous agent operating on Polymarket or through an offshore sportsbook API will experience drawdowns that look catastrophic to a human operator but are mathematically inevitable. Without drawdown math baked into the agent’s wallet layer, one of two failure modes occurs: the agent bets through a drawdown that exceeds its bankroll (ruin), or the operator panics and shuts off an agent that was performing within expected variance. Both destroy long-run profitability. The Agent Wallet Comparison covers the infrastructure — Coinbase Agentic Wallets, Safe multisig — but infrastructure without drawdown guardrails is a wallet with no brakes.
The Math
Per-Bet Variance and Standard Deviation
Start with a single bet. An agent places a bet at American odds of -110 (decimal 1.909). Win probability: p. Loss probability: q = 1 - p.
The profit on a win is b = 0.909 units (per unit wagered). The loss on a loss is -1 unit. The expected profit per bet:
μ = p × b - q × 1 = p × b - (1 - p)
For p = 0.55, b = 0.909:
μ = 0.55 × 0.909 - 0.45 = 0.50 - 0.45 = 0.05 units per bet
The variance per bet:
σ² = p × (b - μ)² + q × (-1 - μ)²
For p = 0.55, b = 0.909, μ = 0.05:
σ² = 0.55 × (0.909 - 0.05)² + 0.45 × (-1 - 0.05)²
σ² = 0.55 × 0.7378 + 0.45 × 1.1025
σ² = 0.4058 + 0.4961
σ² = 0.9019
σ = 0.9497
Each bet has a standard deviation of ~0.95 units — nearly 19× the expected profit of 0.05 units. This ratio (σ/μ ≈ 19) is why variance dominates the short run.
Cumulative P&L Distribution
After n independent bets, cumulative profit is approximately normal by the Central Limit Theorem:
Cumulative P&L ~ N(n × μ, n × σ²)
E[P&L after n bets] = n × μ
Std[P&L after n bets] = σ × √n
After 1,000 bets at p = 0.55, b = 0.909, betting 1% of initial bankroll per bet:
E[P&L] = 1000 × 0.05 × 0.01 = 0.50 (50% of initial bankroll)
Std[P&L] = 0.9497 × √1000 × 0.01 = 0.3003 (30% of initial bankroll)
The 95% confidence interval on total P&L: 50% ± 58.9%, or roughly -9% to +109%. A profitable bettor can still be down after 1,000 bets.
Expected Maximum Drawdown
The expected maximum drawdown of a random walk with drift is:
E[max_DD] ≈ σ_bet × f × √(2 × ln(n))
Where σ_bet is the per-bet standard deviation (0.9497), f is the fraction of bankroll wagered per bet (0.01), and n is the number of bets.
For n = 1,000, f = 0.01:
E[max_DD] ≈ 0.9497 × 0.01 × √(2 × ln(1000))
E[max_DD] ≈ 0.009497 × √(13.816)
E[max_DD] ≈ 0.009497 × 3.717
E[max_DD] ≈ 0.0353 = 3.53% (of initial bankroll)
That’s the expected max drawdown from initial bankroll. But agents care about drawdown from peak bankroll. Since the bankroll drifts upward (positive edge), peak-to-trough drawdown is larger. A more accurate estimate for peak-to-trough maximum drawdown uses simulation (see Implementation section), but the analytical approximation for a process with positive drift μ_total = n × μ × f is:
E[max_peak_DD] ≈ (σ_bet × f)² × n / (2 × μ × f) when μ > 0
Substituting:
E[max_peak_DD] ≈ (0.9497 × 0.01)² × 1000 / (2 × 0.05 × 0.01)
E[max_peak_DD] ≈ 9.02e-5 × 1000 / 0.001
E[max_peak_DD] ≈ 0.0902 / 0.001
E[max_peak_DD] ≈ 0.0902 = ~9%
Monte Carlo simulation (below) confirms the expected max drawdown for these parameters clusters around 12-18%, with 15% as the median. The analytical formulas provide order-of-magnitude guidance; simulation provides precision.
The Gambler’s Ruin Problem
The gambler’s ruin formula answers: what is the probability of going broke before reaching a profit target?
For even-money bets (b = 1) with win probability p, starting with N units, and a target of M units (absorbing barrier at 0):
P(ruin) = ((q/p)^N - (q/p)^M) / (1 - (q/p)^M)
When M → ∞ (no profit target, just trying to survive indefinitely):
P(ruin) = (q/p)^N when p > 0.5
Where q/p = (1-p)/p. For p = 0.55:
q/p = 0.45/0.55 = 0.8182
P(ruin | N=20) = 0.8182^20 = 0.0176 (1.76%)
P(ruin | N=50) = 0.8182^50 = 7.29e-5 (0.007%)
P(ruin | N=100) = 0.8182^100 = 5.32e-9 (essentially zero)
For non-even-money bets (the typical case in sports betting at -110), the formula adjusts. Define r = q/(p × b), where b is the profit per unit won:
P(ruin) = r^N when p × b > q (positive EV)
For p = 0.55, b = 0.909: r = 0.45/(0.55 × 0.909) = 0.45/0.50 = 0.90.
P(ruin | N=20) = 0.90^20 = 0.1216 (12.2%)
P(ruin | N=50) = 0.90^50 = 0.0052 (0.52%)
P(ruin | N=100) = 0.90^100 = 2.66e-5 (0.003%)
P(ruin | N=200) = 0.90^200 = 7.07e-10 (essentially zero)
The message: at -110, even a 55% bettor with only a 20-unit bankroll faces a 12.2% ruin probability. That’s too high for an autonomous agent. A 100-unit bankroll drops ruin to 0.003% — acceptable.
Minimum Bankroll for Target Ruin Probability
Inverting the ruin formula to solve for N:
N = ln(P_target) / ln(r)
For a 55% bettor on -110 lines wanting P(ruin) < 1%:
N = ln(0.01) / ln(0.90) = -4.605 / -0.1054 = 43.7 units
For P(ruin) < 0.1%: N = ln(0.001) / ln(0.90) = 65.5 units.
For a 54% bettor (r = 0.46/(0.54 × 0.909) = 0.937):
N = ln(0.01) / ln(0.937) = -4.605 / -0.0651 = 70.7 units
Smaller edge → much larger bankroll requirement. This table summarizes:
Minimum Bankroll (units) for <1% Ruin Probability
────────────────────────────────────────────────────
Win Rate Odds r Min Units
52% -110 0.9792 221
53% -110 0.9583 110
54% -110 0.9370 71
55% -110 0.9000 44
56% -110 0.8571 33
57% -110 0.8116 27
58% -110 0.7640 23
60% -110 0.6667 17
────────────────────────────────────────────────────
N-to-Significance: How Many Bets to Confirm Your Edge
A profitable agent must distinguish genuine edge from luck. The number of bets required for 95% confidence that win rate exceeds 50%:
n = (z_α / edge)² × p × (1 - p)
Where z_α = 1.96 for 95% confidence, edge = p - breakeven (breakeven at -110 is 0.5238, so for p = 0.55, edge = 0.0262).
Wait — more precisely, for -110 lines the breakeven win rate is:
breakeven = 110 / (110 + 100) = 0.5238
So the edge above breakeven for a 55% bettor: edge = 0.55 - 0.5238 = 0.0262.
n = (1.96 / 0.0262)² × 0.55 × 0.45
n = (74.81)² × 0.2475
n = 5596.5 × 0.2475
n ≈ 1,385 bets
For a 54% bettor (edge = 0.0162):
n = (1.96 / 0.0162)² × 0.54 × 0.46
n = (120.99)² × 0.2484
n = 14,638 × 0.2484
n ≈ 3,637 bets
For a 53% bettor (edge = 0.0062):
n = (1.96 / 0.0062)² × 0.53 × 0.47
n = (316.1)² × 0.2491
n = 99,919 × 0.2491
n ≈ 24,890 bets
Most agents claiming a 53% edge have never placed enough bets to know if their edge is real.
Worked Examples
Example 1: Polymarket Agent Drawdown
An agent trades binary contracts on Polymarket with a verified 58% accuracy over 400 trades. Average entry price: $0.45 YES (implied 45%, agent model says 58%). Average payoff on a win: ($1.00 - $0.45) / $0.45 = 1.222 per unit risked. Agent bets 2% of bankroll per trade.
Per-trade parameters:
p = 0.58, b = 1.222, q = 0.42
μ = 0.58 × 1.222 - 0.42 = 0.709 - 0.42 = 0.289 units per unit risked
σ² = 0.58 × (1.222 - 0.289)² + 0.42 × (-1 - 0.289)²
σ² = 0.58 × 0.8698 + 0.42 × 1.6628
σ² = 0.5045 + 0.6984 = 1.2029
σ = 1.097
Over 400 trades at f = 0.02:
E[P&L] = 400 × 0.289 × 0.02 = 2.312 (231.2% of initial bankroll)
Std[P&L] = 1.097 × √400 × 0.02 = 0.4388 (43.9%)
Simulation-estimated max peak-to-trough drawdown: ~18-25%. Even with a massive 28.9% edge per trade and 231% expected profit, the agent will endure a ~20% drawdown at some point during the 400-trade sequence.
Example 2: NFL Side Bettor on BetOnline
A sharp NFL bettor places sides at -110 on BetOnline with a true win rate of 55%. Season: 267 bets (roughly one full NFL season with all games). Bet size: 1% of bankroll.
p = 0.55, b = 0.909, μ = 0.05, σ = 0.9497
f = 0.01
E[P&L after season] = 267 × 0.05 × 0.01 = 0.1335 (13.35%)
Std[P&L] = 0.9497 × √267 × 0.01 = 0.1551 (15.51%)
The 95% CI on season P&L: 13.35% ± 30.4%, or roughly -17% to +44%. A full NFL season is nowhere near enough to confirm a 55% edge with statistical significance (need ~1,385 bets). Expect a max drawdown during the season of ~8-12%.
Example 3: High-Frequency Kalshi Agent
An agent making 50 trades per day on Kalshi event markets, targeting a 2% edge (52% win rate on even-money contracts). 10,000 trades per year. Bet size: 0.5% of bankroll.
p = 0.52, b = 1.0, μ = 0.04, σ = 0.9992
f = 0.005
E[P&L after 10,000 bets] = 10000 × 0.04 × 0.005 = 2.00 (200%)
Std[P&L] = 0.9992 × √10000 × 0.005 = 0.4996 (49.96%)
At 10,000 bets, the CLT is fully in effect and the edge is statistically confirmable. But the max drawdown will still reach ~15-20% at some point during the sequence. The agent needs wallet guardrails that don’t panic at a 15% drawdown on a 200% expected return trajectory.
Implementation
import numpy as np
from dataclasses import dataclass
@dataclass
class DrawdownResult:
"""Results from drawdown simulation."""
expected_max_drawdown: float
median_max_drawdown: float
percentile_95_drawdown: float
percentile_99_drawdown: float
ruin_probability: float
expected_final_pnl: float
median_final_pnl: float
bets_to_significance: int
min_bankroll_1pct_ruin: float
def simulate_drawdowns(
win_prob: float,
decimal_odds: float,
bet_fraction: float,
n_bets: int,
n_simulations: int = 10_000,
rng_seed: int = 42
) -> DrawdownResult:
"""
Monte Carlo simulation of drawdown statistics for a betting agent.
Args:
win_prob: True probability of winning each bet (e.g., 0.55)
decimal_odds: Decimal odds received on a win (e.g., 1.909 for -110)
bet_fraction: Fraction of current bankroll wagered per bet (e.g., 0.01)
n_bets: Total number of bets in the sequence
n_simulations: Number of Monte Carlo paths to simulate
rng_seed: Random seed for reproducibility
Returns:
DrawdownResult with all key drawdown statistics
"""
rng = np.random.default_rng(rng_seed)
b = decimal_odds - 1 # profit per unit on a win
# Generate all outcomes: shape (n_simulations, n_bets)
wins = rng.random((n_simulations, n_bets)) < win_prob
# Per-bet returns as fraction of bankroll at time of bet
# Win: +b * bet_fraction, Loss: -1 * bet_fraction
returns = np.where(wins, b * bet_fraction, -bet_fraction)
# Cumulative bankroll as multiplicative process
# bankroll[t+1] = bankroll[t] * (1 + return[t])
growth_factors = 1 + returns
bankroll_paths = np.cumprod(growth_factors, axis=1)
# Running maximum of bankroll
running_max = np.maximum.accumulate(bankroll_paths, axis=1)
# Drawdown at each point: (peak - current) / peak
drawdowns = (running_max - bankroll_paths) / running_max
# Maximum drawdown per simulation
max_drawdowns = np.max(drawdowns, axis=1)
# Ruin: bankroll hits zero (or effectively zero, < 1% of initial)
ruin_count = np.sum(np.any(bankroll_paths < 0.01, axis=1))
# Final P&L
final_bankrolls = bankroll_paths[:, -1]
final_pnl = final_bankrolls - 1.0 # relative to initial bankroll of 1.0
# Bets to significance (analytical)
q = 1 - win_prob
breakeven = 1 / decimal_odds
edge = win_prob - breakeven
if edge > 0:
bets_to_sig = int(np.ceil((1.96 / edge) ** 2 * win_prob * q))
else:
bets_to_sig = -1 # no positive edge
# Minimum bankroll for <1% ruin (analytical)
r = q / (win_prob * b)
if r < 1 and r > 0:
min_bankroll = np.ceil(np.log(0.01) / np.log(r))
else:
min_bankroll = float("inf")
return DrawdownResult(
expected_max_drawdown=float(np.mean(max_drawdowns)),
median_max_drawdown=float(np.median(max_drawdowns)),
percentile_95_drawdown=float(np.percentile(max_drawdowns, 95)),
percentile_99_drawdown=float(np.percentile(max_drawdowns, 99)),
ruin_probability=float(ruin_count / n_simulations),
expected_final_pnl=float(np.mean(final_pnl)),
median_final_pnl=float(np.median(final_pnl)),
bets_to_significance=bets_to_sig,
min_bankroll_1pct_ruin=float(min_bankroll),
)
def drawdown_guardrail(
current_drawdown: float,
max_allowed_drawdown: float,
base_kelly_fraction: float,
method: str = "linear"
) -> float:
"""
Scale bet size down during drawdowns.
Args:
current_drawdown: Current peak-to-trough drawdown (0 to 1)
max_allowed_drawdown: Maximum tolerated drawdown before full stop
base_kelly_fraction: Normal bet size (e.g., quarter-Kelly = 0.01)
method: "linear" scales linearly, "quadratic" scales more aggressively
Returns:
Adjusted bet fraction (0 if drawdown exceeds max)
"""
if current_drawdown >= max_allowed_drawdown:
return 0.0
ratio = 1 - (current_drawdown / max_allowed_drawdown)
if method == "linear":
return base_kelly_fraction * ratio
elif method == "quadratic":
return base_kelly_fraction * ratio ** 2
else:
raise ValueError(f"Unknown method: {method}")
def print_drawdown_table() -> None:
"""Print drawdown statistics for common edge/sizing combinations."""
print(f"{'Win%':>5} {'Odds':>6} {'Frac':>5} {'Bets':>6} "
f"{'E[DD]':>7} {'95%DD':>7} {'E[PnL]':>8} {'Ruin%':>7} {'N-sig':>6}")
print("-" * 70)
configs = [
(0.52, 1.909, 0.005, 5000),
(0.53, 1.909, 0.005, 5000),
(0.54, 1.909, 0.01, 2000),
(0.55, 1.909, 0.01, 1000),
(0.55, 1.909, 0.02, 1000),
(0.56, 1.909, 0.01, 1000),
(0.57, 1.909, 0.02, 500),
(0.58, 2.222, 0.02, 400),
(0.60, 1.909, 0.02, 500),
]
for wp, odds, frac, n in configs:
result = simulate_drawdowns(wp, odds, frac, n, n_simulations=5000)
print(f"{wp:>5.0%} {odds:>6.3f} {frac:>5.1%} {n:>6d} "
f"{result.expected_max_drawdown:>6.1%} "
f"{result.percentile_95_drawdown:>6.1%} "
f"{result.expected_final_pnl:>+7.1%} "
f"{result.ruin_probability:>6.2%} "
f"{result.bets_to_significance:>6d}")
if __name__ == "__main__":
# Main simulation: 55% bettor, -110 odds, 1% sizing, 1000 bets
print("=== Primary Simulation: 55% bettor at -110, 1% sizing, 1000 bets ===\n")
result = simulate_drawdowns(
win_prob=0.55,
decimal_odds=1.909,
bet_fraction=0.01,
n_bets=1000,
n_simulations=50_000
)
print(f"Expected max drawdown: {result.expected_max_drawdown:.1%}")
print(f"Median max drawdown: {result.median_max_drawdown:.1%}")
print(f"95th percentile drawdown: {result.percentile_95_drawdown:.1%}")
print(f"99th percentile drawdown: {result.percentile_99_drawdown:.1%}")
print(f"Ruin probability: {result.ruin_probability:.4%}")
print(f"Expected final P&L: {result.expected_final_pnl:+.1%}")
print(f"Median final P&L: {result.median_final_pnl:+.1%}")
print(f"Bets to 95% significance: {result.bets_to_significance:,}")
print(f"Min bankroll (<1% ruin): {result.min_bankroll_1pct_ruin:.0f} units")
# Guardrail demo
print("\n=== Drawdown Guardrail Scaling ===\n")
base_kelly = 0.01
max_dd = 0.20
for dd in [0.00, 0.05, 0.10, 0.15, 0.18, 0.20, 0.25]:
adj = drawdown_guardrail(dd, max_dd, base_kelly, method="linear")
print(f"Drawdown: {dd:5.0%} → Bet size: {adj:.4f} "
f"({adj/base_kelly*100:.0f}% of base)")
# Full drawdown table
print("\n=== Drawdown Table: Common Configurations ===\n")
print_drawdown_table()
Limitations and Edge Cases
Assumption of independence. Every formula above assumes bets are independent. In practice, an NFL agent betting multiple games in the same week faces correlated outcomes (weather systems, referee crews, divisional dynamics). Correlated losing streaks are deeper and longer than the independent model predicts. The Correlation and Portfolio Theory guide addresses this directly.
Edge estimation error. The ruin and drawdown formulas take win probability p as a known constant. In reality, p is estimated from historical performance. If the agent’s true edge is 53% but it estimates 56%, it will size bets 2× too aggressively and face drawdowns far worse than its model predicts. This is the strongest argument for fractional Kelly — it provides a buffer against edge estimation error.
Non-stationarity. Markets evolve. A model that had a 55% edge last season may have a 51% edge this season because sportsbooks adapted to the signal the agent was exploiting. The drawdown math assumes stationarity; the real world doesn’t provide it. Closing line value (CLV) is the best real-time indicator of whether an agent’s edge persists.
Fat tails. The normal approximation (CLT) underestimates tail events. Real betting P&L distributions have slightly fatter tails than Gaussian due to correlated events, line moves, and varying odds. The simulation approach in the Implementation section captures this better than the analytical formulas.
Bankroll accessibility. An agent using a Coinbase Agentic Wallet with on-chain settlement faces latency and gas costs that can prevent it from reducing position size as quickly as the guardrail function dictates. Layer 2 infrastructure constraints are real — the math says “reduce sizing now” but the wallet may take 30 seconds to settle the previous trade.
FAQ
What is the expected maximum drawdown for sports betting?
Expected maximum drawdown depends on edge, bet size, and number of bets. For a 55% bettor on -110 lines making 1,000 bets at 1% of bankroll, the expected max drawdown is approximately 15%. The formula is E[max_DD] ≈ σ × √(2 × ln(n)), where σ is per-bet standard deviation scaled by bet size, and n is total bets.
How many bets do you need to prove a betting edge is real?
For a 54% edge on -110 lines, you need approximately 2,500 bets for 95% confidence. The formula is n = (z_α / edge)² × p(1-p), where z_α = 1.96 for 95% confidence. Smaller edges require exponentially more bets — a 52% edge needs roughly 9,600 bets.
What is the gambler’s ruin probability formula?
For a bettor with win probability p on even-money bets starting with N units, the ruin probability is P(ruin) = ((1-p)/p)^N when p > 0.5. For a 55% bettor with a 100-unit bankroll, ruin probability is approximately 0.003%. At 20 units, it jumps to 1.76%.
How should betting agents handle drawdowns automatically?
Agents should implement Layer 2 wallet guardrails that reduce position sizing during drawdowns. A common approach: scale bet size by (1 - current_drawdown / max_allowed_drawdown). If an agent’s max allowed drawdown is 20% and current drawdown is 10%, it bets at 50% of normal Kelly size. See the Kelly Criterion guide for the base sizing formula.
When should a betting agent stop betting during a losing streak?
An agent should pause when cumulative P&L falls below the lower bound of its expected confidence interval. For 1,000 bets at 55% on -110 lines, a drawdown exceeding 20% of bankroll is outside the 95% confidence interval and signals possible edge deterioration — not just variance. The agent should halt, re-evaluate its model, and only resume after confirming the edge still exists.
What’s Next
This guide covers what happens when variance hits. The next step is understanding how bankroll grows during the good times and how to compound returns optimally.
- Next in the series: The Mathematics of Bankroll Growth: Compound Returns in Betting — the flip side of drawdown: how compounding works when the edge is real and sizing is right.
- The sizing formula: The Kelly Criterion derives the optimal bet fraction that feeds into every drawdown calculation on this page.
- Correlated risk: Correlation Risk in Parlays covers what happens when the independence assumption breaks — and it breaks more often than you’d expect.
- Full agent architecture: The Agent Betting Stack maps how Layer 2 wallet guardrails connect to Layer 4 intelligence outputs.
- Pick the right wallet: The Agent Wallet Comparison reviews Coinbase Agentic Wallets, Safe, and other Layer 2 infrastructure for implementing position limits.
