Files
profitable-expert-advisor/polymarket/docs/STRATEGY_GUIDE.md
T
zhutoutoutousan 98a87a69ca Update
2026-02-13 08:03:25 +01:00

11 KiB

Strategy Development Guide

Complete guide to developing trading strategies for Polymarket.

Table of Contents

Strategy Basics

What is a Strategy?

A strategy is a Python class that:

  1. Analyzes market data
  2. Generates trading signals
  3. Manages risk and positions
  4. Tracks performance

Strategy Lifecycle

  1. Initialization: Set up parameters and initial state
  2. Market Analysis: Receive market data and analyze
  3. Signal Generation: Decide whether to trade
  4. Position Management: Track open positions
  5. Performance Tracking: Monitor PnL and metrics

Creating Your First Strategy

Step 1: Inherit from BaseStrategy

from polymarket.strategies import BaseStrategy, MarketSignal

class MyStrategy(BaseStrategy):
    def __init__(self):
        super().__init__(name="MyStrategy", initial_balance=1000.0)
        # Your initialization code

Step 2: Implement analyze_market()

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    """
    Analyze market and generate signal.
    
    Args:
        market_data: Dictionary with:
            - 'event': Event information
            - 'market': Market information
            - 'prices': Current outcome prices {'Yes': 0.65, 'No': 0.35}
            - 'orderbook': Orderbook data
            - 'timestamp': Current timestamp
    
    Returns:
        MarketSignal or None
    """
    prices = market_data.get('prices', {})
    yes_price = prices.get('Yes', 0.5)
    
    # Your trading logic here
    if yes_price < 0.4:  # Undervalued
        return MarketSignal(
            action='BUY',
            token_id=market_data['market']['clobTokenIds'][0],
            size=0.2,  # 20% of balance
            confidence=0.8,
            reason="Yes probability is undervalued",
            metadata={'yes_price': yes_price}
        )
    
    return None  # No trade

Step 3: Implement get_parameters()

def get_parameters(self) -> Dict[str, Any]:
    """Return strategy parameters"""
    return {
        'threshold': 0.4,
        'position_size': 0.2
    }

Complete Example

from typing import Dict, Optional
from polymarket.strategies import BaseStrategy, MarketSignal

class MeanReversionStrategy(BaseStrategy):
    """
    Simple mean reversion strategy.
    Buys when price deviates significantly from 0.5.
    """
    
    def __init__(self, threshold: float = 0.15):
        super().__init__(name="MeanReversion", initial_balance=1000.0)
        self.threshold = threshold
    
    def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
        prices = market_data.get('prices', {})
        yes_price = prices.get('Yes', 0.5)
        
        # Calculate deviation from fair value (0.5)
        deviation = abs(yes_price - 0.5)
        
        if deviation < self.threshold:
            return None  # Not enough deviation
        
        # Determine action
        if yes_price < (0.5 - self.threshold):
            # Yes is undervalued, buy
            confidence = min(1.0, deviation / self.threshold)
            
            return MarketSignal(
                action='BUY',
                token_id=market_data['market']['clobTokenIds'][0],
                size=0.2,
                confidence=confidence,
                reason=f"Yes price {yes_price:.2%} is {deviation:.2%} below fair value",
                metadata={'yes_price': yes_price, 'deviation': deviation}
            )
        
        elif yes_price > (0.5 + self.threshold):
            # Yes is overvalued, close position if we have one
            token_id = market_data['market']['clobTokenIds'][0]
            if token_id in self.positions:
                return MarketSignal(
                    action='SELL',
                    token_id=token_id,
                    size=1.0,  # Close entire position
                    confidence=confidence,
                    reason=f"Yes price {yes_price:.2%} is {deviation:.2%} above fair value",
                    metadata={'yes_price': yes_price, 'deviation': deviation}
                )
        
        return None
    
    def get_parameters(self) -> Dict:
        return {'threshold': self.threshold}

Advanced Patterns

Using Orderbook Data

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    orderbook = market_data.get('orderbook', {})
    bids = orderbook.get('bids', [])
    asks = orderbook.get('asks', [])
    
    if not bids or not asks:
        return None
    
    # Calculate bid-ask spread
    best_bid = bids[0]['price']
    best_ask = asks[0]['price']
    spread = best_ask - best_bid
    
    # Trade when spread is tight (good liquidity)
    if spread < 0.02:  # 2% spread
        # Your trading logic
        pass

Using Historical Data

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    history = market_data.get('history', [])
    
    if len(history) < 20:
        return None  # Not enough data
    
    # Calculate moving average
    recent_prices = [h['price'] for h in history[-20:]]
    ma = sum(recent_prices) / len(recent_prices)
    
    current_price = market_data['prices']['Yes']
    
    # Mean reversion: buy when below MA
    if current_price < ma * 0.95:
        return MarketSignal(...)

Position Sizing Based on Confidence

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    # Calculate confidence
    confidence = self.calculate_confidence(market_data)
    
    # Size position based on confidence
    # Higher confidence = larger position
    base_size = 0.1  # 10% base
    size = base_size * confidence  # Scale by confidence
    
    return MarketSignal(
        action='BUY',
        token_id=...,
        size=size,
        confidence=confidence,
        ...
    )

Risk Management

class RiskManagedStrategy(BaseStrategy):
    def __init__(self):
        super().__init__(name="RiskManaged", initial_balance=1000.0)
        # Override risk limits
        self.max_position_size = 0.3  # Max 30% per position
        self.max_total_exposure = 0.6  # Max 60% total
        self.min_confidence = 0.7  # Only trade high confidence
    
    def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
        # Check if we can open new position
        if len(self.positions) >= 3:
            return None  # Max 3 positions
        
        # Your trading logic
        signal = self.generate_signal(market_data)
        
        if signal and signal.confidence >= self.min_confidence:
            # Verify we can open position
            size_usdc = signal.size * self.current_balance
            if self.can_open_position(size_usdc, signal.token_id):
                return signal
        
        return None

Best Practices

1. Always Check Data Availability

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    prices = market_data.get('prices', {})
    if not prices:
        return None  # No price data
    
    yes_price = prices.get('Yes')
    if yes_price is None:
        return None  # Missing Yes price

2. Validate Token IDs

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    market = market_data.get('market', {})
    token_ids = market.get('clobTokenIds', [])
    
    if not token_ids:
        return None  # No token IDs available
    
    token_id = token_ids[0]
    # Use token_id...

3. Use Confidence Thresholds

# Only trade high-confidence signals
if signal.confidence < self.min_confidence:
    return None

4. Log Trading Decisions

import logging

logger = logging.getLogger(__name__)

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    signal = self.generate_signal(market_data)
    
    if signal:
        logger.info(f"Signal: {signal.action} {signal.token_id} "
                   f"size={signal.size:.2%} confidence={signal.confidence:.2f} "
                   f"reason: {signal.reason}")
    
    return signal

5. Handle Edge Cases

def analyze_market(self, market_data: Dict) -> Optional[MarketSignal]:
    prices = market_data.get('prices', {})
    yes_price = prices.get('Yes', 0.5)
    no_price = prices.get('No', 0.5)
    
    # Check if prices are valid
    if yes_price <= 0 or yes_price >= 1:
        return None  # Invalid price
    
    # Check if market is close to resolution
    market = market_data.get('market', {})
    end_date = market.get('endDate')
    if end_date and self.is_near_resolution(end_date):
        return None  # Too close to resolution, avoid trading

Common Strategies

1. Mean Reversion

Buy when price deviates from fair value (0.5), sell when it returns.

2. Momentum

Buy when price is trending up, sell when trend reverses.

3. Arbitrage

Exploit price differences between related markets.

4. Market Making

Provide liquidity by placing both buy and sell orders.

5. News-Based

Trade based on external information and news events.

6. Statistical Arbitrage

Use statistical models to identify mispriced markets.

Testing Strategies

Unit Testing

import unittest
from polymarket.strategies.examples import SimpleProbabilityStrategy

class TestStrategy(unittest.TestCase):
    def setUp(self):
        self.strategy = SimpleProbabilityStrategy(threshold=0.15)
    
    def test_analyze_market_undervalued(self):
        market_data = {
            'market': {'clobTokenIds': ['token123']},
            'prices': {'Yes': 0.3, 'No': 0.7}  # Undervalued
        }
        
        signal = self.strategy.analyze_market(market_data)
        
        self.assertIsNotNone(signal)
        self.assertEqual(signal.action, 'BUY')
        self.assertGreater(signal.confidence, 0.7)

Backtesting

from datetime import datetime, timedelta
from polymarket import BacktestEngine

strategy = MyStrategy()
end_date = datetime.now()
start_date = end_date - timedelta(days=30)

engine = BacktestEngine(strategy, start_date, end_date)
results = engine.run()

print(f"Total Return: {results['total_return']:.2f}%")
print(f"Win Rate: {results['win_rate']:.2f}%")

Paper Trading

Test strategies with live data but simulated execution:

from polymarket import LiveTradingEngine

strategy = MyStrategy()
engine = LiveTradingEngine(strategy, poll_interval=60)

# Add markets
engine.monitor_tag(tag_id=21, limit=10)

# Start (will simulate orders)
engine.start()

Strategy Checklist

Before deploying a strategy:

  • Strategy inherits from BaseStrategy
  • analyze_market() implemented
  • get_parameters() implemented
  • Risk management limits set
  • Edge cases handled
  • Data validation included
  • Backtested on historical data
  • Paper traded successfully
  • Performance metrics reviewed
  • Error handling implemented
  • Logging added

Next Steps

  • Read API Reference for detailed API documentation
  • Check Glossary for terminology
  • Review example strategies in strategies/examples/
  • Test your strategy thoroughly before live trading