Python SDK для Polymarket в 2026 году (и уход с py-clob-client)
Если ваш код всё ещё импортирует ClobClient из py_clob_client, он построен на устаревшем пакете — как и большая часть кода для Polymarket, который напишет вам ИИ-ассистент. Вот актуальный SDK и как на него перейти.
Главное
Теперь Polymarket выпускает единые SDK: polymarket-client для Python и @polymarket/client для TypeScript. Они заменяют py-clob-client, @polymarket/clob-client-v2, @polymarket/builder-relayer-client и @polymarket/builder-signing-sdk. Единый SDK для Rust находится в разработке.
Это важнее обычного обновления версии по одной причине: почти все примеры кода для Polymarket в интернете появились раньше. Статьи в блогах, ответы на Stack Overflow, примеры на GitHub и — поскольку модели обучались на этих материалах — код, который пишет ваш ИИ-ассистент, когда вы просите его сделать бота для Polymarket. Если вы ловили себя на отладке импортов, которых не существует, причина в этом.
Что на самом деле изменилось
Старый подход давал по клиенту на каждый сервис Polymarket. Вы импортировали клиент CLOB для стакана, обращались к Gamma по голому HTTP для поиска рынков, отдельно ходили в Data API за позициями и подключали пакет builder-signing, если нужны были транзакции через relayer. Четыре ментальные модели, четыре формата ошибок, четыре стиля пагинации.
Единый SDK сводит всё это в один клиент, покрывающий все части.
| Прежние клиенты | Единый SDK | |
|---|---|---|
| Пакеты | Несколько, по одному на сервис | Один |
| Части Polymarket | Отдельные API для каждого сервиса | Единый клиентский интерфейс |
| Модели данных | Сырые JSON-словари | Типизированные модели |
| Пагинация | Своя в каждом API | Единый согласованный пагинатор |
| Аутентификация и подпись | Реализовывать для каждого клиента | Хелперы SDK |
| Реальное время | Подключение к каждому WebSocket | subscribe() объединяет потоки |
Установка
pip install polymarket-client
# uv add polymarket-client
# poetry add polymarket-clientИмя пакета и импорт различаются
Устанавливаете вы polymarket-client, а импортируете из polymarket. Об это спотыкаются на первой же строке, и это же надёжный способ распознать сгенерированный код, который никто не запускал: если во фрагменте есть import polymarket_client, его никто не выполнял.
Четыре клиента — выбирайте осознанно
| Клиент | Публичные данные | Торговля | Реальное время | Для чего |
|---|---|---|---|---|
AsyncPublicClient | Да | Нет | Да | Боты, сборщики данных |
AsyncSecureClient | Да | Да | Да | Торговые боты |
PublicClient | Да | Нет | Нет | Скрипты, блокноты |
SecureClient | Да | Да | Нет | Скрипты, которые торгуют |
Реальное время — только в асинхронных клиентах
PublicClient и SecureClient не реализуют subscribe(). Если вы собираетесь получать поток обновлений стакана — а любой серьёзный бот должен, — нужен один из асинхронных клиентов. Выбрать синхронный клиент в начале и обнаружить это позже — досадный рефакторинг.
import asyncio
from polymarket import AsyncPublicClient
async def main() -> None:
async with AsyncPublicClient() as client:
pages = client.list_markets(closed=False)
first = await pages.first_page()
for market in first.items:
print(market.slug)
asyncio.run(main())Публичным данным учётные данные не нужны, так что стройте и тестируйте всё, что можно, на AsyncPublicClient, прежде чем добавлять ключ. Поиск рынков, парсинг, пагинацию, генерацию сигналов и отступ можно отработать, ничем не рискуя.
Пагинация
Один интерфейс пагинатора во всех методах получения списков. Три способа его использовать — в зависимости от того, важны ли вам границы страниц:
pages = client.list_markets(closed=False, page_size=10)
# 1. Page at a time — use this when you need to control pacing
# against the tight /markets rate limit (300 req / 10s).
async for page in pages:
for market in page.items:
...
# 2. Item at a time, boundaries ignored.
async for market in pages.iter_items():
...
# 3. Manual, resumable.
page = await pages.first_page()
if page.next_cursor:
nxt = await pages.from_cursor(page.next_cursor).first_page()next_cursor непрозрачен — храните его как есть
Не разбирайте, не декодируйте и не конструируйте курсоры. Сохраняйте строку без изменений, если хотите позже продолжить длинный обход, и не передавайте её, чтобы начать с начала. Собственноручно собранный курсор работает ровно до тех пор, пока не изменится кодировка.
Типизированные модели
Методы возвращают настоящие типы, а не словари, и они экспортируются из пакета верхнего уровня:
from polymarket import Event, Market, OrderBook, PriceHistoryPointЭто наименее эффектное улучшение и, вероятно, самое ценное. В старых клиентах переименованное или отсутствующее поле всплывало как KeyError глубоко в цикле стратегии во время выполнения — часто в продакшене, часто с открытой позицией. Типизированные модели переносят эту ошибку туда, где ей место.
Подписки в реальном времени
subscribe() объединяет несколько потоков в единый поток типизированных событий — это настоящее улучшение по сравнению с ручным управлением несколькими соединениями WebSocket.
from polymarket.streams import MarketSpec, SportsSpec
async with await client.subscribe(
[MarketSpec(token_ids=[token_id]), SportsSpec()],
) as stream:
async for event in stream:
# MarketBookEvent | MarketPriceChangeEvent
# | MarketLastTradePriceEvent | MarketTickSizeChangeEvent
# | MarketBestBidAskEvent | NewMarketEvent
# | MarketResolvedEvent | SportsEvent
handle(event)SDK берёт на себя heartbeat, кадрирование и переподключения, которые иначе пришлось бы реализовывать самому, — включая требование отправлять PING каждые 10 секунд при прямом соединении. Подробности — в руководстве по WebSocket.
Выставление ордера
market = await client.get_market(slug="<market-slug>")
token_id = market.outcomes.yes.token_id
assert token_id is not None
response = await client.place_market_order(
token_id=token_id,
side="BUY",
amount="10", # pUSD to spend, not shares to buy
)
if not response.ok:
raise RuntimeError(response.message)
# Settlement is on-chain and asynchronous.
hashes = await client.wait_for_order_fill_settlement(response)
# Reconcile rather than assuming.
page = await client.list_positions(market=[market.condition_id]).first_page()
position = next((p for p in page.items if p.token_id == token_id), None)amount — это сумма, а не размер
place_market_order(amount="10") означает потратить до 10 pUSD, а не купить 10 акций. На контракте, торгующемся по 0.20, это примерно 50 акций. Неправильно понять это — простой способ открыть позицию в пять раз больше задуманной.
Миграция с py-clob-client
- Составьте перечень всех вызовов Polymarket, включая прямые вызовы
requestsк Gamma и Data API. Они тоже входят в задачу — единый SDK их покрывает, и перенос их в SDK даёт основную пользу. - Установите
polymarket-clientи удалите старые пакеты. Если держать оба, чтобы мигрировать постепенно, легко импортировать не тот символclient. - Замените создание клиентов. Один
AsyncSecureClient.create(...)заменяет старые клиенты для каждого сервиса и их раздельную работу с учётными данными. - Замените доступ к словарю доступом к атрибутам.
market["condition_id"]становитсяmarket.condition_id. Скучно, но именно здесь проверка типов начинает окупаться. - Перепишите пагинацию на интерфейс пагинатора вместо ручных циклов по offset или курсору.
- Замените самописный код WebSocket на
subscribe()и удалите свою логику heartbeat и переподключения. - Сначала перезапустите пути только для чтения на публичном клиенте и только потом позволяйте чему-либо выставлять ордера.
В TypeScript есть адаптеры подписантов
TypeScript SDK поставляется с адаптерами для Viem, Privy и Ethers v5, так что вы подключаете свою существующую библиотеку кошелька вместо реализации подписи, специфичной для CLOB. Если вы поддерживали собственного подписанта поверх старого пакета builder-signing, этот код теперь можно удалить.
Почему ваш ИИ-ассистент ошибается
Стоит сказать об этом прямо, потому что многие попадают сюда именно так. Попросите LLM написать код на Python для Polymarket — и очень часто получите импорты py_clob_client, создание ClobClient(...) и объекты OrderArgs. Модель не сломана — она воспроизводит подавляющее большинство кода для Polymarket, который когда-либо видела, а он появился раньше единых SDK.
- Сначала проверьте строку импорта.
from polymarket import ...— актуально;from py_clob_client...— нет. - Вставьте актуальную документацию в контекст. Polymarket публикует машиночитаемый Markdown на
docs.polymarket.com/llms.txt, и у каждой страницы есть вариант.md. Дать модели настоящий материал лучше, чем спорить с ней. - Не доверяйте уверенному коду, который не запускается. Сгенерированный код часто смешивает старые и новые API в то, чего никогда не существовало.
Та же проблема касается поставщиков данных. Мы публикуем llms.txt, llms-full.txt и спецификацию OpenAPI и разрешаем ИИ-краулеры именно для того, чтобы ассистенты могли писать корректные интеграции с PolyTest без догадок. Некоторые поставщики блокируют эти краулеры — это законный выбор, но тогда ваш ассистент будет додумывать их API.
Чего SDK по-прежнему не умеет
Единый SDK — гораздо более удобный интерфейс к API Polymarket. Но он не меняет того, что в этих API есть, — а того, что создателям ботов нужно чаще всего, в них нет.
Исторического стакана нет. client.get_market() вернёт метаданные разрешившегося рынка, но его стакана уже нет: /book возвращает 404, а prices-history хранит лишь около одной точки в минуту. Ни метод SDK, ни тариф, ни учётные данные стакан не вернут.
Для бэктестинга нужны снимки, записанные, пока рынки работали. PolyTest предоставляет их для крипторынков Up/Down — 240M+ снимков на конкретный момент времени, 8 уровней глубины на сторону, метки времени с точностью до долей секунды, разрешившиеся рынки сохраняются. Это обычный REST API с заголовком X-API-Key, так что он встаёт в тот же асинхронный код рядом с SDK. Начните бесплатно или прочитайте, как создать бота, чтобы пройти весь путь.
Часто задаваемые вопросы
- Какой официальный Python SDK у Polymarket в 2026 году?
- Официальный Python SDK — polymarket-client: устанавливается командой pip install polymarket-client и импортируется как polymarket. Это единый SDK, который покрывает CLOB, Gamma и Data API, а также потоки реального времени через один клиентский интерфейс, и он заменяет py-clob-client. Аналог для TypeScript — @polymarket/client, а единый SDK для Rust находится в разработке.
- py-clob-client устарел?
- Его заменил единый SDK polymarket-client, как и TypeScript-пакеты @polymarket/clob-client-v2, @polymarket/builder-relayer-client и @polymarket/builder-signing-sdk. Polymarket публикует руководство по миграции существующих интеграций. Большинство руководств и сгенерированного ИИ кода всё ещё ссылаются на старые пакеты, потому что появились задолго до единых SDK.
- Какой клиент Python для Polymarket использовать для торгового бота?
- Используйте AsyncSecureClient. Всего клиентов четыре: AsyncPublicClient и PublicClient для публичных данных, AsyncSecureClient и SecureClient для торговли и доступа к аккаунту. Подписки в реальном времени есть только в асинхронных клиентах — синхронные не реализуют subscribe(), — так что любому боту, получающему поток обновлений стакана, нужен асинхронный клиент. Стройте и тестируйте на AsyncPublicClient, прежде чем добавлять учётные данные.
- Как использовать пагинацию в Python SDK Polymarket?
- Методы получения списков возвращают пагинатор. Перебирайте его напрямую, чтобы управлять страницами, вызывайте iter_items(), чтобы перебирать отдельные записи без учёта границ страниц, или используйте first_page() и from_cursor() для ручного обхода с возможностью продолжения. Значение next_cursor непрозрачно, поэтому храните его как есть, не разбирая и не конструируя, и не передавайте его, чтобы начать с первой страницы.
- Почему ChatGPT или Claude генерируют код для Polymarket, который не работает?
- Подавляющее большинство кода для Polymarket в обучающих данных появилось раньше единых SDK, поэтому модели склонны выдавать импорты py_clob_client, создание ClobClient и объекты OrderArgs. Сначала проверьте строку импорта: from polymarket import — актуально, from py_clob_client — нет. Polymarket публикует машиночитаемую документацию на docs.polymarket.com/llms.txt и вариант .md каждой страницы, так что вставить актуальную документацию в контекст эффективнее, чем раз за разом поправлять модель.
- Может ли SDK Polymarket получить исторические данные стакана?
- Нет. SDK — это интерфейс к API Polymarket, и он не может вернуть данные, которых в этих API нет. Метаданные разрешившегося рынка получить можно, но его стакан возвращает 404, а история цен хранится лишь примерно с одной точкой в минуту. Для бэктестинга нужны снимки на конкретный момент времени, записанные третьей стороной, пока рынки работали.
Получите исторические данные, которые Polymarket не хранит
PolyTest записывает крипторынки Polymarket Up/Down в процессе их работы — 240M+ снимков с 8 уровнями глубины стакана, метками времени с точностью до долей секунды и сохранёнными разрешившимися рынками. Начните с 3-дневного бесплатного пробного периода.
Читать дальше
Как создать торгового бота для Polymarket
Большинство руководств по ботам для Polymarket построены на SDK, которых больше не существует. Здесь — актуальный путь от начала до конца: что устанавливать в 2026 году, как на самом деле работает аутентификация, где пробелы в данных и какие сбои убивают ботов в первую неделю.
WebSocket в Polymarket: данные в реальном времени без обрывов
Опрос стакана — самый частый способ впустую сжечь бюджет лимита запросов. Вот четыре потока, параметры подписки, которые никто не документирует, и сбой, при котором ваш бот получает тишину и принимает её за затишье.
Карта API Polymarket: Gamma, CLOB и Data API
Новички теряют день на одной и той же проблеме: у Polymarket не один API, а четыре, и нужный эндпоинт редко оказывается в том, который вы попробовали первым. Вот полная карта.