PolymarketPolymarketDeveloper25 min read2026-01-21

Polymarket Trading Bot Code Review: warproxxx/poly-maker Analysis

AL - Founder of PolyTrack, Polymarket trader & analyst

AL

Founder of PolyTrack, Polymarket trader & analyst

Polymarket Trading Bot Code Review: warproxxx/poly-maker Analysis - Developer Guide for Polymarket Traders | PolyTrack Blog

Deep code review of the most searched Polymarket trading bots on GitHub. With 39+ monthly searches for warproxxx/poly-maker, 15+ searches for trust412/polymarket-spike-bot, and 7+ searches for carlosibcu/polymarket-kalshi-btc-arbitrage-bot, developers are actively studying these implementations. This comprehensive 2026 analysis breaks down each bot's architecture, strategy, code quality, and real-world performance.

Whether you're building your own Polymarket trading bot, learning from successful bot implementations, or evaluating which GitHub codebase to fork, this review provides the technical depth you need. All code has been analyzed for architecture patterns, error handling, performance optimizations, and production readiness.

šŸ“Š Review Methodology

  • • Code Quality: Architecture, error handling, code organization, documentation
  • • Strategy Analysis: Trading logic, risk management, position sizing
  • • Performance: Latency, efficiency, resource usage
  • • Production Readiness: Testing, monitoring, error recovery
  • • Search Volume: Based on Google Search Console data (GSC)

1. warproxxx/poly-maker - Market Making Bot

Search Volume: 39+ monthly searches | GitHub Stars: 50+ | Language: Python | Strategy: Market Making

šŸ” What Developers Are Actually Searching For

GSC data reveals 94+ monthly searches for raw GitHub files from poly-maker:

  • raw.githubusercontent.com warproxxx poly-maker main.py - 39 searches
  • raw.githubusercontent.com warproxxx poly-maker .env.example - 29 searches
  • raw.githubusercontent.com warproxxx poly-maker trading.py - 17 searches
  • github.com/warproxxx/poly-maker/blob/main/trading.py - 15 searches

Developers want to see the actual implementation. View full repository on GitHub. For official Polymarket API documentation, see the CLOB API docs and official py-clob-client library.

Architecture Overview

poly-maker implements a classic market making strategy: providing liquidity on both sides of the orderbook to capture the bid-ask spread. The bot continuously monitors markets, analyzes orderbook depth, and places limit orders at optimal prices.

Core Components

  • Market Scanner: Identifies markets with sufficient liquidity and favorable spreads (typically 2-5% bid-ask spread)
  • Orderbook Analyzer: Calculates optimal bid/ask prices based on current orderbook depth and recent price movements
  • Order Manager: Places, updates, and cancels limit orders using the py-clob-client library
  • Risk Manager: Monitors positions, enforces maximum exposure limits, and implements stop-loss mechanisms
  • Position Tracker: Tracks P&L, position sizes, and fill rates in real-time

Code Structure Analysis

The repository follows a clean, modular architecture:

poly-maker/
ā”œā”€ā”€ main.py              # Entry point, main trading loop
ā”œā”€ā”€ trading.py           # Core trading logic and order management
ā”œā”€ā”€ config.py            # Configuration management
ā”œā”€ā”€ orderbook.py         # Orderbook analysis and spread calculation
ā”œā”€ā”€ risk_manager.py      # Position limits and risk controls
ā”œā”€ā”€ utils.py             # Helper functions and utilities
ā”œā”€ā”€ requirements.txt     # Python dependencies
└── .env.example         # Environment variable template

Key Code Patterns

The bot uses several production-ready patterns:

1. Orderbook Spread Detection
def calculate_spread(orderbook):
    """Calculate bid-ask spread for market making."""
    best_bid = orderbook['bids'][0]['price']
    best_ask = orderbook['asks'][0]['price']
    spread = best_ask - best_bid
    spread_pct = (spread / best_ask) * 100
    return spread, spread_pct

# Target markets with 2-5% spread
if spread_pct >= 2.0 and spread_pct <= 5.0:
    place_market_making_orders(orderbook)
2. Limit Order Placement
from py_clob_client.client import ClobClient
from py_clob_client.order_builder import OrderBuilder

def place_limit_order(client, market_id, side, price, size):
    """Place a limit order with proper error handling."""
    try:
        order = OrderBuilder.create_limit_order(
            market_id=market_id,
            side=side,  # 'BUY' or 'SELL'
            price=price,
            size=size,
            order_type='GTC'  # Good-till-cancel
        )
        signed_order = client.sign_order(order)
        response = client.create_order(signed_order)
        return response
    except Exception as e:
        logger.error(f"Order placement failed: {e}")
        return None
3. Risk Management
class RiskManager:
    def __init__(self, max_position_size=1000, max_exposure=5000):
        self.max_position_size = max_position_size
        self.max_exposure = max_exposure
        self.current_positions = {}
    
    def can_place_order(self, market_id, size, price):
        """Check if order is within risk limits."""
        current_exposure = sum(
            pos['size'] * pos['price'] 
            for pos in self.current_positions.values()
        )
        new_exposure = size * price
        
        if current_exposure + new_exposure > self.max_exposure:
            return False
        if size > self.max_position_size:
            return False
        return True

Code Quality Assessment

āœ… Strengths

  • • Clean, modular architecture with separation of concerns
  • • Comprehensive error handling and logging
  • • Well-documented code with clear function names
  • • Production-ready with proper configuration management
  • • Uses official py-clob-client library
  • • Implements proper risk management controls

āš ļø Considerations

  • • Market making requires significant capital (typically $5,000+)
  • • Requires understanding of orderbook dynamics
  • • Can be exposed to adverse selection if not careful
  • • Needs monitoring for market conditions changes
  • • Python may have higher latency than Rust for HFT

šŸ’” Want to Track Market Makers?

PolyTrack Pro identifies market maker wallets by analyzing their trading patterns: consistent limit orders on both sides, high fill rates, and spread capture. Free users can only track 3 wallets - upgrade to see unlimited market maker wallets with real-time alerts and P&L tracking.

2. trust412/polymarket-spike-bot-v1 - Spike Detection Bot

Search Volume: 15+ monthly searches | GitHub Stars: 30+ | Language: Python | Strategy: Momentum/Spike Detection

This bot detects rapid price movements (spikes) on Polymarket and executes trades automatically. It's designed for traders who want to capitalize on sudden market movements, whether from news events, whale activity, or market inefficiencies.

Strategy Overview

The spike bot monitors markets continuously via the Polymarket Gamma API and WebSocket connections. For official API documentation, see gamma-api.polymarket.com. When a price moves beyond configured thresholds (e.g., 5% in 1 minute), it:

  1. Verifies the spike is legitimate (not a small-volume glitch)
  2. Checks volume requirements (minimum trade volume to confirm signal)
  3. Calculates position size based on risk parameters
  4. Executes market order in the direction of the spike
  5. Sets stop-loss and take-profit levels
  6. Monitors position until exit conditions are met

Code Implementation

Spike Detection Logic
import time
from collections import deque

class SpikeDetector:
    def __init__(self, spike_threshold=0.05, time_window=60):
        self.spike_threshold = spike_threshold  # 5% price change
        self.time_window = time_window  # 60 seconds
        self.price_history = deque(maxlen=100)
        self.volume_history = deque(maxlen=100)
    
    def detect_spike(self, current_price, current_volume):
        """Detect if current price movement is a spike."""
        self.price_history.append({
            'price': current_price,
            'volume': current_volume,
            'timestamp': time.time()
        })
        
        if len(self.price_history) < 2:
            return None
        
        # Calculate price change over time window
        recent_prices = [
            p for p in self.price_history 
            if time.time() - p['timestamp'] <= self.time_window
        ]
        
        if len(recent_prices) < 2:
            return None
        
        oldest_price = recent_prices[0]['price']
        price_change = (current_price - oldest_price) / oldest_price
        
        # Check if spike meets threshold and volume requirements
        if abs(price_change) >= self.spike_threshold:
            avg_volume = sum(p['volume'] for p in recent_prices) / len(recent_prices)
            if current_volume >= avg_volume * 1.5:  # 50% volume increase
                return {
                    'direction': 'UP' if price_change > 0 else 'DOWN',
                    'magnitude': abs(price_change),
                    'volume': current_volume
                }
        
        return None
Automated Trade Execution
def execute_spike_trade(client, market_id, spike_signal):
    """Execute trade when spike is detected."""
    direction = spike_signal['direction']
    magnitude = spike_signal['magnitude']
    
    # Position sizing based on spike magnitude
    # Larger spikes = larger positions (up to max)
    base_size = 100
    size_multiplier = min(magnitude / 0.05, 3.0)  # Cap at 3x
    position_size = int(base_size * size_multiplier)
    
    # Place market order
    order = OrderBuilder.create_market_order(
        market_id=market_id,
        side='BUY' if direction == 'UP' else 'SELL',
        size=position_size
    )
    
    signed_order = client.sign_order(order)
    response = client.create_order(signed_order)
    
    # Set stop-loss at 2% below entry
    stop_loss_price = response['price'] * 0.98 if direction == 'UP' else response['price'] * 1.02
    
    return {
        'order_id': response['id'],
        'entry_price': response['price'],
        'stop_loss': stop_loss_price,
        'take_profit': response['price'] * 1.05 if direction == 'UP' else response['price'] * 0.95
    }

Code Quality Assessment

āœ… Strengths

  • • Simple, focused strategy that's easy to understand
  • • Real-time price monitoring with WebSocket integration
  • • Configurable thresholds for different market conditions
  • • Volume verification prevents false signals
  • • Position sizing based on spike magnitude

āš ļø Considerations

  • • Can be vulnerable to false spikes (flash crashes, low liquidity)
  • • Requires fast execution to capture spikes before they reverse
  • • Market orders have higher fees than limit orders
  • • Needs careful risk management to avoid large losses
  • • May struggle in highly efficient markets

3. carlosibcu/polymarket-kalshi-btc-arbitrage-bot - Cross-Platform Arbitrage

Search Volume: 7+ monthly searches | GitHub Stars: 20+ | Language: Python | Strategy: Cross-Platform Arbitrage

This bot exploits price differences between Polymarket and Kalshi for BTC price prediction markets. When the same event (e.g., "Bitcoin above $100k by Dec 31, 2025") is priced differently on both platforms, the bot buys the cheaper side and sells the more expensive side, locking in risk-free profit. See the official Polymarket platform for live market data.

Arbitrage Strategy

The bot continuously monitors equivalent markets on both platforms:

  • Market Matching: Identifies equivalent markets (same event, same resolution date)
  • Price Comparison: Calculates price difference between platforms
  • Arbitrage Detection: Finds opportunities where combined cost < $1 (guaranteed profit)
  • Simultaneous Execution: Places orders on both platforms simultaneously
  • Profit Locking: One side always wins, ensuring profit regardless of outcome

Code Implementation

Arbitrage Opportunity Detection
def find_arbitrage_opportunity(polymarket_price, kalshi_price):
    """
    Find arbitrage opportunity between Polymarket and Kalshi.
    
    Strategy: Buy both YES on Polymarket and Kalshi
    If combined cost < $1, profit is guaranteed.
    """
    # Normalize prices (Polymarket uses 0-1, Kalshi uses 0-100)
    pm_price = polymarket_price  # Already 0-1
    kalshi_price_normalized = kalshi_price / 100  # Convert to 0-1
    
    # Calculate combined cost
    combined_cost = pm_price + kalshi_price_normalized
    
    # Arbitrage exists if combined cost < 1.0
    if combined_cost < 0.98:  # 2% minimum profit margin
        profit_margin = 1.0 - combined_cost
        return {
            'opportunity': True,
            'polymarket_price': pm_price,
            'kalshi_price': kalshi_price_normalized,
            'combined_cost': combined_cost,
            'profit_margin': profit_margin,
            'recommended_size': calculate_position_size(profit_margin)
        }
    
    return {'opportunity': False}

def calculate_position_size(profit_margin):
    """Calculate optimal position size based on profit margin."""
    # Larger profit margins = larger positions
    base_size = 1000  # $1,000 base
    size_multiplier = profit_margin / 0.02  # Scale with margin
    return int(base_size * min(size_multiplier, 5.0))  # Cap at 5x
Simultaneous Order Execution
import asyncio
from py_clob_client.client import ClobClient
from kalshi_client import KalshiClient

async def execute_arbitrage(arb_opportunity):
    """Execute arbitrage trade on both platforms simultaneously."""
    pm_client = ClobClient()
    kalshi_client = KalshiClient()
    
    size = arb_opportunity['recommended_size']
    
    # Execute on both platforms concurrently
    tasks = [
        place_polymarket_order(pm_client, size),
        place_kalshi_order(kalshi_client, size)
    ]
    
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    # Verify both orders filled
    if any(isinstance(r, Exception) for r in results):
        # Cancel successful order if one failed
        cancel_filled_orders(results)
        return {'success': False, 'error': 'Partial fill'}
    
    return {
        'success': True,
        'polymarket_order': results[0],
        'kalshi_order': results[1],
        'locked_profit': size * arb_opportunity['profit_margin']
    }

Code Quality Assessment

āœ… Strengths

  • • Risk-free arbitrage strategy (guaranteed profit)
  • • Simultaneous execution prevents price slippage
  • • Works with multiple platforms (extensible architecture)
  • • Position sizing based on profit margin
  • • Proper error handling for partial fills

āš ļø Considerations

  • • Requires accounts on both platforms
  • • Arbitrage opportunities are rare and short-lived
  • • Needs fast execution to capture opportunities
  • • Capital requirements for both platforms
  • • Platform-specific API integration complexity

Code Quality Comparison

BotLanguageStarsArchitectureError HandlingDocumentationOverall Quality
poly-makerPython50+⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
spike-botPython30+⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
arbitrage-botPython20+⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

Common Patterns and Best Practices

1. Error Handling and Retry Logic

All three bots implement retry logic for API calls, but with varying sophistication:

from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10)
)
def place_order_with_retry(client, order):
    """Place order with exponential backoff retry."""
    try:
        return client.create_order(order)
    except APIError as e:
        if e.status_code == 429:  # Rate limit
            raise  # Retry with backoff
        elif e.status_code >= 500:  # Server error
            raise  # Retry
        else:
            raise  # Don't retry client errors

2. Configuration Management

All bots use environment variables for sensitive configuration:

import os
from dotenv import load_dotenv

load_dotenv()

class Config:
    POLYMARKET_API_KEY = os.getenv('POLYMARKET_API_KEY')
    POLYMARKET_API_SECRET = os.getenv('POLYMARKET_API_SECRET')
    POLYMARKET_API_URL = os.getenv('POLYMARKET_API_URL', 'https://clob.polymarket.com')
    
    MAX_POSITION_SIZE = int(os.getenv('MAX_POSITION_SIZE', '1000'))
    MAX_EXPOSURE = int(os.getenv('MAX_EXPOSURE', '5000'))
    SPREAD_THRESHOLD = float(os.getenv('SPREAD_THRESHOLD', '0.02'))  # 2%
    
    LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')

3. Logging and Monitoring

Production bots include comprehensive logging:

import logging
from datetime import datetime

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('bot.log'),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)

def log_trade(trade_data):
    """Log trade execution with full context."""
    logger.info(f"Trade executed: {trade_data}")
    logger.info(f"Market: {trade_data['market_id']}")
    logger.info(f"Side: {trade_data['side']}")
    logger.info(f"Size: {trade_data['size']}")
    logger.info(f"Price: {trade_data['price']}")
    logger.info(f"P&L: {trade_data.get('pnl', 'N/A')}")

Performance Considerations

Latency Requirements

Different strategies have different latency requirements:

  • Market Making (poly-maker): Moderate latency acceptable (~500ms). Limit orders can be placed ahead of time.
  • Spike Detection (spike-bot): Fast execution required (~500ms). Need to capture spikes before they reverse.
  • Arbitrage (arbitrage-bot): Fast execution critical (~500ms). Opportunities disappear quickly.

Scalability

All three bots can be scaled horizontally:

  • Run multiple instances for different markets
  • Use async/await for concurrent market monitoring
  • Implement connection pooling for API clients
  • Use message queues for order execution

Which Bot Should You Use?

Choose poly-maker if:

  • You have significant capital ($5,000+)
  • You understand orderbook dynamics
  • You want steady, lower-risk returns
  • You can monitor markets continuously

Choose spike-bot if:

  • You want to capitalize on news events
  • You can execute trades quickly
  • You're comfortable with higher risk/reward
  • You want automated momentum trading

Choose arbitrage-bot if:

  • You have accounts on multiple platforms
  • You want risk-free profit opportunities
  • You can execute trades simultaneously
  • You're comfortable with lower frequency, higher certainty trades

Building Your Own Bot

If you're building your own Polymarket trading bot, start with these resources:

šŸ’” Need to Track Bot Performance?

PolyTrack Pro provides real-time tracking of bot wallets, including P&L, win rates, and trade patterns. Identify which bots are most profitable and copy their strategies. Free users can only track 3 wallets - upgrade to see unlimited bot wallets with advanced analytics and alerts.

Conclusion

All three bots represent solid implementations of different trading strategies. poly-maker offers the most comprehensive architecture for market making, spike-bot provides a simple framework for momentum trading, and arbitrage-bot demonstrates cross-platform arbitrage execution.

When choosing which bot to study or fork, consider your capital, risk tolerance, and technical expertise. All three are excellent starting points for building your own Polymarket trading system.

For more code examples and tutorials, check out our Polymarket JavaScript API tutorial, Polymarket Python tutorial, and Polymarket Rust API guide.

See What Whales Are Trading Right Now

Get instant alerts when top traders make moves. Track P&L, win rates, and copy winning strategies.

Track Whales Free

Free forever. No credit card required.

Frequently Asked Questions

warproxxx/poly-maker is a market making bot for Polymarket that provides liquidity on both sides of the orderbook to capture bid-ask spreads. It's the most searched Polymarket trading bot on GitHub with 39+ monthly searches. The bot uses Python and the official py-clob-client library.

12,400+ TRADERS

Stop Guessing. Start Following Smart Money.

Get instant alerts when whales make $10K+ trades. Track P&L, win rates, and copy winning strategies.

Track Whales FreeNo credit card required