Skip to content

metadata-ipfs/sports-betting-bot

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Polymarket Sports Trailing Bot

A Rust bot for Polymarket that trades sports (binary) markets by slug using a trailing stop strategy. This document describes how it works in detail. More features may be added later.


Quick start

Binary Description
main_sports_trailing Sports trailing bot — slug-based, trailing only
# Build
cargo build --release

# Simulation (no real orders)
cargo run --release -- --simulation

# Live
cargo run --release -- --no-simulation

How it works (detailed)

Overview

The bot trades a single binary market identified by its slug (e.g. nfl-team-a-vs-team-b). The market has two outcome tokens (e.g. Team A / Team B). The strategy:

  1. Track both tokens: For each token, the bot keeps the lowest ask and highest ask seen over time.
  2. Trailing trigger: When the current ask recovers so that ask ≥ lowest_seen + trailing_stop_point, that side is considered to have “recovered” and is a buy candidate.
  3. First buy: The first side that triggers (or the cheaper one if both trigger in the same tick) is bought with a market order. Size is determined by trailing_shares (with a minimum cost of $1).
  4. Second buy: After the first buy, the bot trails only the opposite token. When that side’s ask reaches opposite_lowest + trailing_stop_point, it buys the opposite token with the same share count as the first buy.
  5. Once vs continuous: If continuous is false, the bot stops after one pair of buys. If continuous is true, it resets and repeats (trail both → buy first → trail opposite → buy second) until the market end time.

Prices are read from the Polymarket CLOB (order book): the bot uses the ask (SELL side) as the price to beat for the trailing logic.

State machine

The main loop is driven by a state machine with four states:

State Meaning
WaitingFirst Tracking low/high for both tokens. When one (or both) satisfies ask ≥ low + trailing_stop, pick one and send first buy.
FirstBuyPending First order is in flight. Loop does not process new triggers until the order completes (success or failure).
FirstBought First token bought. Tracking only the opposite token’s lowest ask; when opp_ask ≥ opposite_lowest + trailing_stop, buy opposite side.
Done Both sides bought for this round. If continuous, reset to WaitingFirst; otherwise keep sleeping until market ends.

On first-buy failure, state reverts to WaitingFirst with the last known low/high so the bot can trigger again later.

Diagram

flowchart TB
    subgraph init["Startup"]
        A[Load config.json] --> B[Authenticate with Polymarket]
        B --> C[Get market by slug]
        C --> D[Get condition_id + token0, token1 + end_date]
        D --> E[Init state: WaitingFirst]
    end

    subgraph loop["Main loop (every check_interval_ms)"]
        E --> F{Market ended?}
        F -->|Yes| EXIT[Exit]
        F -->|No| G[Fetch ask prices for token0, token1]
        G --> H{State?}

        H -->|WaitingFirst| I[Update low/high for both]
        I --> J{Trigger? ask ≥ low + trail}
        J -->|One or both| K[Execute first buy]
        K --> L[State = FirstBuyPending]
        L --> M[Wait for order result]
        M -->|OK| N[State = FirstBought]
        M -->|Fail| E
        J -->|None| F

        H -->|FirstBuyPending| F

        H -->|FirstBought| O[Update opposite_lowest]
        O --> P{opp_ask ≥ opposite_lowest + trail?}
        P -->|Yes| Q[Execute second buy]
        Q --> R{continuous?}
        R -->|Yes| E
        R -->|No| S[State = Done]
        P -->|No| F

        H -->|Done| R
        S --> F
    end

    style EXIT fill:#f9f
    style K fill:#9f9
    style Q fill:#9f9
Loading

State transitions (simplified):

stateDiagram-v2
    [*] --> WaitingFirst
    WaitingFirst --> FirstBuyPending : trigger (one side)
    FirstBuyPending --> FirstBought : first buy OK
    FirstBuyPending --> WaitingFirst : first buy fail
    FirstBought --> WaitingFirst : second buy OK + continuous
    FirstBought --> Done : second buy OK + !continuous
    Done --> WaitingFirst : continuous (next round)
    Done --> [*] : market end or exit
Loading

Components

Component Role
main_sports_trailing.rs Entry point: parse args, load config, authenticate, resolve market by slug, run the state-machine loop.
PolymarketApi get_market_by_slug, get_market (tokens, end_date_iso), get_price (BUY/SELL per token).
Trader execute_buy(BuyOpportunity) — places a market buy (or simulates it when --simulation).
Config slug, continuous, trailing_stop_point, trailing_shares, check_interval_ms, plus Polymarket API credentials.

Configuration (reference)

  • --simulation / --no-simulation — If simulation, no real orders are sent.
  • --config <path> — Config file (default: config.json).

Relevant config fields:

  • polymarket: gamma_api_url, clob_api_url, api_key, api_secret, api_passphrase, private_key, optional proxy_wallet_address, signature_type.
  • trading: slug (required), continuous, trailing_stop_point, trailing_shares, check_interval_ms.

Setup

  1. Install Rust (if needed):

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  2. Build:

    cargo build --release
  3. Configure: Create or edit config.json with:

    • polymarket: gamma_api_url, clob_api_url, api_key, api_secret, api_passphrase, private_key
    • Optional: proxy_wallet_address, signature_type (1 = POLY_PROXY, 2 = GNOSIS_SAFE)
    • trading:
      • slug (required) — market slug, e.g. "nfl-team-a-vs-team-b"
      • continuoustrue = repeat trail/buy both sides until market ends; false = one pair per market
      • trailing_stop_point (e.g. 0.03)
      • trailing_shares (e.g. 10)
      • check_interval_ms (e.g. 1000)

Notes

  • The bot runs until the market end time or you stop it (Ctrl+C).
  • Simulation mode logs trades but does not place orders.
  • First buy uses at least $1 cost or trailing_shares, whichever is larger (in share terms); second buy uses the same number of shares as the first.

Security

  • Do not commit config.json with real keys or secrets.
  • Prefer simulation and small sizes when testing.
  • Monitor logs and balances when running in production.

To-do

  • Optional limit orders instead of market-only for first/second buy.
  • Configurable minimum time remaining before placing a buy (e.g. skip last N seconds).
  • Support multiple slugs or a list of markets in one run.
  • Logging/export of trailing state (low/high, trigger levels) for debugging and backtests.
  • Optional webhook or notification on first buy / second buy / errors.
  • Health check / readiness probe for running under a process manager.
  • More robust handling of API rate limits and transient failures (retries, backoff).

About

sports trading bot for polymarket

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Rust 100.0%