Ключевые выводыGamma, Data API и эндпоинты рыночных данных CLOB не требуют аутентификации; торговле в CLOB нужны выведенные через L1 учётные данные, заголовки L2 и подпись самого тела ордера.
- Gamma, Data API и эндпоинты рыночных данных CLOB не требуют аутентификации; торговле в CLOB нужны выведенные через L1 учётные данные, заголовки L2 и подпись самого тела ордера.
- Ставьте актуальный единый SDK для TypeScript или Python: и
py-clob-client, иpy-clob-client-v2отсылают к нему, а официальный клиент на Rust пока прежнего поколения. - Новые аккаунты используют депозитный кошелёк и обеспечение pUSD; типы «прокси» и Safe устарели, а современный клиент определяет тип аккаунта по адресу кошелька.
- Heartbeat ордеров — это dead-man switch: пропустите валидный heartbeat на 10 секунд, и все открытые ордера этих учётных данных будут отменены, причём проверка идёт каждые пять секунд, — отправляйте heartbeat раз в пять секунд, возвращая предыдущий
heartbeat_id. - Рестарты матчинг-движка отвечают
HTTP 425, после чего две минуты действует режим post-only;503сообщает о режиме cancel-only или post-only. Отступайте и меняйте то, что отправляете, а не ретрайте настойчивее. - Защищайте каждый рыночный ордер: сначала оцените уровень исполнения, затем отправляйте
max_price(для продажи —min_price) вместе сmax_spend, который ограничивает итог с комиссиями; без него комиссии начисляются сверхamount. - Матчинг — не расчёт: сеттлмент происходит в блокчейне позже, поэтому «сматчено» не финальный статус. А поскольку клиентского идентификатора ордера в этом API нет, сохраняйте подписанное намерение до отправки и сверяйтесь с открытыми ордерами и недавними сделками, когда исход неоднозначен.
- При переподключении считайте локальную книгу недействительной, переподпишитесь, дождитесь свежего снимка и только потом применяйте инкременты: порядкового номера для сшивки REST-снимка с пропуском в потоке не существует.
- Ордерные лимиты следуют за подписантом, поэтому больше адресов не даёт больше ордеров; лимиты чтения следуют за IP — и только эта сторона масштабируется горизонтально.
Краткое содержание подготовлено с помощью ИИ.
Что нужно боту помимо вызова ордера
API Polymarket для автоматической торговли охватывает три хоста, и бот обращается ко всем. Gamma отвечает, что существует, — рынки, condition ID, ID токенов, которыми вы торгуете. CLOB отвечает, сколько это стоит, и принимает ордера. Data API отвечает, что держит кошелёк, — так вы сверяетесь после перезапуска.
Чтение обходится без церемоний: Gamma, Data API и эндпоинты рыночных данных CLOB — стакан, цены, спреды — не требуют аутентификации вовсе. Торговле в CLOB нужны оба уровня его аутентификации плюс подпись самого ордера. У других механизмов площадки — релеера, моста — свои отдельные схемы, так что «аутентифицированный» здесь не означает что-то одно единообразное. Практический вывод: рыночную половину бота можно построить, протестировать и запустить до того, как вы вообще коснётесь приватного ключа.
Торговая автоматизация здесь раскладывается на шесть слоёв, отказывающих независимо, и только первый — про отправку ордеров:
- Аутентификация — учётные данные, привязанные к типу аккаунта и кошельку с деньгами.
- Сборка ордера — шаг цены, минимальный размер, флаг отрицательного риска и подпись тела.
- Живость — heartbeat, отменяющий ваши стоящие ордера, если процесс встал.
- Сеттлмент — матчинг ещё не является ончейн-сделкой.
- Обработка отказов — отклонения, троттлинг, режимы рестарта и исходы, которые нельзя определить.
- Восстановление — пересборка состояния книги и аккаунта после разрыва.
Большинство ботов, умирающих в проде, умирают на слоях с третьего по шестой — много позже того, как заработал первый.
Как подписать и отправить ордер
Аутентификация двухуровневая. L1 — подпись приватным ключом кошелька поверх сообщения EIP-712; она доказывает владение и используется один раз, чтобы создать или вывести учётные данные API: apiKey, secret, passphrase. L2 — эти данные, применяемые как подпись HMAC-SHA256 к каждому аутентифицированному запросу и передаваемые пятью заголовками: POLY_ADDRESS, POLY_SIGNATURE, POLY_TIMESTAMP, POLY_API_KEY и POLY_PASSPHRASE. Приватный ключ остаётся у вас, торговля — некастодиальной.
Далее деталь, экономящая больше всего времени на отладке, прямо сформулированная в документации: даже при наличии заголовков L2 методы, создающие пользовательские ордера, всё равно требуют, чтобы пользователь подписал тело ордера. L2 аутентифицирует запрос; ордер — отдельно подписываемый объект. Бот с верными заголовками, который всё равно получает отказ, обычно не имеет этой второй подписи, а вовсе не сломан в учётных данных.
Модель аккаунта изменилась. Новые аккаунты Polymarket используют депозитный кошелёк в качестве смарт-кошелька, а прежние типы — прокси и Gnosis Safe — стали устаревшими; обеспечением служит pUSD. В актуальном едином SDK вы передаёте приватный ключ и адрес кошелька, а клиент сам определяет тип аккаунта: явная возня с signature_type, которую показывают старые туториалы, относится к предыдущему поколению клиентов. Торговый бот на Python начинается так — по официальному quickstart:
import asyncio, os
from polymarket import AsyncSecureClient
async def main():
client = await AsyncSecureClient.create(
private_key=os.environ["POLYMARKET_PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"], # ваш депозитный кошелёк
)
market = await client.get_market(slug="some-market-slug")
token_id = market.outcomes.yes.token_id
assert token_id is not None
# 1. Оценить уровень, до которого ордер дойдёт при текущей глубине книги.
estimated = await client.estimate_market_price(
token_id=token_id, side="BUY", amount="10", order_type="FAK",
)
# 2. Отправить с обеими защитами: худшая цена и жёсткий потолок траты.
response = await client.place_market_order(
token_id=token_id,
side="BUY",
amount="10", # номинал до комиссий
max_spend="10", # всего с комиссиями; без него комиссии начислятся сверху
max_price=estimated, # худшая приемлемая цена (для SELL — min_price)
order_type="FAK",
)
if not response.ok:
raise RuntimeError(response.message) # отказ несёт код и сообщение
print(response.order_id)
asyncio.run(main())
На что смотреть. Смысл примера — в двух защитах. max_price — это ограничение худшей цены, а не целевая цена: оно страхует от движения книги между вашей оценкой и отправкой, а для продажи используется min_price. max_spend ограничивает итог с учётом комиссий: SDK уменьшает подписываемую сумму покупки так, чтобы ордер вместе с комиссиями уложился в потолок, — а если параметр опустить, amount считается суммой до комиссий, и комиссии начислятся сверх неё. Для бота это важнее любого хелпера ожидания расчёта, потому что бот отправляет такие ордера без присмотра.
Идентификатор ордера приходит от сервера в response.order_id; клиентского идентификатора, который можно было бы задать самому и потом по нему искать, в этом API нет — это важно для восстановления, о чём ниже. Рыночный ордер никогда не остаётся в книге: всё, что не исполнилось, отменяется. И обратите внимание, о чём ответ умалчивает: матчинг и ончейн-расчёт — разные шаги, об этом в разделе про отказы.
Две рыночные детали, которые нужно читать, а не предполагать. Шаг цены различается у рынков — документированная сетка идёт от 0.1 до 0.0001, — поэтому запрашивайте его для каждого рынка, а не зашивайте: цена вне сетки отклоняется с INVALID_ORDER_MIN_TICK_SIZE. И часть рынков задерживает матчинг: спортивные применяют односекундную задержку размещения к исполняемым по рынку ордерам и вовсе снимают стоящие лимитные ордера в момент начала игры, а на отдельных крипто- и финансовых рынках действует тейкерская задержка в 250 мс. В течение любой такой задержки ордер находится в ожидании и не может быть отменён.
Когда лучше взять SDK вместо прямых запросов
Реализовать L1, L2 и подпись ордера самостоятельно можно, и для необычного языка или аудированного пути подписи это разумно. Во всех остальных случаях SDK для торговых ботов — прагматичный вариант по умолчанию: переписывать пришлось бы ровно то, в чём легче всего ошибиться незаметно, — разделители домена EIP-712, канонизацию HMAC, порядок полей в структуре ордера, единицы времени.
Проверьте, какое поколение вы ставите: их три, и туториалы ссылаются на все. И оригинальный py-clob-client, и его преемник py-clob-client-v2 теперь несут уведомления с рекомендацией перейти на единый SDK, который объединяет REST API и вебсокеты в одном пакете и используется в актуальной документации. Единый SDK сейчас покрывает TypeScript и Python; официальный клиент на Rust остаётся прежнего поколения — polymarket_client_sdk_v2. Если руководство показывает ClobClient с явными signature_type и funder — оно описывает старшее поколение: код, возможно, ещё работает, но вместе с ним вы наследуете его представления о типах аккаунтов.
Одна известная ловушка, которую стоит проверить до выбора типа аккаунта: в мае 2026 года на python- и rust-клиенты v2 завели баг — при типе подписи депозитного кошелька выведенный API-ключ привязывался к подписывающему EOA, а не к депозитному кошельку, из-за чего каждый ордер падал с HTTP 400 — the order signer address has to be the address of the API KEY. Убедитесь, исправлено ли это в той версии, которую ставите.
Где боты ломаются чаще всего
Разработка торговых ботов на Polymarket отказывает узнаваемыми кластерами. Знание их превращает часы диагностики в минуты.
Heartbeat — это dead-man switch, и работает он в обе стороны. У CLOB есть heartbeat ордеров: как только первый принят, площадка ожидает, что вы продолжите их слать, и если валидный heartbeat не приходит в течение 10 секунд, все открытые ордера этих учётных данных отменяются. Проверка выполняется каждые пять секунд, поэтому фактическая отмена может наступить на пять секунд позже таймаута. Документированный паттерн — отправлять heartbeat раз в пять секунд, возвращая heartbeat_id из предыдущего ответа, а на первом вызове передавая пустую строку; неверный или истёкший идентификатор даёт 400 с правильным значением в ответе. Включайте механизм осознанно: это лучшая защита от зависшего процесса, оставившего живые котировки в книге, и одновременно способ потерять всю книгу из-за паузы сборщика мусора, если выставить интервал впритык к лимиту.
У рестартов матчинг-движка свой протокол. В окне рестарта CLOB возвращает HTTP 425 (Too Early) на ордерных эндпоинтах. Это временное состояние, а не ошибка: отступайте экспоненциально, начиная с одной-двух секунд, и продолжайте. После каждого рестарта движок входит в режим post-only на две минуты: отмены принимаются, а новые ордера должны быть post-only — остальные отклоняются. Возможны и ответы 503, сообщающие о режиме cancel-only или post-only. Ничего из этого нельзя ретраить вслепую: каждый случай требует изменить то, что вы отправляете, а не отправлять то же самое чаще. Агрессивные ретраи вдобавок рискуют упереться в лимиты ровно в тот момент, когда движок вернётся.
Матчинг — ещё не расчёт. Ордера матчатся офчейн, затем оператор отправляет сделку в блокчейн, где контракт биржи переводит pUSD и сделка достигает финальности в Polygon. Принятый ответ по ордеру может прийти раньше, чем появится хоть один хеш транзакции. Машина состояний, считающая «сматчено» финальным статусом, будет неверно показывать позиции в промежутке — и ей нужен явный путь на случай, если ончейн-часть не завершится как ожидалось.
Отказы по ордеру кучкуются в предотвратимых причинах: цена вне сетки шага, размер ниже минимального для рынка, недостаточный баланс или разрешение, post-only-ордер, который пересёк бы рынок, fill-or-kill без исполнения. Запрашивайте шаг цены и минимальный размер у рынка до отправки, а после любого ончейн-депозита или апрува обновляйте кешированное биржей представление о вашем балансе и разрешениях.
Лимиты — это две системы сразу. Cloudflare применяет по IP burst- и устойчивые окна и сначала троттлит, а лишь потом отклоняет; поверх лежат токен-бакеты на подписанта с раздельными балансами ордеров и отмен, масштабируемые тиром по объёму, сообщающие состояние в Poly-RateLimit-Remaining, -Reset и -Tier. Читайте эти заголовки и не пытайтесь решить ордерный лимит инфраструктурой: он следует за подписантом, а не за адресом подключения. Цифры на стороне чтения и поведение лимитов на практике — в нашем тесте лимитов Polymarket.
Неоднозначному исходу нужны записи намерений, а не клиентские ID ордеров. Неоднозначен далеко не всякий отказ: документированное отклонение означает, что ордер до книги не дошёл, а 503 с указанием режима cancel-only или post-only имеет известную семантику. Но транспортный таймаут или неклассифицированный серверный сбой действительно оставляют исход неизвестным, и слепой ретрай в этом случае — путь к двум позициям вместо одной. Форма восстановления задана самим API: идентификатор ордера выдаёт сервер, поэтому клиентского идентификатора для последующего поиска не существует. Сохраняйте подписанное намерение до отправки — токен, сторону, цену, размер, отметку времени — и при неоднозначном результате сверяйтесь с открытыми ордерами и недавними сделками, чтобы понять, прошёл ли он. (Не переносите сюда привычки площадок, включая перпетуальный API самой Polymarket, где клиентский идентификатор ордера действительно есть.)
Состояние после переподключения. Обрывы вебсокета — штатная работа. Безопасное восстановление начинается с признания локальной книги недействительной в момент разрыва: переподписаться, дождаться свежего полного снимка книги, который канал рынка присылает при подписке, и только затем применять инкрементальные изменения цен. Универсального порядкового номера, которым можно было бы сшить REST-снимок с неизвестным пропуском в потоке, нет, поэтому склеивать по времени не пытайтесь. Для приватного состояния перед возобновлением стратегии запросите открытые ордера и недавние сделки. Пользовательский канал вдобавок ожидает heartbeat уровня приложения — текстовый фрейм PING примерно раз в десять секунд, на который сервер отвечает PONG, — а соединение, которое так и не подписалось, может быть закрыто.
География проверяется в момент ордера. Polymarket ограничивает торговлю в ряде юрисдикций, и ордера из ограниченных локаций отклоняются. Проверьте свою правомочность до того, как строить ордерный путь, и относитесь к этому как к юридическому ограничению, а не техническому.
Что автоматизируют чаще всего
Два сценария доминируют в вопросах, и оба ограниченнее, чем кажутся.
Арбитражный бот обычно целится либо во внутреннюю комплементарность одного рынка, где Yes и No должны в сумме стоить примерно 1, либо в спред между Polymarket и другой площадкой по одному вопросу о реальном мире. Первое — в основном задача про комиссии и задержку, и комиссии здесь уже не погрешность: площадка применяет тейкерские комиссии к сматченным сделкам в зависимости от типа рынка и ведёт программы мейкерских и тейкерских ребейтов, поэтому читайте конфигурацию комиссий из объекта рынка, а ребейты считайте частью арифметики, а не бонусом. Второе добавляет риск расчёта: две площадки могут разрешить один вопрос по-разному — другая формулировка, другие источники, другое время. Ни то ни другое не бесплатный обед, и эта статья не советует, стоит ли этим торговать.
Копитрейдинговый бот упирается в структурный факт: эндпоинта копитрейдинга у Polymarket нет. Есть публичный доступ на чтение — Data API возвращает позиции и активность любого кошелька по адресу — и ваш собственный аутентифицированный путь ордеров. Поэтому «копирование» — это конвейер, целиком принадлежащий вам: заметить изменение в отслеживаемом кошельке, принять решение, выставить свой ордер по своей цене. Всё, что между, — ваша задержка и ваше проскальзывание, а кошелёк, за которым вы следуете, не обязан оставаться прибыльным.
Именно на стороне чтения обоих сценариев кусаются бюджеты. Наблюдение за многими кошельками или рынками означает опрос эндпоинтов с лимитами по IP-адресу: /positions — 150 запросов за 10 секунд, /markets — 300, что заметно жёстче торгового пути. Эту сторону мы измеряли сами в отдельном тесте лимитов Polymarket, включая поведение площадки за пределом лимита и рост пропускной способности с числом адресов.
Отсюда единственный инфраструктурный вывод, который здесь уместен. Пропускная способность по ордерам привязана к подписанту и добавлением адресов не масштабируется. Пропускная способность чтения считается по IP, поэтому широкий список наблюдения либо замедляется, либо распределяется по исходящим адресам — для этого и нужны наши прокси для криптопроектов: выделенные IPv4-адреса, статичные на весь срок плана, к каждому из которых применяется своя документированная квота. И чтобы не оставалось двусмысленности: речь о стабильном исходящем адресе и масштабировании чтения для правомочной интеграции, а не о способе обойти географические ограничения торговли Polymarket.