Polymarket Bot Tutorial · Chapitre 3 sur 32
Choisissez votre stack Polymarket bot : Python (py-clob-client 0.34.6), Node.js (@polymarket/clob-client-v2 v1.0.6), ou Rust (pas de SDK officiel, basez-vous sur ethers-rs). Avantages, inconvénients, latency, exemples de code.
Ce que couvre ce chapitre
Le choix du langage est bien moins déterminant que la plupart des builders ne le pensent. Polymarket expose les mêmes endpoints REST et WebSocket à tous les langages ; le choix du SDK détermine surtout la quantité de glue code que vous devez écrire vous-même. Python et Node disposent tous deux de SDK officiellement maintenus ; Rust n’en a pas, mais reste tout à fait viable pour le hot path. Ce chapitre passe en revue les compromis, montre la même tâche de "fetch order book" dans chaque langage pour que la différence soit concrète, puis se termine par un pattern mixte que la plupart des bots en production finissent réellement par adopter.
- Cadrage de décision
- Python (choix par défaut)
- Node.js (full-stack devs)
- Rust (latency-critical hot path)
- Commandes de setup par stack
- Squelette de code : récupérer l'order book en 3 langages
- Quand mixer les stacks (Python control plane + Rust hot path)
Cadrage de décision
Trois questions permettent de trancher 90% du choix de stack.
- Avez-vous déjà une compétence forte ? Si vous codez en Python tous les jours, écrivez le bot en Python. Si vous codez en TypeScript tous les jours, écrivez le bot en Node. Les différences de qualité des SDK ci-dessous sont réelles, mais elles sont plus faibles que le coût de lutte avec un langage que vous ne maîtrisez pas.
- La stratégie est-elle critique en latency ? Si votre edge dépend d’une réaction en moins de 50ms (marchés crypto à 5 minutes, market-making pendant l’actualité), le hot path bénéficie de Rust ou Go. La plupart des stratégies n’ont pas besoin de cela.
- Allez-vous exécuter plus d’une stratégie ? Un seul processus Python peut gérer confortablement 10 à 20 marchés. Au-delà, un Node async ou un Python en plusieurs processus scale mieux.
Le choix par défaut honnête pour un premier bot est Python. Ne changez que lorsqu’une contrainte mesurée vous y oblige.
Python (choix par défaut)
Python est le choix par défaut parce que le SDK est le plus complet et que la boucle d’itération est la plus rapide. py-clob-client en version 0.34.6 (mai 2026) couvre tous les endpoints CLOB v2 importants : market et limit orders, variantes FOK/FAK/GTC, lecture de l’order book, lecture du balance/allowance, et opérations on-chain directes via web3.py.
Avantages : SDK mature, data analysis simple avec pandas, grande communauté, web3.py pour les lectures on-chain. Inconvénients : l’ergonomie async est plus pénible que dans JavaScript, le GIL limite les gains multi-core (ce qui compte rarement pour un bot I/O-bound), le temps de démarrage sur des containers froids est lent.
Recommandé pour : 80% des builders. En particulier pour toute personne dont la stratégie implique du backtesting, de l’analyse statistique ou du travail data en parallèle de l’exécution.
Node.js (full-stack devs)
Node.js est la stack la mieux supportée après Python. @polymarket/clob-client-v2 en version 1.0.6 couvre les mêmes endpoints que le SDK Python, avec des types TypeScript partout. L’async est native et rapide ; la gestion des WebSocket est excellente.
Avantages : meilleure histoire async, types TypeScript natifs, large écosystème HTTP + WS, déploiement facile sur le même runtime Node qu’un web dashboard. Inconvénients : la précision numérique exige BigInt ou une gestion en string pour les grands token IDs (les IDs ERC-1155 font 256 bits), les outils de data équivalents à pandas sont moins robustes.
Recommandé pour : les builders qui maintiennent déjà une stack JavaScript et veulent un seul runtime. Aussi : toute personne qui construit un dashboard en parallèle du bot - partager les types entre le core du bot et un dashboard Next.js élimine une classe de bugs.
Rust (latency-critical hot path)
Rust n’a pas de SDK Polymarket officiel. Vous construisez directement contre les APIs V2 REST et WebSocket en utilisant reqwest (HTTP), tokio-tungstenite (WebSocket), et ethers-rs ou alloy pour la signature. Comptez environ deux jours de setup contre 30 minutes en Python.
Avantages : signature EIP-712 native sans sous-process JS, construction d’ordres en sous-milliseconde, profil mémoire déterministe sous charge, pas de pauses GC. Inconvénients : l’absence de SDK signifie que vous réimplémentez ce que les utilisateurs Python obtiennent gratuitement (parsing des clobToken IDs, validation du schéma de réponse, gestion du salt/nonce). Le gain de latency est de 20 à 100ms par rapport à un Python optimisé, ce qui ne compte que pour les stratégies sub-secondes.
Recommandé pour : le hot path d’un bot de market-making, ou la jambe d’exécution d’un bot de news-arb. Presque jamais pour le bot entier.
Commandes de setup par stack
Commandes minimales pour obtenir un ordre signé fonctionnel sur mainnet (un seul endpoint CLOB v2).
Python :
python -m venv venv && source venv/bin/activate
pip install py-clob-client==0.34.6 web3 python-dotenv
# Set POLYGON_RPC, PRIVATE_KEY, POLY_FUNDER in .env
Node :
npm init -y
npm install @polymarket/[email protected] ethers dotenv
# Set POLYGON_RPC, PRIVATE_KEY, POLY_FUNDER in .env
Rust :
cargo new --bin pmt
cd pmt
cargo add tokio reqwest serde serde_json ethers alloy tungstenite tokio-tungstenite
# Hand-write signer + endpoint client; no SDK shortcut.
Time-to-first-order : ~10 min en Python, ~15 min en Node, ~4 à 8 heures en Rust.
Squelette de code : récupérer l'order book en 3 langages
La même tâche - récupérer l’order book d’un token Polymarket - dans chaque stack. Les trois utilisent le même endpoint REST CLOB v2.
Python (py-clob-client) :
from py_clob_client.client import ClobClient
client = ClobClient(host="https://clob.polymarket.com", chain_id=137)
book = client.get_order_book("<token_id>")
print(book.bids[:3], book.asks[:3])
Node (@polymarket/clob-client-v2) :
import { ClobClient } from "@polymarket/clob-client-v2";
const c = new ClobClient({ host: "https://clob.polymarket.com", chain: 137 });
const book = await c.getOrderBook("<token_id>");
console.log(book.bids.slice(0,3), book.asks.slice(0,3));
Rust (direct HTTP) :
let url = format!("https://clob.polymarket.com/book?token_id={}", token);
let book: serde_json::Value = reqwest::get(&url).await?.json().await?;
println!("{:?} {:?}", &book["bids"][..3], &book["asks"][..3]);
La même structure de réponse dans les trois cas. Le coût de Rust se situe partout ailleurs - signature, construction d’ordres, gestion des erreurs - pas sur le read path.
Quand mixer les stacks (Python control plane + Rust hot path)
Le pattern vers lequel convergent de nombreux bots en production : Python pour tout ce qui implique des décisions, Rust pour la jambe d’exécution en millisecondes.
Architecture : un processus Python lit l’état du marché, exécute la logique de stratégie, puis écrit un petit fichier de commande (par exemple {"action":"buy","token":"...","size":10,"price":0.45}) vers un Unix socket. Un daemon Rust écoute sur ce socket, signe l’ordre, puis l’envoie au CLOB. Le processus Python peut être lent et pratique ; le daemon Rust est rapide et minimal.
Le handoff est la clé : en isolant l’étape d’ordre signé, on récupère le crash budget côté Python sans sacrifier la latency. Nous utilisons exactement ce pattern dans nos bots de production - Python émet les intentions, un daemon Node sur /tmp/clob.sock gère la signature. La version Node du daemon est très bien pour du sub-100ms ; Rust ne devient vraiment rentable qu’en dessous de 50ms.












