Polymarket Bot Tutorial · Chapitre 15 sur 32
Sports microstructure bots sur Polymarket : edge en cours de match, mispricing basé sur le score, le tag NBA (745) et le tag Tennis (864), sources de live data, et patterns d’exécution pour les sports markets à haute fréquence.
Ce que couvre ce chapitre
Les sports markets sont le segment non politique le plus constamment actif sur Polymarket. Les bots qui fonctionnent se répartissent en deux catégories bien distinctes : les pre-game line-catchers, qui tradent une fois la line fixée, et les in-game microstructure bots, qui réagissent aux mouvements du order book pendant le match. Ce chapitre couvre les deux, avec les tag IDs spécifiques, les sources de données et les budgets de latence qui s’appliquent à chacun.
Les sports markets sont le segment non politique le plus animé sur Polymarket. Le pattern d’exécution qui fonctionne combine un live-score feed (ESPN, PandaScore) avec des signaux de microstructure du order book. Ce chapitre couvre ce qui fonctionne pour le NFL, le NBA, le soccer et le tennis en particulier, et en quoi l’esports diffère.
- Pourquoi les sports markets sont tradeable
- Pre-game vs in-game (bots différents)
- Tag IDs vérifiés (745 NBA, 864 Tennis)
- Sources de données : ESPN, official APIs, on-screen
- Latency budget pour l’in-game
- Le piège du 0.99 / 0.01
- Code : subscribe à un games book et réagir
Pourquoi les sports markets sont tradeable
Les sports markets se règlent dans des délais définis (de quelques heures à quelques jours), disposent de live data publiques, et attirent un flux d’ordres continu pendant les matchs. Ces trois éléments sont nécessaires pour qu’un market soit tradeable - les markets politiques n’ont pas de "defined timeframe", les weather markets n’ont pas de "continuous flow", et les tournois obscurs n’ont pas de "public live data".
La population de traders sur les sports markets est aussi plus diversifiée que sur, par exemple, les election markets. Les parieurs sportifs occasionnels pricent de manière émotionnelle ; les traders informés corrigent vers la fair value au fil du match. L’écart entre les deux constitue l’edge du bot.
La distribution du volume est inégale : un dimanche NFL peut faire tourner des centaines de millions de dollars sur les sports markets de Polymarket ; un match de Saudi Pro League un mardi soir peut tomber sous les 50k$. Adaptez votre stratégie à l’action là où elle se trouve réellement.
Pre-game vs in-game (bots différents)
Deux designs de bots fondamentalement différents.
Pre-game line-catcher : scanner les markets qui viennent d’ouvrir, identifier les lines mal pricées par rapport à votre modèle ou au number d’un venue plus sharp, placer un buy FOK. Conserver jusqu’au in-play, parfois jusqu’au dénouement. Vitesse : minutes, pas secondes. Edge : modèle + line-shopping.
In-game microstructure : s’abonner au WebSocket du order book d’un match en live, réagir aux signaux d’imbalance + aux events de score en quelques secondes. Vitesse : secondes, pas minutes. Edge : latence + lecture du order flow.
Les deux partagent presque aucun code. Ils ont des risk profiles différents, des sources de données différentes, des exit strategies différentes. Un bot qui essaie de faire les deux finit par ne bien faire ни l’un ni l’autre ; choisissez-en un.
Tag IDs vérifiés (745 NBA, 864 Tennis)
Tag IDs de production vérifiés en mai 2026 pour les principales catégories de sports. Utilisez-les pour filtrer efficacement les appels /events.
| Sport / League | Tag ID | Tag slug | Notes |
|---|---|---|---|
| NBA | 745 | nba | highest volume Oct-Jun |
| NFL | 450 | nfl | peak Sun/Mon Sep-Feb |
| Tennis (all) | 864 | tennis | year-round, tournament cadence |
| Soccer (general) | 1059 | soccer | combine with sub-tags below |
| EPL | 739 | epl | |
| UCL | 2186 | uefa-champions-league | |
| Esports (all) | 702 | esports | LoL+CS2+Valorant+Dota |
| MLB | 1245 | mlb | peak Apr-Oct |
| NHL | 823 | nhl | peak Oct-Jun |
Les tag IDs sont stables d’une année à l’autre. De nouveaux tags sont ajoutés (Saudi Pro League, IPL), mais les anciens tags ne sont pas renumérotés.
Sources de données : ESPN, official APIs, on-screen
Pour les sports traditionnels, l’API gratuite de scoreboard ESPN couvre tout ce dont vous avez besoin : scores, période/clock, win-probability, parfois shot location. Aucune clé requise ; limitation uniquement au niveau IP. Pattern d’endpoint : https://site.api.espn.com/apis/site/v2/sports/<sport>/<league>/scoreboard.
Pour l’esports, ESPN n’a pas de couverture. Options : PandaScore (30-60 $/mois, standard du secteur), HLTV (CS2 seulement, scrapable, pas d’API), Liquipedia (maintenu par la communauté, scrapable, cadence de mise à jour plus lente).
Les on-screen feeds (payer un flux TV et lire le scorebug via OCR) fonctionnent, mais sont lourds en exploitation. Recommandé uniquement si vous avez une stratégie qui nécessite des mises à jour en moins de 3 secondes sur un sport qu’aucune API ne couvre en temps réel.
Latency budget pour l’in-game
Le budget de latence end-to-end pour un in-game reactive bot.
- Le score event se produit : t=0
- Le source feed le reflète : t+3-15s (ESPN : ~10s ; PandaScore : ~3s)
- Votre bot lit le feed : t+10-16s
- Le bot décide l’action : +50ms
- L’ordre FOK est placé : +200-500ms
- Matché sur le CLOB : +300-1000ms (network + matching)
Total : 11-17 secondes. Les firms professionnelles les plus rapides atteignent 3-5 secondes end-to-end avec des premium feeds payants et des VPS co-localisés. Les retail bots tournant sur des hosts standards et l’ESPN gratuit sont du côté le plus lent.
Les stratégies qui nécessitent moins de 5 secondes ne sont pas viables pour le retail. Les stratégies qui fonctionnent dans une fenêtre de 10 à 17 secondes sont : line-catching après un score, fading des sur-réactions, late-game certainty plays.
Le piège du 0.99 / 0.01
L’échec in-play le plus courant d’un sports bot : acheter le heavy favorite à 0.99 avec une minute restante, en espérant un easy +1¢. Trois raisons expliquent l’échec.
Premièrement, la probabilité implicite de 1 % de l’underdog n’est pas nulle - les comeback tardifs se produisent avec une fréquence non négligeable. Une victoire certaine à 99,5 %, jouée 200 fois, produit une perte pour une position pleine.
Deuxièmement, le spread à 0.99/0.01 signifie que vous payez 99c par share, gagnez 1c en cas de succès, perdez 99c lors de la rare inversion. Le risk-reward est brutal.
Troisièmement, le bot qui utilise un GTC sell à 0.999 remplira rarement - il n’y a pas d’acheteurs à ce prix. La position va jusqu’au dénouement. Si elle gagne, vous avez gagné 1c. Si l’inversion se produit, vous perdez 99c.
Le piège coûte de l’argent réel à des builders qui n’ont pas fait le calcul. Restez à l’écart des markets pricés à 0.95+ sauf si votre stratégie est spécifiquement conçue pour le redemption-arbitrage profile.
Code : subscribe à un games book et réagir
Référence : subscribe au WebSocket d’un match NBA spécifique, logger les book updates, déclencher un FOK sur signal d’imbalance.
import websocket, json
THRESHOLD = 0.5 # imbalance level to trigger
def on_message(ws, message):
msg = json.loads(message)
if msg.get("event_type") != "book": return
bids = msg.get("bids", [])
asks = msg.get("asks", [])
bid_depth = sum(float(b["price"]) * float(b["size"]) for b in bids[:5])
ask_depth = sum(float(a["price"]) * float(a["size"]) for a in asks[:5])
total = bid_depth + ask_depth
if total < 100: return # too illiquid
imb = (bid_depth - ask_depth) / total
if abs(imb) > THRESHOLD:
print(f"signal imb={imb:.2f} bid={bid_depth:.0f} ask={ask_depth:.0f}")
# fire FOK here
ws = websocket.WebSocketApp(
"wss://ws-subscriptions-clob.polymarket.com/ws/market",
on_open=lambda ws: ws.send(json.dumps({"type":"Market","markets":["<CONDITION_ID>"]})),
on_message=on_message
)
ws.run_forever()
Ajouts en production : cooldown entre les déclenchements, per-token inventory cap, kill sur book stale (aucun message en 30s).





