A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.
What it does:
- Discovers and scores the top-performing wallets on Polymarket
- Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
- Polls tracked wallets every 5 minutes for new positions
- Sends Telegram alerts with direct market links when high-conviction signals are detected
- Supports "high conviction" alerts when 2+ whales enter the same market
Why it matters: Following consistent winners on prediction markets can improve decision-making and reduce research overhead.
- Language: Python 3.11+
- Async HTTP:
httpxwith retry logic & rate limiting - Scheduler: APScheduler (5-minute polling + daily digest)
- Database: SQLite (with aiosqlite)
- Telegram:
python-telegram-botv20+ - Logging:
loguru - Config:
python-dotenv
PolyTrackerBot/
├── polytracker/
│ ├── __init__.py
│ ├── config.py # Load config from .env
│ ├── db.py # SQLite database + queries
│ ├── main.py # Entry point
│ ├── scheduler.py # APScheduler job definitions
│ │
│ ├── polymarket/
│ │ ├── __init__.py
│ │ ├── client.py # Async Polymarket API client
│ │ ├── wallet_scanner.py # Discover & score wallets
│ │ └── trade_monitor.py # Poll tracked wallets for new positions
│ │
│ ├── signals/
│ │ ├── __init__.py
│ │ ├── filter.py # Apply 7 viability filters
│ │ └── scorer.py # Wallet scoring formula
│ │
│ └── telegram/
│ ├── __init__.py
│ ├── bot.py # Telegram bot setup
│ └── alerts.py # Format & send alerts
│
├── tests/
│ ├── test_scorer.py
│ ├── test_filter.py
│ └── conftest.py
│
├── .env.example # Template (copy to .env)
├── requirements.txt # Dependencies
├── Dockerfile # Container setup
├── docker-compose.yml # Local dev
└── README.md # This file
All endpoints are public — no authentication required.
| Endpoint | Purpose |
|---|---|
GET /v1/leaderboard | Top traders by PnL or volume |
GET /v1/user/{address}/positions | Current open positions |
GET /v1/user/{address}/trades | Recent trade history |
GET /v1/user/{address}/activity | Recent activity stream |
GET /v1/profiles/{address}/public-profile | Public wallet stats (PnL, win rate, vol) |
Parameters for leaderboard:
category: OVERALL, POLITICS, SPORTS, CRYPTO, CULTURE, etc. (default: OVERALL)timePeriod: DAY, WEEK, MONTH, ALL (default: DAY)orderBy: PNL or VOL (default: PNL)limit: 1-50 (default: 25)offset: Pagination (default: 0)
Market & event metadata (no auth).
| Endpoint | Purpose |
|---|---|
GET /v1/markets/{slug} | Market details by slug |
GET /v1/conditions/{id} | Market details by condition ID |
Orderbook & pricing (public endpoints only).
| Endpoint | Purpose |
|---|---|
GET /v1/prices/midpoint | Current midpoint price |
GET /v1/orderbook?token_id=... | Liquidity estimate |
- Message
@BotFatheron Telegram - Type
/startthen/newbot - Follow prompts to name your bot
- Save the bot token (e.g.,
123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)
- Create a channel (e.g.,
@polytracker) or use existing one - Add your bot as admin
- Forward any message to
@userinfobotto get theCHANNEL_ID- Look for
-100...format (e.g.,-1001234567890)
- Look for
cd~/code/openclaw/projects
git clone <repo-url> PolyTrackerBot
cd PolyTrackerBot
# Copy and fill config
cp .env.example .env
# Edit .env:# TELEGRAM_BOT_TOKEN=your_token# TELEGRAM_CHANNEL_ID=-100...python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtpython -m polytracker.mainYou should see:
INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...
| Variable | Default | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN | (required) | Bot token from @BotFather |
TELEGRAM_CHANNEL_ID | (required) | Channel ID (with -100 prefix) |
MIN_WIN_RATE | 0.60 | Minimum win rate (0-1) |
MIN_TOTAL_PNL | 5000 | Minimum lifetime PnL in USD |
MIN_TRADES | 25 | Minimum trade count for validity |
MIN_AVG_POSITION | 200 | Minimum average position size USD |
MIN_VOLUME_30D | 2000 | Minimum 30-day volume USD |
MAX_WALLETS_TRACKED | 50 | Max tracked wallets at once |
MIN_SIGNAL_POSITION | 500 | Minimum position size to alert USD |
MIN_MARKET_LIQUIDITY | 10000 | Minimum market liquidity USD |
MIN_HOURS_REMAINING | 48 | Minimum hours until market close |
POLL_TRADES_INTERVAL_MINUTES | 5 | How often to check for new positions |
DATABASE_PATH | ./data/polytracker.db | SQLite database path |
LOG_LEVEL | INFO | Logging level (DEBUG, INFO, WARNING, ERROR) |
| Job | Frequency | Purpose |
|---|---|---|
| discover_wallets | Every 6 hours | Find new high-performing wallets |
| rescore_wallets | Every 24 hours | Re-evaluate existing wallets |
| poll_trades | Every 5 minutes | Check tracked wallets for new positions |
| check_closures | Every 1 hour | Cleanup resolved/closed markets |
| daily_digest | 08:00 UTC daily | Send summary of day's signals |
📡 POLYTRACKER SIGNAL
Wallet: 0x1234...abcd [Score: 87/100]
Win Rate: 73% | PnL: $24,300 | ROI: +142%
📌 Market: "Will X happen by Dec 31?"
Position: YES @ 34¢
Size: $1,200
Liquidity: $85,400
Closes: 14d 6h
🔗 Market: https://polymarket.com/event/will-x-happen
🔗 Wallet: https://polymarket.com/profile/0x1234...abcd
Risk: MEDIUM | Confidence: HIGH
🔥 HIGH CONVICTION — POLYTRACKER
2 tracked whales entered the same market!
Wallets:
• 0x1234...abcd (Score: 87) → YES @ 34¢ ($1,200)
• 0x5678...efgh (Score: 91) → YES @ 36¢ ($3,400)
📌 "Will X happen by Dec 31?"
Combined Position: $4,600
Liquidity: $85,400
Closes: 14d 6h
🔗 https://polymarket.com/event/will-x-happen
- address (PRIMARY KEY)
- score (0-100)
- win_rate (0-1)
- total_pnl (USD)
- roi (%)
- volume_30d (USD)
- avg_position (USD)
- total_trades (int)
- last_seen (timestamp)
- added_at (timestamp)
- is_active (bool)- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- market_slug
- market_title
- direction (YES/NO)
- price (0-1)
- size_usd
-timestamp- market_closes (timestamp)
- alerted (bool)- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')score = (win_rate * 40) + (log(total_pnl) * 20) + (roi * 20) + (recency_bonus * 20)
recency_bonus:
1.0 if last_trade < 7 days
0.5 if 7-30 days
0.0 if > 30 days
- ✅ Tracked wallet opens new position
- ✅ Market is still open (not resolved)
- ✅ Position size ≥ $500 (configurable)
- ✅ Market liquidity ≥ $10,000 (configurable)
- ✅ ≥ 48 hours remaining (configurable)
- ✅ No previous alert for this wallet-market pair
- ✅ Position direction matches wallet's historical edge in category
docker-compose up --builddocker build -t polytracker:latest .
docker run -d \
--name polytracker \
-e TELEGRAM_BOT_TOKEN=... \
-e TELEGRAM_CHANNEL_ID=... \
--restart=always \
-v $(pwd)/data:/app/data \
polytracker:latestCreate /etc/systemd/system/polytracker.service:
[Unit]Description=PolyTracker Bot
After=network.target
[Service]Type=simple
User=bot
WorkingDirectory=/home/bot/PolyTrackerBot
Environment="PATH=/home/bot/PolyTrackerBot/venv/bin"EnvironmentFile=/home/bot/PolyTrackerBot/.env
ExecStart=/home/bot/PolyTrackerBot/venv/bin/python -m polytracker.main
Restart=on-failure
RestartSec=10
[Install]WantedBy=multi-user.targetEnable & start:
sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f| Issue | Solution |
|---|---|
| Bot not sending alerts | Check TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env |
| "Rate limited" errors | Reduce MAX_REQUESTS_PER_SECOND or increase polling interval |
| Missing wallets | Run wallet discovery job manually: python -m polytracker.main --discover-now |
| Database locked | Ensure only one instance is running; check data/polytracker.db permissions |
- Web dashboard (React UI)
- Webhook support (replace polling with real-time events)
- Wallet clustering by trading style
- Backtesting framework
- Position sizing advice (Kelly Criterion)
- Multi-platform alerts (Discord, SMS)
- GraphQL API for custom queries
TBD
- Issues: Open a GitHub issue
- Questions: See
/docsfolder or checkAGENTS.md
Built with Python, APScheduler, and caffeine. ⚡