Polymarket Bot Tutorial · Chapitre 8 sur 32
API Polymarket CLOB pour bots : endpoints REST pour les order book snapshots, subscriptions WebSocket pour les mises à jour en temps réel, parsing des bids/asks, calcul du mid-price et de la depth, exemples de code.
Ce que couvre ce chapitre
L'API CLOB est l'endroit où les orders sont signés, envoyés, matchés, et où vit l'order book. Polymarket a deux générations de SDK - la v1 obsolète et la v2 actuelle. Ce chapitre couvre uniquement la v2 ; la v1 ne devrait apparaître dans aucun bot que vous déployez en 2026. Nous passons en revue le chemin du snapshot REST, le channel de mise à jour WebSocket, les détails de parsing qui piègent les nouveaux builders, et la logique de reconnect sans laquelle un bot long-running se désynchronise en quelques heures.
- CLOB v1 vs v2 (utilisez v2)
- Order book REST snapshot
- WebSocket subscriptions : channels market et user
- Parsing bids/asks/depth
- Calcul du mid-price et du best-bid/ask
- Maker fees, taker fees, rebates
- Code : connecter WS et traiter les événements de price-change
- Reconnect et gestion des gaps
CLOB v1 vs v2 (utilisez v2)
Polymarket maintient deux générations de SDK. La v1 (@polymarket/clob-client sur npm, py-clob-client <0.30) est obsolète et manque plusieurs order types ajoutés en 2024. La v2 (@polymarket/clob-client-v2 v1.0.6 en Node, py-clob-client 0.34.6+ en Python) est le standard actuel.
Trois différences concrètes. La v2 prend en charge le flag negRisk pour les marchés à plusieurs issues - requis depuis le lancement de l'exchange NegRisk fin 2024. La v2 fournit des types TypeScript pour les formes des messages WebSocket ; la v1 renvoie any. La v2 gère nativement le flux de signature Gnosis Safe d'août 2025 ; la v1 nécessite un custom signing glue.
Le reste de ce chapitre est rédigé en supposant la v2 partout. Si vous voyez du code v1 dans un ancien tutorial, considérez-le comme cassé jusqu'à preuve du contraire - le placement d'ordres sur les marchés NegRisk en particulier sera silencieusement routé vers le mauvais exchange contract sous v1.
Order book REST snapshot
L'endpoint REST snapshot renvoie l'order book complet pour un token unique à un instant donné.
GET https://clob.polymarket.com/book?token_id=<ERC1155_TOKEN_ID>
Forme de la réponse :
{
"market": "0x...",
"asset_id": "5413...",
"timestamp": "1715600000000",
"hash": "0x...",
"bids": [{"price":"0.45","size":"120"}, {"price":"0.44","size":"380"}, ...],
"asks": [{"price":"0.47","size":"85"}, {"price":"0.48","size":"210"}, ...]
}
Les prices sont des strings avec 2 à 3 décimales ; les sizes sont des strings représentant des quantités de shares (pas des dollars). Les bids sont triés du plus haut au plus bas, les asks du plus bas au plus haut. hash est un marqueur de déduplication - des polls répétés d'un book inchangé renvoient le même hash et votre bot peut ignorer le traitement.
Le snapshot REST est le bon choix pour des consultations ponctuelles (vérification du prix au moment de la décision d'entrée). Pour une surveillance continue, utilisez le channel WebSocket ci-dessous.
WebSocket subscriptions : channels market et user
Deux channels WebSocket sont importants.
Channel market : wss://ws-subscriptions-clob.polymarket.com/ws/market. Abonnez-vous à un ou plusieurs tokens ; recevez les mises à jour de l'order book en temps réel.
{"type":"Market","markets":["0xCondId1","0xCondId2"]}
Les messages arrivent à chaque changement. Les types incluent book (snapshot complet), price_change (delta), tick_size_change (rare), et last_trade_price (dernier fill).
Channel user : wss://ws-subscriptions-clob.polymarket.com/ws/user. Authentifié ; recevez vos propres événements d'order - fills, partial fills, cancellations.
{"type":"User","auth":{"apiKey":"...","secret":"...","passphrase":"..."}}
Le channel user est la manière la plus propre de détecter un fill. Le polling de l'endpoint REST des orders coûte plus cher et peut manquer des changements d'état entre deux polls ; le WebSocket pousse l'événement dès que le matcher l'accepte.
Parsing bids/asks/depth
L'order book est une liste de niveaux de prix avec une size agrégée. Deux conventions de parsing sont à bien maîtriser.
Sens des ordres : les bids sont des ordres d'achat (quelqu'un veut ACHETER à ce prix). Quand VOTRE bot vend, il tape un bid. Quand votre bot achète, il prend un ask. L'interface Polymarket affiche le même sens ; certains autres exchanges l'inversent.
Tri : les bids arrivent triés par ordre décroissant (meilleur bid en premier). Les asks arrivent triés par ordre croissant (meilleur ask en premier). Le meilleur bid est bids[0] ; le meilleur ask est asks[0]. Attention : le WebSocket public envoie parfois des mises à jour partielles du book qui ne sont pas pré-triées - re-triez toujours de manière défensive après chaque merge.
La depth à un niveau est la valeur en dollars transigeable : price * size. La depth sur les 5 premiers niveaux est une métrique de liquidité courante : sum(b.price * b.size for b in bids[:5]). Si la depth des 5 premiers niveaux est inférieure à 100 $, le book est illiquide et la plupart des hypothèses de stratégie s'effondrent.
Calcul du mid-price et du best-bid/ask
Trois points de prix dérivés dont votre bot a besoin.
- Best bid / best ask :
bids[0].priceetasks[0].price. Les prix auxquels vous pouvez réellement trader, pour une share. - Mid-price :
(best_bid + best_ask) / 2. Le centre mathématique du spread. Utile pour la valorisation ; vous ne tradez jamais au mid. - Prix VWAP pour une taille N : parcourez l'order book jusqu'à ce que la size cumulée atteigne N, puis renvoyez la moyenne pondérée par la size. Le coût réel pour ACHETER N shares immédiatement, en tenant compte du sweep dans les niveaux plus profonds.
Cas limite : un côté bid ou ask vide (personne ne vend, ou personne n'achète) signifie que le book est one-sided. Dans la structure de marché de Polymarket, cela arrive sur les marchés resolved ou presque resolved où un côté est à 0.999 et personne n'offre de liquidité du côté perdant. Traitez best-bid = 0 ou best-ask = 1 comme des signaux « ne pas trader ».
Maker fees, taker fees, rebates
Pendant l'essentiel de son histoire, Polymarket n'a prélevé aucuns frais de trading. Cela a changé en 2026 : des frais ont d'abord été introduits sur les marchés crypto à 15 minutes en début d'année, étendus aux Sports le 30 mars 2026, puis déployés sur la plupart des catégories depuis. Tout tutoriel qui affirme encore que Polymarket est sans frais est dépassé - et se tromper là-dessus dévore discrètement une stratégie à haute fréquence. Voici comment fonctionne réellement le modèle, à la mi-2026.
D'abord, les deux côtés de chaque trade. Un maker est celui qui place un ordre limite passif qui attend dans le book ; un taker est celui qui envoie un ordre qui s'exécute immédiatement contre la liquidité existante. Les makers paient toujours zéro frais et touchent en plus un rebate ; seuls les takers paient un frais.
Le taker fee n'est pas un pourcentage fixe. Il suit une courbe qui dépend à la fois de la taille de l'ordre et du prix :
fee = shares × feeRate × price × (1 - price)
Le terme price × (1 - price) est maximal à un prix de 0,50 (un marché vraiment à pile ou face) et diminue vers 0 ou 1. Autrement dit : vous payez le plus de frais sur les marchés les plus incertains, et presque rien sur ceux quasiment tranchés. Le feeRate est fixé par catégorie :
- Crypto : feeRate 0,07 (le plus élevé, pic autour de 1,8 % effectif), maker rebate 20 %.
- Sports : feeRate 0,03 (pic autour de 0,75 %), maker rebate 25 %.
- Finance, Politics, Tech, Mentions : feeRate 0,04, maker rebate 25 %.
- Economics, Culture, Weather, général : feeRate 0,05, maker rebate 25 %.
- Geopolitics et grands événements mondiaux : 0, toujours sans frais.
Un exemple chiffré. Supposons que votre bot prenne 100 shares d'un marché crypto au prix de 0,50. Le frais est de 100 × 0,07 × 0,50 × (1 - 0,50) = 100 × 0,07 × 0,25 = 1,75 $. Prenez les mêmes 100 shares à 0,90 et le frais tombe à 100 × 0,07 × 0,90 × 0,10 = 0,63 $, parce que le prix est loin du milieu incertain. Pour un bot, la leçon est directe : prendre de la liquidité sur des marchés crypto et sports volatils et quasi équilibrés coûte le plus de frais - ce sont donc précisément les marchés où quoter en tant que maker (et toucher le rebate au lieu de payer le frais) rapporte le plus.
Au-delà du frais explicite, vous payez le spread bid-ask chaque fois que vous le traversez. Le spread est l'écart entre le meilleur prix d'achat et le meilleur prix de vente, et pour une stratégie qui entre et sort en tant que taker, cet écart est un coût réel qui s'ajoute au frais. Comptez 1 à 3 cents d'aller-retour sur les books typiques, davantage sur les illiquides. Les marchés NegRisk (l'exchange multi-issues) utilisent le même modèle de frais mais se règlent sur un contrat séparé, donc leurs rewards s'accumulent séparément. Le chapitre 19 couvre le liquidity-rewards farming, où toucher les maker rebates est la stratégie elle-même et pas seulement un effet secondaire.
Code : connecter WS et traiter les événements de price-change
Exemple Node minimal : connexion, subscription, journalisation de chaque événement de price-change pour un token.
import WebSocket from "ws";
const ws = new WebSocket("wss://ws-subscriptions-clob.polymarket.com/ws/market");
ws.on("open", () => {
ws.send(JSON.stringify({ type: "Market", markets: ["<CONDITION_ID>"] }));
});
ws.on("message", (data) => {
const msg = JSON.parse(data.toString());
if (msg.event_type === "price_change") {
console.log("price_change", msg.asset_id, msg.changes);
} else if (msg.event_type === "book") {
console.log("book snapshot", msg.bids?.[0], msg.asks?.[0]);
}
});
ws.on("close", () => console.log("closed"));
ws.on("error", (e) => console.error("err", e.message));
Abonnez-vous confortablement à jusqu'à environ 30 tokens par connexion WebSocket. Au-delà, répartissez sur plusieurs connexions - le serveur laisse parfois tomber de grosses subscriptions sans erreur, ce qui produit des lectures de book périmées de manière silencieuse.
Reconnect et gestion des gaps
Une connexion WebSocket long-running finira par se couper. Cloudflare recycle les connexions toutes les quelques heures ; les réseaux clignotent ; Polymarket déploie parfois des mises à jour. Anticipez-le.
Stratégie de reconnect : sur close ou error, attendez min(2^attempt, 30) secondes avec jitter, puis re-subscrivez. Réinitialisez le compteur de tentatives au premier message réussi après reconnexion.
La gestion des gaps compte plus que la vitesse de reconnect. Pendant que le WebSocket était déconnecté, le book a bougé. À chaque reconnexion, re-fetch le snapshot REST de chaque token souscrit et réconciliez : toute position ouverte dont le book a bougé de manière significative nécessite une nouvelle vérification d'état, les exits peuvent devoir se déclencher, les alarms peuvent être périmées. Le cas « j'ai raté 30 secondes de mises à jour du book » est le tueur silencieux des bots long-running - ils continuent à fonctionner sur un état obsolète et placent des ordres à des prix qui n'existent plus.
Pattern défensif : snapshot de chaque book souscrit une fois par minute, indépendamment de l'état du WebSocket, et traitez le WS comme une optimisation de fast-path au-dessus du polling de snapshot.










