Skip to content

Poly-Sports/polymarket-sports-arbitrage-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Polymarket Cross-Line Arbitrage Bot

0f0acf14-94f9-4fc7-a95f-a5179ae14f57

A polymarket trading bot that detects temporary pricing inefficiencies across connected Polymarket sports markets.

TypeScript Node.js License Polymarket

proof.mp4

Why Open Source?

This repository is not a commercial product.

It exists for one reason:

To share a real working trading system instead of publishing endless AI-generated articles that provide no practical value.

There are thousands of blog posts explaining arbitrage.

Very few people actually build one.

This project is my attempt to bridge that gap.

Everything inside this repository comes from building, testing, breaking, and rebuilding real trading infrastructure.


A Few Honest Notes

This bot will not magically print money.

I don't hide that.

Markets evolve.

Edges disappear.

Liquidity changes.

Competition increases.

This repository is a foundation, not a guaranteed income machine.

However, it contains many of the engineering ideas, mathematical models, and architecture that I used before becoming consistently profitable.

If you're interested in quantitative trading, prediction markets, market microstructure, or TypeScript architecture, I hope you'll learn something useful.


Trading is Mathematics

While building this project I also created:

STAKE-MATH

A Node.js library implementing Kelly-based stake sizing and probability mathematics.

Trading is not gambling.

Trading is probability management.

Without mathematics, risk management becomes guessing.

Many of the position sizing models used here are based on the Kelly Criterion, fractional Kelly, expected value, and bankroll optimization.

Those mathematical foundations have been responsible for far more of my long-term success than any individual trading strategy.


My Recommendation

If you decide to experiment with this project:

  • start with simulation mode
  • understand every trade the bot makes
  • test your own ideas
  • use small position sizes
  • never risk money you cannot afford to lose

Happy Trading ❀️


Features

  • ⚑ Real-time Polymarket CLOB streaming
  • 🧠 Cross-line arbitrage detection
  • πŸ“ˆ Kelly Criterion stake sizing
  • πŸ’° Paper trading & Live trading
  • πŸ›‘ Risk management engine
  • πŸ“Š Beautiful terminal dashboard
  • 🧩 Modular architecture
  • πŸ“ Structured logging
  • πŸš€ Production-oriented TypeScript codebase

Strategy

Sports markets inside a single event should satisfy several no-arbitrage relationships.

Whenever one market reprices faster than another after new information arrives, temporary inefficiencies can appear.

The bot continuously:

Gamma API
      β”‚
      β–Ό
Discover connected markets
      β”‚
      β–Ό
Stream live CLOB orderbooks
      β”‚
      β–Ό
Detect pricing violations
      β”‚
      β–Ό
Risk evaluation
      β”‚
      β–Ό
Kelly stake sizing
      β”‚
      β–Ό
Submit limit orders
      β”‚
      β–Ό
Track positions & PnL

Current arbitrage checks include:

  • Complementary YES/NO pairs
  • Totals ladder relationships
  • Spread ladder relationships
  • Moneyline vs Spread
  • Three-way market sums
  • BTTS relationships

Supported Sports

By default the bot focuses on the markets where liquidity is strongest.

Sport Markets
πŸ€ NBA Games, Futures, Draft, Trades, Props
⚽ FIFA World Cup Match Winner, Groups, Knockout, Tournament Winner
SPORT_FOCUS=nba,world_cup

Discovery logs look like:

Discovery refresh:

40 events
520 tokens

NBA: 10
World Cup: 30

Adding another sport only requires creating another profile inside

src/model/sportsRegistry.ts

Quick Start

git clone https://github.com/PolySports/polymarket-cross-line-arbitrage-bot.git

cd polymarket-cross-line-arbitrage-bot

cp .env.example .env

npm install

npm run start:sim

CLI

npm start -- --mode sim
npm start -- --mode live --confirm-live
npm start -- --event nba-lal-bos-2026-01-15
npm start -- --tag 100381

CLI Options

Flag Description
--mode sim Simulation mode
--mode live Live trading
--event Watch specific event
--tag Filter Gamma tags
--confirm-live Required safety confirmation

Terminal Dashboard

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Header                                                       β”‚
β”‚ Mode β€’ WS Status β€’ Balance β€’ PnL β€’ Uptime                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Tracked Markets            β”‚ Opportunities                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ PnL Chart                                           Exposure  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Orders / Fills             β”‚ Alerts                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

[p] Pause

[f] Flatten

[q] Quit

Logs are written separately using Pino so they never corrupt the dashboard.


Configuration

See .env.example.

Important variables:

Variable Default Description
MODE sim sim or live
MIN_NET_EDGE_BPS 50 Minimum edge
MAX_POSITION_USD 500 Max Kelly stake
KELLY_FRACTION 0.5 Half Kelly
MIN_STAKE_USD 5 Minimum trade
MAX_EVENT_EXPOSURE_USD 200 Event exposure cap
DAILY_LOSS_LIMIT_USD 100 Kill switch
SIM_INITIAL_BALANCE 10000 Paper balance

Kelly Stake Sizing

The project sizes positions using the Kelly Criterion.

f* = (p βˆ’ price)
     ───────────
      (1-price)
stake = bankroll
      Γ— Kelly
      Γ— Fractional Kelly

Position sizes are automatically clamped between:

  • Minimum stake
  • Maximum position
  • Event exposure limits

Supported for:

  • Locked arbitrage
  • Relative value
  • Hedged ladder trades

Default configuration uses Half Kelly (0.5) to reduce variance.


Architecture

                Gamma REST
                     β”‚
                     β–Ό
               Event Graph
                     β”‚
                     β–Ό
              Market Classifier
                     β”‚
                     β–Ό
           CLOB REST / WebSocket
                     β”‚
                     β–Ό
             OrderBook Store
                     β”‚
                     β–Ό
            Arbitrage Detector
                     β”‚
                     β–Ό
              Risk Management
                     β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό                         β–Ό
 Sim Executor              Live Executor
        β”‚                         β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β–Ό
            Portfolio + Dashboard

Live Trading

Live mode requires:

PRIVATE_KEY

CLOB_API_KEY

CLOB_API_SECRET

CLOB_API_PASSPHRASE

and either

--confirm-live

or

CONFIRM_LIVE=true

Execution uses

@polymarket/clob-client-v2

against production endpoints.


Project Structure

src/

β”œβ”€β”€ arb/
β”‚   └── Arbitrage detection

β”œβ”€β”€ config/
β”‚   └── Zod configuration

β”œβ”€β”€ core/
β”‚   └── Engine

β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ Gamma
β”‚   β”œβ”€β”€ CLOB REST
β”‚   └── WebSocket

β”œβ”€β”€ exec/
β”‚   β”œβ”€β”€ Simulation
β”‚   β”œβ”€β”€ Live
β”‚   └── Order Manager

β”œβ”€β”€ model/
β”‚   β”œβ”€β”€ Event Graph
β”‚   └── Classifier

β”œβ”€β”€ portfolio/
β”‚   └── PnL

β”œβ”€β”€ risk/
β”‚   └── Exposure controls

β”œβ”€β”€ ui/
β”‚   └── blessed-contrib dashboard

└── util/
    β”œβ”€β”€ Logging
    β”œβ”€β”€ Math
    └── Rate limiting

Testing

npm test

Roadmap

  • Additional sports
  • Historical backtesting
  • Strategy plugins
  • Multi-exchange support
  • Automatic parameter optimization
  • Portfolio analytics
  • Web dashboard
  • Discord notifications

Contributing

Contributions are welcome.

Whether you're interested in:

  • quantitative trading
  • prediction markets
  • TypeScript
  • market microstructure
  • performance optimization

feel free to open an Issue or Pull Request.


Disclaimer

This repository is provided for educational purposes only.

Nothing contained here should be interpreted as financial advice.

Prediction markets involve substantial financial risk.

Always test thoroughly using simulation before deploying capital.

Past performance does not guarantee future results.


Built with ❀️ for the Polymarket developer community.

If this repository helped you learn something new, consider giving it a ⭐.

About

Polymarket trading bot that detects temporary pricing inefficiencies across connected Polymarket sports markets.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors