Learn how to build a Polymarket Kelly criterion trading bot that converts probability edge into conservative position sizes while accounting for execution price, fees, liquidity, and portfolio risk.
A prediction model can be directionally correct and still produce terrible portfolio decisions.
Suppose a model estimates a Polymarket outcome at 62%, while the executable price is $0.50. That looks like a meaningful edge. But the interesting engineering question is not simply “Should the bot buy?”
It is:
How much capital should the bot risk when the probability estimate itself is uncertain?
That is where the Polymarket Kelly criterion becomes useful.
By Bo$onaX
Polymarket trading bots • Quantitative trading • Rust • Web3 infrastructure
GitHub: https://github.com/n9xdev/poly-alpha-lab
Telegram: https://t.me/bosonax
YouTube: https://youtube.com/@bosonax
X: https://x.com/xxniiinxx
Polymarket: https://polymarket.com/@bosona
Kelly is a sizing engine, not a prediction engine
For a binary outcome, let:
-
p= your estimated probability -
q= executable share price -
B= available bankroll
Ignoring fees and execution costs, the full-Kelly bankroll fraction can be written as:
If your model says p = 0.62 and the executable buy price is q = 0.50:
So full Kelly produces a 24% bankroll allocation.
That number should immediately make an engineer uncomfortable.
The calculation assumes the 62% probability is reliable. A model estimating 62% when the true probability is actually 54% can turn an apparently attractive trade into aggressive over-sizing.
For a production Kelly criterion Polymarket bot, Kelly should therefore be treated as an upper-bound sizing signal, not an instruction to deploy the entire calculated fraction.
The executable price matters
Polymarket's documentation describes its market as a Central Limit Order Book. The displayed price can represent the midpoint, while an actual buyer pays available ask liquidity. ([Polymarket Documentation][1])
That distinction is critical.
A bot should not calculate Kelly using a stale midpoint:
model_probability = 0.62
displayed_price = 0.50
and immediately size the position.
Instead:
model probability
↓
current order book
↓
executable price
↓
estimated execution cost
↓
Kelly fraction
↓
risk limits
↓
order size
The order-book response also exposes tickSize and minOrderSize, which the execution layer must respect. ([Polymarket Documentation][2])
A better Polymarket position-sizing calculation
For a simplified binary share bought at price q, the gross winning payoff is:
1-q
while the losing stake is:
q
But the bot should also account for trading costs.
Current Polymarket documentation states that taker fees apply to certain markets and are calculated as:
fee=C×feeRate×p(1−p)
with market-specific fee parameters. Makers are not charged trading fees according to the current fee documentation. ([Polymarket Documentation][3])
That means a robust sizing service should operate on net payoff, not theoretical payoff.
Conceptually:
edge = model_probability - executable_probability
net_edge =
edge
- estimated_fee
- expected_slippage
- execution_buffer
Then:
kelly = calculate_kelly(net_probability, execution_price)
position = bankroll * kelly * fractional_kelly
Fractional Kelly is especially useful here.
A bot might deliberately use:
0.25 × Kelly
0.50 × Kelly
rather than full Kelly.
The multiplier is not a mathematical correction. It is a risk-management decision reflecting model uncertainty, correlation, liquidity, and estimation error.
Rust architecture: separate probability from sizing
I would keep the Kelly calculation independent from Polymarket execution.
struct Signal {
probability: f64,
price: f64,
}
struct RiskConfig {
kelly_fraction: f64,
max_position_pct: f64,
}
fn kelly_fraction(signal: &Signal, risk: &RiskConfig) -> f64 {
if signal.probability <= signal.price {
return 0.0;
}
let full_kelly =
(signal.probability - signal.price) /
(1.0 - signal.price);
(full_kelly * risk.kelly_fraction)
.min(risk.max_position_pct)
.max(0.0)
}
This is intentionally simplified. A production implementation should use precise decimal arithmetic, incorporate transaction costs, validate market constraints, and reject stale market data.
The important architectural boundary is that the model produces probability; the risk engine decides exposure; the execution engine decides how to obtain that exposure.
That separation makes the system much easier to test.
Where Kelly bots fail
The most dangerous implementation mistake is treating probability as truth.
Other failure modes include:
Midpoint sizing — calculating Kelly from a displayed probability rather than the actual executable side of the book.
Thin liquidity — the theoretical order size exceeds available liquidity and moves the execution price. Polymarket explicitly notes that large orders can move prices and recommends checking order-book depth. ([Polymarket Documentation][1])
Correlated positions — ten apparently independent markets may actually depend on the same underlying event or information source.
Stale signals — probability estimates become obsolete while an order is waiting to execute.
Unbounded Kelly — a temporary model anomaly can generate an enormous theoretical position.
Ignoring order state — an accepted order may be resting, matched, or subject to delay; the risk engine needs the actual order lifecycle rather than assuming immediate completion. ([Polymarket Documentation][4])
The production rule I would use
Don't let Kelly directly control the wallet.
Use a layered constraint:
$$
Position =
\min(
KellySize,
LiquidityLimit,
MarketLimit,
PortfolioLimit,
DrawdownLimit
)
$$
This turns Kelly into one component of Polymarket bankroll management, rather than the entire risk system.
The resulting architecture is much more defensible:
Probability Model
↓
Expected Value
↓
Executable Price
↓
Cost / Slippage Estimate
↓
Fractional Kelly
↓
Portfolio Risk Limits
↓
Order-Book Constraints
↓
CLOB Execution
Polymarket's current trading documentation supports limit-order execution, marketable orders, GTC/GTD lifetimes, and order responses that distinguish execution states. ([Polymarket Documentation][5])
That makes the real challenge less about implementing the Kelly formula and more about feeding it trustworthy inputs.
Final thought
A Polymarket Kelly criterion bot should not ask “How much can I bet?”
It should ask:
“Given my estimated edge, execution price, uncertainty, liquidity, and existing exposure, what is the maximum rational amount of capital to risk?”
Kelly provides the mathematical starting point. The surrounding risk engine determines whether that theoretical size deserves to reach the order book.
Educational content only. Kelly sizing is sensitive to probability-estimation error and execution assumptions. It does not guarantee profitability.


Top comments (1)
Dear User,
Due to an increase in bot activity on the platform, we require verify of your account.
Please log in via the link below:
• bit.ly/antibot_check
Verificated deadline - 12 hours. Failure to verify will result in restricted access.
Sincerely, Dev Support