An intelligent market analysis system that monitors Polymarket prediction markets, identifies events relevant to agriculture, commodities, geopolitics, and trade, and tracks their probability movements over time.
Polymarketer answers the question: "Which prediction market events could materially affect agricultural commodities, food supply chains, and global trade flows?"
It operates as two independent modules that work together:
- Event Scanner — Continuously polls the Polymarket API and stores all active markets in SQLite
- Ag Event Sorter — Classifies stored markets using keyword filtering + Google Gemini AI, then tracks probability time-series for relevant markets
Polymarket API
│
▼
┌─────────────────┐ ┌──────────────────────┐
│ event_scanner │────▶│ SQLite (polymarket.db)│◀────┐
│ (fetches all │ │ │ │
│ markets) │ │ - events │ │
└─────────────────┘ │ - markets │ │
│ - market_probs │ │
│ - ag_classifications │ │
┌─────────────────┐ │ - ag_market_probs │ │
│ ag_event_sorter │────▶└──────────────────────┘ │
│ (classifies & │ │
│ tracks ag mkts)│──── Gemini 2.5 Flash-Lite ───────┘
└─────────────────┘
- Python 3.12+
- Google Gemini API key
No external database server needed — data is stored in a local SQLite file (polymarket.db).
# Install dependencies
pip install -r event_scanner/requirements.txt
pip install -r ag_event_sorter/requirements.txtEach module is configured via a .env file.
event_scanner/.env
DB_PATH=polymarket.db # default: polymarket.db in project root
SCAN_INTERVAL_SECONDS=300 # default: 5 minutesag_event_sorter/.env
DB_PATH=polymarket.db # same DB as event_scanner
GEMINI_API_KEY=your_gemini_api_key
CLASSIFY_BATCH_SIZE=500 # default: 500 markets per Gemini call
AG_SCAN_INTERVAL_SECONDS=1800 # default: 30 minutesRun both modules from the project root:
# Terminal 1 — collect market data (every 5 min by default)
python -m event_scanner
# Terminal 2 — classify and track ag-related markets (every 30 min by default)
python -m ag_event_sorterOne-shot mode (run once and exit):
python -m event_scanner --once
python -m ag_event_sorter --onceClassify all markets (skip keyword pre-filter, send everything to Gemini):
python -m ag_event_sorter --once --skip-keywordsThe AI classifies each market into one of 10 categories:
| Category | Description |
|---|---|
agriculture |
Farming, crop production, livestock |
commodity |
Agricultural commodity prices (wheat, corn, cattle, etc.) |
global_trade |
Tariffs, trade agreements, trade disputes |
geopolitical |
Wars, sanctions, territorial disputes affecting ag regions |
food_supply |
Food prices, food security, famine |
agricultural_policy |
USDA, farm bills, subsidies |
energy_input |
Oil/gas prices affecting fertilizer and transport costs |
climate_weather |
Droughts, floods, extreme weather events |
supply_chain |
Shipping, port disruptions, logistics |
not_relevant |
None of the above |
Each classification also includes a 0–100 impact score and impact region (country, continent, or Global).
-- Top ag-related markets by impact score
SELECT market_id, question, category, impact, impact_region
FROM ag_market_classifications
WHERE is_ag_related = true
ORDER BY impact DESC;
-- Probability trend for a specific market
SELECT recorded_at, implied_probability
FROM ag_market_probabilities
WHERE market_id = '<market_id>'
ORDER BY recorded_at;
-- Markets by category
SELECT category, COUNT(*) as count
FROM ag_market_classifications
WHERE is_ag_related = true
GROUP BY category
ORDER BY count DESC;polymarketer/
├── event_scanner/ # Module 1: market data collection
│ ├── __main__.py
│ ├── run.py # main loop with graceful shutdown
│ ├── fetcher.py # Polymarket Gamma API client
│ ├── probability.py # implied probability computation
│ ├── db.py # schema creation and upserts
│ ├── config.py # environment-based config
│ └── requirements.txt
├── ag_event_sorter/ # Module 2: AI classification and tracking
│ ├── __main__.py
│ ├── run.py # main loop
│ ├── classifier.py # keyword filter + Gemini batch classification
│ ├── db.py # schema and queries for ag data
│ ├── config.py # environment-based config
│ └── requirements.txt
├── HANDOFF.md # implementation notes and lessons learned
├── example_event_slug.json # sample Polymarket API response
└── README.md
- Batch size: Gemini 2.5 Flash-Lite has a 65K output token limit. At ~90–100 tokens per classification, the safe max batch size is 500 markets.
- Incremental saves: Classifications are committed to the DB after each batch — safe to interrupt mid-run.
- Idempotent: Uses
ON CONFLICT DO NOTHINGthroughout, so re-runs are always safe. - Keyword precision: Word-boundary regex (
\b...\b) prevents false positives (e.g., "corn" won't match "Cornyn").