Most people trading on Polymarket trading formulas rely on gut feeling. They read the news, form an opinion, and place a bet. Professional quant funds do the opposite — they build mathematical frameworks that find mispriced markets systematically, without opinion or emotion.
This is not theoretical. These six formulas are actively used by hedge funds to extract consistent returns from prediction markets. The math is real. The code runs. And you do not need a finance degree to understand what each one does.
Formula 1 — LMSR: How Polymarket Sets Its Prices
Before you can find a mispriced market, you need to understand how prices are generated in the first place. Polymarket uses a mechanism called LMSR — Logarithmic Market Scoring Rule. It is the engine underneath every price you see.
The formula looks intimidating but the idea is simple: every time someone buys a position, the price moves. How much it moves depends on how deep the liquidity pool is.
The Formula
Price_YES = e^(q_yes / b) / (e^(q_yes / b) + e^(q_no / b))
Where:
q_yes = total shares bought on YES
q_no = total shares bought on NO
b = liquidity depth (higher b = less price movement per trade)
What This Looks Like Visually
The chart below shows how the YES price changes as more YES shares are purchased, with a liquidity parameter b = 100:
| Shares Bought (q_yes) | YES Price | Visual |
|---|---|---|
| 0 | $0.50 | ██████████░░░░░░░░░░ |
| 100 | $0.73 | ██████████████░░░░░░ |
| 200 | $0.88 | █████████████████░░░ |
| 300 | $0.95 | ███████████████████░ |
| 500 | $0.99 | ████████████████████ |
The key insight: in a thin market (low b), buying just 10 shares can move the price by 5%. Quants use this to front-run large orders and arbitrage price impact before other traders react.
Python Code
import numpy as np
import matplotlib.pyplot as plt
b = 100
qs = np.linspace(0, 500, 100)
prices = np.exp(qs / b) / (np.exp(qs / b) + 1)
plt.plot(qs, prices)
plt.xlabel('YES Shares Bought')
plt.ylabel('YES Price')
plt.title('LMSR Pricing Curve (b=100)')
plt.grid(True)
plt.show()
Practical edge: check the b value via the Polymarket API before entering. Markets with b < 50 are thin — your own order moves the price significantly, which creates arbitrage opportunities but also risk if a whale enters after you.
Formula 2 — Kelly Criterion: How Much to Bet
Knowing which market to bet on is only half the problem. The other half is knowing how much to put in. Bet too little and you leave money on the table. Bet too much and a few losses wipe you out.
Kelly Criterion is the mathematical answer to that question. It is used by Renaissance Technologies, Two Sigma, and every serious quantitative fund. The formula tells you the exact fraction of your bankroll to bet in order to maximize long-term growth.
The Formula
f* = (p × odds − (1 − p)) / odds
Where:
p = your estimated probability of winning
odds = (1 / market_price) − 1
f* = fraction of bankroll to bet
A Real Example
Market: JD Vance wins 2028 election. Market price: 21% ($0.21). Your model says 25% based on polling and sentiment data.
odds = (1 / 0.21) - 1 = 3.76
f* = (0.25 × 3.76 - 0.75) / 3.76
f* = (0.94 - 0.75) / 3.76
f* = 0.19 / 3.76
f* = 0.05 → Bet 5% of your bankroll
Growth vs. Bet Size — Why You Should Never Go Full Kelly
| Bet Size | Expected Growth | Risk Level |
|---|---|---|
| 25% of Kelly (f* × 0.25) | Steady growth ✅ | Low |
| 50% of Kelly (f* × 0.50) | Good growth ✅ | Moderate |
| 100% of Kelly (full) | Peak growth ⚠️ | High variance |
| 200% of Kelly (double) | Guaranteed ruin ❌ | Catastrophic |
The math proves it: betting more than full Kelly always destroys your bankroll over time, even if your probability estimates are correct. Most professional traders use quarter Kelly (f* × 0.25) as their default.
Python Code
import numpy as np
def kelly(p, market_price):
odds = (1 / market_price) - 1
f_star = (p * odds - (1 - p)) / odds
return max(0, f_star) # Never bet negative
# Example
p = 0.25
price = 0.21
full_kelly = kelly(p, price)
quarter_kelly = full_kelly * 0.25
print(f"Full Kelly: {full_kelly:.2%}")
print(f"Quarter Kelly: {quarter_kelly:.2%}")
Formula 3 — Expected Value Gap: The Core Mispricing Detector
This is the most practical formula on this list. Expected Value (EV) tells you, in a single number, whether a trade is worth taking at all.
The idea: if you think the real probability is higher than what the market is pricing, there is a gap. That gap is your edge. If the gap is large enough to cover fees, you bet. If not, you skip it.
The Formula
EV = (p_true − market_price) × (1 / market_price)
Entry signal: EV > 0.05 after fees (roughly 1-2% on Polymarket)
A Real Example
Iran ceasefire market. Market price: 47%. Your news-based model says 52%.
EV = (0.52 − 0.47) × (1 / 0.47)
EV = 0.05 × 2.13
EV = 0.106 → +10.6% edge per dollar
That clears the 5% threshold. This is a trade worth taking.
EV Distribution Across a Market Scan
| EV Range | What It Means | Action |
|---|---|---|
| EV < 0 | Market is overpriced vs your model | Skip ❌ |
| EV 0 to 0.05 | Edge exists but fees eat it | Skip after fees ⚠️ |
| EV 0.05 to 0.15 | Clear edge above fee threshold | Bet (quarter Kelly) ✅ |
| EV > 0.15 | Strong mispricing | Bet (half Kelly) ✅ |
Python Code
import pandas as pd
# df has columns: 'market_price' and 'model_p'
df['ev'] = (df['model_p'] - df['market_price']) * (1 / df['market_price'])
df['ev_after_fees'] = df['ev'] - 0.02 # Subtract 2% fee estimate
opportunities = df[df['ev_after_fees'] > 0.05]
print(f"Markets worth trading: {len(opportunities)}")
print(opportunities[['market_name', 'market_price', 'model_p', 'ev_after_fees']])
Formula 4 — KL-Divergence: Finding Correlated Market Mispricings
Some markets are logically connected. If Candidate A goes up, Candidate B should go down. If they do not move together, one of them is wrong — and that is your trade.
KL-Divergence measures the “distance” between two probability distributions. A high KL number between two correlated markets signals that they have drifted apart and one is mispriced relative to the other.
The Formula
D_KL(P || Q) = Σ P_i × log(P_i / Q_i)
Where:
P = probability distribution of market A
Q = probability distribution of market B
Signal threshold: D_KL > 0.2 suggests exploitable divergence
Example: 2028 Election Markets
| Candidate | Market Price (YES) | Market Price (NO) |
|---|---|---|
| Vance | 21% | 79% |
| Newsom | 17% | 83% |
These two candidates compete for the same pool of voters. A large KL score between their markets means the market is pricing them inconsistently — a hedge position on both captures the correction when they realign.
Python Code
from scipy.stats import entropy
# Vance market: [YES, NO]
p_vance = [0.21, 0.79]
# Newsom market: [YES, NO]
p_newsom = [0.17, 0.83]
kl_score = entropy(p_vance, p_newsom)
print(f"KL Divergence: {kl_score:.4f}")
if kl_score > 0.2:
print("→ Signal: these markets have drifted — consider a hedge position")
else:
print("→ No significant divergence detected")
Formula 5 — Bregman Projection: Multi-Outcome Arbitrage
In a market with multiple outcomes — like Best Picture at the Oscars — all the probabilities must add up to 100%. If they do not, there is a free arbitrage sitting there. Bregman Projection is the algorithm that finds it.
This is the most mathematically advanced formula on the list. You do not need to understand the full derivation to use it. The code does the heavy lifting.
The Core Idea
Think of it like this: you have 5 Oscar nominees, each with a market price. If you add them all up and the total is 115% instead of 100%, that extra 15% is market inefficiency. Bregman Projection finds the combination of bets that locks in risk-free profit from that inconsistency.
Convergence Chart
| Iteration | Objective Value | Progress |
|---|---|---|
| 1 | 0.842 | ██░░░░░░░░░░░░░░░░░░ |
| 25 | 0.312 | ████████░░░░░░░░░░░░ |
| 50 | 0.089 | ████████████░░░░░░░░ |
| 100 | 0.011 | ████████████████████ |
| 150 | 0.001 | ████████████████████ ✅ |
The algorithm converges in 50–150 steps. Each step refines the probability projection until it finds the exact set of bets that clears the arbitrage.
Python Code
import cvxpy as cp
import numpy as np
# Example: 3-outcome market (extend to any number)
# Market prices (should sum to 1.0 — if they don't, arb exists)
market_prices = np.array([0.40, 0.35, 0.30]) # Sums to 1.05 — mispriced
print(f"Market sum: {market_prices.sum():.2f}") # Should be 1.00
# Find the nearest valid probability distribution
mu = cp.Variable(3)
objective = cp.Minimize(cp.sum(cp.kl_div(mu, market_prices)))
constraints = [cp.sum(mu) == 1, mu >= 0]
prob = cp.Problem(objective, constraints)
prob.solve()
print("Arbitrage-free probabilities:", mu.value.round(3))
print("Implied edge per outcome:", (market_prices - mu.value).round(3))
Formula 6 — Bayesian Update: Adjusting in Real Time
All five formulas above assume your probability estimate is static. In reality, new information arrives constantly — a tweet, a poll, a news headline. Bayesian updating is how you fold that information into your model without throwing away everything you already knew.
It is how human experts think when they reason well. It is also how the best quant models stay accurate as events develop.
The Formula
P(H | E) = P(E | H) × P(H) / P(E)
Where:
P(H) = your prior probability (before new evidence)
P(E | H) = how likely the evidence is if H is true
P(E) = overall probability of seeing this evidence
P(H | E) = updated probability (posterior)
Example: Elon Musk Tweets About a Market
You are watching a market on crypto regulation. Your starting estimate is 50%. Elon tweets something bullish about the underlying asset. Past data shows his tweets correlate with YES outcomes 70% of the time on similar markets.
| Time | Event | Probability |
|---|---|---|
| T=0 | No new information | 50% |
| T=1 | Elon tweet (bullish) | ↑ 62% |
| T=2 | Major news outlet picks it up | ↑ 71% |
| T=3 | Contradicting report published | ↓ 58% |
Each piece of evidence nudges the probability up or down. The Bayesian model does this mathematically rather than by gut feel — and it does it consistently across thousands of markets at once.
Python Code
def bayesian_update(prior, likelihood_if_true, likelihood_if_false):
"""
prior = P(H) before evidence
likelihood_if_true = P(E | H is true)
likelihood_if_false= P(E | H is false)
"""
numerator = likelihood_if_true * prior
denominator = (likelihood_if_true * prior) + (likelihood_if_false * (1 - prior))
posterior = numerator / denominator
return round(posterior, 4)
# Starting probability: 50%
# New evidence: Elon tweet
# P(tweet | YES resolves) = 0.70
# P(tweet | NO resolves) = 0.35
posterior = bayesian_update(
prior = 0.50,
likelihood_if_true = 0.70,
likelihood_if_false = 0.35
)
print(f"Updated probability: {posterior:.0%}") # → 67%
How to Connect All 6 Into One System
Each formula solves one part of the problem. Together, they form a complete decision pipeline:
| Step | Formula | What It Does |
|---|---|---|
| 1 | LMSR | Understand how your order will move the price before placing it |
| 2 | Bayesian Update | Build your true probability estimate from current evidence |
| 3 | EV Gap | Check if the gap between your estimate and the market price is worth trading |
| 4 | KL-Divergence | Scan correlated markets for additional confirmation or hedge opportunities |
| 5 | Bregman Projection | Check multi-outcome markets for arbitrage before entering |
| 6 | Kelly
|

Leave a Reply