Туторіал з бота Полімаркет · Розділ 8 із 32
Полімаркет CLOB API для botів: REST endpoints для order book snapshots, WebSocket subscriptions для real-time updates, parsing bids/asks, обчислення mid-price і depth, code samples.
Що охоплює цей розділ
CLOB API - це місце, де orders підписуються, надсилаються, match-аться, і де живе order book. У Полімаркет є два покоління SDK - застарілий v1 і поточний v2. У цьому розділі розглядається лише v2; v1 не має з’являтися в жодному bot, який ви випускаєте у 2026 році. Ми пройдемо шлях REST snapshot, канал WebSocket updates, деталі parsing, на яких спотикаються нові розробники, і reconnect logic, без якої long-running bot за кілька годин роз’їжджається із синхронізації.
- CLOB v1 vs v2 (use v2]
- REST snapshot біржового стакана
- WebSocket-підписки: канали market і user
- Парсинг bids/asks/depth
- Обчислення mid-price і best-bid/ask
- Maker fees, taker fees, rebates (комісії та винагороди)
- Code: підключення WS і обробка price-change events
- Перепідключення та обробка пропусків
CLOB v1 vs v2 (use v2]
Полімаркет підтримує два покоління SDK. v1 (@polymarket/clob-client на npm, py-clob-client <0.30) застарілий і не має кількох типів orders, доданих у 2024 році. v2 (@polymarket/clob-client-v2 v1.0.2 у Node, py-clob-client 0.34.6+ у Python) - поточний стандарт.
Три конкретні відмінності. v2 підтримує прапорець negRisk для markets із кількома outcome - це потрібно з моменту запуску NegRisk exchange наприкінці 2024 року. v2 постачається з TypeScript types для формату повідомлень WebSocket; v1 повертає any. v2 нативно обробляє signature flow Gnosis Safe від серпня 2025 року; v1 потребує custom signing glue.
Уся решта цього розділу написана з припущенням, що всюди використовується v2. Якщо ви бачите код v1 в старішому tutorial, вважайте його зламаним, доки не доведено протилежне - особливо placement orders у NegRisk markets під v1 може мовчки піти до неправильного exchange contract.
REST snapshot біржового стакана
REST snapshot endpoint повертає повний book для одного token у конкретний момент часу.
GET https://clob.polymarket.com/book?token_id=<ERC1155_TOKEN_ID>
Форма відповіді:
{
"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"}, ...]
}
Ціни подаються як strings із 2-3 знаками після коми; sizes - як strings, що представляють кількість shares (не долари). Bids відсортовані від вищої до нижчої ціни, asks - від нижчої до вищої. hash - це marker дедуплікації: повторні запити до незмінного book повертають той самий hash, і ваш bot може пропустити обробку.
REST snapshot - правильний вибір для разових перевірок (price check під час ухвалення рішення про вхід). Для безперервного моніторингу використовуйте канал WebSocket нижче.
WebSocket-підписки: канали market і user
Мають значення два канали WebSocket.
Market channel: wss://ws-subscriptions-clob.polymarket.com/ws/market. Підписуйтеся на один або багато tokens; отримуйте order-book updates у міру їх появи.
{"type":"Market","markets":["0xCondId1","0xCondId2"]}
Повідомлення приходять при кожній зміні. Типи включають book (повний snapshot), price_change (delta), tick_size_change (рідко) і last_trade_price (останнє виконання).
User channel: wss://ws-subscriptions-clob.polymarket.com/ws/user. Authenticated; отримуйте події власних orders - fills, partial fills, cancellations.
{"type":"User","auth":{"apiKey":"...","secret":"...","passphrase":"..."}}
User channel - найчистіший спосіб виявити fill. Polling endpoint REST для orders коштує дорожче і може пропускати зміни стану між запитами; WebSocket надсилає подію в момент, коли matcher її підтверджує.
Парсинг bids/asks/depth
Order book - це список цінових рівнів із агрегованим обсягом. Є дві конвенції parsing, які важливо зробити правильно.
Напрямок order: bids - це buy orders (хтось хоче КУПИТИ за цією ціною). Коли ВАШ bot продає, ви б’єте bid. Коли ваш bot купує, ви піднімаєте ask. Полімаркет UI показує той самий напрямок; на деяких інших exchanges він інвертований.
Сортування: bids приходять відсортованими за спаданням (найкращий bid першим). asks приходять відсортованими за зростанням (найкращий ask першим). Найкращий bid - це bids[0]; найкращий ask - asks[0]. Увага: public WebSocket іноді надсилає partial book updates, які не відсортовані заздалегідь - завжди перестраховуйтеся й повторно сортуйте після будь-якого merge.
Depth на рівні - це грошовий обсяг, який можна виконати: price * size. Depth на перших 5 рівнях - поширений metric ліквідності: sum(b.price * b.size for b in bids[:5]). Якщо depth на top-5 менший за $100, book є неліквідним, і більшість припущень strategy ламаються.
Обчислення mid-price і best-bid/ask
Три похідні цінові точки, які потрібні вашому bot.
- Best bid / best ask:
bids[0].priceіasks[0].price. Ціни, за якими ви реально можете торгувати, одна share. - Mid-price:
(best_bid + best_ask) / 2. Математичний центр spread. Корисний для valuation; ви ніколи не торгуєте по mid. - VWAP price for size N: проходьте book, доки cumulative size не досягне N, і повертайте size-weighted average price. Реальна вартість КУПІВЛІ N shares прямо зараз з урахуванням sweep у глибші рівні.
Крайній випадок: порожня сторона bid або ask (немає тих, хто продає, або немає тих, хто купує) означає, що book односторонній. У структурі markets Полімаркет це трапляється для resolved або майже resolved markets, де одна сторона стоїть на 0.999, а ніхто не пропонує ліквідність на стороні, що програла. Сприймайте best-bid = 0 або best-ask = 1 як сигнал «не торгувати».
Maker fees, taker fees, rebates (комісії та винагороди)
Полімаркет використовує fee model maker-taker. Значення станом на травень 2026 року:
- Taker fee: 0 (zero) - orders, що забирають існуючу book liquidity, не сплачують fee. Зверніть увагу, що витрати на gas / network застосовуються для proxy operations.
- Maker rebate: невеликий позитивний, programmatic, виплачується за кожен filled rested order у markets, що підпадають під reward-program. Не всі markets мають rewards.
- NegRisk markets: та сама fee structure, але на окремому exchange contract; rewards нараховуються окремо.
Нульова taker fee робить Полімаркет суттєво відмінним від традиційних CFD venues - більшість trading «cost» тут становить сам bid-ask spread, а не явна fee. Для strategy, що перетинає spread у кожній угоді, spread tax - це реальна вартість; припускайте 1-3 центи round-trip на типових books, більше - на неліквідних.
За maker rebates варто ганятися лише тоді, коли markets, що мають право на liquidity-rewards, збігаються з ідеями strategy. Розділ 19 присвячений liquidity-rewards farming як окремому підходу.
Код: підключення WS і обробка price-change events
Мінімальний Node приклад: підключитися, підписатися, логувати кожну подію price-change для одного 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));
Комфортно підписуватися на приблизно до 30 tokens на одне WebSocket connection. Понад це краще розподіляти навантаження на кілька connections - сервер іноді тихо відкидає великі subscriptions без помилки, що призводить до мовчазно застарілих reads book.
Перепідключення та обробка пропусків
Long-running WebSocket connection обов’язково обірветься. Cloudflare циклічно перезапускає connections кожні кілька годин; мережі «мигають»; Полімаркет іноді розгортає оновлення. Плануйте це заздалегідь.
Стратегія reconnect: при close або error зачекайте min(2^attempt, 30) секунд із jitter, а потім повторно підпишіться. Скидайте лічильник attempt після першого успішного повідомлення після reconnect.
Gap-handling важливіший за швидкість reconnect. Поки WebSocket був від’єднаний, book рухався. Після кожного reconnect повторно отримуйте REST snapshot для кожного підписаного token і звіряйте: будь-які open positions, чий book суттєво зрушив, потребують повторної перевірки стану, exits можуть вимагати спрацювання, alarms можуть бути застарілими. Сценарій «я пропустив 30 секунд book updates» - це тихий убивця long-running bots: вони продовжують працювати на застарілому стані й виставляють orders за цінами, яких уже не існує.
Defensive pattern: робіть snapshot кожного підписаного book раз на хвилину незалежно від стану WebSocket і розглядайте WS як fast-path optimization поверх polling snapshot.


