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

โค้ดการจัดการความเสี่ยงระดับ production-grade สำหรับ Polymarket bots: position caps, daily loss limits, halt sentinels, fill-rate watchdogs, reconcile-on-restart, idempotent retries. รูปแบบโค้ดจากเทรดเดอร์ production จริง

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

โค้ดด้าน risk คือส่วนใหญ่ของ production trading bot จริง ๆ Strategy logic เป็นส่วนที่ง่าย; ส่วน caps, halts, watchdogs และ reconcilers ที่อยู่รอบ ๆ นั่นแหละคือสิ่งที่ตัดสินว่า bot จะรอดจากสัปดาห์แย่ครั้งแรกได้ไหม บทนี้คือ production-grade risk pattern

  • ทำไม risk code ถึงเป็นส่วนใหญ่ของ trading bot จริง
  • Position caps (per-market, per-strategy, total)
  • Daily loss kill switch
  • Halt sentinels (file-based emergency stop)
  • Fill-rate watchdog
  • Reconcile diary vs on-chain on restart
  • Code: production-grade halt-aware loop

ทำไม risk code ถึงเป็นส่วนใหญ่ของ trading bot จริง

จากการวัดใน codebase ของ bot เราเอง: 60% ของ LOC คือ risk code (caps, halts, watchdogs, reconciliation) 30% คือ strategy 10% คือ glue

สัดส่วนนั้นถูกต้องแล้ว Strategy คือส่วนที่ง่าย-การอธิบายว่าจะเข้าเมื่อไรและออกเมื่อไรใช้แค่ไม่กี่สิบบรรทัด Risk code คือทุกอย่างที่เหลือ: ต้องทำอะไรเมื่อราคาวิ่งสวนคุณเร็วเกินคาด, ต้องทำอะไรเมื่อ fills หยุดเข้า, ต้องทำอะไรเมื่อ WebSocket หลุด, ต้องทำอะไรเมื่อ strategy กลายเป็นขาดทุน

เรื่องเล่าความล้มเหลวของ builder ส่วนใหญ่มีโครงแบบเดียวกัน: strategy ใช้ได้ แต่ bot ยังเทรดต่อผ่าน regime change เพราะไม่มี halt ทำงาน เขียน halts ก่อนเขียน strategy

Position caps (per-market, per-strategy, total)

มี 3 caps ที่ต้องบังคับใช้ในโค้ด

  • Per-market cap: สูงสุด $X ต่อ market ไม่ว่า edge confidence จะเป็นเท่าไร โดยทั่วไป: $25-100 สำหรับ bot เล็ก ๆ, $200-500 สำหรับ production ช่วยจำกัดผลกระทบจากการตัดสินใจผิดใน market เดียว
  • Per-strategy cap: ถ้าคุณรันหลาย strategy แต่ละตัวจะได้ส่วนแบ่งของทุนรวม โดยทั่วไป: 30-50% ต่อ strategy ป้องกันไม่ให้วันที่แย่ของ strategy ตัวหนึ่งกินทุนของตัวอื่นหมด
  • Total cap: สูงสุด % ของ wallet balance ที่ deploy พร้อมกัน โดยทั่วไป: 50-70% เหลือทุนไว้สำหรับโอกาสที่ไม่คาดคิด หรือไว้จับ bugs ด้าน bookkeeping ของ bot เอง

cap ทั้งสามแบบควรถูกบังคับใช้ภายในฟังก์ชันวาง order ไม่ใช่แค่ใน strategy logic เท่านั้น Strategy อาจมี bug ได้; เกตสำหรับวาง order คือแนวป้องกันด่านสุดท้าย

Daily loss kill switch

การควบคุมความเสี่ยงที่สำคัญที่สุดเพียงอย่างเดียว: daily-loss kill switch

กฎ: ถ้า realized + unrealized PnL ตั้งแต่เที่ยงคืน UTC ต่ำกว่า -X% ของ starting daily balance ให้ bot หยุดเปิด position ใหม่ และ (ถ้าต้องการ) ปิดสถานะเดิมให้แบนราบ Typical X: 5-10%

คณิตศาสตร์คือ: bot ที่มี expected win rate 60% อาจมีโอกาสประมาณ 5% ที่จะเจอ losing streak 10 trades ถ้าไม่มี kill switch streak แบบนี้จะทบกัน: ขาดทุน $200 → bot ยังเทรดต่อ → ขาดทุนอีก $200 → wallet ลง 40% พอ switch ทำงานที่ -10% วันที่แย่ก็จะจบที่ $200 และพรุ่งนี้ bot เริ่มใหม่ได้

switch นี้บังคับฝั่ง server: เขียน halt file หรือ set database flag ที่ trading loop ตรวจทุก iteration รีสตาร์ตได้เฉพาะหลังจากตรวจสอบด้วยมือแล้ว

Halt sentinels (file-based emergency stop)

กลไก halt ที่ง่ายที่สุด: bot ตรวจหาไฟล์ (เช่น /opt/pmt/HALT) ทุกครั้งที่วนลูป และหยุดเทรดถ้ามีไฟล์นี้อยู่

def trading_loop():
    while True:
        if os.path.exists("/opt/pmt/HALT"):
            log("HALT file detected, sleeping")
            time.sleep(30)
            continue
        run_one_iteration()
        time.sleep(5)

ถ้าต้องการหยุดทันทีจากที่ไหนก็ได้ (SSH, Telegram bot, monitoring system): touch /opt/pmt/HALT ถ้าจะกลับมาทำงาน: rm /opt/pmt/HALT

แนวทางแบบ file-based ถูกตั้งใจให้ low-tech เพราะมันใช้ได้ในสถานการณ์ที่กลไก halt ที่ซับซ้อนกว่าล้มเหลว: ตอนที่ bot crash บางส่วน, ตอนที่ database เข้าไม่ถึง, ตอนที่ API key โดน rate-limit การเข้าถึง file-system ใช้ได้เสมอ

Fill-rate watchdog

strategy สมมติว่า FOK orders จะ fill ในอัตราหนึ่ง (มัก 60-80%) เมื่ออัตรานั้นตกลงอย่างมีนัยสำคัญ แปลว่ามีบางอย่างเปลี่ยนไป: market makers ถอนตัว, strategy ของคุณถูกจับได้, หรือมี API outage เกิดขึ้น ไม่ว่าเหตุผลอะไร สมมติฐานที่ใช้คำนวณ PnL ของ strategy พังแล้ว

ตรรกะของ watchdog: นับ rolling 24-hour fill-rate ถ้าต่ำกว่า 30% (หรือ 50% ของที่คาดไว้) ให้ alert + auto-halt กลับมาเทรดได้เฉพาะหลัง manual review

watchdog ยังมีประโยชน์ในเชิงวินิจฉัยด้วย การที่ fill-rate ลดลงแบบฉับพลันมักสัมพันธ์กับเหตุการณ์ภายนอก (Polymarket deploy, Polygon congestion, IP ของคุณโดน rate-limit) ซึ่งเป็นสิ่งที่คุณควรรู้ไม่ว่าผลกระทบต่อการเทรดจะเป็นอย่างไร

Reconcile diary vs on-chain on restart

bot จะเก็บ diary ของ position ที่คิดว่าตัวเองถืออยู่ chain จะเก็บความจริง ทั้งสองอย่างควรตรงกันเสมอ; ถ้าไม่ตรง bot กำลังทำงานบนความเชื่อที่ผิดและจะเทรดผิด

ตรรกะการ reconcile: ทุกครั้งที่รีสตาร์ต และทุก ๆ ชั่วโมงระหว่างการทำงานปกติ ให้ดึง on-chain balances ของทุก token ที่ bot เคยแตะมา เปรียบเทียบกับ diary; ถ้าบาลานซ์ของ token ใดต่างจาก diary เกินกว่าค่าความคลาดเคลื่อนจากการปัดเศษ ให้ alert + halt

สาเหตุที่พบบ่อยที่สุดของ divergence คือ order สำเร็จ แต่ API call ของ bot พลาดไป (timeout, retry ที่ไม่ถูกบันทึก) chain มี position อยู่; bot คิดว่าไม่มี ถ้าไม่ reconcile bot จะไม่วาง take-profit exit และ position จะถือไปจนถึง resolution

Code: production-grade halt-aware loop

อ้างอิง: trading loop สำหรับ production ที่ผูก risk controls ทั้งหมดไว้แล้ว

def production_loop():
    while True:
        # Halt checks
        if os.path.exists("/opt/pmt/HALT"):
            sleep_with_log(30); continue
        if daily_pnl_below_threshold():
            create_halt("daily PnL kill"); continue

        # Reconcile every hour
        if now() - last_reconcile > 3600:
            ok = reconcile_diary_vs_chain()
            last_reconcile = now()
            if not ok: create_halt("reconciliation failed"); continue

        # Fill-rate watchdog
        if recent_fill_rate() < 0.30:
            create_halt("fill rate collapse"); continue

        # Strategy
        try:
            run_strategy_once()
        except Exception as e:
            log_exception(e)
            if consecutive_exceptions >= 5:
                create_halt(f"exceptions: {e}"); continue
        time.sleep(5)

รูปแบบคือ: ทุก iteration ต้องผ่านเกตเสมอ bugs ของ strategy ไม่สามารถข้าม controls ได้โดยโครงสร้างของระบบ

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

Halt sentinel คืออะไร?
ไฟล์ (เช่น data/halt_autobuy) ที่ bot ตรวจทุกครั้งก่อนวาง order ถ้าไฟล์นี้มีอยู่ bot จะปฏิเสธการวาง order แม้ว่า strategy จะบอกให้ทำก็ตาม ช่วยให้คุณหยุด bot ระหว่างเกิดเหตุได้ด้วยคำสั่ง touch เพียงครั้งเดียว เราเพิ่มรูปแบบนี้เข้า production trader ของเราหลังจากเกิดเหตุ fill ค้างในเดือนเมษายน 2026
ควรกำหนด position caps เท่าไร?
Per-market: 1-5% ของ bankroll. Per-strategy: 10-20%. Total open exposure: 50-70% ของ bankroll (เก็บ cash buffer ไว้) จำกัด order เดียวที่ 1-2% ของ bankroll ไม่ว่า strategy จะเป็นอะไร - order ที่กดพลาดเพียงครั้งเดียวไม่ควรมีขนาดเท่าทั้งบัญชี
จะ implement daily loss kill switch อย่างไร?
ติดตาม realized + unrealized PnL รายวันแบบ UTC ถ้า daily PnL ต่ำกว่า -3 ถึง -5% ของ bankroll ให้ set halt sentinel และแจ้งตัวเอง bot จะหยุดรับ order ใหม่; ส่วน position ที่มีอยู่ให้จัดการด้วยมือ รีเซ็ตทุกวันตอน 00:00 UTC
ควรให้ bot ทำอะไรเมื่อรีสตาร์ตหลัง crash?
มี 3 ขั้น: (1) Reconcile open orders ผ่าน SDK เทียบกับ local diary ของคุณ (2) ตรวจ open positions on-chain เทียบกับ local state (3) ถ้ามีอะไรไม่ตรงกัน ให้ halt bot และต้องตรวจด้วยมือ ห้าม auto-resume เข้าไปอยู่ใน state ที่ไม่สอดคล้องกัน
จะป้องกันไม่ให้บั๊กตัวเดียวล้างบัญชีได้อย่างไร?
ใช้ limits แบบ layered: code-level position cap, code-level order-size cap, file-level halt sentinel, exchange-level (Polymarket) implicit minimum/maximum, monitoring alerts ที่แจ้งคุณเมื่ออัตราวาง order ผิดปกติ ไม่มีกลไกชั้นเดียวไหนพอ - มันต้องทำงานร่วมกัน
ถ้า logging ล้มเหลว bot ควรเทรดต่อไหม?
ไม่ควร ถ้า bot เขียน diary ไม่ได้ มันจะ reconcile ตอน restart ไม่ได้ ซึ่งหมายความว่า crash แล้วจะเข้าสู่ inconsistent state ให้ hard-fail bot ถ้า logging ล้มเหลว bot สำหรับ production ที่ดีจะระแวดระวังเรื่อง observability ของตัวเองมาก