Polymarket Bot Tutorial · Rozdział 3 z 32
Wybierz swój Polymarket bot stack: Python (py-clob-client 0.34.6), Node.js (@polymarket/clob-client-v2 v1.0.2) albo Rust (bez oficjalnego SDK, budowa na ethers-rs). Zalety, wady, latency, przykłady kodu.
Co obejmuje ten rozdział
Wybór języka ma znacznie mniejsze znaczenie, niż większość builderów zakłada. Polymarket udostępnia te same REST i WebSocket endpoints każdemu językowi; wybór SDK głównie decyduje o tym, ile glue code napiszesz samodzielnie. Python i Node mają oficjalnie utrzymywane SDK; Rust nie ma, ale nadaje się do hot path. Ten rozdział omawia kompromisy, pokazuje to samo zadanie „fetch order book” w każdym języku, żeby różnice były konkretne, a na końcu przedstawia mixed-stack pattern, na który w praktyce decyduje się większość production botów.
- Framework decyzyjny
- Python (domyślny wybór]
- Node.js (full-stack devs)
- Rust (latency-critical hot path)
- Komendy setup dla każdego stacku
- Szkielet kodu: fetch order book w 3 językach
- Kiedy mieszać stacki (Python control plane + Rust hot path)
Framework decyzyjny
Trzy pytania rozwiązują 90% wyboru stacku.
- Czy masz już mocną, istniejącą biegłość? Jeśli codziennie piszesz w Pythonie, napisz bota w Pythonie. Jeśli codziennie piszesz w TypeScript, napisz bota w Node. Różnice w jakości SDK poniżej są realne, ale mniejsze niż koszt walki z nieznanym językiem.
- Czy strategia jest krytyczna pod względem latency? Jeśli twoja przewaga zależy od reakcji w czasie poniżej 50ms (5-minute crypto markets, market-making podczas newsów), hot path skorzysta na Rust lub Go. Większość strategii tego nie potrzebuje.
- Czy będziesz uruchamiać więcej niż jedną strategię? Jeden proces Pythona może wygodnie obsługiwać 10-20 marketów. Powyżej tego async Node albo rozdzielenie na osobne procesy w Pythonie skalują się lepiej.
Uczciwym domyślnym wyborem dla pierwszego bota jest Python. Zmieniaj go tylko wtedy, gdy wymuszają to zmierzone ograniczenia.
Python (domyślny wybór]
Python jest domyślnym wyborem, ponieważ SDK jest najbardziej kompletne, a pętla iteracji najszybsza. py-clob-client w wersji 0.34.6 (maj 2026) obejmuje każdy istotny endpoint CLOB v2: market i limit orders, warianty FOK/FAK/GTC, odczyt order book, odczyt balance/allowance oraz bezpośrednie operacje on-chain przez web3.py.
Zalety: dojrzałe SDK, łatwa analiza danych z pandas, duża społeczność, web3.py do odczytów on-chain. Wady: ergonomia async jest mniej wygodna niż w JavaScript, GIL ogranicza przyspieszenie wielordzeniowe (rzadko ma to znaczenie w bocie I/O-bound), czas startu na zimnych kontenerach jest powolny.
Polecany dla: 80% builderów. Zwłaszcza dla każdego, czyja strategia obejmuje backtesting, analizę statystyczną albo jakąkolwiek pracę z danymi obok execution.
Node.js (full-stack devs)
Node.js to drugi najlepiej wspierany stack. @polymarket/clob-client-v2 w wersji 1.0.2 pokrywa te same endpoints co Python SDK, z TypeScript types w całym kodzie. Async jest natywny i szybki; obsługa WebSocket jest świetna.
Zalety: najlepsza historia async, natywne TypeScript types, duży ekosystem dla HTTP + WS, łatwy deploy na tym samym Node runtime co web dashboard. Wady: precyzja liczb wymaga BigInt albo pracy na stringach dla dużych token IDs (ERC-1155 IDs mają 256 bitów), narzędzia danych odpowiedniki pandas są słabsze.
Polecany dla: builderów, którzy już utrzymują JavaScript stack i chcą jednego runtime. Również dla każdego, kto buduje dashboard obok bota — współdzielenie types między core bota a dashboardem Next.js usuwa całą klasę bugów.
Rust (latency-critical hot path)
Rust nie ma oficjalnego Polymarket SDK. Budujesz bezpośrednio przeciwko V2 REST i WebSocket APIs używając reqwest (HTTP), tokio-tungstenite (WebSocket) oraz ethers-rs lub alloy do signing. To mniej więcej dwa dni setupu zamiast 30 minut w Pythonie.
Zalety: natywne EIP-712 signing bez JS subprocess, sub-millisecond order construction, deterministyczny memory profile pod obciążeniem, brak GC pauses. Wady: brak SDK oznacza, że musisz zaimplementować samemu to, co użytkownicy Pythona dostają za darmo (parsowanie clobToken ID, walidację response schema, zarządzanie salt/nonce). Zysk w latency to 20-100ms względem dobrze zoptymalizowanego Pythona, co ma znaczenie tylko dla strategii sub-second.
Polecany dla: hot path market-making bota albo trade-firing leg bota do news-arb. Niemal nigdy dla całego bota.
Komendy setup dla każdego stacku
Minimalne komendy do działającego signed order przeciw mainnetowi (pojedynczy 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 Python, ~15 min Node, ~4-8 godzin Rust.
Szkielet kodu: fetch order book w 3 językach
To samo zadanie — pobranie order book dla tokena Polymarket — w każdym stacku. Wszystkie trzy trafiają do tego samego REST endpointu 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]);
Taka sama response shape we wszystkich trzech. Koszt Rust pojawia się wszędzie indziej — signing, order construction, error handling — a nie w read path.
Kiedy mieszać stacki (Python control plane + Rust hot path)
Pattern, do którego dochodzi wiele production botów: Python do wszystkiego, co wymaga decyzji, Rust do millisecond execution leg.
Architektura: proces Pythona odczytuje stan marketu, uruchamia logikę strategii i zapisuje mały plik komendy (np. {"action":"buy","token":"...","size":10,"price":0.45}) do Unix socket. Rust daemon nasłuchuje na tym socket, podpisuje order i wysyła go do CLOB. Proces Pythona może być wolny i wygodny; Rust daemon jest szybki i minimalistyczny.
Handoff jest kluczowy: przez odizolowanie signed-order step odzyskujesz crash budget Pythona bez poświęcania latency. Używamy dokładnie tego patternu w naszych production botach — Python emituje intencje, Node daemon na /tmp/clob.sock zajmuje się signing. Wersja Node daemona jest dobra dla sub-100ms; Rust zaczyna naprawdę zarabiać dopiero poniżej 50ms.











