Skip to content

jaccus/polybate

Repository files navigation

Polybate

Polymarket betting analysis tool. Fetches market data from Polymarket, analyzes it using AI (Perplexity), and produces bet recommendations with position sizing.

Prerequisites

Install via script (no sudo):

curl -sSL https://dot.net/v1/dotnet-install.sh | bash -s -- --channel 10.0 --install-dir ~/.dotnet
export PATH="$HOME/.dotnet:$PATH"

Setup

  1. Clone the repo
  2. Copy config.local.json and add your API keys:
    # config.local.json is git-ignored and holds your secrets
    # Edit it and add your Perplexity API key:
    {
      "analysisProviders": {
        "perplexity": {
          "apiKey": "pplx-your-key-here"
        }
      }
    }
    Get a key at perplexity.ai/settings/api
  3. Adjust capitalManagement.maxCapitalUsd in config.json to your desired max capital
  4. (Optional) Add your Polymarket wallet address to track positions:
    {
      "user": {
        "walletAddress": "0x..."
      }
    }

Usage

# Fetch current market data from Polymarket (no API key needed)
dotnet run --project src/Polybate -- fetch

# Analyze latest snapshot with Perplexity (requires API key)
dotnet run --project src/Polybate -- analyze

# Analyze with a specific provider
dotnet run --project src/Polybate -- analyze --provider=perplexity

# Run all providers and combine into master recommendations
dotnet run --project src/Polybate -- master-analysis

# Fetch your current Polymarket positions (requires wallet address in config)
dotnet run --project src/Polybate -- current

Pipeline

The tool operates in two stages:

  1. Fetch - Retrieves events, markets, and price data from Polymarket's Gamma and CLOB APIs. Also fetches 7-day price history for the top 20 markets. Saves a JSON snapshot to data/snapshots/.
  2. Analyze - Loads the latest snapshot, sends market data (including historical trends) to an AI analysis provider (Perplexity), and produces recommendations saved to data/recommendations/ as both JSON and Markdown.

Stages are independent. You can fetch once and run analysis multiple times on the same snapshot.

Historical Price Data

The fetch command retrieves 7 days of price history for the top 20 markets (by volume, filtered for meaningful uncertainty). This data is included in analysis prompts to help detect:

  • Momentum: Sustained price movement may indicate emerging consensus or new information
  • Reversals: Recent direction change may indicate market overreaction or correction
  • Stability: Stable prices with sudden movement warrant investigation

Historical data is summarized per-outcome in the prompt (not raw data points) to keep prompt size manageable. Example trend line: 7d Trend: +0.082 (+8.2%), strongly rising

Analysis algorithm

The analyze command does not send the entire snapshot to Perplexity. A snapshot typically contains 10,000+ markets; the algorithm narrows that down to 20 before making the API call, then post-processes the response into sized recommendations. The steps:

1. Market selection

Three filters are applied in sequence, then the result is sorted and truncated:

Step Filter Purpose
1 Active && !Closed Drop resolved or inactive markets
2 Volume > $1,000 Drop illiquid markets where you can't get meaningful fill
3 At least one outcome price in the 5%–95% range Key filter. The highest-volume Polymarket markets are overwhelmingly near-certainties (99%+ or <1%) — long-tail questions like "will celebrity X win nomination." These have no edge. This filter keeps only markets with genuine uncertainty.
4 Sort by volume descending, take top 20 Among the uncertain markets, prefer the most liquid. 20 is the practical limit for a single prompt.

2. Prompt construction

Each of the 20 markets is included with: numeric ID, question text, each outcome with its current price and implied probability, total volume, liquidity, and end date.

The prompt frames the task as pure probability estimation: estimate the true probability of each outcome and flag where the market price is wrong by more than 3 percentage points. Capital and bet-size constraints are deliberately excluded — telling the LLM about a $2 max bet causes it to self-censor and dismiss all opportunities. Position sizing is handled after parsing by the Kelly criterion.

Perplexity's built-in web search provides current news and data relevant to each market question.

3. Response parsing

The response is split on the literal keyword RECOMMENDATION. Each fragment is scanned line-by-line for structured fields: market_id, outcome, estimated_probability, confidence, timeframe, explanation. A recommendation is kept only if the market ID matches one of the 20 markets sent and the outcome matches a valid outcome name on that market. The confidence text (low/medium/high) maps to a numeric score (0.35 / 0.60 / 0.85).

4. Position sizing (fractional Kelly)

Each recommendation is sized independently:

b = (1 / currentPrice) - 1          // decimal odds
kellyFraction = (b×p - q) / b       // full Kelly, where p = estimated prob, q = 1-p
f = kellyFraction × kellyConfig × confidenceScore

f is clamped to [0, maxSingleBetFraction]. If the total dollar allocation across all recommendations exceeds maxCapitalUsd, all amounts are scaled down proportionally.

Configuration

Configuration is split into two files:

  • config.json - versioned in git, contains all non-sensitive settings
  • config.local.json - git-ignored, contains secrets (API keys)

config.local.json is deep-merged on top of config.json at startup. You only need to put the keys you want to override in the local file.

config.json (versioned)

Section Default Description
capitalManagement.maxCapitalUsd 1000.00 Maximum total capital for recommendations
capitalManagement.kellyFraction 0.25 Fractional Kelly multiplier (0.25 = quarter-Kelly)
capitalManagement.maxSingleBetFraction 0.10 Max fraction of capital per single bet
polymarket.historyDays 7 Days of historical price data to fetch
polymarket.historyInterval "6h" Price history resolution (1m, 1h, 6h, 1d, 1w)
polymarket.historyMarketsLimit 20 Number of markets to fetch history for
analysisProviders.perplexity.model "sonar-pro" Perplexity model for analysis
masterAnalysis.model "sonar-reasoning" Model used for combining multi-provider results

config.local.json (secrets, git-ignored)

Section Description
analysisProviders.perplexity.apiKey Perplexity API key
user.walletAddress Your Polymarket wallet address (for current command)

Output

Recommendations are saved to data/recommendations/ with both JSON and Markdown formats:

  • perplexity_20260203_143000.json - machine-readable recommendations
  • perplexity_20260203_143000.md - human-readable report with summary table and detailed analysis

The raw AI response from the most recent analyze run is always saved to data/last_raw_response_perplexity.txt (overwritten each run) for debugging.

Each recommendation includes:

  • Market link, question, outcomes, current prices
  • Estimated probability and edge over market price
  • Confidence score
  • Recommended amount (Kelly criterion-based)
  • Timeframe rationale
  • Detailed explanation with sources

Architecture

src/Polybate/
├── Program.cs              # Entry point, config loading, command routing
├── Commands/               # CLI command implementations
│   ├── ICommand.cs
│   ├── FetchCommand.cs
│   ├── AnalyzeCommand.cs
│   ├── MasterAnalysisCommand.cs
│   └── CurrentCommand.cs
├── Models/                 # Data models (config, domain, analysis)
├── Services/               # Business logic
│   ├── PolymarketService.cs         # Polymarket API integration
│   ├── IAnalysisProvider.cs         # Extensible analysis interface
│   ├── PerplexityAnalysisProvider.cs
│   └── RecommendationEngine.cs      # Master analysis combiner
└── Storage/
    └── FileStorageService.cs        # JSON + Markdown persistence

Adding a New Analysis Provider

  1. Implement IAnalysisProvider (see PerplexityAnalysisProvider.cs as reference)
  2. Add provider config section to config.json under analysisProviders
  3. Register in Program.cs alongside the Perplexity provider
  4. Use via dotnet run --project src/Polybate -- analyze --provider=yourprovider

APIs Used

  • Polymarket Gamma API (gamma-api.polymarket.com) - market discovery, no auth needed
  • Polymarket CLOB API (clob.polymarket.com) - pricing data, no auth needed
  • Polymarket Data API (data-api.polymarket.com) - user positions, no auth needed (just wallet address)
  • Perplexity API (api.perplexity.ai) - AI analysis with web search and citations

Dependencies

Zero external NuGet packages. Uses only built-in .NET libraries (System.Text.Json, HttpClient).

About

Polymarket -> AI models analysis -> betting recommendations -> $

Resources

Stars

Watchers

Forks

Sponsor this project

Contributors

Languages