Skip to content

bindok1/PolyMind

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PolyMind

An automated prediction-market trading bot that uses a two-stage AI pipeline to find and bet on mispriced markets on Polymarket.

Go Claude Gemini Redis License


What It Does

PolyMind watches 200+ live prediction markets in real time via WebSocket, runs each event through a two-stage AI pipeline, and places bets when the AI's probability estimate diverges significantly from the market price.

The core hypothesis: Polymarket frequently has illiquid markets where the implied probability is flat 50% by default, while news-aware AI can assign a much more accurate estimate — creating a tradable edge.

Default mode: DRY_RUN=true — no real orders are submitted until you explicitly flip the flag.


Pipeline Architecture

Polymarket WebSocket
        │
        ▼
┌──────────────┐
│   Watcher    │  Dedup · Price recording · Spread filter (≥90% dropped at source)
└──────┬───────┘
       │ chan MarketEvent (500 buffer)
       ▼
┌──────────────────────────────────────┐
│   Analyzer  (N parallel workers)     │
│                                      │
│  1. Cooldown check  (Redis)          │
│  2. AI budget check ($2/day cap)     │
│  3. Spread pre-filter (>15% skip)    │
│  4. News fetch  (NewsAPI + Serper)   │
│  5. Gemini 2.5 Flash  ← Stage 1     │  cheap fast relevance check
│     └─ not relevant → drop + cooldown│
│  6. Claude Sonnet     ← Stage 2     │  calibrated probability estimate
│     └─ low confidence → drop        │
└──────┬───────────────────────────────┘
       │ chan Prediction (100 buffer)
       ▼
┌──────────────────────────────────────┐
│   Risk Engine  (single goroutine)    │
│                                      │
│  · Order book fetch (REST)           │
│  · Spread check     (≤3%)           │
│  · Depth check      (≥$50/side)     │
│  · Drawdown guard                   │
│  · Kelly criterion sizing           │
│  · Per-market & total exposure caps │
└──────┬───────────────────────────────┘
       │ chan OrderRequest (10 buffer)
       ▼
┌──────────────────────────────────────┐
│   Executor                           │
│                                      │
│  · EIP-712 gasless order signing    │
│  · Submit to CLOB REST API          │
│  · Poll PENDING → MATCHED/CANCELLED │
│  · Consecutive-loss circuit breaker │
│  · Audit trail → SQLite             │
└──────────────────────────────────────┘

Key Technical Decisions

Two-Stage AI Pipeline

Calling Claude Sonnet on every event would cost ~$0.003/call × hundreds of events/hour. Instead, Gemini 2.5 Flash acts as a cheap ($0.00003) relevance pre-filter — only events with actionable news context reach Claude.

Kelly Criterion Bet Sizing

Rather than fixed bet sizes, PolyMind uses the Kelly Criterion with a 0.25× safety multiplier (quarter-Kelly):

f* = (edge) / (odds)
bet_size = f* × 0.25 × available_bankroll × confidence_multiplier

Where edge = AI_probability - market_implied_probability.

Three-Layer Spread Filter

Illiquid markets (bid=0.001, ask=0.999) were burning AI budget before any orders could be placed. Three layers of defense now stop them at different stages:

Layer Where Threshold Purpose
Source WS parser ≥ 90% Drop placeholder order books
Pre-AI Analyzer > 15% Save AI budget on wide markets
Final Risk engine > 3% Hard trading gate

Circuit Breakers on All External APIs

Every external call (Gemini, Claude, Polymarket REST, news) is wrapped in a circuit breaker with configurable failure threshold and probe timeout — the bot stays alive even when individual services go down.

Clean Architecture

The codebase follows hexagonal architecture — each layer depends only on interfaces, not concrete implementations:

cmd/bot/           ← wiring only
internal/
  entity/          ← domain types (no dependencies)
  dto/             ← data transfer objects
  repository/      ← external adapters (Polymarket, Claude, Gemini, Redis, SQLite)
  usecase/         ← business logic (watcher, analyzer, riskengine, executor)
  pkg/             ← utilities (kelly, circuitbreaker, ratelimiter, crypto, fsm)
  bootstrap/       ← config loading, logger, health server

Sample Output

{"level":"INFO","msg":"analyzer: prediction ready",
  "market":"Will Iran win the 2026 FIFA World Cup?",
  "probability":0.01,"confidence":0.85,
  "reasoning":"Multiple credible reports confirm Iran's sports minister stated Iran
   won't participate in the 2026 World Cup in the US, making a win essentially impossible."}

{"level":"INFO","msg":"riskengine: order request ready",
  "market":"Will Iran win the 2026 FIFA World Cup?",
  "price":0.018,"size":0.42,"kelly_f*":0.031}

The bot identified a market priced at 50% (coin flip) for a team that publicly announced they won't participate — a clear 49-point edge.


Tech Stack

Component Technology
Language Go 1.22+
AI Stage 1 Google Gemini 2.5 Flash
AI Stage 2 Anthropic Claude Sonnet
News NewsAPI + Serper (fallback)
Market data Polymarket CLOB WebSocket + REST
State / cooldowns Redis
Audit trail SQLite
Order signing EIP-712 (gasless)
Deployment Railway (Docker)

Risk Controls

Control Value
Max drawdown $5 hard stop
Max total exposure 60% of bankroll
Max per-market bet 20% of bankroll
Kelly fraction 0.25× (quarter-Kelly)
Max bid-ask spread ≤ 3%
Min order book depth ≥ $50 each side
Consecutive loss pause 3 losses → 1h trading pause
AI daily budget $2.00/day

Getting Started

Prerequisites

  • Go 1.22+
  • Redis 7.x
  • API keys: Gemini, Claude, NewsAPI, Serper

1. Clone & install

git clone https://github.com/<you>/PolyMind
cd PolyMind
go mod download

2. Configure API keys

cp .env.example .env

Fill in .env:

GEMINI_API_KEY=AIza...
CLAUDE_API_KEY=sk-ant-...
NEWS_API_KEY=...
SERPER_API_KEY=...
REDIS_URL=redis://localhost:6379
BANKROLL_USD=15.0

3. Derive Polymarket credentials (one-time, required for live mode)

Polymarket uses EIP-712 signed authentication. Run this once with your wallet private key to exchange it for API credentials:

PRIVATE_KEY=<hex_key_no_0x_prefix> \
go run ./cmd/authsetup

Copy the printed values into your .env:

POLY_API_KEY=...
POLY_SECRET=...
POLY_PASSPHRASE=...
POLY_ADDRESS=0x...

You only need to do this once per wallet. The credentials don't expire.

4. Run (dry-run — safe, no real orders)

redis-server &
go run ./cmd/bot

5. Run tests

go test ./...
# No external services required — Redis uses miniredis, AI uses MockClients

Live mode

After verifying predictions look correct in dry-run for 48h:

DRY_RUN=false go run ./cmd/bot

Make sure PRIVATE_KEY, POLY_API_KEY, POLY_SECRET, POLY_PASSPHRASE, and POLY_ADDRESS are all set in your .env before flipping DRY_RUN=false.


Configuration

All values can be set via config/config.yaml or environment variables:

Variable Default Description
DRY_RUN true No real orders when true
BANKROLL_USD 15.0 Starting capital in USD
MAX_DRAWDOWN_USD 5.0 Hard stop loss
KELLY_FRACTION 0.25 Safety multiplier
MAX_EXPOSURE_PCT 0.60 Max % bankroll in open positions
MAX_SINGLE_MARKET_PCT 0.20 Max % per market
AI_DAILY_BUDGET_USD 2.00 Max AI spend per day
ANALYZER_WORKER_COUNT 10 Parallel analysis goroutines
ANALYZER_MAX_SPREAD_PCT 0.15 Skip market before AI if spread > this
COOLDOWN_DEFAULT_MINUTES 5 Re-analysis cooldown per market
LOG_LEVEL info debug / info / warn / error

Deploying to Railway

  1. Push to GitHub
  2. New Railway project → connect repo
  3. Set all secret env vars in Railway Variables panel
  4. Railway auto-detects Dockerfile
  5. Monitor health at https://<service>.railway.app/health

About

Prediction market for polymind

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages