Polymarket Bot Tutorial · Capitolo 8 di 32

Polymarket CLOB API per bot: endpoint REST per snapshot del order book, iscrizioni WebSocket per aggiornamenti in tempo reale, parsing di bids/asks, calcolo di mid-price e depth, esempi di codice.

Cosa copre questo capitolo

La CLOB API è il punto in cui gli ordini vengono firmati, inviati, matched e dove vive il order book. Polymarket ha due generazioni di SDK — la v1 deprecata e la v2 attuale. Questo capitolo copre solo la v2; la v1 non dovrebbe comparire in nessun bot che distribuisci nel 2026. Vediamo il percorso REST per lo snapshot, il canale WebSocket di update, i dettagli di parsing che mettono in difficoltà i nuovi builder e la logica di reconnect senza la quale un bot a lunga esecuzione finisce fuori sync nel giro di poche ore.

Questo è il capitolo 8 della nostra serie in 32 parti sulla costruzione di un Polymarket trading bot. Trattiamo l'argomento in profondità nelle sezioni qui sotto. I contenuti principali di ogni sezione vengono scritti e rilasciati capitolo per capitolo; le risposte FAQ e i riferimenti sono già completi e riflettono l'esperienza di produzione maturata gestendo il nostro trader.

  • CLOB v1 vs v2 (usa v2)
  • Snapshot REST del order book
  • WebSocket subscriptions: canali market e user
  • Parsing di bids/asks/depth
  • Calcolo di mid-price e best-bid/ask
  • Maker fees, taker fees, rebates
  • Code: connect WS e process price-change events
  • Reconnect e gap-handling

CLOB v1 vs v2 (usa v2)

Polymarket mantiene due generazioni di SDK. La v1 (@polymarket/clob-client su npm, py-clob-client <0.30) è deprecata e manca di diversi order types aggiunti nel 2024. La v2 (@polymarket/clob-client-v2 v1.0.2 in Node, py-clob-client 0.34.6+ in Python) è lo standard attuale.

Tre differenze concrete. La v2 supporta il flag negRisk per i mercati multi-outcome — richiesto da quando il NegRisk exchange è stato lanciato alla fine del 2024. La v2 include tipi TypeScript per le forme dei messaggi WebSocket; la v1 restituisce any. La v2 gestisce nativamente il flusso di firma Gnosis Safe di agosto 2025; la v1 richiede glue di signing personalizzato.

Il resto di questo capitolo è scritto assumendo sempre la v2. Se in un tutorial vecchio vedi codice v1, consideralo rotto finché non è dimostrato il contrario — in particolare, il placement degli ordini sui mercati NegRisk sotto v1 può instradare silenziosamente verso il contract di exchange sbagliato.

Snapshot REST del order book

L'endpoint REST per lo snapshot restituisce il book completo di un singolo token in un dato momento.

GET https://clob.polymarket.com/book?token_id=<ERC1155_TOKEN_ID>

Forma della response:

{
  "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"}, ...]
}

I prezzi sono stringhe con 2-3 decimali; le size sono stringhe che rappresentano il numero di share (non dollari). I bids sono ordinati dal più alto al più basso, gli asks dal più basso al più alto. hash è un marker di deduplica — poll ripetuti di un book invariato restituiscono lo stesso hash e il tuo bot può saltare il processing.

Lo snapshot REST è la scelta giusta per lookup one-off (controllo del prezzo in fase decisionale). Per il monitoraggio continuo, usa il canale WebSocket qui sotto.

WebSocket subscriptions: canali market e user

Due canali WebSocket contano davvero.

Market channel: wss://ws-subscriptions-clob.polymarket.com/ws/market. Iscriviti a uno o più token; ricevi gli aggiornamenti del order book in tempo reale.

{"type":"Market","markets":["0xCondId1","0xCondId2"]}

I messaggi arrivano a ogni cambio. I tipi includono book (snapshot completo), price_change (delta), tick_size_change (raro) e last_trade_price (ultimo fill).

User channel: wss://ws-subscriptions-clob.polymarket.com/ws/user. Autenticato; ricevi gli eventi dei tuoi ordini — fill, partial fill, cancellazioni.

{"type":"User","auth":{"apiKey":"...","secret":"...","passphrase":"..."}}

Il canale user è il modo più pulito per rilevare un fill. Fare polling dell'endpoint REST degli ordini costa di più e può perdere cambi di stato tra un poll e l'altro; il WebSocket spinge l'evento nel momento in cui il matcher lo conferma.

Parsing di bids/asks/depth

Il order book è un elenco di livelli di prezzo con size aggregata. Ci sono due convenzioni di parsing da gestire correttamente.

Direzione dell'ordine: i bids sono ordini di acquisto (qualcuno vuole COMPRARE a questo prezzo). Quando il TUO bot vende, colpisce un bid. Quando il tuo bot compra, solleva un ask. La UI di Polymarket mostra la stessa direzione; alcuni altri exchange la invertono.

Sorting: i bids arrivano ordinati in modo decrescente (best bid per primo). Gli asks arrivano ordinati in modo crescente (best ask per primo). Il best bid è bids[0]; il best ask è asks[0]. Attenzione: il WebSocket pubblico a volte invia update parziali del book che non sono pre-ordinati — fai sempre un re-sort difensivo dopo ogni merge.

La depth a un livello è il valore transabile in dollari: price * size. La depth sui primi 5 livelli è una metrica di liquidità molto comune: sum(b.price * b.size for b in bids[:5]). Se la depth top-5 è sotto i $100, il book è illiquido e la maggior parte delle assunzioni di strategia si rompe.

Calcolo di mid-price e best-bid/ask

Tre punti di prezzo derivati che il tuo bot deve conoscere.

  • Best bid / best ask: bids[0].price e asks[0].price. I prezzi a cui puoi effettivamente tradare, per una share.
  • Mid-price: (best_bid + best_ask) / 2. Il centro matematico dello spread. Utile per la valutazione; non tradi mai al mid.
  • Prezzo VWAP per size N: scorri il book finché la size cumulata raggiunge N, poi restituisci il prezzo medio ponderato per size. Il costo reale per COMPRARE N share adesso, tenendo conto dello sweep nei livelli più profondi.

Edge case: un lato bid o ask vuoto (nessuno vende, o nessuno compra) significa che il book è one-sided. Nella market structure di Polymarket succede nei mercati risolti o quasi risolti, dove un lato è a 0.999 e nessuno offre liquidità dal lato perdente. Tratta best-bid = 0 o best-ask = 1 come segnali "do not trade".

Maker fees, taker fees, rebates

Polymarket usa un modello di fee maker-taker. Numeri a maggio 2026:

  • Taker fee: 0 (zero) — gli ordini che sollevano liquidità già presente nel book non pagano fee. Nota che per le operazioni via proxy si applicano i costi di gas / network.
  • Maker rebate: piccolo valore positivo, erogato in modo programmatico per ogni rested order riempito nei mercati idonei al programma reward. Non tutti i mercati hanno rewards.
  • Mercati NegRisk: stessa struttura di fee ma su un contract di exchange separato; i rewards maturano separatamente.

La zero taker fee rende Polymarket molto diverso dai venue CFD tradizionali — la maggior parte del "costo" di trading è lo spread bid-ask stesso, non una fee esplicita. Per una strategia che attraversa lo spread a ogni trade, la spread tax è il vero costo; considera 1-3 centesimi round-trip sui book tipici, di più su quelli illiquidi.

I maker rebates valgono la pena solo quando i mercati idonei ai liquidity rewards si allineano con le idee di strategia. Il Capitolo 19 copre il liquidity-rewards farming come approccio dedicato.

Code: connect WS e process price-change events

Esempio Node minimale: connect, subscribe, logga ogni price-change event per 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));

Iscriversi a circa 30 token per connessione WebSocket è gestibile senza problemi. Oltre quel limite, distribuisci su più connessioni — il server a volte scarta le subscription grandi senza segnalare errore, producendo letture del book stale in modo silenzioso.

Reconnect e gap-handling

Una connessione WebSocket a lunga durata può cadere. Cloudflare cicla le connessioni ogni poche ore; le reti hanno momenti di buio; Polymarket a volte fa deploy. Pianifica tutto questo.

Strategia di reconnect: su close o error, attendi min(2^attempt, 30) secondi con jitter, poi fai di nuovo subscribe. Resetta il contatore degli attempt al primo messaggio ricevuto con successo dopo il reconnect.

Il gap-handling conta più della velocità di reconnect. Mentre il WebSocket era disconnesso, il book si è mosso. A ogni reconnect, rifai il fetch dello snapshot REST di ogni token sottoscritto e riconcilia: qualsiasi posizione aperta il cui book si è mosso in modo significativo richiede un nuovo state check, gli exit potrebbero dover scattare, gli alert potrebbero essere stale. Il caso "ho perso 30 secondi di aggiornamenti del book" è il killer silenzioso dei bot a lunga esecuzione — continuano a girare su uno stato obsoleto e piazzano ordini a prezzi che non esistono più.

Pattern difensivo: snapshot di ogni book sottoscritto una volta al minuto indipendentemente dallo stato del WebSocket, e considera il WS come una fast-path optimization sopra il polling dello snapshot.

Domande frequenti

Qual è l'endpoint Polymarket CLOB API?
L'endpoint base CLOB è https://clob.polymarket.com (REST) e wss://ws-subscriptions-clob.polymarket.com/ws/market (WebSocket). Questi sono gli endpoint V2 usati da @polymarket/clob-client-v2 e py-clob-client.
Mi serve una API key per leggere il order book?
No. Le letture del order book (snapshot e WebSocket subscriptions) sono pubbliche e non richiedono autenticazione. Serve una API key solo per piazzare/cancellare ordini e leggere dati specifici dell'account (posizioni, fill).
Quanto velocemente il WebSocket CLOB invia gli aggiornamenti di prezzo?
Alla velocità con cui gli ordini si matchano. I mercati attivi vedono update ogni poche centinaia di millisecondi; i mercati poco liquidi si aggiornano solo in presenza di ordini reali. Sia i cambi di depth sia gli eventi di trade passano dallo stesso canale WS - fai parse del tipo di evento per gestirli correttamente.
Come calcolo la mid-price di un Polymarket order book?
mid = (best_bid + best_ask) / 2 se entrambi esistono; altrimenti usa last_trade_price come fallback. Fai attenzione ai book sottili in cui best_bid è molto sotto best_ask - il mid può non avere significato. Considera sempre anche lo spread prima di trattare il mid come un fair price.
Qual è la maker fee su Polymarket nel 2026?
0% sulla maggior parte delle categorie. I maker guadagnano rebates pari al 20-25% delle taker fees. Le taker fees variano per categoria: 0,75% sport, 1,00% politics, 1,25% economics, 1,80% crypto. L'asimmetria tra rebate e fee è il motivo per cui i bot attivi quotano quasi sempre con limit orders invece che con market orders.
Come gestisco i disconnect del WebSocket?
Riconnettiti con exponential backoff (1s, 2s, 4s, massimo 30s), rifai subscribe sugli stessi mercati e rifetch uno snapshot REST per colmare ogni gap. Non fidarti mai di un order book stale - se sei stato disconnesso per più di 5 secondi, richiedi uno snapshot fresco prima di piazzare ordini.