# Polymarket Prediction Market Agent Module ## Quick Start ### Prerequisites ```bash # Create virtual environment (Python 3.10+) python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt # Set up API keys (at least one LLM provider required) cp .env.example .env # Edit .env and fill in your API key ``` ### Usage ```python from tradingagents.prediction_market import PMTradingAgentsGraph from tradingagents.prediction_market.pm_config import PM_DEFAULT_CONFIG from dotenv import load_dotenv load_dotenv() config = PM_DEFAULT_CONFIG.copy() config["llm_provider"] = "anthropic" # openai, google, anthropic, xai, openrouter, ollama config["deep_think_llm"] = "claude-sonnet-4-6" config["quick_think_llm"] = "claude-sonnet-4-6" pm = PMTradingAgentsGraph(debug=True, config=config) # market_id from Polymarket website or Gamma API _, decision = pm.propagate("", "2026-03-23", "Market question (optional)") print(decision) ``` ### How to Get a Market ID The market_id is a numeric ID from the Polymarket Gamma API. You can find it by: ```python import requests # Option 1: Browse top markets by volume resp = requests.get("https://gamma-api.polymarket.com/markets", params={ "active": "true", "closed": "false", "order": "volume24hr", "ascending": "false", "limit": 10, }) for m in resp.json(): print(f'{m["id"]} | {m["question"]}') # Option 2: Look up from a Polymarket web URL slug # e.g. https://polymarket.com/event/xxx → use the slug to search ``` ### CLI Usage You can also use the CLI, which supports pasting Polymarket URLs directly: ```bash python -m cli.main # Step 1: Select "Polymarket Market ID (prediction market)" # Step 2: Paste a Polymarket URL or enter a numeric market ID ``` --- ## Architecture Overview The system is built as a **LangGraph** state machine with 4 phases and 10+ LLM agents: ``` Input: market_id + trade_date + market_question | v +-------------------------------------+ | Phase 1: Analyst Team (4 Analysts) | | Event -> Odds -> Information -> Sent| +----------------+--------------------+ v +-------------------------------------+ | Phase 2: Research Debate | | YES Researcher <-> NO Researcher | | -> Research Manager | +----------------+--------------------+ v +-------------------------------------+ | Phase 3: Trading Decision | | PM Trader (Kelly Criterion) | +----------------+--------------------+ v +-------------------------------------+ | Phase 4: Risk Management | | Aggressive <-> Conservative <-> Neut| | -> Risk Judge | +----------------+--------------------+ v Structured JSON Output ``` --- ## Phase 1: Analyst Team Four analysts run sequentially, each with a tool loop that calls Polymarket APIs until sufficient data is collected. Uses `quick_think_llm`. | Analyst | Tools | Responsibility | |---------|-------|----------------| | **Event Analyst** | `get_market_info`, `get_resolution_criteria`, `get_event_context` | Analyze the event: what is being predicted, resolution criteria clarity, timeline | | **Odds Analyst** | `get_market_info`, `get_market_price_history`, `get_order_book` | Market microstructure: current prices, liquidity, bid/ask spread, pricing efficiency | | **Information Analyst** | `get_news`, `get_global_news`, `get_related_markets`, `search_markets` | Find information not yet priced in, cross-reference related markets | | **Sentiment Analyst** | `get_news`, `get_global_news` | Public opinion analysis: news, social sentiment, expert vs crowd divergence | Each analyst produces a report (`event_report`, `odds_report`, `information_report`, `sentiment_report`) that feeds into subsequent phases. --- ## Phase 2: Research Debate | Role | LLM | Responsibility | |------|-----|----------------| | **YES Researcher** | `quick_think_llm` | Build the case for the event occurring, citing analyst reports | | **NO Researcher** | `quick_think_llm` | Build the case against, rebutting YES arguments | | **Research Manager** | `deep_think_llm` | Synthesize both sides into an `investment_plan` | - YES and NO debate for `max_debate_rounds` rounds (default 1 round = 2 turns) - Both researchers have a **BM25 memory system** that recalls lessons from past similar markets - Research Manager uses the stronger `deep_think_llm` for final synthesis --- ## Phase 3: Trading Decision The **PM Trader** (using `quick_think_llm`) receives all reports and the investment plan, then: 1. Estimates the **true probability** based on all analysis 2. Compares against the **market price** from the Odds report 3. Calculates **edge** = |estimated probability - market price| 4. If edge < **5% threshold** -> **PASS** 5. If edge >= 5% -> calculate position size using **0.25x Fractional Kelly Criterion**: - Kelly fraction = edge / odds_against - Position size = 0.25 x Kelly fraction x bankroll Decision options: - **BUY_YES**: Estimated probability > market price + 5% (event more likely than market implies) - **BUY_NO**: Estimated probability < market price - 5% (event less likely than market implies) - **PASS**: Edge below threshold or uncertainty too high --- ## Phase 4: Risk Management Three-way debate + final ruling: | Role | LLM | Stance | |------|-----|--------| | **Aggressive Analyst** | `quick_think_llm` | Advocates for the trade, emphasizes edge and upside | | **Conservative Analyst** | `quick_think_llm` | Argues against, emphasizes downside risk and uncertainty | | **Neutral Analyst** | `quick_think_llm` | Balanced perspective, proposes compromise | | **Risk Judge** | `deep_think_llm` | Final ruling after hearing all sides | The three analysts debate for `max_risk_discuss_rounds` rounds (default 1 round = 3 turns, one per analyst). --- ## Output Format The Risk Judge's natural language output is converted to structured JSON by the **Signal Processor**: ```json { "signal": "BUY_YES | BUY_NO | PASS", "estimated_probability": 0.65, "market_price": 0.50, "edge": 0.15, "position_size": 0.03, "confidence": "high | medium | low" } ``` --- ## Reflection & Learning After a trade resolves, invoke the reflection mechanism to let agents learn from outcomes: ```python # After the trade resolves, pass the actual returns pm.reflect_and_remember(returns_losses=1000) ``` The system will: 1. Review each agent's decisions (YES/NO Researcher, Trader, Research Manager, Risk Judge) 2. Analyze which judgments were correct or incorrect, and why 3. Store lessons learned in a BM25 memory system 4. Automatically reference past experience when encountering similar markets in the future --- ## Configuration All parameters are in `tradingagents/prediction_market/pm_config.py`: ```python PM_DEFAULT_CONFIG = { # LLM settings "llm_provider": "openai", # openai, google, anthropic, xai, openrouter, ollama "deep_think_llm": "gpt-5.2", # For Research Manager, Risk Judge (deep reasoning) "quick_think_llm": "gpt-5-mini", # For Analysts, Researchers, Trader (speed priority) # Polymarket API "polymarket_gamma_url": "https://gamma-api.polymarket.com", "polymarket_clob_url": "https://clob.polymarket.com", # Trading parameters "kelly_fraction": 0.25, # Conservative Kelly multiplier (quarter Kelly) "min_edge_threshold": 0.05, # Minimum edge threshold (5%) "max_position_pct": 0.05, # Max single position as % of bankroll (5%) "max_cluster_exposure_pct": 0.15, # Max exposure to correlated markets (15%) "bankroll": 10000, # Simulated bankroll # Debate settings "max_debate_rounds": 1, # YES/NO debate rounds "max_risk_discuss_rounds": 1, # Risk management debate rounds } ``` --- ## Data Sources | Source | Purpose | API Key Required | |--------|---------|-----------------| | **Polymarket Gamma API** | Market info, resolution criteria, event context, search | No (public API) | | **Polymarket CLOB API** | Price history, order book | No (public API) | | **yfinance News** | News search (`get_news`, `get_global_news`) | No | > **Note**: The news tools are shared with the stock analysis module (yfinance-based), so coverage for political markets may be limited. --- ## Current Limitations - **Analysis only, no order execution**: v1 does not place actual trades on Polymarket - **Binary markets only**: Supports Yes/No outcomes; multi-outcome and numeric markets are not supported - **REST API only**: Uses polling, no WebSocket real-time streaming - **No backtesting**: No historical backtesting framework included - **Limited news coverage**: Political market news search is limited since the news tools are designed for stocks --- ## File Structure ``` tradingagents/prediction_market/ ├── __init__.py # Exports PMTradingAgentsGraph ├── pm_config.py # Default configuration ├── agents/ │ ├── analysts/ │ │ ├── event_analyst.py # Event analysis │ │ ├── odds_analyst.py # Odds/pricing analysis │ │ ├── information_analyst.py # Information gathering │ │ └── sentiment_analyst.py # Sentiment analysis │ ├── researchers/ │ │ ├── yes_researcher.py # YES-side researcher │ │ └── no_researcher.py # NO-side researcher │ ├── trader/ │ │ └── pm_trader.py # Trading decisions (Kelly Criterion) │ ├── managers/ │ │ ├── research_manager.py # Research manager (debate synthesis) │ │ └── risk_manager.py # Risk manager (final ruling) │ ├── risk_mgmt/ │ │ ├── aggressive_debator.py # Aggressive stance │ │ ├── conservative_debator.py # Conservative stance │ │ └── neutral_debator.py # Neutral stance │ └── utils/ │ ├── pm_agent_states.py # LangGraph state definitions │ ├── pm_agent_utils.py # Shared utilities │ └── pm_tools.py # @tool decorator wrappers ├── dataflows/ │ └── polymarket.py # Polymarket API client (Gamma + CLOB) └── graph/ ├── pm_trading_graph.py # Main graph class ├── setup.py # Graph construction logic ├── propagation.py # State initialization & propagation ├── conditional_logic.py # Conditional branching (tool loop, debate control) ├── signal_processing.py # JSON output structuring └── reflection.py # Reflection & learning mechanism ```