آموزش Polymarket Bot · فصل 10 از 32

توضیح order typeهای Polymarket برای bot builderها: Fill-or-Kill (FOK)، Fill-and-Kill (FAK)، Good-til-Cancelled (GTC)، و trade-offهای limit در برابر market. همراه با decision ruleهای production-grade.

این فصل چه چیزهایی را پوشش می‌دهد

ابهام در order typeها، پرهزینه‌ترین دسته bug برای bot builderهای تازه‌کار است. فرستادن FOK وقتی GTC لازم بود باعث از دست رفتن entryها می‌شود؛ فرستادن GTC وقتی FOK لازم بود orderهای معلقی باقی می‌گذارد که ساعت‌ها بعد با قیمت‌های وحشتناک fill می‌شوند. این فصل، decision tree و defaultهای production است که در هزاران order دوام آورده‌اند.

  • Quick decision tree
  • FOK: وقتی باید fill شود یا skip شود
  • FAK: وقتی partialها قابل قبول‌اند
  • GTC: وقتی می‌خواهید روی book بمانید
  • Limit در برابر market و spread tax
  • Defaultهای production ما (FOK buys، GTC sells)
  • Code: ثبت هر نوع order

Quick decision tree

سه سؤال، هر order placement را تعیین می‌کنند.

  1. آیا به یک fill تضمینی همین الان نیاز دارید، و اگر نتواند همین الان fill شود اصلاً نمی‌خواهید؟ → FOK.
  2. آیا می‌خواهید هر مقدار fill که همین الان می‌شود بگیرید، partial را بپذیرید، و هیچ resting orderی نداشته باشید؟ → FAK.
  3. آیا می‌خواهید روی book با قیمت خودتان بمانید و منتظر بمانید کسی به شما برسد؟ → GTC.

همین. بیشتر bugهای bot حول order typeها از انتخاب #1 وقتی #3 را می‌خواستید می‌آیند (یک «buy» تبدیل می‌شود به «no position چون spread خیلی باز بود») یا انتخاب #3 وقتی #1 را می‌خواستید (یک «buy» تبدیل می‌شود به resting orderی که ساعت‌ها بعد در زمان اشتباه fill می‌شود).

FOK: وقتی باید fill شود یا skip شود

Fill-or-Kill کل order را با قیمت درخواستی یا بهتر، بلافاصله match می‌کند. اگر کل size نتواند فوراً fill شود، order رد می‌شود و هیچ اتفاقی نمی‌افتد. نه resting، نه partial.

از FOK استفاده کنید برای: ورودهای news-arbitrage (فقط در قیمت خبر می‌خواهید وارد شوید، نه جایی که بازار 30 ثانیه بعد است)؛ exitهای take-profit در یک target مشخص که partialها bookkeeping را به‌هم می‌زنند؛ هر زمانی که strategy اجرای atomic را فرض می‌کند.

trade-off این است که FOK بیشتر از سایر order typeها reject می‌شود، مخصوصاً روی bookهای illiquid. همیشه یک fallback path داشته باشید - conditionهای strategy را دوباره ارزیابی کنید و اگر هنوز معتبر بود retry کنید، یا به مرحله بعد بروید.

FAK: وقتی partialها قابل قبول‌اند

Fill-and-Kill (که به آن "immediate or cancel" هم گفته می‌شود) هر مقدار که بتواند را همین الان match می‌کند، سپس باقی‌مانده fill نشده را cancel می‌کند. ممکن است size کامل، یک partial، یا صفر بگیرید.

از FAK استفاده کنید برای: market-buy با یک price ceiling مشخص (ask را تا N cents بالاتر از mid بالا بکشید)؛ sellهای sweep-the-book وقتی باید urgently inventory را کم کنید؛ هر strategyای که در آن «بعضی position بهتر از هیچ‌چیز است».

از نظر عملی پیچیده‌تر از FOK است، چون bot باید قبل از تصمیم‌گیری برای قدم بعدی بداند 100% گرفته یا 30%. پاسخ fill شامل فیلد filled_size است - همیشه آن را بخوانید.

GTC: وقتی می‌خواهید روی book بمانید

Good-til-Cancelled روی book با قیمت شما می‌ماند تا وقتی fill شود یا خودتان cancel کنید. هیچ timeoutی ندارد (سایر order typeها در API v2 شامل GTD با expiry هستند).

از GTC استفاده کنید برای: take-profit sellها در +Nc بالاتر از entry؛ stop-loss sellها در -Nc پایین‌تر از entry (با caveatها - پایین‌تر را ببینید)؛ market-making با quoteهای دوطرفه؛ هر positionی که bot حاضر است برای قیمت بهتر صبر کند.

قانون سخت: GTC به ≥ 5 shares نیاز دارد. orderهای زیر 5 shares توسط CLOB رد می‌شوند با Size (X) lower than the minimum: 5. یک bot که یک GTC sell چهار-share ثبت می‌کند، بی‌سروصدا fail می‌شود و exit را تنظیم نمی‌کند و position را تا resolution نگه می‌دارد. همیشه قبل از ثبت GTC بررسی کنید inventory ≥ 5 باشد؛ اگر کمتر بود به FAK یا ride-to-resolve fallback کنید.

Limit در برابر market و spread tax

هر order در Polymarket از نظر فنی یک limit order است - حتی چیزی که botها آن را «market buy» می‌نامند هم یک price ceiling مشخص می‌کند. تفاوت این است که آیا آن قیمت روی بهترین ask است (عملاً یک market order، و در برابر book fill می‌شود) یا پایین‌تر از آن است (و روی book می‌ماند).

spread tax هزینه crossing است - bid 0.45، ask 0.47، mid 0.46. یک round trip که ask می‌خرد و bid می‌فروشد، به ازای هر share دو سنت پرداخت می‌کند. در یک strategy با win-rate 60% و targetهای +3c/-4c، همان spread 2c تفاوت بین سود و زیان است.

الگوی maker (ثبت GTC در bid یا پایین‌تر، و منتظر hit شدن ماندن) به‌جای پرداخت spread، آن را جمع می‌کند. هزینه‌اش fill نامطمئن است - ممکن است هیچ‌وقت hit نشوید. برای tradeهای با conviction بالا، spread را بپردازید. برای accumulation passive، book را کار کنید.

Defaultهای production ما (FOK buys، GTC sells)

الگویی که بیشتر botهای production ما به آن می‌رسند:

  • Entryها: FOK در ask + 0-2 cents. اگر bot تصمیم به buy گرفته، باید همین الان buy کند یا skip شود. معلق گذاشتن یک entry order به‌ندرت ارزش دارد - موقعیتی که باعث تصمیم buy شده سریع‌تر از مدت معلق ماندن order تغییر می‌کند.
  • Exitهای take-profit: GTC در target price. بلافاصله بعد از fill شدن entry ثبت می‌شود. می‌گذاریم بازار به سمت ما بیاید؛ bid را پایین تعقیب نمی‌کنیم. با ≥ 5 shares.
  • Stop-loss: case-by-case. GTC برای strategyهای کند که تغییرات قیمت در آن‌ها bounded است خوب کار می‌کند. برای بازارهای سریع، یک GTC stop اگر قیمت از روی آن بپرد fill نمی‌شود؛ ما به سبک option-D تا resolution می‌رویم (memory: trader-gtc-sell.md).

این الگو محافظه‌کارانه است - fill کمتر، slippage کمتر. یک variant تهاجمی‌تر از FAK برای entry و FAK برای exit استفاده می‌کند و partial fillها را می‌پذیرد. یکی را انتخاب کنید و ثابت بمانید؛ مخلوط کردن تصمیم‌ها در هر trade باعث ابهام می‌شود.

Code: ثبت هر نوع order

نمونه order placement در 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 و غیره استفاده کنید؛ method برابر createAndPostOrder است. flag مربوط به negRisk (فصل 11) باید در آرگومان دوم برای بازارهای multi-outcome تنظیم شود - اگر نباشد، درخواست به contract اشتباه exchange route می‌شود.

پرسش‌های متداول

FOK در Polymarket چیست؟
Fill-or-Kill. order باید فوراً و به‌طور کامل fill شود وگرنه cancel می‌شود - نه partial fill، نه resting روی book. ما در trader production خودمان به‌صورت پیش‌فرض از FOK برای buyها استفاده می‌کنیم چون ابهام phantom-fill را حذف می‌کند (order یا کاملاً fill شده یا کاملاً از بین رفته، هرگز نیمه‌گیر نکرده).
FAK در Polymarket چیست؟
Fill-and-Kill (که به آن IOC، یعنی Immediate-or-Cancel هم گفته می‌شود). order هر مقدار liquidity را که فوراً در دسترس باشد برمی‌دارد و باقی‌مانده fill نشده را cancel می‌کند. وقتی partial fill را می‌پذیرید اما هرگز نمی‌خواهید order بماند، مفید است. در order bookهای fragmented از FOK سریع‌تر است.
GTC در Polymarket چیست؟
Good-til-Cancelled. order روی book می‌ماند تا fill شود یا شما آن را cancel کنید. GTC چیزی است که برای maker بودن (ارائه liquidity)، گرفتن rebate و اجتناب از taker fee استفاده می‌کنید. ما در setup production خودمان از GTC برای sellها استفاده می‌کنیم تا spread را در exitها capture کنیم.
آیا bot من باید از limit order استفاده کند یا market order؟
تقریباً همیشه limit order. market orderها taker fee (0.75% تا 1.80%) و spread را می‌پردازند؛ limit orderها maker rebate (20-25% از taker fee) می‌گیرند. تنها دلیل خوب برای استفاده از market order زمانی است که خبر رسیده و قیمت قبل از fill شدن limit شما احتمالاً از spread عبور می‌کند.
آیا Polymarket به‌صورت native stop-loss order پشتیبانی می‌کند؟
خیر. stop-loss یک مفهوم سمت کلاینت است: bot شما قیمت را رصد می‌کند و وقتی شرط trigger برآورده شد، یک market یا FAK sell order ثبت می‌کند. exchange primitive بومی برای stop ندارد، پس باید منطق آن را داخل bot خودتان بسازید.
حداقل orderها چقدر است؟
Market order: حداقل notional برابر 1 USD. Limit order: حداقل 5 shares. بعضی بازارهای thin، orderهای خیلی کوچک را رد می‌کنند - SDK یک error code مشخص برمی‌گرداند که می‌توانید آن را تشخیص دهید و بر اساس آن size را دوباره تنظیم کنید.