How to Build a Polymarket Arbitrage Bot: $40M Opportunity Guide
Arbitrage traders have extracted over $40 million in profits from Polymarket between April 2024 and April 2025. This guide reveals exactly how they do it—from detecting opportunities to building automated bots that capture risk-free profits in seconds.
What is Polymarket Arbitrage?
Arbitrage exploits price inefficiencies to lock in guaranteed profits regardless of outcome. On prediction markets like Polymarket, this happens when:
- YES + NO prices don't sum to $1.00 (intra-market)
- Multiple outcomes don't sum to $1.00 (multi-outcome)
- Same event priced differently across platforms (cross-platform)
Types of Arbitrage Opportunities
1. Market Rebalancing (Intra-Market)
The simplest form. In a binary market, YES + NO should always equal $1.00.
Example:
- YES price: $0.45
- NO price: $0.50
- Combined cost: $0.95
- Guaranteed payout: $1.00
- Risk-free profit: $0.05 (5.3% return)
2. Combinatorial (Multi-Outcome)
In markets with multiple outcomes (e.g., "Who will win the election?"), all outcome prices should sum to $1.00.
Example:
- Candidate A: $0.25
- Candidate B: $0.24
- Candidate C: $0.26
- Candidate D: $0.245
- Total cost: $0.995
- Profit: $0.005 per share (0.5% return)
3. Cross-Platform Arbitrage
Exploiting price differences between Polymarket and other platforms like Kalshi, Robinhood, or PredictIt.
Example (Bitcoin > $100k):
- Polymarket YES: $0.55
- Kalshi YES: $0.62
- Buy Polymarket, sell Kalshi
- Locked profit: $0.07 (12.7% on capital)
4. Endgame Arbitrage
Buying near-certain outcomes (95-99% probability) close to market resolution. Lower margins but extremely high annualized returns.
Example:
- Market resolves in 2 days
- Current price: $0.97
- Buy and hold until $1.00
- 3% profit in 2 days
- Annualized: 548% return
Real Data: How Much Can You Make?
| Metric | Value |
|---|---|
| Total arbitrage profits (Apr 2024-2025) | $40 million+ |
| Top 3 wallets combined profits | $4.2 million |
| Average arbitrage margin | 2-3% |
| Typical opportunity window | Seconds (not minutes) |
| Profitable users (>$1k) | Only 0.51% |
Key Insight
One documented trader turned $10,000 into $100,000 over 6 months by participating in 10,000+ markets with pure arbitrage strategies—no gambling or insider information.
See What Whales Are Trading Right Now
Get instant alerts when top traders make moves. Track P&L, win rates, and copy winning strategies.

Free forever. No credit card required.
Building an Arbitrage Detection Bot
Basic Intra-Market Detector
from py_clob_client.client import ClobClient
client = ClobClient("https://clob.polymarket.com")
def detect_binary_arbitrage(market):
"""Detect arbitrage in YES/NO markets."""
tokens = market.get("tokens", [])
if len(tokens) != 2:
return None
yes_token = next((t for t in tokens if t["outcome"] == "Yes"), None)
no_token = next((t for t in tokens if t["outcome"] == "No"), None)
if not yes_token or not no_token:
return None
yes_price = float(yes_token.get("price", 0.5))
no_price = float(no_token.get("price", 0.5))
combined = yes_price + no_price
# Arbitrage exists if combined < 1.0
if combined < 0.995: # Account for fees
profit_margin = 1.0 - combined
profit_pct = (profit_margin / combined) * 100
return {
"type": "BUY_BOTH",
"market": market.get("question"),
"yes_price": yes_price,
"no_price": no_price,
"cost": combined,
"profit": profit_margin,
"profit_pct": profit_pct
}
return None
# Scan all markets
def scan_markets():
markets = client.get_markets()
opportunities = []
for market in markets.get("data", []):
arb = detect_binary_arbitrage(market)
if arb:
opportunities.append(arb)
print(f"ARBITRAGE FOUND: " + str(arb['market']))
print(f" Cost: $" + format(arb['cost'], '.4f') + ", Profit: " + format(arb['profit_pct'], '.2f') + "%")
return opportunities
if __name__ == "__main__":
scan_markets()Multi-Outcome Arbitrage Detector
def detect_multi_outcome_arbitrage(market):
"""Detect arbitrage in multi-outcome markets."""
tokens = market.get("tokens", [])
if len(tokens) < 3:
return None
total_cost = sum(float(t.get("price", 0)) for t in tokens)
# All outcomes should sum to 1.0
if total_cost < 0.995: # Account for fees
profit = 1.0 - total_cost
profit_pct = (profit / total_cost) * 100
return {
"type": "COMBINATORIAL",
"market": market.get("question"),
"outcomes": len(tokens),
"total_cost": total_cost,
"profit": profit,
"profit_pct": profit_pct,
"tokens": [
{"outcome": t["outcome"], "price": t["price"]}
for t in tokens
]
}
return NoneCross-Platform Detector (Polymarket vs Kalshi)
def detect_cross_platform_arbitrage(poly_market, kalshi_market):
"""Compare prices between Polymarket and Kalshi."""
poly_yes = float(poly_market.get("yes_price", 0.5))
kalshi_yes = float(kalshi_market.get("yes_price", 0.5))
# Platform fees
POLY_FEE = 0.0001 # 0.01%
KALSHI_FEE = 0.007 # 0.7%
# Opportunity 1: Poly cheaper
if poly_yes < kalshi_yes:
gross_spread = kalshi_yes - poly_yes
net_spread = gross_spread - POLY_FEE - KALSHI_FEE
if net_spread > 0.005: # Minimum 0.5% profit
return {
"type": "CROSS_PLATFORM",
"buy_platform": "Polymarket",
"sell_platform": "Kalshi",
"buy_price": poly_yes,
"sell_price": kalshi_yes,
"gross_profit": gross_spread,
"net_profit": net_spread,
"roi_pct": (net_spread / poly_yes) * 100
}
# Opportunity 2: Kalshi cheaper
elif kalshi_yes < poly_yes:
gross_spread = poly_yes - kalshi_yes
net_spread = gross_spread - POLY_FEE - KALSHI_FEE
if net_spread > 0.005:
return {
"type": "CROSS_PLATFORM",
"buy_platform": "Kalshi",
"sell_platform": "Polymarket",
"buy_price": kalshi_yes,
"sell_price": poly_yes,
"gross_profit": gross_spread,
"net_profit": net_spread,
"roi_pct": (net_spread / kalshi_yes) * 100
}
return NoneReal-Time Monitoring with WebSockets
REST API polling is too slow for arbitrage. Use WebSocket streaming for real-time detection:
from websocket import WebSocketApp
import json
import time
class ArbitrageMonitor:
def __init__(self, asset_pairs):
self.asset_pairs = asset_pairs # {condition_id: [yes_token, no_token]}
self.prices = {}
self.url = "wss://ws-subscriptions-clob.polymarket.com"
def on_message(self, ws, message):
data = json.loads(message)
if data.get("event_type") == "price_change":
for change in data.get("price_changes", []):
asset_id = change["asset_id"]
best_bid = float(change.get("best_bid", 0))
best_ask = float(change.get("best_ask", 1))
mid_price = (best_bid + best_ask) / 2
self.prices[asset_id] = mid_price
self.check_arbitrage()
def check_arbitrage(self):
for condition_id, tokens in self.asset_pairs.items():
yes_token, no_token = tokens
if yes_token in self.prices and no_token in self.prices:
yes_price = self.prices[yes_token]
no_price = self.prices[no_token]
combined = yes_price + no_price
if combined < 0.99:
profit = 1.0 - combined
print(f"ARBITRAGE: {condition_id}")
print(f" YES: {yes_price}, NO: {no_price}")
print(f" Cost: {combined}, Profit: " + format(profit, '.4f'))
self.execute_arbitrage(condition_id, yes_token, no_token)
def execute_arbitrage(self, condition_id, yes_token, no_token):
# Implement order execution here
# See py-clob-client for placing orders
pass
def on_open(self, ws):
all_tokens = []
for tokens in self.asset_pairs.values():
all_tokens.extend(tokens)
subscription = {
"assets_ids": all_tokens,
"type": "market"
}
ws.send(json.dumps(subscription))
print(f"Monitoring {len(all_tokens)} tokens for arbitrage...")
def start(self):
ws = WebSocketApp(
self.url + "/ws/market",
on_open=self.on_open,
on_message=self.on_message
)
ws.run_forever()Execution Strategy
Atomic Execution
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY
import os
client = ClobClient(
"https://clob.polymarket.com",
key=os.getenv("PK"),
chain_id=137
)
client.set_api_creds(client.create_or_derive_api_creds())
def execute_binary_arbitrage(yes_token, no_token, size=10):
"""Execute arbitrage by buying both YES and NO."""
# Get current prices
yes_price = float(client.get_price(yes_token, side="BUY"))
no_price = float(client.get_price(no_token, side="BUY"))
combined = yes_price + no_price
if combined >= 0.995:
print("Opportunity no longer exists")
return None
try:
# Buy YES
yes_order = OrderArgs(
token_id=yes_token,
price=yes_price + 0.01, # Slightly above market
size=size,
side=BUY
)
yes_signed = client.create_order(yes_order)
yes_response = client.post_order(yes_signed, OrderType.FOK)
# Buy NO
no_order = OrderArgs(
token_id=no_token,
price=no_price + 0.01,
size=size,
side=BUY
)
no_signed = client.create_order(no_order)
no_response = client.post_order(no_signed, OrderType.FOK)
actual_cost = (yes_price + no_price) * size
guaranteed_payout = size
profit = guaranteed_payout - actual_cost
print("Arbitrage executed!")
print(" Cost: $" + format(actual_cost, '.2f'))
print(" Payout: $" + format(guaranteed_payout, '.2f'))
print(" Profit: $" + format(profit, '.2f'))
return {
"yes_order": yes_response,
"no_order": no_response,
"profit": profit
}
except Exception as e:
print(f"Execution failed: {e}")
return NoneTools and Resources
EventArb Calculator
URL: eventarb.com - Free web-based calculator supporting Polymarket, Kalshi, Robinhood, and Interactive Brokers. Features email alerts and fee-adjusted calculations.
Open Source Bots
- polymarket-arbitrage-bot - github.com/0xalberto/polymarket-arbitrage-bot - Single and multi-market detection
- polymarket-kalshi-btc-arbitrage-bot - github.com/CarlosIbCu/polymarket-kalshi-btc-arbitrage-bot - Cross-platform BTC arbitrage
- event-contract-arbitrage - github.com/akhan280/event-contract-arbitrage - EventArb source code
DeFi Rate Calculators
defirate.com/prediction-markets/calculators/ - Arbitrage, odds converter, hedging, and EV calculators.
Risks and Challenges
Execution Risk: Slippage
Markets move fast. Your planned 3% profit can become 0.5% (or a loss) if prices change before execution.
- Use limit orders with slight premium over market
- Check order book depth before trading
- Start with small positions (1-5% of available liquidity)
- Avoid thin markets (<$1,000 liquidity)
Speed Competition
Reality Check
"Arbitrage opportunities on Polymarket exist for only a few seconds. Today, they are captured not by people but by bots operating on Polygon nodes."
- Manual trading is uncompetitive for standard arbitrage
- Sub-second execution required
- Consider co-located servers near Polygon nodes
- Focus on less competitive strategies (endgame, cross-platform)
Black Swan Events
Even 99% probability markets can reverse. Political scandals, health events, and resolution disputes happen.
- Never assume any position is "guaranteed"
- Diversify across many markets
- Limit position size (max 1/10 of portfolio per market)
Fee Considerations
| Platform | Fee |
|---|---|
| Polymarket (US) | 0.01% trading fee |
| Polymarket (International) | 2% on net winnings |
| Kalshi | ~0.7% trading fee |
| Polygon gas | ~$0.007 per transaction |
Example: $1,000 cross-platform arbitrage with 3% gross profit:
- Gross profit: $30
- Polymarket fee: $0.10
- Kalshi fee: $7.00
- Gas: $0.01
- Net profit: $22.89 (2.29%)
Recommended Strategy by Experience Level
Beginner: Manual Endgame Arbitrage
- Focus on 95-99% probability markets near resolution
- Use EventArb calculator for cross-platform opportunities
- Capital: $1,000-$10,000
- Expected returns: 10-30% annualized
Intermediate: Semi-Automated Detection
- Build detection scripts with manual execution
- Focus on multi-outcome markets
- Capital: $10,000-$100,000
- Expected returns: 30-100% annualized
Advanced: Fully Automated Bots
- Sub-second detection and execution
- WebSocket streaming for real-time data
- Co-located infrastructure
- Capital: $100,000+
- Expected returns: 100-300%+ annualized (highly competitive)
Key Takeaways
What Works
- ✅ Automated detection is mandatory for consistent profits
- ✅ Speed is critical—opportunities last seconds
- ✅ High-volume events (elections, sports) create more opportunities
- ✅ Cross-platform and endgame arbitrage more accessible
- ✅ Market making + arbitrage combination most profitable
What Doesn't Work
- ❌ Manual monitoring of standard arbitrage (too slow)
- ❌ Large positions in thin markets (slippage eats profits)
- ❌ Ignoring fees (can eliminate profits entirely)
- ❌ Treating 99% as 100% (black swans happen)
Track Arbitrage Opportunities with PolyTrack
PolyTrack helps you monitor market prices, track whale movements, and identify potential arbitrage opportunities. Start your free trial and trade smarter.
Next Steps
- Python Tutorial - Set up py-clob-client for trading
- WebSocket Tutorial - Real-time data streaming
- Trading Bot Guide - Complete bot architecture
- API Guide - Full REST API reference
Frequently Asked Questions
Over $40 million in arbitrage profits were extracted from Polymarket between April 2024 and April 2025. The top 3 wallets alone generated approximately $4.2 million in profits.
Related Articles
Stop Guessing. Start Following Smart Money.
Get instant alerts when whales make $10K+ trades. Track P&L, win rates, and copy winning strategies.