Polymarket Bot Tutorial · บทที่ 10 จาก 32

อธิบาย order types ของ Polymarket สำหรับผู้สร้าง bot: Fill-or-Kill (FOK), Fill-and-Kill (FAK), Good-til-Cancelled (GTC) และ trade-offs ระหว่าง limit กับ market พร้อม decision rules ระดับ production

บทนี้ครอบคลุมอะไรบ้าง

ความสับสนเรื่อง order type เป็นบั๊กที่แพงที่สุดอันดับต้นๆ สำหรับผู้สร้าง bot มือใหม่ การส่ง FOK ตอนที่ควรใช้ GTC จะทำให้พลาด entry; การส่ง GTC ตอนที่ควรใช้ FOK จะทิ้ง resting order ไว้ แล้วไป fill ที่ราคาย่ำแย่หลายชั่วโมงถัดมา บทนี้คือ decision tree และค่าเริ่มต้นระดับ production ที่ผ่านการใช้งานกับคำสั่งซื้อขายนับพันรายการ

  • Quick decision tree
  • FOK: เมื่อคุณต้อง fill หรือไม่ก็ข้าม
  • FAK: เมื่อ partials ยอมรับได้
  • GTC: เมื่อคุณต้องการ rest ไว้บน book
  • Limit vs market และ spread tax
  • ค่าเริ่มต้นระดับ production ของเรา (FOK buys, GTC sells)
  • Code: place แต่ละ order type

Quick decision tree

มี 3 คำถามที่ใช้ตัดสินการวาง order ทุกครั้ง

  1. คุณต้องการ guaranteed fill ทันที และถ้าทำไม่ได้ตอนนี้ก็ไม่เอาเลยใช่ไหม? → FOK.
  2. คุณต้องการ fill ให้มากที่สุดเท่าที่ทำได้ตอนนี้ ยอมรับ partial ได้ และไม่ต้องการ resting order ใช่ไหม? → FAK.
  3. คุณต้องการ rest บน book ที่ราคาของคุณ แล้วรอให้คนอื่นเข้ามาหาคุณใช่ไหม? → GTC.

แค่นี้เอง บั๊กส่วนใหญ่ของ bot ที่เกี่ยวกับ order type มักมาจากการเลือกข้อ #1 ทั้งที่คุณต้องการข้อ #3 ("buy" กลายเป็น "no position เพราะ spread กว้างเกินไป") หรือเลือกข้อ #3 ทั้งที่คุณต้องการข้อ #1 ("buy" กลายเป็น resting order ที่ไป fill อีกหลายชั่วโมงถัดมาในจังหวะที่ไม่เหมาะ)

FOK: เมื่อคุณต้อง fill หรือไม่ก็ข้าม

Fill-or-Kill จะ match order ทั้งหมดที่ราคาที่ขอหรือดีกว่า ภายในทันที ถ้าจำนวนเต็มไม่สามารถ fill ได้ทันที order จะถูกปฏิเสธ และจะไม่มีอะไรเกิดขึ้น ไม่มี resting และไม่มี partial

ใช้ FOK สำหรับ: news-arbitrage entries (คุณต้องการเข้าที่ราคาตอนข่าวออกเท่านั้น ไม่ใช่ราคาตลาดในอีก 30 วินาที); take-profit exits ที่ target เฉพาะเจาะจงซึ่ง partial จะทำให้ bookkeeping สับสน; ทุกครั้งที่ strategy ของคุณสมมติว่าการ execute ต้องเป็นแบบ atomic

trade-off คือ FOK จะ reject บ่อยกว่า order type อื่น โดยเฉพาะในตลาดที่สภาพคล่องต่ำ ควรมี fallback path เสมอ-ประเมินเงื่อนไข strategy ใหม่แล้วลองอีกครั้งถ้ายัง valid อยู่ หรือไม่ก็ข้ามไป

FAK: เมื่อ partials ยอมรับได้

Fill-and-Kill (เรียกอีกอย่างว่า "immediate or cancel") จะ match ให้มากที่สุดเท่าที่ทำได้ตอนนี้ แล้วค่อยยกเลิกส่วนที่ยังไม่ถูก fill คุณอาจได้ครบจำนวน ได้บางส่วน หรือไม่ได้เลย

ใช้ FAK สำหรับ: market-buy ที่มี price ceiling เฉพาะ (lift ask ได้สูงสุด N cents เหนือ mid); sweep-the-book sells เมื่อต้องลด inventory อย่างเร่งด่วน; กลยุทธ์ใดๆ ที่ "มี position บ้างดีกว่าไม่มีเลย"

ในเชิง operation จะยุ่งยากกว่า FOK เพราะ bot ต้องรู้ว่าตัวเองได้ 100% หรือแค่ 30% ก่อนตัดสินใจขั้นถัดไป response ของ fill จะมีฟิลด์ filled_size-ต้องอ่านเสมอ

GTC: เมื่อคุณต้องการ rest บน book

Good-til-Cancelled จะ rest บน book ที่ราคาของคุณจนกว่าจะถูก fill หรือคุณยกเลิก ไม่มี timeout (order type อื่นใน v2 API มี GTD ที่กำหนดวันหมดอายุได้)

ใช้ GTC สำหรับ: take-profit sells ที่ +Nc เหนือ entry; stop-loss sells ที่ -Nc ต่ำกว่า entry (พร้อมข้อควรระวัง-ดูด้านล่าง); market-making quotes ทั้งสองฝั่ง; position ใดๆ ที่ bot ยอมรอราคาที่ดีกว่าได้

กฎที่เข้มงวด: GTC ต้องมี ≥ 5 shares. Order ที่ต่ำกว่า 5 shares จะถูก CLOB ปฏิเสธด้วย Size (X) lower than the minimum: 5. bot ที่ส่ง GTC sell 4 shares จะล้มเหลวแบบเงียบๆ ในการตั้ง exit และปล่อย position ไหลไปจนถึง resolution ต้องตรวจ inventory ให้ ≥ 5 ก่อนส่ง GTC เสมอ; ถ้าต่ำกว่านั้นให้ fallback ไป FAK หรือ ride-to-resolve

Limit vs market และ spread tax

ทุก order ของ Polymarket ในทางเทคนิคคือ limit order-แม้แต่สิ่งที่ bot เรียกว่า "market buy" ก็ยังระบุ price ceiling อยู่ ความแตกต่างคือราคานั้นอยู่ที่ best ask (เท่ากับ market order โดยพฤติกรรม จะ fill เข้าชน book) หรืออยู่ต่ำกว่านั้น (จะ rest บน book)

spread tax คือค่าใช้จ่ายของการ cross-bid 0.45, ask 0.47, mid 0.46 การ round trip ที่ซื้อที่ ask แล้วขายที่ bid จะจ่าย 2 เซนต์ต่อ share บนกลยุทธ์ win-rate 60% ที่มี target +3c/-4c สเปรด 2c นี้คือเส้นแบ่งระหว่างกำไรกับขาดทุน

maker pattern (ส่ง GTC ที่ bid หรือต่ำกว่า แล้วรอให้ถูก hit) จะเก็บ spread แทนที่จะจ่าย ข้อเสียคือการ fill ไม่แน่นอน-คุณอาจไม่ถูก hit เลย สำหรับ trade ที่มั่นใจสูง จ่าย spread ไปเลย สำหรับการสะสมแบบ passive ให้ค่อยๆ ทำงานบน book

ค่าเริ่มต้นระดับ production ของเรา (FOK buys, GTC sells)

pattern ที่ bot ระดับ production ของเราส่วนใหญ่ลงเอยด้วย:

  • Entries: FOK ที่ ask + 0-2 cents. ถ้า bot ตัดสินใจจะซื้อ ก็ควรซื้อเดี๋ยวนี้หรือไม่ก็ข้ามไป การตั้ง entry order ให้ rest ไว้แทบไม่คุ้ม-สถานการณ์ที่กระตุ้นให้ตัดสินใจซื้อเปลี่ยนเร็วกว่าช่วงที่ order จะ rest
  • Take-profit exits: GTC ที่ target price. ส่งทันทีหลัง entry fill เสร็จ เราปล่อยให้ตลาดเข้ามาหาเรา; ไม่ไล่ bid ลงไป ด้วยจำนวน ≥ 5 shares
  • Stop-loss: แล้วแต่กรณี. GTC ใช้ได้กับกลยุทธ์ที่เคลื่อนตัวช้าและ price changes มีขอบเขต แต่สำหรับตลาดที่เคลื่อนเร็ว stop แบบ GTC จะไม่ fill ถ้าราคาพุ่งทะลุผ่านมัน; เราจะ ride to resolution ในแนว option-D (memory: trader-gtc-sell.md)

pattern นี้ค่อนข้าง conservative-fill น้อยลง, slippage น้อยลง เวอร์ชันที่ aggressive กว่าใช้ FAK ทั้ง entry และ exit โดยยอมรับ partial fills เลือกแบบหนึ่งแล้วใช้ให้สม่ำเสมอ; การผสมการตัดสินใจแบบราย trade จะสร้างความสับสน

Code: place แต่ละ order type

ตัวอย่างการวาง 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 เป็นต้น; method คือ createAndPostOrder. ต้องตั้งค่า negRisk flag (บทที่ 11) ในอาร์กิวเมนต์ตัวที่สองสำหรับตลาดแบบ multi-outcome-ถ้าไม่ได้ตั้ง ระบบจะ route ไปยังสัญญา exchange ผิดตัว

คำถามที่พบบ่อย

FOK บน Polymarket คืออะไร?
Fill-or-Kill คำสั่งต้อง fill ให้ครบทั้งหมดทันที ไม่เช่นนั้นจะถูกยกเลิก - ไม่มี partial fills และไม่มีการ rest บน book เราใช้ FOK เป็นค่าเริ่มต้นสำหรับ buys ใน production trader ของเรา เพราะมันตัดความกำกวมเรื่อง phantom-fill ออกไป (order จะถูก fill ทั้งหมดหรือหายไปทั้งหมด ไม่เคยค้างครึ่งๆ)
FAK บน Polymarket คืออะไร?
Fill-and-Kill (เรียกอีกอย่างว่า IOC, Immediate-or-Cancel) order จะเอาสภาพคล่องที่มีอยู่ทันทีเท่าที่ทำได้ แล้วส่วนที่ยังไม่ถูก fill จะถูกยกเลิก เหมาะเมื่อคุณยอมรับ partial fills ได้ แต่ไม่ต้องการให้ rest เร็วกกว่า FOK ใน order book ที่กระจายตัว
GTC บน Polymarket คืออะไร?
Good-til-Cancelled order จะ rest บน book จนกว่าจะถูก fill หรือคุณยกเลิก GTC คือสิ่งที่ใช้เมื่อคุณต้องการเป็น maker (provide liquidity), รับ rebates และหลีกเลี่ยง taker fees เราใช้ GTC สำหรับ sells ใน production setup เพื่อเก็บ spread ตอน exit
bot ของฉันควรใช้ limit orders หรือ market orders?
เกือบตลอดเวลาให้ใช้ limit orders ตลาด order จะจ่าย taker fee (0.75% ถึง 1.80%) และ spread; limit orders จะได้รับ maker rebate (20-25% ของ taker fees) เหตุผลที่ดีจริงๆ ในการใช้ market order คือเมื่อข่าวออกแล้ว และราคากำลังจะเคลื่อนผ่าน spread ก่อนที่ limit ของคุณจะ fill ได้
Polymarket รองรับ stop-loss orders แบบ native ไหม?
ไม่รองรับ Stop-loss เป็นแนวคิดฝั่ง client: bot ของคุณจะเฝ้าดูราคา และเมื่อถึง trigger condition ก็จะส่ง market หรือ FAK sell order exchange ไม่มี stop primitive แบบ native ดังนั้นคุณต้องสร้าง logic นี้ใน bot ของคุณเอง
ขั้นต่ำของ order คือเท่าไหร่?
Market orders: minimum notional 1 USD. Limit orders: ขั้นต่ำ 5 shares. บางตลาดที่บางมากจะปฏิเสธ order ขนาดเล็กมาก - SDK จะคืน error code เฉพาะที่คุณสามารถตรวจจับและปรับขนาดใหม่ได้