Kelly Criterion Parameter Tuning for Polymarket Bots
Explains how to calibrate fractional Kelly sizing for binary prediction markets on Polymarket, including edge estimation from historical resolution data, bet-sizing grid search, and drawdown constraints to avoid ruin.
Kelly criterion parameter tuning for Polymarket bots is one of those problems that looks trivial until you run it in production and watch a 40% drawdown appear from nowhere. The classic Kelly formula assumes you know your edge with certainty and can bet the same market repeatedly — neither assumption holds cleanly on a binary prediction market where every contract resolves once and your edge estimate is noisy. Here is how to build something that actually survives.
Why Raw Kelly Destroys Polymarket Accounts
The Kelly formula f* = (p * b - q) / b gives the fraction of bankroll to bet, where p is your estimated win probability, q = 1 - p, and b is the net odds (payout per dollar risked). On Polymarket a YES contract at 0.62 with fair value at 0.70 gives b = (1/0.62) - 1 ≈ 0.613 and f* = (0.70 * 0.613 - 0.30) / 0.613 ≈ 0.21 — bet 21% of bankroll on a single market. Do that across five correlated political markets on the same election and you are implicitly betting over 100% of bankroll on one outcome.
Two structural problems compound this. First, Polymarket's house edge via the spread is already baked into the contract price, so your gross edge has to clear that hurdle before Kelly sees any positive value. Second, edge estimation error dominates at thin edges — if true fair value is 0.65 instead of 0.70, your "21%" Kelly bet becomes a negative-EV trade. Raw Kelly applied to an uncertain edge produces aggressive sizing on exactly the bets you should be smallest on.
Estimating Your Edge from Historical Resolution Data
Before you can size anything you need an honest edge estimate. Pull your bot's full prediction history — every market where you had a position, your implied fair-value estimate at entry, and the resolution outcome. The key metric is Brier score decomposed into calibration and resolution components.
For each probability bucket (e.g. 0.60–0.65, 0.65–0.70, …), compute:
n_bucket= number of bets where your fair-value estimate fell in that rangep_mean= average of your fair-value estimates in the bucketr_rate= actual resolution rate (fraction that resolved YES)- Calibration error =
(p_mean - r_rate)²
If your 0.70 bucket is resolving at 0.64, you have a systematic over-confidence bias and your raw Kelly inputs are inflated. Apply a shrinkage correction: p_adjusted = p_raw * alpha + p_prior * (1 - alpha) where p_prior is the market price and alpha is a credibility weight that increases with sample size. At fewer than 50 resolved samples per bucket, alpha should be below 0.5 — you do not have enough data to trust your model over the market.
Minimum viable dataset before going live with real sizing: 200 resolved markets with your fair-value estimates logged at entry. Anything less and you are fitting noise.
Fractional Kelly and the Grid Search
Once you have calibrated edge estimates, fractional Kelly is mandatory. The standard practice is to multiply f* by a fraction k ∈ (0, 1]. The question is which k to use.
Run a grid search over your historical resolved markets. For each candidate k in {0.10, 0.15, 0.20, 0.25, 0.33, 0.50}, simulate the bankroll path bet-by-bet using your actual logged estimates. Track:
- Terminal CAGR — the compounded growth rate over the backtest period
- Maximum drawdown (peak-to-trough on the equity curve)
- Calmar ratio = CAGR / max drawdown
- Ruin proximity — number of times bankroll dropped below 20% of starting capital
Optimizing for Calmar rather than terminal wealth avoids the common mistake of picking the k that looked best by luck in a volatile sample. In most Polymarket backtests, the Calmar-optimal k lands between 0.20 and 0.35. Above 0.50 you are nearly always taking on excess variance without proportionate return; below 0.15 you are leaving too much edge on the table.
A sample grid search result structure:
| k | CAGR | Max DD | Calmar |
|---|---|---|---|
| 0.10 | 14.2% | 8.1% | 1.75 |
| 0.20 | 22.8% | 14.3% | 1.59 |
| 0.33 | 28.1% | 24.7% | 1.14 |
| 0.50 | 19.3% | 41.2% | 0.47 |
Notice that at k = 0.50, CAGR actually dropped versus k = 0.33 — overbetting erodes the geometric mean through variance drag even before you hit a bad run.
Drawdown Constraints as a Hard Governor
The grid search tells you where to start, but production needs a live circuit breaker. Implement a drawdown-contingent Kelly reduction: if current drawdown from peak exceeds a threshold, automatically reduce k.
if drawdown > 0.15:
k_effective = k_base * 0.50
elif drawdown > 0.25:
k_effective = k_base * 0.25
elif drawdown > 0.35:
k_effective = 0.0 # flat until manual review
This is not optional risk theater — it is the mechanism that prevents a bad calibration period (new model, regime change, corrupt data feed) from compounding into account destruction. At a 35% drawdown something structural is wrong; stop betting and investigate.
Set the thresholds based on your grid search ruin proximity stats. If k = 0.25 showed zero ruin-proximity events in the backtest but k = 0.33 showed three, your circuit breaker at 15% drawdown is correctly calibrated to the structural risk of the higher-k regime.
Correlation Adjustments Across Open Positions
Polymarket markets cluster around the same events. Three "Will candidate X win state Y" markets on the same election are not independent bets — they are partially correlated positions. Naive Kelly applied independently to each will over-size the aggregate exposure.
The correction is straightforward. Estimate the pairwise correlation ρ between outcomes (for binary markets on the same event, this is often 0.6–0.8). The effective portfolio Kelly fraction scales down as:
Effective allocation = f* / (1 + (n-1) * ρ) where n is the number of correlated bets.
For n = 3 correlated markets at ρ = 0.7: effective multiplier = 1 / (1 + 2 * 0.7) = 0.42. Your per-market Kelly drops by more than half. This is why bots that individually appear well-sized can still blow up on election nights — they are running a 2.4x levered position on a single outcome.
Implement a simple correlation grouper: tag each market by its primary event (election, macro release, sports fixture) and cap total allocation to any event tag at a hard percentage of bankroll, regardless of what per-market Kelly says. A ceiling of 10–15% total exposure per event is a reasonable starting point.
Practical Implementation Notes
A few things that only surface in production:
- Edge has a shelf life. Re-run your calibration check monthly. Markets evolve, your model drift, and an edge that was real six months ago may be gone. Automate the Brier score computation on each resolved batch.
- Bet count matters more than bet size at low bankrolls. Below ~$5,000, transaction costs and minimum order sizes on the Polymarket CLOB constrain your sizing anyway — size for minimum viable positions first, Kelly second.
- Log everything at entry. You need your fair-value estimate, the market price, the order fill price, and the resolution outcome in a single queryable table. Without this you cannot run the calibration loop that makes Kelly meaningful.
- The market price is a prior, not an oracle. Polymarket is reasonably efficient but not perfectly so. Your model can beat it at the margin; that margin is what Kelly is sizing. Never let
p_adjusteddiverge from market price by more than 15–20 percentage points without a very specific information reason — that divergence is almost always a model bug.
For bots handling multiple market types — spread-making on 5-minute crypto markets alongside longer-duration event markets — run separate Kelly stacks per strategy type. The edge structure, resolution frequency, and correlation profile are different enough that mixing them into a single Kelly computation degrades both.
If you want a Polymarket bot with calibrated Kelly sizing, drawdown governors, and a proper edge-tracking pipeline built in from day one, get in touch — this is exactly the kind of production system we build at TierZero.
Need a bot like this built?
We design, build and run trading bots on Solana, Hyperliquid and Polymarket.
Start a projectMore from the blog
Public vs Paid RPC: How to Run a Fair Benchmark
A fair comparison of public and paid RPC endpoints must account for quotas, workload, freshness and support guarantees.
Read articleRPC Benchmark Percentiles Explained: p50, p95 and p99
Why averages hide the latency spikes that break trading bots, wallets and production blockchain applications.
Read articleHyperliquid REST vs WebSocket Benchmark: What to Measure
A benchmark plan for Hyperliquid market data that separates request latency from streaming freshness and recovery.
Read article