Cross-platform arbitrage detection between Polymarket and Kalshi prediction markets
Features • Demo • Quick Start • Dashboard • Configuration
Author: ImMike
Watch the bot in action - scanning 5,000+ markets and finding opportunities in real-time
Scanning 5,000+ live Polymarket markets
Testing with simulated opportunities - 99.6% win rate, $573 profit
- 🔀 Cross-Platform Arbitrage - Detects price differences between Polymarket and Kalshi for the same prediction
- 🔍 Bundle Arbitrage Detection - Identifies when YES + NO prices don't sum to ~$1.00
- 📊 Market Making - Captures spreads by placing competitive bid/ask orders
- 🛡️ Risk Management - Position limits, loss limits, kill switch
- 📈 Live Dashboard - Real-time web UI showing opportunities and bot activity
- 🔄 Dual Data Modes - Switch between real market data and simulation
- 💰 Fee Accounting - Realistic edge calculations including fees & gas costs
- 📝 Comprehensive Logging - Detailed logs for trades, opportunities, and errors
- 🤖 Market Matching AI - Automatically matches similar predictions across platforms using text similarity
The bot supports two data modes, configurable in config.yaml:
mode:
data_mode: "simulation" # Generates fake data with opportunities- Generates simulated order books with realistic price dynamics
- Periodically introduces mispricings to create arbitrage opportunities
- Perfect for screenshots, demos, and testing strategies
- Fast updates to see the bot in action
mode:
data_mode: "real" # Fetches actual Polymarket data- Connects to Polymarket's Gamma API for market discovery
- Fetches real order books from the CLOB (Central Limit Order Book) API
- Scans 5,000+ markets across all categories
- Real markets are highly efficient - arbitrage opportunities are rare!
polymarket-arbitrage/
├── main.py # Main entry point
├── run_with_dashboard.py # Bot + live dashboard
├── config.yaml # Configuration (edit this!)
├── requirements.txt # Python dependencies
│
├── polymarket_client/ # Polymarket API client
│ ├── api.py # REST + WebSocket integration
│ └── models.py # Data classes
│
├── kalshi_client/ # Kalshi API client (NEW!)
│ ├── api.py # Kalshi REST API integration
│ └── models.py # Kalshi data classes
│
├── core/ # Trading logic
│ ├── data_feed.py # Real-time market data manager
│ ├── arb_engine.py # Single-platform opportunity detection
│ ├── cross_platform_arb.py # Cross-platform arbitrage (NEW!)
│ ├── execution.py # Order management
│ ├── risk_manager.py # Risk limits & kill switch
│ └── portfolio.py # Position & PnL tracking
│
├── dashboard/ # Web dashboard
│ ├── server.py # FastAPI server
│ └── integration.py # Bot-dashboard bridge
│
├── utils/ # Utilities
│ ├── config_loader.py # YAML config parser
│ ├── logging_utils.py # Colored console logging
│ └── backtest.py # Backtesting engine
│
├── tests/ # Unit tests
│ ├── test_arb_engine.py
│ ├── test_risk_manager.py
│ └── test_portfolio.py
│
└── logs/ # Log files (auto-created)
git clone https://github.com/ImMike/polymarket-arbitrage.git
cd polymarket-arbitrage
# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txtEdit config.yaml:
mode:
trading_mode: "dry_run" # Start with dry run!
data_mode: "real" # Use "simulation" for demos
cross_platform_enabled: true # Enable Polymarket + Kalshi arbitrage
kalshi_enabled: true # Enable Kalshi monitoring
trading:
min_edge: 0.01 # 1% minimum edge
default_order_size: 5 # Start small
risk:
max_position_per_market: 15
max_global_exposure: 50
max_daily_loss: 10# Run bot with live dashboard
python run_with_dashboard.py
# Open http://localhost:8000 in your browser# Bot only (no dashboard)
python main.py
# Verbose logging
python main.py -v
# Specify config file
python main.py --config config.live.yamlThe dashboard provides real-time visibility into bot operations:
| Metric | Description |
|---|---|
| Opportunities | Bundle arb & market-making signals found |
| Markets Monitored | Total markets being scanned |
| Order Books | Markets with live price data |
| Uptime | Bot running time |
| PnL | Profit/Loss tracking |
Access at http://localhost:8000 when running with run_with_dashboard.py
Detects when the same prediction is priced differently on Polymarket vs Kalshi:
| Condition | Action | Profit |
|---|---|---|
| Polymarket YES cheaper than Kalshi YES | Buy on Polymarket, Sell on Kalshi | Price difference |
| Kalshi YES cheaper than Polymarket YES | Buy on Kalshi, Sell on Polymarket | Price difference |
Example:
- "Will Trump win?" YES is $0.52 on Polymarket
- Same prediction YES is $0.58 on Kalshi
- Profit opportunity: Buy on Polymarket, sell on Kalshi = 6% edge (minus fees)
The bot uses text similarity matching to automatically find equivalent predictions across platforms.
Detects when YES + NO tokens are mispriced within a single platform:
| Condition | Action | Profit |
|---|---|---|
ask_yes + ask_no < $1.00 |
Buy both | Guaranteed $1 payout |
bid_yes + bid_no > $1.00 |
Sell both | Lock in premium |
Example: If YES trades at $0.45 and NO at $0.52, buying both costs $0.97 but pays out $1.00 = 3% profit
Places orders inside wide spreads:
- If spread ≥ 5¢, place bid slightly above best bid
- Place ask slightly below best ask
- Profit when both sides fill
| Section | Parameter | Description | Default |
|---|---|---|---|
mode |
trading_mode |
"dry_run" or "live" |
dry_run |
mode |
data_mode |
"simulation" or "real" |
real |
mode |
cross_platform_enabled |
Enable Polymarket + Kalshi | true |
mode |
kalshi_enabled |
Enable Kalshi monitoring | true |
mode |
min_match_similarity |
Market matching threshold | 0.6 |
trading |
min_edge |
Min profit after fees | 0.01 (1%) |
trading |
min_spread |
Min spread for MM | 0.05 (5¢) |
trading |
mm_enabled |
Enable market making | true |
risk |
max_position_per_market |
Max $ per market | 200 |
risk |
max_global_exposure |
Max total exposure | 5000 |
risk |
max_daily_loss |
Stop-loss limit | 500 |
trading:
maker_fee_bps: 0 # Polymarket maker fee (0%)
taker_fee_bps: 0 # Polymarket taker fee (0%)
estimated_gas_per_order: 0.001 # Polygon gas (minimal)Store sensitive data in environment variables:
export POLYMARKET_API_KEY="your_api_key"
export POLYMARKET_PRIVATE_KEY="your_private_key"# Run all tests
pytest tests/ -v
# Run specific test
pytest tests/test_arb_engine.py -v
# With coverage report
pytest tests/ --cov=core --cov=polymarket_client┌─────────────────────────────────────────────────────────────────────────────┐
│ CROSS-PLATFORM ARBITRAGE FLOW │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ Polymarket │────────▶│ Market │◀────────│ Kalshi │ │
│ │ 5000+ mkts │ │ Matcher │ │ 5000+ mkts │ │
│ └──────────────┘ └───────┬───────┘ └──────────────┘ │
│ │ │ │ │
│ │ Matched Pairs │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ Data Feed │────────▶│ Cross-Platform│◀────────│ Kalshi │ │
│ │ (orderbooks)│ │ Arb Engine │ │ Orderbooks │ │
│ └──────────────┘ └───────┬───────┘ └──────────────┘ │
│ │ │ │ │
│ │ Opportunities │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ Dashboard │◀────────│ Execution │────────▶│ Portfolio │ │
│ │ (live UI) │ │ (orders) │ │ (tracking) │ │
│ └──────────────┘ └───────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Real prediction markets are highly efficient. Arbitrage opportunities are rare and fleeting. The bot is designed to catch them when they occur, but don't expect constant profits.
- 🧪 Start in dry run mode - Always test before using real money
- 💵 Start small - Begin with minimal capital ($50-100)
- 👀 Monitor actively - Don't leave running unattended
- 📉 Expect losses - Trading always carries risk
- 🔬 This is experimental - Use at your own risk
- Polymarket uses a hybrid model: centralized order matching, on-chain settlement
- No gas fees for trading (Polymarket covers them)
- Funds are held in USDC on Polygon
- API keys required for live trading
- Kalshi is a CFTC-regulated US prediction market exchange
- Prices are in cents (e.g., 55¢ for YES)
- No authentication required for public market data
- Must be US-based to trade (KYC required)
- API documentation: docs.kalshi.com
- Add detection logic in
core/arb_engine.py - Create
Opportunityobjects with entry/exit prices - Execution engine handles order placement
The dashboard uses FastAPI + vanilla JS. Add new endpoints in dashboard/server.py and update the HTML in get_embedded_html().
MIT License - See LICENSE for details
- GitHub: @ImMike
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
Made with ☕ and Python by ImMike

