Polymarket Bot Tutorial · บทที่ 13 จาก 32
การทำ market making บน Polymarket: วิธีตั้ง bid และ ask, เก็บส่วนต่าง spread, รับ maker rebate (20-25% ของ taker fees), คณิตศาสตร์ของ inventory risk, และเมื่อไหร่ที่ MM ใช้ได้ผลบน prediction markets.
บทนี้ครอบคลุมอะไรบ้าง
Market making บน Polymarket หมายถึงการตั้งราคา buy (bid) และ sell (ask) ทั้งสองฝั่งของ order book อย่างต่อเนื่อง และทำกำไรจาก spread ในแต่ละ round trip กลยุทธ์นี้เป็นที่เข้าใจกันดีในวงการการเงินแบบดั้งเดิม แต่สิ่งที่เฉพาะกับ Polymarket คือโปรแกรม maker rebate และลักษณะ adverse selection ของ prediction markets ซึ่งสูงกว่าแพลตฟอร์ม CFD บทนี้เป็นคณิตศาสตร์แบบตรงไปตรงมา
- Market making แบบเข้าใจง่าย
- จุดได้เปรียบจาก spread + rebate
- ความเสี่ยง inventory และ skew
- เมื่อ MM ใช้ได้บน Polymarket (และเมื่อไหร่ที่ไม่ใช่)
- โครง code: ตั้งราคา bid/ask ทั้งสองฝั่งที่ +/- N เซนต์
- ปรับ quote ตามข่าวสารที่เข้ามา
- ปิด bot เมื่อ adverse selection พุ่งสูง
Market making แบบเข้าใจง่าย
Market maker จะตั้งราคา bid (ราคาซื้อ) และ ask (ราคาขาย) ทั้งสองฝั่งอย่างต่อเนื่อง โดยให้กว้างกว่าราคา mid ตาม spread ที่กำหนด เมื่อมีคน hit bid maker ก็ซื้อได้ในราคาถูก; เมื่อมีคน lift ask maker ก็ขายได้ในราคาสูง; ส่วนต่างระหว่าง bid และ ask คือรายได้ของ maker ต่อหนึ่ง round trip
กลยุทธ์นี้ขับเคลื่อนด้วย order flow ไม่ใช่การคาดเดาทิศทาง Maker ไม่ได้มีมุมมองว่า YES จะชนะหรือไม่; สิ่งที่ทำคือเชื่อว่า flow จะยังคงไหลเข้ามา และ spread จะถูกเก็บได้ต่อเนื่อง
ความเสี่ยงคือ adverse selection: คนที่ hit bid ของคุณอาจมีข้อมูลที่คุณไม่มี เมื่อเวลาผ่านไป กำไรของ MM จะขึ้นอยู่กับว่า spread กว้างพอจะชดเชย slippage จากเทรดเดอร์ที่มีข้อมูลเหนือกว่าหรือไม่
จุดได้เปรียบจาก spread + rebate
มีแหล่งรายได้สองทางสำหรับ maker บน Polymarket
Spread capture: ตั้ง bid ที่ 0.45 และ ask ที่ 0.47 รอบ mid ที่ 0.46 ทุก fill ฝั่ง bid ที่คุณสามารถออกทาง ask ภายหลังได้จะทำกำไร 2 เซนต์ จุดได้เปรียบสุทธิขึ้นอยู่กับความไม่สมดุลของ fill และการเคลื่อนไหวของราคา
Maker rebate: โปรแกรม liquidity-rewards ของ Polymarket จ่าย rebate ต่อหุ้นจาก maker fills ในตลาดที่เข้าเกณฑ์ ตัวเลขมีการเปลี่ยนแปลง; โปรดตรวจสอบหน้า rewards ทางการสำหรับค่าปัจจุบัน rebate จะถูกจ่ายเป็น pUSD เป็นระยะ แยกจากตัวการเทรดเอง
สำหรับตลาดส่วนใหญ่ รายได้หลักจะมาจาก spread capture rebate จะมีความหมายมากขึ้นเมื่อคุณสามารถ quote ในตลาดกว้างๆ ได้ (เช่น ปีเลือกตั้ง, รอบเพลย์ออฟกีฬารายใหญ่) ซึ่ง Polymarket จะเพิ่ม rebate เพื่อดึงสภาพคล่อง
ความเสี่ยง inventory และ skew
MM ที่ถูก hit ฝั่ง bid ซ้ำๆ จะสะสมสถานะ long ความเสี่ยงคือ mid ลดลงในขณะที่ inventory เป็น long; maker จะขาดทุนจากสถานะนั้นแม้จะได้รายได้จาก spread แล้วก็ตาม
วิธีป้องกัน: quote skew (เลื่อน bid ลงเมื่อ inventory long, และเลื่อน ask ขึ้นเมื่อ short เพื่อไม่ให้เกิด fill ฝั่งเดียวมากเกินไป); inventory cap (หยุด quote ฝั่งที่คุณถือยาวเกินไปแล้ว); active rebalancing (บางครั้ง cross spread เพื่อ ลดสถานะเมื่อ inventory อยู่ที่ขีดจำกัด)
คณิตศาสตร์คือ: ถ้า 60% ของ fills ฝั่ง bid ไม่เคยออกก่อนราคาจะเคลื่อนสวนทาง 2 เซนต์ กลยุทธ์นี้ก็ขาดทุนจาก fills เหล่านั้นเพียงอย่างเดียว ปรับ skew อย่างหนักเมื่อ fill imbalance > 65/35
เมื่อ MM ใช้ได้บน Polymarket (และเมื่อไหร่ที่ไม่ใช่)
MM ใช้ได้บน Polymarket เมื่อมีเงื่อนไข 3 ข้อนี้
- Liquid book: มีการแข่งขันด้าน quote มากพอจน spread ของคุณยังแข่งขันได้แต่ไม่เป็นศูนย์ ตลาดเลือกตั้งปี 2024 เกม NFL/NBA รายใหญ่ และ BTC ขึ้น/ลง 5 นาที ล้วนเข้าเกณฑ์
- Two-sided flow: มีทั้งผู้ซื้อและผู้ขาย active ตลาดที่มีทางเดียว (เกือบจบแล้วที่ 0.95+) ไม่มีอะไรให้ maker เก็บ
- Bounded price moves: การเก็บ spread ไม่ถูกกินด้วยการกระโดดของราคา 5 เซนต์ ตลาดที่ mid อยู่ในช่วงคงที่ (0.40-0.60) จะเป็นมิตรที่สุด
MM จะล้มเหลวใน: ตลาดที่ขับเคลื่อนด้วยข่าวสาร ซึ่ง mid กระโดดเร็วเกินกว่าที่คุณจะ re-quote; order book ที่บางจนคุณเป็น quote เดียวและการเทรดถัดไปไล่กินไป 5 ระดับ; ตลาดที่ใกล้ปิดผลลัพธ์ซึ่งด้านหนึ่งกำลัง converge ไป 0 หรือ 1
โครง code: ตั้งราคา bid/ask ทั้งสองฝั่งที่ +/- N เซนต์
pseudocode สำหรับ maker ที่ใช้งานได้ขั้นต่ำที่สุด
SPREAD_CENTS = 2
INVENTORY_CAP_SHARES = 50
def make_loop(token_id):
while True:
book = fetch_book(token_id)
mid = (book.best_bid + book.best_ask) / 2
inv = chain_balance(token_id)
# Skew: pull the side we are too long on
bid_px = mid - SPREAD_CENTS/200 - (0.005 if inv > INVENTORY_CAP_SHARES * 0.6 else 0)
ask_px = mid + SPREAD_CENTS/200 + (0.005 if inv < -INVENTORY_CAP_SHARES * 0.6 else 0)
cancel_my_existing_quotes(token_id)
if inv < INVENTORY_CAP_SHARES:
place_gtc(token_id, side="BUY", price=bid_px, size=5)
if inv > -INVENTORY_CAP_SHARES:
place_gtc(token_id, side="SELL", price=ask_px, size=min(5, inv))
time.sleep(2)
makers ระดับ production จะเพิ่ม: การติดตาม inventory แยกตามฝั่ง, การจัดลำดับ cancel ก่อน place, การสุ่ม jitter ระหว่างการ re-quote เพื่อไม่ให้เดาง่าย, kill-switch เมื่อ adverse selection รุนแรง (หัวข้อถัดไป)
ปรับ quote ตามข่าวสารที่เข้ามา
เมื่อมีข่าวเข้ามา fair value จะขยับก่อนที่ quote ของคุณจะทันตามไป MM ที่ไม่ดึง quote ออกตอนข่าวมาก็จะโดน pick off
สัญญาณคือ: อัตรา cancel ของ incoming fills พุ่งเกิน baseline ประมาณ 3 เท่าภายใน 30 วินาที หรือมีการ cross-check กับ event stream ที่กว้างกว่า (Polymarket Twitter/Discord, Bloomberg headline feed) เมื่อพบสัญญาณนี้ maker จะถอน quote ทั้งหมดเป็นเวลา 60-120 วินาที ปล่อยให้ mid ใหม่ทรงตัว แล้วค่อย re-quote รอบศูนย์กลางใหม่
การทำงานที่ง่ายที่สุดคือเฝ้าดู last-trade-price stream ของ token ถ้าราคากระโดดมากกว่า 2 standard deviations จากค่าเฉลี่ยใน rolling window จะสั่งพัก bot แล้ว bot จะกลับมาใช้งานเมื่อราคาทรงตัวต่อเนื่อง 30 วินาทีขึ้นไป
ปิด bot เมื่อ adverse selection พุ่งสูง
ทางออกแบบแข็ง ถ้า fill PnL ของ bot ใน 50 fills ล่าสุดติดลบอย่างชัดเจน แปลว่ามีบางอย่างผิดปกติ: ตลาดอาจกลายเป็นตลาดที่ขับเคลื่อนด้วยข่าวและคุณไม่ควรเป็น market maker หรือ spread ของคุณอาจแคบเกินไปเมื่อเทียบกับระดับ adverse selection ในตอนนั้น
เงื่อนไขในการปิดที่ควรเขียนไว้:
- hit bid ติดต่อกัน 5 ครั้งโดยไม่มี ask fill และ mid ลดลง > 1c ตั้งแต่ fill แรก
- Realized PnL ของ last 25 round-trip fills ต่ำกว่า -25% ของค่าที่คาดไว้
- WebSocket หลุด หรือพบว่า book ค้าง
- inventory แตะ cap ฝั่งใดฝั่งหนึ่งนาน > 5 นาที
เมื่อเกิดเงื่อนไข ให้ยกเลิกทุกคำสั่ง ปิด inventory ด้วย market order หยุดพักอย่างน้อย 15 นาที market maker ที่ไม่มี kill switch จะเสียเงินในช่วงที่ผันผวนจนกว่า trader จะสังเกตเห็นเอง-ซึ่งมักใช้เวลานานกว่าที่คุณคิดเสมอ












