Polymarket Bot Tutorial · Глава 10 из 32

Типы order на Polymarket, объяснённые для bot builders: Fill-or-Kill (FOK), Fill-and-Kill (FAK), Good-til-Cancelled (GTC), а также trade-offs limit-vs-market. С production-grade decision rules.

Что охватывает эта глава

Путаница с order types - это самый дорогой класс bugs для новых bot builders. Отправка FOK, когда нужен был GTC, приводит к пропущенным entries; отправка GTC, когда нужен был FOK, оставляет resting orders, которые спустя часы исполняются по ужасным ценам. Эта глава - decision tree и production defaults, которые выдержали испытание на тысячах orders.

  • Быстрый decision tree
  • FOK: когда нужно исполнить или пропустить
  • FAK: когда допустимы partial fills
  • GTC: когда вы хотите rest on the book
  • Limit vs market и spread tax
  • Наши production defaults (FOK buys, GTC sells)
  • Code: размещение каждого типа order

Быстрый decision tree

Три вопроса определяют каждое размещение order.

  1. Нужен ли вам гарантированный fill прямо сейчас, и вообще не нужен, если получить его сейчас нельзя? → FOK.
  2. Хотите ли вы получить как можно больший fill прямо сейчас, принимая partial fills, без resting order? → FAK.
  3. Хотите ли вы остаться на book по своей цене и ждать, пока кто-то придёт к вам? → GTC.

Вот и всё. Большинство bugs bot вокруг order types возникают из-за выбора #1, когда нужен был #3 (buy превращается в "no position because the spread was too wide"), или выбора #3, когда нужен был #1 (buy превращается в resting order, который исполняется спустя часы в неправильный момент).

FOK: когда нужно исполнить или пропустить

Fill-or-Kill мгновенно сопоставляет весь order по запрошенной цене или лучше. Если полный размер нельзя исполнить мгновенно, order отклоняется, и ничего не происходит. Никакого resting, никаких partials.

Используйте FOK для: news-arbitrage entries (вам нужно войти только по цене новости, а не по тому, где рынок окажется через 30 секунд); take-profit exits по конкретной цели, где partials будут мешать учёту; любого случая, когда стратегия предполагает atomic execution.

Trade-off: FOK отклоняется чаще, чем другие типы order, особенно на illiquid books. Всегда имейте fallback path - пересчитайте условие стратегии и повторите попытку, если оно всё ещё валидно, или идите дальше.

FAK: когда допустимы partial fills

Fill-and-Kill (также называется "immediate or cancel") исполняет столько, сколько может прямо сейчас, а затем отменяет неисполненный остаток. Вы можете получить полный size, partial или zero.

Используйте FAK для: market-buy с заданным price ceiling (поднять ask до N cents выше mid); sweep-the-book sell при срочном сокращении inventory; любой стратегии, где "some position is better than none."

С operational точки зрения это сложнее, чем FOK, потому что bot должен понять, получил ли он 100% или 30%, прежде чем решать следующий шаг. Ответ на fill содержит поле filled_size - всегда читайте его.

GTC: когда вы хотите rest on the book

Good-til-Cancelled остаётся на book по вашей цене, пока не исполнится или вы не отмените order. Таймаута нет (другие order types в v2 API включают GTD с expiry).

Используйте GTC для: take-profit sells на +Nc выше entry; stop-loss sells на -Nc ниже entry (с оговорками - см. ниже); market-making обеими сторонами quotes; любой позиции, где bot готов ждать лучшей цены.

Жёсткое правило: GTC требует ≥ 5 shares. Orders меньше 5 shares отклоняются CLOB с сообщением Size (X) lower than the minimum: 5. Bot, который выставляет GTC sell на 4 shares, молча не устанавливает exit и несёт позицию до resolution. Всегда проверяйте inventory ≥ 5 перед публикацией GTC; если меньше - переходите на FAK или ride-to-resolve.

Limit vs market и spread tax

Каждый order на Polymarket технически является limit order - даже то, что bot называет "market buy", указывает price ceiling. Разница в том, находится ли эта цена на best ask (по сути market order, будет исполнена против book) или ниже него (будет rest on the book).

Spread tax - это стоимость crossing - bid 0.45, ask 0.47, mid 0.46. Round trip, который покупает по ask и продаёт по bid, платит 2 cents на share. Для стратегии с win-rate 60% и целями +3c/-4c этот spread в 2c - разница между profit и loss.

Maker pattern (post GTC по bid или ниже, ждать, пока вас заберут) забирает spread вместо того, чтобы платить его. Цена - неопределённый fill: вас могут так и не исполнить. Для высокоубеждённых trades платите spread. Для пассивного накопления работайте book.

Наши production defaults (FOK buys, GTC sells)

Паттерн, к которому сходятся большинство наших production bots:

  • Entries: FOK at ask + 0-2 cents. Если bot решил купить, он должен купить сейчас или пропустить. Resting order на entry редко оправдан - ситуация, вызвавшая решение о покупке, меняется быстрее, чем order будет ждать.
  • Take-profit exits: GTC at target price. Выставляется сразу после исполнения entry. Мы даём рынку прийти к нам; мы не гоним bid вниз. При inventory ≥ 5 shares.
  • Stop-loss: case-by-case. GTC подходит для медленных strategies, где изменения цены ограничены. На быстро движущихся markets GTC stop не исполнится, если цена пролетит через него; мы ride to resolution в стиле option-D (memory: trader-gtc-sell.md).

Паттерн консервативный - меньше fills, меньше slippage. Более агрессивный вариант использует FAK entries и FAK exits, принимая partial fills. Выберите один и придерживайтесь его; смешивание решений по каждому trade ведёт к путанице.

Code: размещение каждого типа order

Reference размещения order в Python с py-clob-client (v0.34.6).

from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType
c = ClobClient(host="https://clob.polymarket.com", chain_id=137,
               key=PRIVATE_KEY, signature_type=2, funder=PROXY)
c.set_api_creds(creds)

# FOK buy: fill 10 shares at price 0.45 or skip
args = OrderArgs(token_id=TOKEN, price=0.45, size=10, side="BUY")
resp = c.create_and_post_order(args, OrderType.FOK)

# FAK buy: take as much as you can at 0.45 or below
resp = c.create_and_post_order(args, OrderType.FAK)

# GTC sell: rest a sell at 0.85 for 10 shares
sell_args = OrderArgs(token_id=TOKEN, price=0.85, size=10, side="SELL")
resp = c.create_and_post_order(sell_args, OrderType.GTC)

Те же операции в Node с @polymarket/clob-client-v2: замените OrderType.FOK на clob.OrderType.GTC и т. д.; метод - createAndPostOrder. Флаг negRisk (глава 11) должен быть установлен во втором аргументе для multi-outcome markets - если его не указать, запрос уйдёт в неверный exchange contract.

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

Что такое FOK на Polymarket?
Fill-or-Kill. Order должен полностью исполниться немедленно, иначе он отменяется - никаких partial fills, никакого resting on the book. Мы по умолчанию используем FOK для buys в нашем production trader, потому что это устраняет неоднозначность phantom-fill (order либо исполняется полностью, либо полностью исчезает, но никогда не зависает наполовину).
Что такое FAK на Polymarket?
Fill-and-Kill (также называется IOC, Immediate-or-Cancel). Order забирает всю доступную ликвидность немедленно и отменяет неисполненный остаток. Полезно, когда вы принимаете partial fills, но никогда не хотите rest. Быстрее, чем FOK, в фрагментированных order books.
Что такое GTC на Polymarket?
Good-til-Cancelled. Order остаётся на book, пока не исполнится или вы не отмените его. GTC - это то, что вы используете, чтобы быть maker (предоставлять ликвидность), получать rebates и избегать taker fees. Мы используем GTC для sells в нашей production setup, чтобы захватывать spread на exits.
Должен ли мой bot использовать limit orders или market orders?
Почти всегда limit orders. Market orders платят taker fee (0.75% to 1.80%) и spread; limit orders получают maker rebate (20-25% от taker fees). Единственная хорошая причина использовать market order - когда вышла новость и цена вот-вот уйдёт за spread до того, как ваш limit успеет исполниться.
Поддерживает ли Polymarket stop-loss orders нативно?
Нет. Stop-loss - это client-side концепция: ваш bot следит за ценой, и когда условие срабатывания выполнено, размещает market или FAK sell order. У exchange нет нативного stop primitive, поэтому логику нужно реализовать в вашем bot.
Каковы minimums для order?
Market orders: minimum notional 1 USD. Limit orders: minimum 5 shares. Некоторые thin markets отклоняют очень маленькие orders - SDK возвращает specific error code, который можно определить и пересчитать size.