Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PolyTracker Bot — Polymarket Whale Tracker

A production-grade Python bot that monitors high-performing wallets on Polymarket and sends Telegram alerts when they make profitable trade signals.

Overview

What it does:

  1. Discovers and scores the top-performing wallets on Polymarket
  2. Tracks only wallets that meet profitability thresholds (60%+ win rate, $5k+ lifetime profit, etc.)
  3. Polls tracked wallets every 5 minutes for new positions
  4. Sends Telegram alerts with direct market links when high-conviction signals are detected
  5. 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.


Tech Stack

  • Language: Python 3.11+
  • Async HTTP:httpx with retry logic & rate limiting
  • Scheduler: APScheduler (5-minute polling + daily digest)
  • Database: SQLite (with aiosqlite)
  • Telegram:python-telegram-bot v20+
  • Logging:loguru
  • Config:python-dotenv

Project Structure

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

Verified Polymarket API Endpoints

Data API (https://data-api.polymarket.com)

All endpoints are public — no authentication required.

EndpointPurpose
GET /v1/leaderboardTop traders by PnL or volume
GET /v1/user/{address}/positionsCurrent open positions
GET /v1/user/{address}/tradesRecent trade history
GET /v1/user/{address}/activityRecent activity stream
GET /v1/profiles/{address}/public-profilePublic 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)

Gamma API (https://gamma-api.polymarket.com)

Market & event metadata (no auth).

EndpointPurpose
GET /v1/markets/{slug}Market details by slug
GET /v1/conditions/{id}Market details by condition ID

CLOB API (https://clob.polymarket.com)

Orderbook & pricing (public endpoints only).

EndpointPurpose
GET /v1/prices/midpointCurrent midpoint price
GET /v1/orderbook?token_id=...Liquidity estimate

Setup Instructions

1. Create Telegram Bot

  1. Message @BotFather on Telegram
  2. Type /start then /newbot
  3. Follow prompts to name your bot
  4. Save the bot token (e.g., 123456789:ABCdefGHIjkLmNoPQRstUVWxYzAbcD...)

2. Create/Get Channel ID

  1. Create a channel (e.g., @polytracker) or use existing one
  2. Add your bot as admin
  3. Forward any message to @userinfobot to get the CHANNEL_ID
    • Look for -100... format (e.g., -1001234567890)

3. Clone & Setup

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...

4. Install Dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. Run Locally

python -m polytracker.main

You should see:

INFO | PolyTracker Bot started
INFO | Scheduler running with 5 jobs
INFO | Wallet discovery job scheduled for every 6 hours
...

Configuration Reference

VariableDefaultDescription
TELEGRAM_BOT_TOKEN(required)Bot token from @BotFather
TELEGRAM_CHANNEL_ID(required)Channel ID (with -100 prefix)
MIN_WIN_RATE0.60Minimum win rate (0-1)
MIN_TOTAL_PNL5000Minimum lifetime PnL in USD
MIN_TRADES25Minimum trade count for validity
MIN_AVG_POSITION200Minimum average position size USD
MIN_VOLUME_30D2000Minimum 30-day volume USD
MAX_WALLETS_TRACKED50Max tracked wallets at once
MIN_SIGNAL_POSITION500Minimum position size to alert USD
MIN_MARKET_LIQUIDITY10000Minimum market liquidity USD
MIN_HOURS_REMAINING48Minimum hours until market close
POLL_TRADES_INTERVAL_MINUTES5How often to check for new positions
DATABASE_PATH./data/polytracker.dbSQLite database path
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR)

Scheduler Jobs

JobFrequencyPurpose
discover_walletsEvery 6 hoursFind new high-performing wallets
rescore_walletsEvery 24 hoursRe-evaluate existing wallets
poll_tradesEvery 5 minutesCheck tracked wallets for new positions
check_closuresEvery 1 hourCleanup resolved/closed markets
daily_digest08:00 UTC dailySend summary of day's signals

Alert Format

Standard Alert (1 whale)

📡 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 Alert (2+ whales same market)

🔥 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

Database Schema

wallets

- 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)

trades

- 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)

alerts_sent

- id (PRIMARY KEY)
- wallet_address (FK)
- market_id
- sent_at (timestamp)
- alert_type ('standard'or'high_conviction')

Wallet Scoring Formula

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

Signal Viability Filter (All 7 Must Pass)

  1. ✅ Tracked wallet opens new position
  2. ✅ Market is still open (not resolved)
  3. ✅ Position size ≥ $500 (configurable)
  4. ✅ Market liquidity ≥ $10,000 (configurable)
  5. ≥ 48 hours remaining (configurable)
  6. No previous alert for this wallet-market pair
  7. ✅ Position direction matches wallet's historical edge in category

Docker Deployment

Build & Run Locally

docker-compose up --build

Production Deployment

docker 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:latest

Systemd Service (Linux)

Create /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.target

Enable & start:

sudo systemctl enable polytracker
sudo systemctl start polytracker
sudo journalctl -u polytracker -f # Watch logs

Testing

# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_scorer.py -v
# With coverage
pytest tests/ --cov=polytracker --cov-report=html

Monitoring & Troubleshooting

Check Logs

# Local
tail -f logs/polytracker.log
# Docker
docker logs -f polytracker
# Systemd
journalctl -u polytracker -f

Common Issues

IssueSolution
Bot not sending alertsCheck TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID in .env
"Rate limited" errorsReduce MAX_REQUESTS_PER_SECOND or increase polling interval
Missing walletsRun wallet discovery job manually: python -m polytracker.main --discover-now
Database lockedEnsure only one instance is running; check data/polytracker.db permissions

Future Enhancements (V2)

  • 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

License

TBD


Support

  • Issues: Open a GitHub issue
  • Questions: See /docs folder or check AGENTS.md

Built with Python, APScheduler, and caffeine. ⚡

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages