Prediction Markets

Automating Polymarket Trades with Python: Step-by-Step Guide

Polymarket has an open API. This step-by-step Python guide shows you how to authenticate, browse markets, analyze probabilities with AI, and place automated trades on prediction markets.

A
AI Agents Hubยท2025-05-17ยท6 min readยท1,067 words

Builder of AI agents, crypto trading bots, and open-source automation tools. Sharing practical guides on how to build, deploy, and profit from AI and DeFi technology.

What Is Polymarket and Why Automate It?

Polymarket is the largest prediction market in the world. People buy YES/NO shares on real-world events. The price represents the implied probability.

Why automate trades?

  • Markets are often mispriced for 10โ€“30 minutes after news breaks
  • You cannot monitor 200+ active markets manually
  • AI can assess probabilities more objectively than humans
  • Position management (scaling in/out) is too complex to do manually at scale

Prerequisites

  • Python 3.10+
  • A crypto wallet (MetaMask or similar)
  • USDC on Polygon network
  • Polymarket account (note: US users need to use a non-US approach)

Step 1: Set Up the SDK

Polymarket uses a CLOB (Central Limit Order Book) system. They provide an official Python client:

pip install py-clob-client eth-account requests python-dotenv
import os
from dotenv import load_dotenv
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import ApiCreds, OrderArgs, OrderType

load_dotenv()

# Initialize client
# You need to derive API keys from your wallet private key
HOST = "https://clob.polymarket.com"
KEY = os.getenv("PRIVATE_KEY")          # Your wallet private key
CHAIN_ID = 137                           # Polygon mainnet

client = ClobClient(HOST, key=KEY, chain_id=CHAIN_ID)

# Create API credentials (one-time setup)
api_creds = client.create_or_derive_api_creds()
print(f"API Key: {api_creds.api_key}")
print(f"API Secret: {api_creds.api_secret}")
print(f"API Passphrase: {api_creds.api_passphrase}")

# Save these to .env!

Step 2: Browse and Search Markets

from py_clob_client.client import ClobClient

# Authenticated client
client = ClobClient(
    HOST,
    key=KEY,
    chain_id=CHAIN_ID,
    creds=ApiCreds(
        api_key=os.getenv("POLY_API_KEY"),
        api_secret=os.getenv("POLY_API_SECRET"),
        api_passphrase=os.getenv("POLY_API_PASSPHRASE"),
    )
)

def search_markets(query: str = "", min_volume: float = 10000) -> list[dict]:
    """Search for active markets."""
    markets = client.get_markets()
    
    # Filter by query and minimum volume
    filtered = [
        m for m in markets
        if query.lower() in m['question'].lower()
        and float(m.get('volume', 0)) > min_volume
        and m.get('active', False)
    ]
    
    return filtered

def get_market_prices(condition_id: str) -> dict:
    """Get current YES/NO prices for a market."""
    order_book = client.get_order_book(condition_id)
    
    # Best ask = what you pay to buy YES
    best_ask = float(order_book['asks'][0]['price']) if order_book['asks'] else None
    # Best bid = what you receive when you sell YES
    best_bid = float(order_book['bids'][-1]['price']) if order_book['bids'] else None
    
    return {
        'yes_price': best_ask,  # This is the current "YES" probability
        'no_price': 1 - best_ask if best_ask else None,  # NO = 1 - YES
        'spread': (best_ask - best_bid) if best_ask and best_bid else None,
        'condition_id': condition_id
    }

# Example
crypto_markets = search_markets("bitcoin", min_volume=50000)
for m in crypto_markets[:5]:
    print(f"\nQuestion: {m['question']}")
    prices = get_market_prices(m['conditionId'])
    print(f"YES price: {prices['yes_price']:.2%}")
    print(f"Volume: ${float(m.get('volume', 0)):,.0f}")

Step 3: AI Probability Assessment

import json
from openai import OpenAI

client_ai = OpenAI()

def assess_market_probability(question: str, current_price: float) -> dict:
    """
    Use GPT-4o to estimate the true probability vs. current market price.
    Returns edge if market is mispriced.
    """
    response = client_ai.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": """You are an expert forecaster and prediction market analyst. 
                Assess event probabilities based on base rates and available information.
                Be calibrated โ€” your estimates should reflect uncertainty.
                
                Key principles:
                1. Reference classes matter (what has happened in similar situations?)
                2. Avoid anchoring to the current market price  
                3. Update on concrete evidence, not vibes
                4. Consider resolution criteria carefully"""
            },
            {
                "role": "user",
                "content": f"""Market question: {question}
                
Current market price (implied probability): {current_price:.1%}

Provide your independent probability estimate. Return JSON:
{{
  "ai_probability": 0.0-1.0,
  "confidence": "low/medium/high",
  "reasoning": "key factors driving your estimate",
  "data_needed": "what information would most change your estimate",
  "edge": "positive/negative/none"
}}

Be specific. Reference base rates. Do NOT anchor to the current market price."""
            }
        ],
        response_format={"type": "json_object"}
    )
    
    result = json.loads(response.choices[0].message.content)
    result['market_price'] = current_price
    result['raw_edge'] = result['ai_probability'] - current_price
    return result

Step 4: Placing Orders

from py_clob_client.clob_types import OrderArgs, OrderType, PartialCreateOrderOptions

def buy_yes(condition_id: str, price: float, size_usdc: float) -> dict:
    """
    Buy YES shares at specified price.
    price = probability (0.0 to 1.0)
    size_usdc = dollar amount to spend
    """
    order_args = OrderArgs(
        price=price,
        size=size_usdc / price,  # Number of shares = USDC / price per share
        side="BUY",
        token_id=condition_id,
    )
    
    signed_order = client.create_order(order_args)
    response = client.post_order(signed_order, OrderType.GTC)  # Good Till Cancelled
    
    return response

def buy_no(condition_id: str, size_usdc: float) -> dict:
    """
    Buy NO shares (= sell YES at complement price).
    NO shares effectively trade at (1 - YES price).
    """
    order_book = client.get_order_book(condition_id)
    no_price = 1 - float(order_book['asks'][0]['price'])
    
    order_args = OrderArgs(
        price=no_price,
        size=size_usdc / no_price,
        side="BUY", 
        token_id=condition_id + "_NO",  # NO token
    )
    
    signed_order = client.create_order(order_args)
    return client.post_order(signed_order, OrderType.GTC)

Step 5: The Full Automated Agent

import time
from dataclasses import dataclass

@dataclass 
class Position:
    condition_id: str
    question: str
    side: str  # YES or NO
    entry_price: float
    size_usdc: float

class PolymarketAgent:
    def __init__(self, max_position_usdc: float = 50, min_edge: float = 0.08):
        self.max_position = max_position_usdc
        self.min_edge = min_edge  # Only trade if AI sees 8%+ edge
        self.positions: dict[str, Position] = {}
    
    def run(self):
        """Main agent loop."""
        print("๐Ÿ”ฎ Polymarket agent started")
        
        while True:
            try:
                # 1. Get active markets with good volume
                markets = search_markets(min_volume=20000)
                print(f"Analyzing {len(markets)} markets...")
                
                for market in markets[:20]:  # Analyze top 20 by volume
                    cid = market['conditionId']
                    
                    # Skip if already have position
                    if cid in self.positions:
                        continue
                    
                    # Get current prices
                    prices = get_market_prices(cid)
                    if not prices['yes_price']:
                        continue
                    
                    # AI assessment
                    assessment = assess_market_probability(
                        market['question'], 
                        prices['yes_price']
                    )
                    
                    edge = assessment['raw_edge']
                    confidence = assessment['confidence']
                    
                    # Only trade with significant edge and high confidence
                    if abs(edge) >= self.min_edge and confidence == 'high':
                        side = "YES" if edge > 0 else "NO"
                        
                        print(f"\n๐Ÿ“Š Found opportunity:")
                        print(f"  Question: {market['question'][:80]}...")
                        print(f"  Market price: {prices['yes_price']:.1%}")
                        print(f"  AI estimate: {assessment['ai_probability']:.1%}")
                        print(f"  Edge: {edge:+.1%} โ†’ {side}")
                        print(f"  Reasoning: {assessment['reasoning'][:100]}...")
                        
                        # Place trade
                        size = min(self.max_position, 50)  # Cap at $50 per position
                        
                        if side == "YES":
                            result = buy_yes(cid, prices['yes_price'], size)
                        else:
                            result = buy_no(cid, size)
                        
                        self.positions[cid] = Position(
                            condition_id=cid,
                            question=market['question'],
                            side=side,
                            entry_price=prices['yes_price'],
                            size_usdc=size
                        )
                        print(f"  โœ… Placed {side} order: ${size}")
                
                # Check every 15 minutes
                print(f"\n๐Ÿ’ค Sleeping 15 minutes. Active positions: {len(self.positions)}")
                time.sleep(900)
                
            except Exception as e:
                print(f"Error: {e}")
                time.sleep(60)

# Run the agent
agent = PolymarketAgent(max_position_usdc=50, min_edge=0.08)
agent.run()

Risk Management for Prediction Markets

  • Never bet more than 2โ€“5% of bankroll per market
  • Diversify across many markets โ€” correlations between markets can be high
  • Check resolution criteria โ€” How exactly does this resolve? Could be ambiguous.
  • Manage time value โ€” Positions that do not resolve for months have capital tied up

Expected Returns

Skilled prediction market traders with genuine edge earn 20โ€“60% annually. The key word: genuine edge (not just trading more).

Get the full Polymarket bot with portfolio management and risk controls on our Tools page.

Related Articles