Учебник по ботам Полимаркет · Глава 24 из 32

У Полимаркет Perps есть полноценный публичный API с официальными SDK для TypeScript и Python. В этой главе мы строим бота на реальном интерфейсе: аутентификация через прокси-ключ для торговли, рыночные данные по REST и WebSocket, ордера с тейк-профитом и стоп-лоссом, а также контроль рисков, который не даёт боту с кредитным плечом опустошить счёт.

Build your own theme park, free in your browserРеклама Реклама здесь
Перед началом работы. Размещение ордеров в Perps не разрешено из США, Канады, Кубы, Ирана, Северной Кореи, Сирии, Крыма, Донецка и Луганска, а polymarket.com блокирует и другие страны. Бот или зарубежный сервер этого не меняют. С кредитным плечом ошибка в коде быстро приводит к потере денег, поэтому тестируйте на минимальном размере. Впервые знакомитесь с Perps? Начните с руководства по Полимаркет Perps.

О чём эта глава

  • Ключевые цифры для разработчиков ботов
  • Как устроен API Perps
  • Шаг 1: установка SDK и открытие сессии
  • Шаг 2: чтение рыночных данных по REST и WebSocket
  • Шаг 3: ордера с тейк-профитом и стоп-лоссом
  • Шаг 4: каркас бота с контролем рисков в коде
  • Ошибки, выключатель мертвеца, правила для ботов и хостинг

Каждый метод SDK и каждый эндпоинт в этой главе взяты из документации Полимаркет по Perps (docs.polymarket.com/perps, прочитано 6 ноября 2026 г.). Наша собственная логика отмечена в комментариях, а функция стратегии является помеченной заглушкой.

Ключевые цифры для разработчиков ботов (на ноябрь 2026 г.)

ПараметрЗначение
Базовый URL RESThttps://api.perpetuals.polymarket.com
WebSocketwss://ws.perpetuals.polymarket.com/v1/ws
SDK для TypeScript@polymarket/client (с viem для подписи)
SDK для Pythonpolymarket-client (асинхронный)
Публичные данные/v1/info/*, без аутентификации
Приватное чтение/v1/account/* с заголовками polymarket-proxy и polymarket-secret
Подписанная запись/v1/trade/*, подпись EIP-712 прокси-ключом, действует 5 минут
Учётные данные сессииПо умолчанию истекают через неделю
Минимальный ордер$10 номинала; минимальный депозит 10 pUSD
Максимальный рыночный ордер$1 млн на рынках с плечом 50x и 20x, $500 тыс. на большинстве остальных, $50 тыс. на монетах с плечом 3x и 5x
Формат цены и размераДесятичные строки, не больше знаков после запятой, чем допускает рынок, и не более 5 значащих цифр
Максимальное плечо50x (BTC, ETH, USA500, US100), на остальных рынках 20x, 10x, 5x или 3x, для крупных позиций ниже
Комиссии (базовый уровень)Тейкер 0.040%, мейкер 0.0125%; для ANT в два раза дешевле
ФинансированиеЕжечасно, не более +/-4% в час
Триггеры TP/SLЦена маркировки, а не последняя сделка
Поддержание соединения WebSocketPing примерно каждые 25 секунд; считайте соединение устаревшим примерно после 65 секунд тишины
Актуальность тикераЗадержка до 10 секунд

Как устроен API Perps

Perps представляет собой гибридную биржу: сопоставление ордеров происходит offchain, а хранение средств и расчёты проходят в Polygon. Ончейн выполняются только депозиты и выводы, поэтому за ордер газ не платится. API состоит из трёх уровней:

  • Публичные данные (/v1/info/): инструменты, тикеры, стакан заявок, свечи, сделки, финансирование, комиссии. Ключ не нужен, географической блокировки нет.
  • Приватное чтение (/v1/account/): портфель, балансы, ордера, исполнения, настройки.
  • Подписанная запись (/v1/trade/): ордера, отмены, плечо, изолированная маржа, автоотмена. Каждый запрос на запись кодируется в MessagePack, хешируется keccak256 и подписывается прокси-ключом как типизированные данные EIP-712.

Подпись SDK выполняют за вас. Также есть спецификация OpenAPI (/api-spec/perps-openapi.json на сайте документации) и спецификация AsyncAPI для WebSocket.

Символы отличаются от примеров в документации. В документации указан BTC-PERP. Рабочий API возвращает BTC-USD, SP500-USD (USA500), NAS100-USD (US100), ANT-USD и так далее. Загрузите список инструментов, найдите нужный актуальный symbol и сохраните числовой id. Не копируйте ID из примеров: в рабочей среде у BTC ID 6, а у SP500 ID 1.

Шаг 1: установка SDK и открытие сессии

Установите SDK командой pip install polymarket-client или npm install @polymarket/client@latest viem. Боту нужны адрес вашего кошелька Полимаркет и приватный ключ подписанта, которому принадлежит аккаунт Perps (аккаунт привязан к EOA подписанта, а не к Safe). При открытии сессии выполняется одна подпись, которая авторизует новый прокси-ключ для торговли. Дальше каждый ордер подписывает он, так что ключ кошелька с вашими средствами никогда не торгует. Сохраните session.credentials в зашифрованном виде, чтобы позже возобновить сессию.

import asyncio
import os
from datetime import timedelta

from polymarket import AsyncSecureClient


async def main():
    client = await AsyncSecureClient.create(
        private_key=os.environ["PRIVATE_KEY"],
        wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
    )
    # One signature creates a proxy trading key. Orders are signed by the proxy,
    # not by your wallet key. Credentials expire after one week by default.
    session = await client.open_perps_session(
        expires_in=timedelta(days=1),
        label="perps-bot",
    )
    stored = session.credentials.model_dump(mode="json")  # keep it encrypted

    instruments = await client.fetch_perps_instruments()
    btc = next(i for i in instruments if i.symbol == "BTC-USD")
    print(btc.id, btc.max_leverage, btc.min_notional, btc.price_decimals)


asyncio.run(main())
import { createSecureClient } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";

const client = await createSecureClient({
  wallet: process.env.POLYMARKET_WALLET_ADDRESS!,
  signer: privateKey(process.env.PRIVATE_KEY!),
});

// One signature creates a proxy trading key. Orders are signed by the proxy,
// not by your wallet key. Credentials expire after one week by default.
const session = await client.openPerpsSession({
  expiresIn: 24 * 60 * 60 * 1000,
  label: "perps-bot",
});
const stored = session.credentials; // keep it encrypted

const instruments = await client.fetchPerpsInstruments();
const btc = instruments.find((i) => i.symbol === "BTC-USD");
if (!btc) throw new Error("BTC-USD not listed");
console.log(btc.id, btc.maxLeverage, btc.minNotional, btc.priceDecimals);

Для депозита из кода (deposit_to_perps / depositToPerps) дополнительно нужен ключ Relayer API, который выдаётся на polymarket.com в разделе Settings, API Keys. Проще и безопаснее пополнять счёт в веб-приложении и вообще не допускать бота к движению денег. С 5 ноября 2026 г. аккаунты, у которых есть адресная книга для вывода, могут выводить средства только на сохранённые адреса. Для дашбордов используйте ключ только для чтения (прокси с меткой read-only:, который отклоняет подписанные запросы на запись) и никогда не используйте для них торговый ключ. Хранение ключей разобрано в нашей главе о кошельках и аутентификации.

Шаг 2: чтение рыночных данных по REST и WebSocket

У тикера три цены: индексная (справедливая стоимость по данным фидов Pyth, Chainlink Data Streams, Hyperliquid и других), цена маркировки (по ней считаются PnL, маржа, ликвидация и TP/SL) и цена последней сделки (только для исполнения). Кроме того, тикер содержит ставку финансирования и время следующего начисления. Стройте сигналы на цене маркировки или на индексной цене.

# Inside your async main(), after Step 1 (btc is the BTC-USD instrument)
from polymarket import AsyncPublicClient
from polymarket.streams import PerpsBboSpec

client = AsyncPublicClient()

ticker = await client.fetch_perps_ticker(instrument_id=btc.id)
print(ticker.mark_price, ticker.index_price, ticker.funding_rate)

stream = await client.subscribe(PerpsBboSpec(instrument_id=btc.id))
async for event in stream:
    print(event.payload.bid_price, event.payload.ask_price)
// After Step 1 (btc is the BTC-USD instrument)
import { createPublicClient } from "@polymarket/client";

const client = createPublicClient();

const ticker = await client.fetchPerpsTicker({ instrumentId: btc.id });
console.log(ticker.markPrice, ticker.indexPrice, ticker.fundingRate);

const stream = await client.subscribe([{ topic: "perps.bbo", instrumentId: btc.id }]);
for await (const event of stream) {
  console.log(event.payload.bidPrice, event.payload.askPrice);
}

Без SDK подписаться можно напрямую через WebSocket сообщением {"id": 1, "req": "sub", "chs": ["bbo::6"]}. Среди каналов: bbo::<id>, book::<id>, trades::<id>, tickers::<id> и klines::<id>::1m. У каждого обновления есть порядковый номер sq: после пропуска или переподключения заново прочитайте состояние через REST. Для бэктестов list_perps_candles / listPerpsCandles загружает историю постранично (эндпоинт REST возвращает до 1 000 свечей за вызов).

Шаг 3: ордера с тейк-профитом и стоп-лоссом

У ордера есть side (BUY или SELL), quantity в единицах базового актива, необязательная price в pUSD и срок действия (gtc, ioc или fok). Для post-only нужен GTC; reduce-only может только уменьшать позицию. Отдельного флага лонга или шорта нет: если позиции нет, BUY открывает лонг, а SELL открывает шорт.

Брекет-ордер прикрепляет к входному ордеру один тейк-профит и один стоп-лосс. Они неактивны, пока вход не исполнится полностью, и отменяются, если вход отменён или исполнен лишь частично. Цены ниже гипотетические.

# Inside your async main(), after Step 1 (btc is the BTC-USD instrument)
from polymarket import PerpsTpSlTrigger

result = await session.place_order(
    instrument_id=btc.id,
    side="BUY",
    price="100000",
    quantity="0.01",
    time_in_force="gtc",
    take_profit=PerpsTpSlTrigger(trigger_price="104000"),
    stop_loss=PerpsTpSlTrigger(trigger_price="98000"),
)
print(result.order.id, result.order.status)
// After Step 1 (btc is the BTC-USD instrument)
import { OrderSide, PerpsTimeInForce } from "@polymarket/client";

const result = await session.placeOrder({
  instrumentId: btc.id,
  side: OrderSide.BUY,
  price: "100000",
  quantity: "0.01",
  timeInForce: PerpsTimeInForce.GTC,
  takeProfit: { triggerPrice: "104000" },
  stopLoss: { triggerPrice: "98000" },
});
console.log(result.order.id, result.tpSl.stopLoss?.orderId);

Для открытой позиции place_position_tp_sl / placePositionTpSl добавляет триггеры, которые закрывают всю позицию. Правила:

  • Триггеры отслеживают цену маркировки и отправляют ордер reduce-only. TP/SL позиции закрывает её по рынку, поэтому в тонком стакане заявок ждите проскальзывания.
  • На одном рынке допускается один тейк-профит и один стоп-лосс позиции. Чтобы перенести стоп, его нужно отменить и создать заново, и эта операция не атомарна.
  • Триггер, который цена маркировки уже пересекла, отклоняется; лимитные цены, слишком далёкие от цены маркировки, тоже не принимаются.

Чтобы опробовать работу с ордерами вручную до автоматизации, откройте рынок BTC на Полимаркет Perps и разместите минимально допустимый ордер. Когда вы увидите исполнения, комиссии и панель позиции своими глазами, ответы API станет проще читать.

Шаг 4: каркас бота с контролем рисков в коде

Каркас на Python ниже использует только документированные вызовы SDK; логика управления рисками наша. Три уровня защиты:

  1. Ограничение плеча. Плечо устанавливается на 3x или на максимум рынка, если он ниже, с изолированной маржой, а размеры, которые попадают в уровень риска с более низким лимитом плеча, отклоняются.
  2. Аварийные выключатели. Файл HALT, дневной лимит убытка 5% и выход при ликвидации. Выключатель закрывает позиции ордерами IOC reduce-only, отменяет оставшиеся ордера, а затем проверяет, что не осталось ни позиций, ни ордеров.
  3. Стоп на каждой позиции. Входы fill-or-kill исключают незащищённые частичные исполнения. После каждого исполнения выставляются стоп и тейк-профит позиции; если их отклоняют, позиция сразу закрывается.
import asyncio
import logging
import os
from datetime import timedelta
from decimal import Decimal, ROUND_DOWN

from polymarket import AsyncSecureClient, PerpsPositionTpSlTrigger

SYMBOL = "BTC-USD"                   # live API symbol; docs examples say "BTC-PERP"
LEVERAGE_CAP = 3                     # our cap, far below the 50x BTC allows
RISK_PER_TRADE = Decimal("20")       # pUSD we accept losing if the stop fills
STOP_PCT = Decimal("0.02")           # stop 2% from entry
TAKE_PCT = Decimal("0.04")           # take profit 4% from entry
MAX_NOTIONAL = Decimal("2000")       # hard cap per position, in pUSD
MAX_SLIPPAGE = Decimal("0.002")      # worst entry price: ask + 0.2%
MAX_FUNDING = Decimal("0.0005")      # skip longs if funding > 0.05% per hour
DAILY_LOSS_LIMIT = Decimal("0.05")   # kill switch at -5% of start equity
HALT_FILE = "/opt/perps-bot/HALT"    # touch this file to stop the bot


def fit(value: Decimal, decimals: int, sig: int = 5) -> str:
    """Round down to the market's decimals and to 5 significant figures."""
    v = value.quantize(Decimal(1).scaleb(-decimals), rounding=ROUND_DOWN)
    if v != 0:
        step = Decimal(1).scaleb(v.adjusted() - sig + 1)
        if step > Decimal(1).scaleb(-decimals):
            v = v.quantize(step, rounding=ROUND_DOWN)
    return format(v, "f")


def tier_cap(inst, notional: Decimal) -> int:
    """Max leverage allowed for this notional by the market's risk tiers."""
    cap = inst.max_leverage
    for tier in inst.risk_tiers:
        if notional >= Decimal(tier.lower_bound):
            cap = tier.max_leverage
    return cap


async def close_all(session):
    """Close every position with reduce-only IOC orders, then cancel the rest."""
    portfolio = await session.fetch_portfolio()
    for pos in portfolio.positions:
        if pos.size != 0:
            await session.place_order(
                instrument_id=pos.instrument_id,
                side="SELL" if pos.size > 0 else "BUY",
                quantity=abs(pos.size),
                time_in_force="ioc",
                reduce_only=True,
            )
    await session.cancel_all_orders()


async def kill_switch(session, reason: str):
    logging.error("KILL SWITCH: %s", reason)
    for attempt in range(3):
        await close_all(session)
        portfolio = await session.fetch_portfolio()
        open_orders = await session.fetch_open_orders()
        if not open_orders and all(p.size == 0 for p in portfolio.positions):
            return
        await asyncio.sleep(2)
    logging.critical("Positions still open after kill switch: act manually")


async def open_long(client, session, inst):
    ticker = await client.fetch_perps_ticker(instrument_id=inst.id)
    if Decimal(ticker.funding_rate) > MAX_FUNDING:
        return                                     # longs would pay too much
    book = await client.fetch_perps_book(instrument_id=inst.id, depth=10)
    if not book.asks:
        return
    ask = Decimal(book.asks[0].price)
    stop = ask * (1 - STOP_PCT)
    qty = RISK_PER_TRADE / (ask - stop)            # size from the stop, not leverage
    qty = min(qty, MAX_NOTIONAL / ask)
    notional = qty * ask
    if notional < Decimal(inst.min_notional):
        return
    if tier_cap(inst, notional) < LEVERAGE_CAP:
        return                                     # size would break our cap

    entry = await session.place_order(
        instrument_id=inst.id,
        side="BUY",
        price=fit(ask * (1 + MAX_SLIPPAGE), inst.price_decimals),
        quantity=fit(qty, inst.quantity_decimals),
        time_in_force="fok",                       # all or nothing
    )
    if entry.order.status != "filled":
        return

    try:                                           # stop on the whole position
        await session.place_position_tp_sl(
            instrument_id=inst.id,
            take_profit=PerpsPositionTpSlTrigger(
                trigger_price=fit(ask * (1 + TAKE_PCT), inst.price_decimals)),
            stop_loss=PerpsPositionTpSlTrigger(
                trigger_price=fit(stop, inst.price_decimals)),
        )
    except Exception:
        logging.exception("TP/SL rejected: closing the unprotected position")
        await close_all(session)


async def my_signal(client, inst) -> bool:
    """PLACEHOLDER: your strategy goes here. Not part of the SDK."""
    return False


async def main():
    logging.basicConfig(level=logging.INFO)
    client = await AsyncSecureClient.create(
        private_key=os.environ["PRIVATE_KEY"],
        wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
    )
    session = await client.open_perps_session(
        expires_in=timedelta(days=1), label="perps-bot")
    inst = next(i for i in await client.fetch_perps_instruments()
                if i.symbol == SYMBOL)

    # Control 1: leverage cap and isolated margin, set before any order
    await session.update_leverage(
        instrument_id=inst.id,
        leverage=min(LEVERAGE_CAP, inst.max_leverage),
        cross_margin=False,
    )

    # Field names below follow the documented portfolio JSON
    # (margin.total_account_value, in_liquidation). Check them in your SDK.
    start_equity = Decimal((await session.fetch_portfolio()).margin.total_account_value)

    while True:
        portfolio = await session.fetch_portfolio()
        equity = Decimal(portfolio.margin.total_account_value)

        # Control 2: kill switches
        if os.path.exists(HALT_FILE):
            await kill_switch(session, "HALT file found")
            break
        if equity < start_equity * (1 - DAILY_LOSS_LIMIT):
            await kill_switch(session, f"daily loss limit hit: {equity}")
            break
        if portfolio.in_liquidation:
            await kill_switch(session, "account in liquidation")
            break

        in_position = any(p.instrument_id == inst.id and p.size != 0
                          for p in portfolio.positions)
        if not in_position and await my_signal(client, inst):
            await open_long(client, session, inst)   # Control 3 lives here

        await asyncio.sleep(5)


asyncio.run(main())

Расчёт размера позиции. Размер определяется расстоянием до стопа, а не плечом. При гипотетическом аске BTC 100 000 pUSD и стопе 2% стоп находится на уровне 98 000. Риск на единицу составляет 2 000, поэтому количество равно 20 / 2 000 = 0.01 BTC, то есть номинал 1 000 pUSD. При плече 3x для этого нужно около 333 pUSD маржи. Уровень поддерживающей маржи для BTC составляет 1% (0.5 / 50x), поэтому цена ликвидации лонга равна 100 000 x (1 - 1/3) / (1 - 0.01) = примерно 67 340, что соответствует падению на 32.7%. Стоп на -2% срабатывает задолго до этого. Если стоп исполнится по цене триггера, убыток составит 20 pUSD плюс комиссии: 0.40 при открытии и около 0.39 при закрытии по тарифу тейкера 0.040%, итого около 20.79 pUSD без учёта проскальзывания. Плечо определяет только объём задействованной маржи. На убыток при срабатывании стопа оно не влияет.

Перед запуском в рабочем режиме добавьте дневной лимит сделок, оповещения об исполнениях и срабатывании аварийных выключателей, а также сверку состояния при запуске (fetch_portfolio, fetch_open_orders, fetch_orders, list_fills). Смотрите наши главы о коде управления рисками и бумажной торговле, руководство по кредитному плечу и ликвидации в Perps и руководство по ставкам финансирования в Perps.

Ошибки, повторные попытки и выключатель мертвеца

  • 503 service_unavailable не означает, что запрос точно не выполнен. Повторяйте запросы на чтение и изменения плеча с нарастающей задержкой и соблюдайте Retry-After. Для подписанных изменений баланса (маржа, выводы) повторно отправляйте только тот же самый исходный подписанный запрос; новая подпись означает вторую корректировку.
  • signature expired: подписи больше 5 минут. Держите часы синхронизированными.
  • insufficient_margin / invalid_leverage: проверки учитывают вашу позицию плюс все активные ордера.
  • message_rate_limited: лимит сообщений WebSocket исчерпан. Ключи только для чтения получают 1 000 сообщений в минуту на IP (всплеск до 50) и четыре соединения на аккаунт на шлюз; остальные лимиты смотрите на странице Rate Limits в документации.
  • Ошибки формата: слишком много знаков после запятой или больше 5 значащих цифр. Для этого и нужна fit().

Автоотмена отменяет все открытые ордера, если бот перестаёт её перевзводить. Срок должен быть минимум на 5 секунд впереди, а число срабатываний за сутки по UTC ограничено, поэтому при штатном завершении работы отключайте её.

// For quoting bots: cancel all resting orders if this process dies
await session.armAutoCancel({ cancelAt: Date.now() + 60_000 });
const rearm = setInterval(() => {
  // A missed re-arm is fail-safe: the armed switch still fires.
  session.armAutoCancel({ cancelAt: Date.now() + 60_000 }).catch(console.error);
}, 20_000);

// On a clean shutdown
clearInterval(rearm);
await session.disarmAutoCancel();
Автоотмена и стопы. В документации автоотмена указана как одна из причин отмены ордера TP/SL, поэтому сбой бота может снять стоп с открытой позиции. Автоотмена подходит для котирующих ботов, например маркетмейкеров. В нашем каркасе нет висящих входных ордеров, поэтому автоотмена в нём выключена, чтобы стопы оставались в силе. В любом случае от ликвидации упавшего бота защищает именно низкое плечо.

Соревнования, коды билдеров и правила для ботов

В документации среди вариантов использования API названы «торговые боты, реагирующие на рыночные сигналы» и маркетмейкеры. Действуют два набора правил.

  • Соревнования. Запрещены фиктивная торговля (wash trading), сделки с самим собой, несколько аккаунтов, торговля в основном ради объёма и «боты, скрипты или автоматизированные средства, предназначенные для манипулирования Программой». Бот, который торгует по-настоящему, допустим; бот, накручивающий объём, может быть дисквалифицирован.
  • Коды билдеров. Приложение, которое торгует для других пользователей, может добавлять комиссию до 10 базисных пунктов с согласия каждого трейдера. Оно обязано проверять местоположение каждого пользователя и блокировать ордера из юрисдикций с ограничениями, а не просто предупреждать.

Вознаграждения мейкерам за ликвидность и соревнования описаны в руководстве по Полимаркет Perps.

Хостинг бота

Бот с кредитным плечом не должен работать на ноутбуке. Ему нужно поддерживать соединение WebSocket, реагировать на исполнения за секунды и переживать обрыв домашнего интернета. Запускайте его на VPS под systemd с автоматическим перезапуском, храните ключ в файле окружения, доступном для чтения только пользователю бота, и синхронизируйте часы. Размещать ордера из мест с ограничениями запрещено, поэтому не размещайте бота в США или Канаде и никогда не используйте VPS, чтобы обойти блокировку, которая распространяется на вас. Своих собственных ботов мы запускаем на TradingVPS (партнёрская ссылка: мы получаем небольшую комиссию, а цена для вас не меняется). В нашей главе о VPS-хостинге он сравнивается с другими провайдерами по задержке, цене и регионам.

После бумажной торговли пополните счёт небольшой суммой на странице Полимаркет Perps и неделю работайте на минимальном размере, прежде чем наращивать объёмы.

Главное

  • Используйте официальные SDK: @polymarket/client или polymarket-client. Ваш кошелёк подписывает один раз, а ордера подписывает прокси-ключ.
  • Сопоставляйте рынки по актуальному символу (BTC-USD, а не BTC-PERP) и сохраняйте числовой ID.
  • Рассчитывайте размер от расстояния до стопа, ограничивайте плечо в коде, используйте изолированную маржу и ставьте стоп на каждую позицию сразу после исполнения.
  • TP/SL срабатывает по цене маркировки и закрывает позицию по рынку. Автоотмена может снять стопы.
  • Боты разрешены, манипулирование соревнованиями запрещено. Никогда не торгуйте из страны с ограничениями.

Часто задаваемые вопросы

Есть ли у Полимаркет Perps API для торговых ботов?
Да. Есть REST API по адресу api.perpetuals.polymarket.com, WebSocket по адресу ws.perpetuals.polymarket.com и официальные SDK: @polymarket/client для TypeScript и polymarket-client для Python. В документации Полимаркет торговые боты и системы маркетмейкинга названы среди поддерживаемых вариантов использования.
Какой SDK выбрать: для TypeScript или для Python?
Подойдёт любой. Оба покрывают один и тот же сценарий: создать защищённый клиент, открыть сессию Perps, загрузить инструменты, разместить ордера с TP/SL и получать поток событий. SDK для TypeScript использует viem для подписи. SDK для Python асинхронный. Выбирайте язык, на котором уже написан ваш бот.
Нужен ли боту приватный ключ моего основного кошелька?
Только для открытия сессии. Эта единственная подпись авторизует прокси-ключ для торговли, и дальше ордера подписывает прокси. Учётные данные сессии по умолчанию истекают через неделю. Храните их в зашифрованном виде, а для дашбордов используйте ключи только для чтения.
Как установить стоп-лосс через API Perps?
Прикрепите триггеры takeProfit и stopLoss к входному ордеру как брекет-ордер или вызовите placePositionTpSl (place_position_tp_sl в Python) для открытой позиции. Триггеры отслеживают цену маркировки и закрывают позицию ордером reduce-only. TP/SL позиции закрывает всю позицию по рынку.
Какой минимальный размер ордера на Полимаркет Perps?
$10 номинала на ордер, минимальный депозит 10 pUSD (на ноябрь 2026 г.). Кроме того, цены и размеры должны соответствовать допустимому для рынка числу знаков после запятой и содержать не более 5 значащих цифр, иначе ордер отклоняется.
Есть ли аварийный выключатель или выключатель мертвеца?
Да. Автоотмена отменяет все открытые ордера, если бот перестаёт её перевзводить, а cancelAllOrders снимает ордера по запросу. В документации автоотмена указана как одна из причин отмены ордера TP/SL, поэтому сбой может снять и ваши стопы. Напишите также собственный аварийный выключатель.
Можно ли запускать бота для Полимаркет Perps из США или Канады?
Нет. Размещение ордеров в Perps не разрешено из США, Канады, Кубы, Ирана, Северной Кореи, Сирии, Крыма, Донецка и Луганска. Не размещайте там бота и не используйте VPS или VPN, чтобы обойти блокировку, которая распространяется на вас.
Разрешены ли боты в торговых соревнованиях Полимаркет Perps?
Торговать с помощью бота разрешено. Правила соревнований запрещают фиктивную торговлю (wash trading), сделки с самим собой, несколько аккаунтов, торговлю в основном ради создания объёма, а также ботов или скрипты, предназначенные для манипулирования программой. Нарушение правил может привести к дисквалификации.