Продукты
Безлимитные прокси от $19/мес Ротационные прокси от $49/мес ISP прокси от $33/мес Персональные прокси от $3.50/мес UDP прокси от $5/мес Попробовать прокси
По целям
Парсинг и данные ИИ-сервисы Соцсети и мессенджеры Медиа и развлечения Все задачи →
Цены
Полная таблица цен Все 20 стран Гарантия возврата
Ресурсы
Блог MCP-сервер Инструкции по настройке Частые вопросы Для бизнеса О сервисе Партнёрская программа
Русский
English Русский
← Блог PapaProxy.net

Как построить торгового бота на API Polymarket

Отправить один ордер на Polymarket — работа на вечер. Удерживать бота живым месяцами — другая задача: учётные данные, зависящие от типа аккаунта, сеттлмент, происходящий уже после матчинга, heartbeat, который отменяет вашу книгу, если он прекратился, и рестарты, отвечающие HTTP 425 вместо привычной ошибки.

Автоматизация · API и данные 9 августа 2026 5 минут Alex Young Alex Young Технический специалист
Ключевые выводы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 нужны оба уровня его аутентификации плюс подпись самого ордера. У других механизмов площадки — релеера, моста — свои отдельные схемы, так что «аутентифицированный» здесь не означает что-то одно единообразное. Практический вывод: рыночную половину бота можно построить, протестировать и запустить до того, как вы вообще коснётесь приватного ключа.

Торговая автоматизация здесь раскладывается на шесть слоёв, отказывающих независимо, и только первый — про отправку ордеров:

  1. Аутентификация — учётные данные, привязанные к типу аккаунта и кошельку с деньгами.
  2. Сборка ордера — шаг цены, минимальный размер, флаг отрицательного риска и подпись тела.
  3. Живость — heartbeat, отменяющий ваши стоящие ордера, если процесс встал.
  4. Сеттлмент — матчинг ещё не является ончейн-сделкой.
  5. Обработка отказов — отклонения, троттлинг, режимы рестарта и исходы, которые нельзя определить.
  6. Восстановление — пересборка состояния книги и аккаунта после разрыва.

Большинство ботов, умирающих в проде, умирают на слоях с третьего по шестой — много позже того, как заработал первый.

Как подписать и отправить ордер

Аутентификация двухуровневая. 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:

Python
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.