Все статьи
РуководстваPythonSDKAPI Polymarket

Python SDK для Polymarket в 2026 году (и уход с py-clob-client)

Если ваш код всё ещё импортирует ClobClient из py_clob_client, он построен на устаревшем пакете — как и большая часть кода для Polymarket, который напишет вам ИИ-ассистент. Вот актуальный SDK и как на него перейти.

10 мин чтения

Главное

Теперь 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
Реальное времяПодключение к каждому WebSocketsubscribe() объединяет потоки

Установка

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

  1. Составьте перечень всех вызовов Polymarket, включая прямые вызовы requests к Gamma и Data API. Они тоже входят в задачу — единый SDK их покрывает, и перенос их в SDK даёт основную пользу.
  2. Установите polymarket-client и удалите старые пакеты. Если держать оба, чтобы мигрировать постепенно, легко импортировать не тот символ client.
  3. Замените создание клиентов. Один AsyncSecureClient.create(...) заменяет старые клиенты для каждого сервиса и их раздельную работу с учётными данными.
  4. Замените доступ к словарю доступом к атрибутам. market["condition_id"] становится market.condition_id. Скучно, но именно здесь проверка типов начинает окупаться.
  5. Перепишите пагинацию на интерфейс пагинатора вместо ручных циклов по offset или курсору.
  6. Замените самописный код WebSocket на subscribe() и удалите свою логику heartbeat и переподключения.
  7. Сначала перезапустите пути только для чтения на публичном клиенте и только потом позволяйте чему-либо выставлять ордера.

В 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-дневного бесплатного пробного периода.

Читать дальше