Add official Polymarket API support, one-click setup, and redesigned README

- Add TRADE_API_MODE setting to switch between official (public, no auth) and internal API
- Implement _fetch_trades_official() using Polymarket data-api /trades endpoint
- Default to official API so users can run without private API access
- Add interactive setup.sh that guides users through API key configuration
- Add Makefile with common commands (setup, run, dashboard, etc.)
- Add Dockerfile and .dockerignore for container deployment
- Redesign README with badges, feature tables, mermaid diagram, architecture
- Clean up .env.example with organized sections and signup links
- Update pyproject.toml dependencies to match requirements.txt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
SII-leiyu
2026-04-22 16:12:17 +08:00
parent 88a5309bd9
commit 09b203110c
9 changed files with 811 additions and 201 deletions
+13
View File
@@ -0,0 +1,13 @@
venv/
.env
.git/
__pycache__/
*.pyc
data/
reports/
daily_briefings/
leading_signals/
price_volatility/
anomaly_signals/
*.db
*.json.bak
+55 -28
View File
@@ -1,35 +1,62 @@
# LLM API (Gemini official)
GEMINI_API_KEY=your_api_key_here
# ============================================================
# Polymarket Whale Watcher - Configuration
# ============================================================
# Copy to .env and fill in your API keys:
# cp .env.example .env
#
# Only GEMINI_API_KEY is required. Everything else is optional.
# ============================================================
# --- Required ---
GEMINI_API_KEY=your_gemini_api_key_here
# --- Trade Data Source ---
# "official" = Polymarket public API (no auth needed, default)
# "internal" = Private API (requires INTERNAL_API_URL + INTERNAL_API_KEY)
TRADE_API_MODE=official
# Internal API (only needed when TRADE_API_MODE=internal)
# INTERNAL_API_URL=http://103.197.25.170:18088
# INTERNAL_API_KEY=your_internal_api_key_here
# --- LLM Settings ---
LLM_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/
# Internal trade data API
INTERNAL_API_URL=http://103.197.25.170:18088
INTERNAL_API_KEY=your_internal_api_key_here
# Polygon Wallet Private Key (for trade execution)
POLYGON_WALLET_PRIVATE_KEY=your_private_key_here
# MongoDB Connection String
MONGODB_URI=mongodb://localhost:27017/whale_watcher
# Whale Detection Settings
MIN_TRADE_SIZE_USD=1000
MIN_PRICE=0
MAX_PRICE=0.7
# Monitoring Settings
FETCH_INTERVAL_SECONDS=5
TRENDING_MARKETS_LIMIT=50
# LLM Settings
LLM_MODEL=gemini-3-flash-preview
LLM_TEMPERATURE=0
# Trade Execution (set to true to enable actual trading)
# --- Optional: Search & Data APIs (enhances LLM analysis) ---
# TAVILY_API_KEY= # Web search (https://tavily.com)
# TWITTER_API_KEY= # Twitter sentiment
# SERPER_API_KEY= # Web search fallback (https://serper.dev)
# POLYGON_API_KEY= # Stocks, forex (https://polygon.io)
# FRED_API_KEY= # Economic indicators (https://fred.stlouisfed.org)
# ETHERSCAN_API_KEY= # On-chain data (https://etherscan.io)
# CONGRESS_API_KEY= # US legislation (https://api.congress.gov)
# --- Optional: Telegram Monitoring ---
# TELEGRAM_API_ID=
# TELEGRAM_API_HASH=
# TELEGRAM_SESSION_STRING=
# TELEGRAM_CHANNELS=
# --- Whale Detection Tuning ---
MIN_TRADE_SIZE_USD=1000
MIN_PRICE=0
MAX_PRICE=0.7
FETCH_INTERVAL_SECONDS=15
TRENDING_MARKETS_LIMIT=50
# --- Email Alerts (optional) ---
EMAIL_ENABLED=false
# EMAIL_SMTP_SERVER=smtp.qq.com
# EMAIL_SMTP_PORT=465
# EMAIL_SENDER=
# EMAIL_PASSWORD=
# EMAIL_RECIPIENT=
# --- Trade Execution (disabled by default, use with caution) ---
ENABLE_TRADE_EXECUTION=false
# POLYGON_WALLET_PRIVATE_KEY=
# Tavily API Key for web search
TAVILY_API_KEY=your_tavily_api_key_here
# Logging
# --- Logging ---
LOG_LEVEL=INFO
+17
View File
@@ -0,0 +1,17 @@
FROM python:3.12-slim
WORKDIR /app
# Install dependencies first (cached layer)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY src/ src/
COPY pyproject.toml .
# Create data directories
RUN mkdir -p data reports daily_briefings
# Default command
CMD ["python", "-m", "src.main", "run"]
+43
View File
@@ -0,0 +1,43 @@
.PHONY: setup run dashboard briefing markets test lint clean docker-build docker-run help
PYTHON = python3
VENV = venv
PIP = $(VENV)/bin/pip
PY = $(VENV)/bin/python
help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
setup: ## One-click setup (venv + dependencies + .env)
@chmod +x setup.sh && ./setup.sh
run: ## Start the whale watcher
$(PY) -m src.main run
run-debug: ## Start with debug logging
$(PY) -m src.main run --debug
dashboard: ## Start the web dashboard
$(PY) -m src.main dashboard
briefing: ## Generate today's briefing
$(PY) -m src.main briefing --today
markets: ## Show trending markets
$(PY) -m src.main check-markets --limit 20
test: ## Run tests
$(PY) -m pytest tests/ -v
lint: ## Run linter
$(VENV)/bin/ruff check src/
clean: ## Remove generated files (keep data)
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
find . -type f -name '*.pyc' -delete 2>/dev/null || true
docker-build: ## Build Docker image
docker build -t polymarket-whale-watcher .
docker-run: ## Run in Docker
docker run --env-file .env -v $(PWD)/data:/app/data -v $(PWD)/reports:/app/reports polymarket-whale-watcher
+288 -161
View File
@@ -1,13 +1,40 @@
<div align="center">
# Polymarket Whale Watcher
AI-powered whale trade surveillance and analysis system for Polymarket prediction markets. Combines real-time monitoring, multi-dimensional anomaly detection, LLM-driven investigation with 14 autonomous tools, and signal accuracy tracking.
**AI-powered whale trade surveillance for Polymarket prediction markets**
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Polymarket](https://img.shields.io/badge/Polymarket-Official_API-purple.svg)](https://docs.polymarket.com/)
Real-time monitoring | Multi-dimensional anomaly detection | LLM investigation with 14 autonomous tools | Signal accuracy tracking
[Quick Start](#-quick-start) | [How It Works](#-how-it-works) | [Features](#-features) | [Configuration](#-configuration) | [Dashboard](#-dashboard)
</div>
---
## What It Does
Whale Watcher continuously monitors 50+ trending Polymarket markets, detects large trades with anomalous patterns, and uses an LLM agent with 14 autonomous research tools to investigate whether the trader may possess an information advantage. It tracks signal accuracy over time, achieving **63.5% win rate** with **+28.3% average ROI** on high-confidence signals.
```
Trending Markets → Whale Detection → Anomaly Scoring → LLM Investigation → Signal Tracking
(50+) ($1k-$100k+) (5 dimensions) (14 tools, 5 rounds) (win rate, ROI)
```
---
## Demo
<details>
<summary><b>Terminal Output</b> — Real-time whale detection and LLM analysis</summary>
<details open>
<summary><b>Terminal Output</b> — Real-time whale detection and analysis</summary>
```
$ python -m src.main run
╭──────────────────────────────────────────────────────────╮
│ 🐋 Polymarket Whale Watcher │
│ │
@@ -39,25 +66,25 @@ AI-powered whale trade surveillance and analysis system for Polymarket predictio
→ "Over 9M committed to P2P" resolved YES — Signal CORRECT (ROI: +67%)
```
See full example: [docs/examples/sample_terminal.txt](docs/examples/sample_terminal.txt)
</details>
<details>
<summary><b>Analysis Report</b> — LLM investigation with tool-use</summary>
<summary><b>Analysis Report</b> — LLM investigation with autonomous tool-use</summary>
Each whale trade generates a detailed markdown report:
- **Trade details** — amount, direction, price, trader wallet
- **Trader profile** — rank, PnL, history, recent trades
- **LLM investigation** — 5 autonomous tool calls (web, Twitter, Telegram, on-chain, DeFi)
- **Trader profile** — leaderboard rank, PnL, history, recent trades
- **LLM investigation** — autonomous tool calls (web, Twitter, Telegram, on-chain, DeFi)
- **Information asymmetry assessment** — score, evidence, reasoning
Example findings:
Example finding:
> *"New ERC-20 contract deployed by MegaETH deployer wallet 6 hours before trade — not yet publicly announced. KOL tweets about insider knowledge preceded the trade by ~3 hours."*
>
> **Information Asymmetry Score: 0.72** | Trader Credibility: HIGH
See full example: [docs/examples/sample_report.md](docs/examples/sample_report.md)
</details>
<details>
@@ -68,7 +95,6 @@ Daily briefings include:
- Price volatility alerts
- Historical signal performance (win rate, ROI by confidence tier)
Example stats:
| Metric | Value |
|--------|-------|
| Win Rate | **63.5%** |
@@ -76,193 +102,294 @@ Example stats:
| Signals with IAS >= 60% | 3 today |
See full example: [docs/examples/sample_briefing.md](docs/examples/sample_briefing.md)
</details>
## Features
- **Real-Time Monitoring** — Parallel per-market polling of 50+ trending markets
- **Multi-Dimensional Anomaly Detection** — Scores trades on size, price uncertainty, time-of-day, trader deviation, and cluster signals
- **Trader Profiling** — Leaderboard ranking, trading history, recent behavior analysis
- **LLM Analysis with Tool-Use** — 14 autonomous tools (Twitter, web search, Telegram, crypto prices, stocks, economic data, Congress bills, DeFi metrics, on-chain analysis)
- **Signal Accuracy Tracking** — Automatic market resolution checking, win rate stats by confidence tier
- **Daily Intelligence Briefing** — Automated 10:00 AM daily summary with high-confidence signals
- **Email Alerts** — Real-time notifications for high-IAS signals (>= 60%)
- **Web Dashboard** — FastAPI-based signal performance dashboard
- **Leading Signal Research** — "Price leads news" dataset collection
---
## Quick Start
### One-Click Setup
```bash
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env with your API keys
# Start the whale watcher
python -m src.main run
# With debug logging
python -m src.main run --debug
git clone https://github.com/chaoleiyv/polymarket-whale-watcher.git
cd polymarket-whale-watcher
chmod +x setup.sh && ./setup.sh
```
The setup script will:
1. Check Python 3.10+ is installed
2. Create a virtual environment
3. Install all dependencies
4. Create `.env` from template
Then add your API key and start:
```bash
# Add your Gemini API key (the only required key)
echo "GEMINI_API_KEY=your_key_here" >> .env
# Activate the environment and run
source venv/bin/activate
python -m src.main run
```
> **Get a free Gemini API key**: https://aistudio.google.com/apikey
### Docker
```bash
docker build -t whale-watcher .
docker run --env-file .env -v ./data:/app/data -v ./reports:/app/reports whale-watcher
```
### Make Commands
```bash
make setup # One-click setup
make run # Start monitoring
make run-debug # Start with debug logging
make dashboard # Start web dashboard
make markets # View trending markets
make briefing # Generate today's briefing
make help # Show all commands
```
---
## Features
| Feature | Description |
|---------|-------------|
| **Real-Time Monitoring** | Parallel per-market polling of 50+ trending markets |
| **Anomaly Detection** | 5-dimensional scoring: size, price uncertainty, time-of-day, trader deviation, cluster signals |
| **Trader Profiling** | Leaderboard ranking, PnL, trading history, recent behavior |
| **LLM Analysis** | 14 autonomous tools across 5 rounds of investigation |
| **Signal Tracking** | Automatic market resolution checking, win rate stats by confidence tier |
| **Daily Briefing** | Automated 10:00 AM summary with high-confidence signals |
| **Email Alerts** | Real-time notifications for high information-asymmetry signals (>= 60%) |
| **Web Dashboard** | FastAPI-based signal performance dashboard |
| **Official API** | Works with Polymarket's public API — no private API access needed |
### 14 LLM Research Tools
The LLM agent autonomously selects and uses these tools during investigation:
| Category | Tools |
|----------|-------|
| **Social Sentiment** | `search_twitter`, `search_telegram`, `search_web` |
| **Crypto Data** | `get_crypto_price`, `get_defi_metrics`, `get_token_unlocks` |
| **Financial Data** | `get_stock_price`, `get_economic_indicators` |
| **On-Chain** | `get_wallet_transactions`, `get_contract_info` |
| **Legislation** | `search_congress` |
| **Market Data** | `get_market_history`, `get_trader_positions` |
---
## How It Works
```mermaid
flowchart LR
A[Polymarket API] --> B[Market Fetcher]
B --> C[50+ Trending Markets]
C --> D[Trade Monitor]
D --> E{Whale Trade?}
E -->|No| D
E -->|Yes| F[Anomaly Detector]
F --> G{Score > Threshold?}
G -->|No| D
G -->|Yes| H[LLM Analyzer]
H --> I[14 Research Tools]
I --> J[Signal + Report]
J --> K[Resolution Tracker]
K --> L[Stats Dashboard]
```
### Pipeline
1. **Market Selection** — Fetches top trending markets by 24h volume from Polymarket, filters out sports/weather/short-term price markets, refreshes every 15 minutes
2. **Trade Monitoring** — Runs parallel async tasks per market, polls for new trades incrementally, deduplicates by transaction hash
3. **Anomaly Detection** — Multi-dimensional scoring on 5 axes:
- **Size** — Trade size relative to market 24h volume
- **Price uncertainty** — Closer to 0.5 = more interesting
- **Time-of-day** — ET hour-based suspicion weights
- **Trader deviation** — Trade size vs trader's historical average
- **Cluster signal** — Same-direction trades within 5-minute window
4. **LLM Investigation** — Builds rich context (trade + trader profile + market data), LLM autonomously uses tools to investigate (up to 5 rounds), produces structured recommendation with information asymmetry score
5. **Signal Tracking** — Resolution tracker checks every 30 minutes for resolved markets, validates signal correctness, computes theoretical ROI, aggregates win rates by confidence tier
---
## Configuration
Copy `.env.example` to `.env` and configure:
**Required:**
- `GEMINI_API_KEY` — Gemini API key for LLM analysis
- `INTERNAL_API_URL` / `INTERNAL_API_KEY` — Trade data API (currently using internal API, can be replaced with [Polymarket CLOB API](https://docs.polymarket.com/))
### Required
**Optional:**
- `TAVILY_API_KEY` — Web search (primary)
- `TWITTER_API_KEY` — Twitter sentiment search
- `POLYGON_API_KEY` — Stock/ETF data
- `FRED_API_KEY` — Economic indicators
- `ETHERSCAN_API_KEY` — On-chain data
- `EMAIL_*` — Email alert settings
- `MIN_TRADE_SIZE_USD` — Minimum trade size (default: 1000)
- `MIN_PRICE` / `MAX_PRICE` Price range filter (default: 0-0.7)
| Variable | Description | Get It |
|----------|-------------|--------|
| `GEMINI_API_KEY` | Gemini API key for LLM analysis | [Google AI Studio](https://aistudio.google.com/apikey) |
### Trade Data Source
| Variable | Default | Description |
|----------|---------|-------------|
| `TRADE_API_MODE` | `official` | `official` = Polymarket public API (no auth needed), `internal` = private API |
The bot works out of the box with Polymarket's official public API. No private API access required.
### Optional (enhances analysis)
| Variable | Description | Get It |
|----------|-------------|--------|
| `TAVILY_API_KEY` | Web search (primary) | [tavily.com](https://tavily.com) |
| `TWITTER_API_KEY` | Twitter sentiment search | [Twitter Developer](https://developer.twitter.com) |
| `POLYGON_API_KEY` | Stock/ETF/forex data | [polygon.io](https://polygon.io) |
| `FRED_API_KEY` | Economic indicators | [FRED](https://fred.stlouisfed.org/docs/api/api_key.html) |
| `ETHERSCAN_API_KEY` | On-chain wallet analysis | [etherscan.io](https://etherscan.io/apis) |
| `CONGRESS_API_KEY` | US legislation data | [congress.gov](https://api.congress.gov/) |
### Whale Detection Tuning
| Variable | Default | Description |
|----------|---------|-------------|
| `MIN_TRADE_SIZE_USD` | `1000` | Minimum trade size to consider |
| `MIN_PRICE` / `MAX_PRICE` | `0` / `0.7` | Price range filter |
| `FETCH_INTERVAL_SECONDS` | `15` | Polling interval per market |
| `TRENDING_MARKETS_LIMIT` | `50` | Number of markets to monitor |
---
## Commands
```bash
# Start monitoring
python -m src.main run [--debug]
# Core
python -m src.main run [--debug] # Start monitoring
python -m src.main check-markets --limit 20 # View trending markets
python -m src.main test-analyze <market_id> # Test LLM on a specific market
# Check trending markets
python -m src.main check-markets --limit 20
# Reports
python -m src.main briefing --today # Generate today's briefing
python -m src.main briefing --date 2026-04-17 # Briefing for a specific date
# Test LLM analysis on a specific market
python -m src.main test-analyze <market_id>
# Dashboard
python -m src.main dashboard --port 8000 # Start web dashboard
# Generate daily briefing
python -m src.main briefing --today
python -m src.main briefing --date 2026-04-17
# Migrate legacy JSON signals to SQLite
python -m src.main migrate
# Start web dashboard
python -m src.main dashboard --port 8000
# Maintenance
python -m src.main migrate # Migrate legacy JSON to SQLite
```
---
## Dashboard
Start the web dashboard to view signal performance:
```bash
python -m src.main dashboard
# Open http://localhost:8000
```
The dashboard shows:
- Overall signal statistics (total signals, win rate, avg ROI)
- Performance breakdown by confidence tier
- Top best/worst signals by theoretical ROI
- Paginated signal history
---
## Project Structure
```
src/
├── config/settings.py # Environment configuration (Pydantic)
├── models/ # Data models
│ ├── market.py # Market, TrendingMarket
│ ├── trade.py # TradeActivity, WhaleTrade, TraderRanking
│ ├── decision.py # TradeRecommendation, LLMDecision
│ └── anomaly_signal.py # AnomalySignal (stored signal)
├── services/ # Business logic (23 modules)
│ ├── market_fetcher.py # Polymarket Gamma API
│ ├── trade_monitor.py # Per-market parallel monitoring (official + internal API)
│ ├── anomaly_detector.py # Multi-dimensional anomaly scoring
│ ├── llm_analyzer.py # LLM with tool-use (14 tools, 5 rounds)
│ ├── tools.py # Tool registry
│ ├── resolution_tracker.py # Market resolution checking
│ ├── stats_engine.py # Performance statistics
│ ├── daily_briefing.py # Daily summary generation
│ └── [data services] # Twitter, Telegram, CoinGecko, DeFiLlama,
│ # FRED, Polygon, Etherscan, Congress, web search
├── db/database.py # SQLite signal storage
├── prompts/ # LLM system prompts & tool schemas
├── dashboard.py # FastAPI web dashboard
└── main.py # CLI entry point (Typer)
```
---
## Architecture
```
Polymarket API Internal Trade API Gamma API
| | |
v v v
MarketFetcher TradeMonitor PriceMonitor
| | |
v v v
TrendingMarkets AnomalyDetector VolatilityAnalyzer
|
v
LLMAnalyzer (14 tools)
| |
v v
AnomalySignal Reports/Alerts
|
v
ResolutionTracker → StatsEngine → Dashboard
┌─────────────────────────────┐
│ Polymarket Gamma API │
│ (trending markets, prices) │
└──────────────┬──────────────┘
┌──────────────▼──────────────┐
│ Market Fetcher │
│ (filter sports/weather/etc) │
└──────────────┬──────────────┘
┌────────────────────▼────────────────────┐
│ Trade Monitor (async) │
│ 50+ parallel market polling tasks │
│ Official API ←→ Internal API (switch) │
└────────────────────┬────────────────────┘
┌────────────────────▼────────────────────┐
│ Anomaly Detector │
│ 5-axis scoring: size, price, time, │
│ trader deviation, cluster signals │
└────────────────────┬────────────────────┘
┌────────────────────▼────────────────────┐
│ LLM Analyzer (Gemini) │
│ 14 tools × 5 rounds of investigation │
├─────────┬────────┬────────┬─────────────┤
│ Twitter │ Web │ DeFi │ On-Chain │
│Telegram │ Search │ Crypto │ Congress │
└─────────┴───┬────┴────────┴─────────────┘
┌─────────────▼──────────────────────────┐
│ Signal Storage (SQLite) │
│ → Resolution Tracker (every 30min) │
│ → Stats Engine (win rate, ROI) │
│ → Dashboard (FastAPI) │
│ → Email Alerts (IAS >= 60%) │
└────────────────────────────────────────┘
```
### Project Structure
```
src/
├── config/settings.py # Environment configuration
├── models/
│ ├── market.py # Market, TrendingMarket
│ ├── trade.py # TradeActivity, WhaleTrade, TraderRanking
│ ├── decision.py # TradeRecommendation, LLMDecision
│ ├── anomaly_signal.py # AnomalySignal (stored signal)
│ └── leading_signal.py # LeadingSignal (price leads news)
├── services/
│ ├── market_fetcher.py # Polymarket API, market filtering
│ ├── trade_monitor.py # Per-market parallel monitoring
│ ├── price_monitor.py # Volatility detection
│ ├── anomaly_detector.py # Multi-dimensional anomaly scoring
│ ├── llm_analyzer.py # LLM with tool-use (14 tools, 5 rounds max)
│ ├── volatility_analyzer.py # Leading signal detection
│ ├── trader_profiler.py # Trader profile generation
│ ├── tools.py # Tool registry
│ ├── daily_briefing.py # Daily summary generation
│ ├── resolution_tracker.py # Market resolution checking
│ ├── stats_engine.py # Performance statistics
│ ├── anomaly_history.py # Signal storage (SQLite)
│ ├── coingecko.py # Crypto prices
│ ├── fred.py # Economic indicators (FRED)
│ ├── polygon.py # Stock prices & news
│ ├── congress.py # US legislation
│ ├── defillama.py # DeFi TVL, revenue, token unlocks
│ ├── etherscan.py # On-chain wallet analysis
│ ├── twitter_search.py # Twitter API
│ ├── telegram_search.py # Telegram channels
│ └── web_search.py # Unified search (Tavily → Serper → DDG)
├── db/database.py # SQLite signal storage
├── prompts/
│ ├── whale_analyzer.py # LLM system prompt & tool schemas
│ └── volatility_analyzer.py # Volatility analysis prompt
├── dashboard.py # FastAPI web dashboard
└── main.py # Entry point (WhaleWatcher orchestrator)
data/ # SQLite database + processed transactions
reports/ # Analysis reports (by date)
daily_briefings/ # Daily intelligence summaries
leading_signals/ # "Price leads news" research dataset
price_volatility/ # Volatility alert records
```
## How It Works
### 1. Market Selection
- Fetches top trending markets by 24h volume from Polymarket Gamma API
- Filters out sports, weather, and short-term price markets
- Refreshes market list every 15 minutes
### 2. Trade Monitoring
- Runs parallel async tasks per monitored market
- Polls internal API incrementally (new trades since last check)
- Rate-limited at 5 QPS to respect API limits
- Deduplicates by transaction hash
### 3. Anomaly Detection
Multi-dimensional scoring on 5 axes:
- **Size** — Trade size relative to market 24h volume
- **Price uncertainty** — Closer to 0.5 = more interesting
- **Time-of-day** — ET hour-based suspicion weights
- **Trader deviation** — Trade size vs trader's historical average
- **Cluster signal** — Same-direction trades within 5-minute window
### 4. LLM Investigation
When a whale trade triggers:
1. Builds rich context: trade details + trader profile + market data + historical signals
2. LLM autonomously uses tools to investigate (up to 5 rounds):
- Search Twitter/Telegram for insider chatter
- Check crypto prices, DeFi metrics, on-chain activity
- Look up stock movements, economic data, Congress bills
- Web search for breaking news
3. Produces structured recommendation: action, confidence, information asymmetry score (0-1)
4. Generates markdown report saved to `reports/`
### 5. Signal Tracking
- Resolution tracker checks every 30 minutes for resolved markets
- Validates signal correctness against actual outcomes
- Computes theoretical ROI for each signal
- Stats engine aggregates win rates by confidence tier
---
## Safety
- Trade execution disabled by default (`ENABLE_TRADE_EXECUTION=false`)
- Trade execution **disabled by default** (`ENABLE_TRADE_EXECUTION=false`)
- Position size capped at 20% of balance if enabled
- Minimum 60% confidence threshold for execution
- Price range filter avoids obvious outcomes (0-0.7)
- Price range filter avoids obvious outcomes
- All decisions logged for audit trail
- Rate limiting on all external APIs
## Disclaimer
This system is for research and educational purposes. Prediction market trading involves significant risk. Never trade with funds you cannot afford to lose. Always verify recommendations independently.
---
## License
MIT
+5 -9
View File
@@ -9,22 +9,18 @@ description = "AI-powered whale trade detection and analysis bot for Polymarket"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "your@email.com"}
]
dependencies = [
"httpx>=0.27.0",
"pydantic>=2.0.0",
"pydantic-settings>=2.0.0",
"python-dotenv>=1.0.0",
"openai>=1.0.0",
"langchain>=0.1.0",
"langchain-openai>=0.0.5",
"pymongo>=4.6.0",
"motor>=3.3.0",
"py-clob-client>=0.17.0",
"web3>=6.0.0",
"rich>=13.0.0",
"typer>=0.9.0",
"duckduckgo-search>=7.0.0",
"telethon>=1.36.0",
"fastapi>=0.100.0",
"uvicorn>=0.20.0",
]
[project.optional-dependencies]
Executable
+220
View File
@@ -0,0 +1,220 @@
#!/usr/bin/env bash
# Polymarket Whale Watcher - One-Click Setup
# Usage: chmod +x setup.sh && ./setup.sh
set -e
CYAN='\033[0;36m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
DIM='\033[2m'
BOLD='\033[1m'
NC='\033[0m'
echo -e "${CYAN}"
echo "╭──────────────────────────────────────────────────────────╮"
echo "│ 🐋 Polymarket Whale Watcher Setup │"
echo "╰──────────────────────────────────────────────────────────╯"
echo -e "${NC}"
# ============================================================
# Step 1: Check Python
# ============================================================
echo -e "${CYAN}[1/4]${NC} Checking Python version..."
if ! command -v python3 &> /dev/null; then
echo -e "${RED}Error: Python 3 is required but not installed.${NC}"
echo " Install from https://www.python.org/downloads/"
exit 1
fi
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
PYTHON_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
if [ "$PYTHON_MAJOR" -lt 3 ] || ([ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 10 ]); then
echo -e "${RED}Error: Python 3.10+ required, found $PYTHON_VERSION${NC}"
exit 1
fi
echo -e " ${GREEN}${NC} Python $PYTHON_VERSION"
# ============================================================
# Step 2: Virtual environment
# ============================================================
echo -e "${CYAN}[2/4]${NC} Setting up virtual environment..."
if [ ! -d "venv" ]; then
python3 -m venv venv
echo -e " ${GREEN}${NC} Virtual environment created"
else
echo -e " ${GREEN}${NC} Virtual environment already exists"
fi
# ============================================================
# Step 3: Install dependencies
# ============================================================
echo -e "${CYAN}[3/4]${NC} Installing dependencies..."
source venv/bin/activate
pip install --upgrade pip -q
pip install -r requirements.txt -q
echo -e " ${GREEN}${NC} Dependencies installed"
# Create data directories
mkdir -p data reports daily_briefings
# ============================================================
# Step 4: API Key Configuration
# ============================================================
echo -e "${CYAN}[4/4]${NC} Configuring API keys..."
echo ""
if [ -f ".env" ]; then
echo -e " ${YELLOW}Found existing .env file.${NC}"
read -p " Overwrite and reconfigure? [y/N] " overwrite
if [[ ! "$overwrite" =~ ^[Yy]$ ]]; then
echo -e " ${GREEN}${NC} Keeping existing .env"
echo ""
echo -e "${GREEN}Setup complete! Run:${NC}"
echo " source venv/bin/activate"
echo " python -m src.main run"
exit 0
fi
fi
cp .env.example .env
# Helper function: prompt for a key and write to .env
set_key() {
local var_name="$1"
local prompt_text="$2"
local url="$3"
local required="$4"
echo ""
if [ "$required" = "required" ]; then
echo -e " ${BOLD}${var_name}${NC} ${RED}(required)${NC}"
else
echo -e " ${BOLD}${var_name}${NC} ${DIM}(optional, press Enter to skip)${NC}"
fi
echo -e " ${DIM}$prompt_text${NC}"
echo -e " ${DIM}$url${NC}"
while true; do
read -p " Key: " key_value
if [ -z "$key_value" ]; then
if [ "$required" = "required" ]; then
echo -e " ${RED}This key is required. Please enter a value.${NC}"
continue
else
echo -e " ${DIM}Skipped${NC}"
return
fi
fi
break
done
# Replace the placeholder in .env
if grep -q "^${var_name}=" .env; then
sed -i.bak "s|^${var_name}=.*|${var_name}=${key_value}|" .env
elif grep -q "^# ${var_name}=" .env; then
sed -i.bak "s|^# ${var_name}=.*|${var_name}=${key_value}|" .env
else
echo "${var_name}=${key_value}" >> .env
fi
rm -f .env.bak
echo -e " ${GREEN}✓ Saved${NC}"
}
echo -e "${CYAN}╭──────────────────────────────────────────────────────────╮${NC}"
echo -e "${CYAN}│ API Key Configuration │${NC}"
echo -e "${CYAN}│ │${NC}"
echo -e "${CYAN}│ The more keys you add, the better the analysis. │${NC}"
echo -e "${CYAN}│ Only Gemini is required. Others are optional but │${NC}"
echo -e "${CYAN}│ strongly recommended for full coverage. │${NC}"
echo -e "${CYAN}╰──────────────────────────────────────────────────────────╯${NC}"
# --- Required ---
echo ""
echo -e "${YELLOW}━━━ Required (LLM Engine) ━━━${NC}"
set_key "GEMINI_API_KEY" \
"Powers the LLM analysis (free tier available)" \
"https://aistudio.google.com/apikey" \
"required"
# --- Core Search ---
echo ""
echo -e "${YELLOW}━━━ Web Search (strongly recommended) ━━━${NC}"
echo -e "${DIM} Without these, LLM falls back to DuckDuckGo (lower quality)${NC}"
set_key "TAVILY_API_KEY" \
"Best web search quality, 1000 free searches/month" \
"https://app.tavily.com/home"
set_key "SERPER_API_KEY" \
"Google search fallback, 2500 free searches" \
"https://serper.dev"
# --- Social Sentiment ---
echo ""
echo -e "${YELLOW}━━━ Social Sentiment ━━━${NC}"
set_key "TWITTER_API_KEY" \
"Twitter/X sentiment & breaking news search" \
"https://developer.x.com/en/portal/dashboard"
# --- Financial Data ---
echo ""
echo -e "${YELLOW}━━━ Financial & On-Chain Data ━━━${NC}"
set_key "POLYGON_API_KEY" \
"Stock, ETF, forex, commodities data (free tier)" \
"https://polygon.io/dashboard/signup"
set_key "FRED_API_KEY" \
"US economic indicators (free, instant approval)" \
"https://fred.stlouisfed.org/docs/api/api_key.html"
set_key "ETHERSCAN_API_KEY" \
"On-chain wallet & contract analysis (free tier)" \
"https://etherscan.io/myapikey"
set_key "CONGRESS_API_KEY" \
"US legislation & bills tracking (free)" \
"https://api.congress.gov/sign-up/"
# --- Summary ---
echo ""
echo ""
# Count configured keys
configured=0
total=8
for var in GEMINI_API_KEY TAVILY_API_KEY SERPER_API_KEY TWITTER_API_KEY POLYGON_API_KEY FRED_API_KEY ETHERSCAN_API_KEY CONGRESS_API_KEY; do
val=$(grep "^${var}=" .env 2>/dev/null | cut -d= -f2-)
if [ -n "$val" ] && [ "$val" != "your_gemini_api_key_here" ]; then
configured=$((configured + 1))
fi
done
echo -e "${GREEN}╭──────────────────────────────────────────────────────────╮${NC}"
echo -e "${GREEN}│ ✅ Setup Complete! │${NC}"
echo -e "${GREEN}│ │${NC}"
echo -e "${GREEN}│ API Keys configured: ${configured}/${total}${NC}"
echo -e "${GREEN}╰──────────────────────────────────────────────────────────╯${NC}"
if [ "$configured" -lt 4 ]; then
echo ""
echo -e " ${YELLOW}Tip: More API keys = better analysis coverage.${NC}"
echo -e " ${YELLOW}You can edit .env anytime to add more keys later.${NC}"
fi
echo ""
echo " Start monitoring:"
echo -e " ${BOLD}source venv/bin/activate${NC}"
echo -e " ${BOLD}python -m src.main run${NC}"
echo ""
echo " Other commands:"
echo " python -m src.main check-markets # View trending markets"
echo " python -m src.main dashboard # Web dashboard"
echo " python -m src.main briefing --today # Daily briefing"
echo ""
+4 -1
View File
@@ -15,7 +15,10 @@ class Settings(BaseSettings):
gemini_api_key: str = Field(default="", alias="GEMINI_API_KEY")
llm_base_url: str = Field(default="http://apicz.boyuerichdata.com/v1/", alias="LLM_BASE_URL")
# Internal trade data API
# Trade data API mode: "internal" (private API) or "official" (Polymarket data-api)
trade_api_mode: str = Field(default="official", alias="TRADE_API_MODE")
# Internal trade data API (only used when TRADE_API_MODE=internal)
internal_api_url: str = Field(default="http://103.197.25.170:18088", alias="INTERNAL_API_URL")
internal_api_key: str = Field(default="", alias="INTERNAL_API_KEY")
+166 -2
View File
@@ -158,7 +158,7 @@ class TradeMonitor:
logger.info(f"Now monitoring {len(self._monitored_markets)} markets")
# ================================================================
# Internal API: fetch trades
# Trade fetching: dispatches to internal or official API
# ================================================================
_MAX_RETRIES = 3
@@ -166,7 +166,171 @@ class TradeMonitor:
async def fetch_market_trades(self, market_id: str) -> List[TradeActivity]:
"""
Fetch recent taker trades for a market using the /flows API.
Fetch recent trades for a market. Dispatches to internal or official API
based on TRADE_API_MODE setting.
"""
if self.settings.trade_api_mode == "internal":
return await self._fetch_trades_internal(market_id)
else:
return await self._fetch_trades_official(market_id)
# ================================================================
# Official Polymarket data-api: fetch trades
# ================================================================
async def _fetch_trades_official(self, market_id: str) -> List[TradeActivity]:
"""
Fetch recent trades using the official Polymarket data-api /trades endpoint.
The official API returns trades with fields:
- id, taker_order_id, market, asset, side, size, price, status
- match_time, transaction_hash, outcome, bucket_index, owner, type
"""
try:
market = self._monitored_markets.get(market_id)
if not market:
return []
# The official /trades endpoint uses condition_id as the "market" param
condition_id = market.condition_id
if not condition_id:
return []
last_ts = self._market_last_ts.get(market_id)
params: Dict[str, object] = {
"market": condition_id,
"limit": 50 if last_ts is None else 500,
}
# Incremental polling: only fetch trades after last seen timestamp
if last_ts is not None:
params["after"] = last_ts + 1
sem = self._api_sem or asyncio.Semaphore(20)
last_err: Optional[Exception] = None
async with sem:
for attempt in range(self._MAX_RETRIES):
try:
async with self._api_lock:
now = _time.monotonic()
wait = self._api_global_interval - (now - self._api_last_request)
if wait > 0:
await asyncio.sleep(wait)
self._api_last_request = _time.monotonic()
response = await self._client.get(
f"{self.data_api_url}/trades", params=params,
)
response.raise_for_status()
break
except httpx.HTTPStatusError as e:
if e.response.status_code in (502, 503, 504) and attempt < self._MAX_RETRIES - 1:
delay = self._RETRY_BACKOFF[attempt]
logger.debug(
f"Official API {e.response.status_code} for {market_id} "
f"(attempt {attempt + 1}/{self._MAX_RETRIES}), "
f"retrying in {delay}s"
)
await asyncio.sleep(delay)
continue
raise
except httpx.HTTPError as e:
last_err = e
if attempt < self._MAX_RETRIES - 1:
delay = self._RETRY_BACKOFF[attempt]
logger.debug(
f"Official API retry for {market_id} "
f"(attempt {attempt + 1}/{self._MAX_RETRIES}): "
f"{type(e).__name__}, retrying in {delay}s"
)
await asyncio.sleep(delay)
else:
logger.warning(
f"Official API connection error for {market_id} "
f"(attempt {attempt + 1}/{self._MAX_RETRIES}, giving up): "
f"{type(e).__name__}: {e}"
)
return []
else:
return []
data = response.json()
if not data:
return []
activities = []
max_ts = last_ts or 0
for item in data:
try:
side = item.get("side", "").upper()
# Only track BUY trades (new positions)
if side != "BUY":
continue
size = float(item.get("size", 0) or 0)
price = float(item.get("price", 0) or 0)
usdc_size = size * price # Official API: USDC value = tokens * price
outcome = item.get("outcome", "Yes")
outcome_index = int(item.get("outcomeIndex", 0 if outcome == "Yes" else 1))
# Timestamp is epoch seconds in the official API
ts = int(item.get("timestamp", 0) or 0)
if ts == 0:
ts = int(_time.time())
if ts > max_ts:
max_ts = ts
tx_hash = item.get("transactionHash", "")
activity = TradeActivity(
transaction_hash=tx_hash,
timestamp=ts,
condition_id=item.get("conditionId", condition_id),
asset=item.get("asset", ""),
side="BUY",
size=size,
usdc_size=usdc_size,
price=price,
outcome=outcome,
outcome_index=outcome_index,
title=item.get("title", ""),
slug=item.get("slug"),
event_slug=item.get("eventSlug"),
proxy_wallet=item.get("proxyWallet"),
name=item.get("name") or item.get("pseudonym"),
)
activities.append(activity)
except Exception as e:
logger.debug(f"Failed to parse official API trade: {e}")
continue
if max_ts > 0:
self._market_last_ts[market_id] = max_ts
return activities
except httpx.HTTPStatusError as e:
logger.warning(
f"Official trades API HTTP {e.response.status_code} for {market_id}: "
f"{e.response.text[:200]}"
)
return []
except Exception as e:
logger.warning(f"Error fetching official trades for {market_id}: {type(e).__name__}: {e}")
return []
# ================================================================
# Internal API: fetch trades
# ================================================================
async def _fetch_trades_internal(self, market_id: str) -> List[TradeActivity]:
"""
Fetch recent taker trades for a market using the internal /flows API.
/flows returns one record per taker per transaction (already aggregated
across maker fills), with accurate usd_amount and real execution price.