Туторіал з бота Полімаркет · Розділ 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.

Часті запитання

Який endpoint Полімаркет CLOB API?
Базовий CLOB endpoint - https://clob.polymarket.com (REST) і wss://ws-subscriptions-clob.polymarket.com/ws/market (WebSocket). Це V2 endpoints, які використовують @polymarket/clob-client-v2 і py-clob-client.
Чи потрібен мені API key, щоб читати order book?
Ні. Reads order book (snapshots і WebSocket subscriptions) є public і не потребують authentication. API key потрібен лише для розміщення/скасування orders і читання account-specific data (positions, fills).
Наскільки швидко CLOB WebSocket надсилає price updates?
Так швидко, як відбувається match orders. На активних markets updates приходять кожні кілька сотень мілісекунд; на тонких markets - лише під час реальних orders. І зміни depth, і trade events проходять через той самий канал WS - аналізуйте event type, щоб обробляти кожен правильно.
Як обчислити mid-price order book Полімаркет?
mid = (best_bid + best_ask) / 2, якщо обидва існують; інакше використовуйте last_trade_price як fallback. Будьте обережні з тонкими books, де best_bid далеко нижчий за best_ask - тоді mid може бути беззмістовним. Завжди також враховуйте spread, перш ніж вважати mid справедливою ціною.
Яка maker fee на Полімаркет у 2026 році?
0% для більшості категорій. Makers отримують rebates, що дорівнюють 20-25% taker fees. Taker fees залежать від категорії: 0.75% sports, 1.00% politics, 1.25% economics, 1.80% crypto. Саме асиметрія rebate-vs-fee пояснює, чому активні bots майже завжди виставляють quotes через limit orders, а не market orders.
Як обробляти WebSocket disconnects?
Підключайтеся з exponential backoff (1s, 2s, 4s, max 30s), повторно підписуйтеся на ті самі markets і знову отримуйте REST snapshot, щоб заповнити будь-який gap. Ніколи не довіряйте застарілому order book - якщо ви були відключені більше ніж 5 секунд, запросіть свіжий snapshot перед розміщенням orders.