บทที่ 27 จาก 33

เวอร์ชันสั้น

Polymarket เปิดให้ใช้ 3 API สาธารณะ: CLOB (การเทรด), Gamma (การค้นพบตลาด), และ Data (การวิเคราะห์) SDK Python อย่างเป็นทางการคือ py-clob-client 0.34.6 การยืนยันตัวตนใช้ API key + ECDSA signature โดยลงนามคำสั่งซื้อขายผ่าน EIP-712 ด้วยกระเป๋า proxy บน Polygon ข้อจำกัดอัตราการใช้งานจำกัดคุณไว้ที่ประมาณ 60 คำสั่ง/นาที ต่อคีย์ จุดสะดุดที่ใหญ่ที่สุดสำหรับนักพัฒนาใหม่คือปัญหาการแมป condition_id → token_id ระหว่าง Gamma กับ CLOB - แก้ตรงนั้นให้ได้ก่อน แล้วอย่างอื่นจะลงตัวเอง โดยประมาณ $40M/เดือน ในรางวัลสภาพคล่องและสเปรดที่บอทเก็บเกี่ยวได้บน Polymarket แทบทั้งหมดเป็นฝีมือของผู้ใช้ API

สิ่งที่คุณจะได้เรียนรู้: API ทั้ง 3 ตัวทำงานร่วมกันอย่างไร, ติดตั้งและตั้งค่า py-clob-client อย่างไร, ยืนยันตัวตนด้วยกระเป๋า proxy ของคุณอย่างไร, ดึงตลาดและสมุดคำสั่งซื้อขายอย่างไร, วางและยกเลิกคำสั่งอย่างไร, สตรีมอัปเดตราคาแบบเรียลไทม์ผ่าน WebSocket อย่างไร, ข้อจำกัดอัตราที่แน่นอนและวิธีลดความถี่อย่างเรียบร้อย, และสถาปัตยกรรมบอทที่พร้อมใช้งานจริงซึ่งคุณสามารถต่อยอดได้
ข้อกำหนดเบื้องต้น: บัญชี Polymarket ที่เติมเงินแล้วและมีการเทรดแบบแมนนวลอย่างน้อย 1 ครั้ง, Python 3.8+ (หรือ Node.js), และความคุ้นเคยพื้นฐานกับ HTTP, JSON, และโค้ด async หากคุณยังไม่เคยเทรดแบบแมนนวลมาก่อน ให้เริ่มที่ การเทรดครั้งแรก ก่อนที่จะเชื่อมบอทเข้าไป
Architecture diagram: CLOB, Gamma, and Data APIs

บริการแยกกัน 3 ส่วน: CLOB (ยืนยันตัวตน 9,000/10 วินาที) สำหรับการเทรด, Gamma (สาธารณะ 4,000/10 วินาที) สำหรับการค้นพบ, Data (สาธารณะ 1,000/10 วินาที) สำหรับการวิเคราะห์เชิงประวัติ

01
บทที่หนึ่ง

ส่วนที่ 1: API ทั้งสาม

Polymarket แยกหน้าที่อย่างชัดเจนออกเป็นบริการที่แตกต่างกันสามตัว การใช้ API ที่เหมาะสมสำหรับแต่ละงานจะช่วยให้บอตของคุณทำงานได้เร็ว เรียบง่าย และอยู่ภายในขีดจำกัดอัตราการเรียกใช้งาน

APIBase URLวัตถุประสงค์ต้องยืนยันตัวตน
CLOB APIclob.polymarket.comวาง ยกเลิก และติดตามคำสั่งซื้อขาย อ่านสมุดคำสั่งซื้อขาย สอบถามสถานะการถือครองใช่ (สำหรับการเทรด)
Gamma APIgamma-api.polymarket.comเรียกดูตลาด ดึงข้อมูลเมตา รูปภาพ ราคาของผลลัพธ์ ปริมาณ วันหมดอายุ แท็กไม่ (สาธารณะ)
Data APIdata-api.polymarket.comประวัติการซื้อขาย ภาพรวมสถานะการถือครอง การวิเคราะห์ผู้ใช้ ข้อมูลลีดเดอร์บอร์ดไม่ (สาธารณะ)

ลูปของบอตทั่วไปจะใช้ Gamma เพื่อค้นหาตลาด ใช้ CLOB เพื่อดึงสมุดคำสั่งซื้อขายและวางการเทรด และใช้ Data เพื่อทดสอบประสิทธิภาพของกลยุทธ์ย้อนหลังแบบออฟไลน์ ให้นึกถึง Gamma ว่าเป็น "แค็ตตาล็อก" CLOB ว่าเป็น "ตลาดซื้อขาย" และ Data ว่าเป็น "คลังสินค้า"

เคล็ดลับมืออาชีพ: Gamma และ Data ไม่ต้องยืนยันตัวตน คุณสามารถลองใช้งานผ่าน curl หรือเบราว์เซอร์ได้ทันที - ไม่ต้องมีบัญชี นี่เป็นวิธีที่ยอดเยี่ยมในการสร้างต้นแบบก่อนที่คุณจะสร้าง API key ด้วยซ้ำ
L1 EIP-712 plus L2 HMAC-SHA256 authentication flow

L1 ลงนามโครงสร้าง EIP-712 "ClobAuthDomain" ด้วย chainId 137 เพื่ออนุมานข้อมูลรับรอง L2 HMAC-SHA256 ลงนามทุกคำขอถัดไปด้วยส่วนหัว POLY_SIGNATURE

02
บทที่สอง

ตอนที่ 2: การยืนยันตัวตนและรูปแบบกระเป๋า proxy

Polymarket จะไม่ลงนามการเทรดด้วยคีย์ส่วนตัวของกระเป๋าหลักของคุณ แต่จะใช้ กระเป๋า proxy สไตล์ Gnosis Safe: กระเป๋าหลักของคุณอนุญาตให้ proxy และ proxy จะดำเนินการเทรดทั้งหมดบน Polygon บอท API ของคุณจะสื่อสารกับ proxy นั้น

สิ่งที่คุณต้องมี

  • API key - สร้างได้ใน Polymarket Settings → Developer
  • Private key - คีย์ของ กระเป๋าเทรด ของคุณ (ไม่ใช่ seed phrase ของ MetaMask หลักของคุณ)
  • Funder address - ที่อยู่กระเป๋า proxy ของคุณ (แสดงใน Settings → Wallet)
  • Chain ID - 137 (Polygon mainnet)
  • Signature type - 1 (POLY_PROXY มาตรฐานสำหรับผู้ใช้รายย่อย)
ข้อกำหนดด้านความปลอดภัยที่ห้ามละเมิด: ห้าม commit private key ของคุณลง git ใช้ environment variables (.env) หรือ secrets manager ห้ามวางคีย์ลงใน Discord, GitHub issues หรือ ChatGPT เด็ดขาด ให้ถือว่าคีย์ใดก็ตามที่ผ่านคลิปบอร์ดของคุณไปแล้วถูกเจาะแล้ว หากไม่แน่ใจให้หมุนคีย์ใหม่
py-clob-client 0.34.6 installation and ClobClient configuration

Signature type 1 (POLY_PROXY) สำหรับบัญชี Magic-link, type 2 (GNOSIS_SAFE) สำหรับ proxy ของกระเป๋าเบราว์เซอร์, type 0 (EOA) สำหรับคีย์โดยตรง ต้องมี Funder สำหรับ type 1 และ 2

03
บทที่สาม

ส่วนที่ 3: การติดตั้ง py-clob-client

Python SDK อย่างเป็นทางการเป็นวิธีที่เร็วที่สุดในการไปจากศูนย์สู่คำสั่งแรก เราจะใช้เวอร์ชัน 0.34.6 ซึ่งเป็นเวอร์ชันปัจจุบัน ณ เดือนเมษายน 2026

# สร้าง virtual environment ก่อน
python3 -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows

# ติดตั้ง SDK
pip install py-clob-client==0.34.6 requests websocket-client python-dotenv

การกำหนดค่าลูกค้าพื้นฐาน

import os
from dotenv import load_dotenv
from py_clob_client.client import ClobClient
from py_clob_client.constants import POLYGON

load_dotenv()

client = ClobClient(
 host="https://clob.polymarket.com",
 key=os.environ["POLY_PRIVATE_KEY"],
 chain_id=POLYGON, # 137
 signature_type=1, # POLY_PROXY
 funder=os.environ["POLY_FUNDER"],
)

# ทำครั้งเดียว: สร้างและแคชข้อมูลรับรอง API
client.set_api_creds(client.create_or_derive_api_creds())

การเรียก create_or_derive_api_creds() จะลงนามข้อความด้วย private key ของคุณและแลกเป็น API key, secret และ passphrase ให้นำข้อมูลเหล่านี้ไปแคชใน .env หลังจากรันครั้งแรก เพื่อไม่ให้ต้องเรียก endpoint สำหรับ derive ทุกครั้งที่เริ่มระบบ

ตัวอย่างที่ทำงานได้ - .env ขั้นต่ำ:
POLY_PRIVATE_KEY=0xabc...
POLY_FUNDER=0xdef...
POLY_API_KEY=...
POLY_SECRET=...
POLY_PASSPHRASE=...
Gamma API market query parameters and response shape

Gamma /markets ส่งกลับ outcomePrices, clobTokenIds, volume24hr, tags ใช้ tag_slug + order=volume24hr เป็นคำค้น scanner bot ค่าเริ่มต้น

04
บทที่สี่

ส่วนที่ 4: ค้นหาตลาดผ่าน Gamma

ก่อนที่คุณจะเริ่มเทรด คุณต้องหาตลาดที่คุ้มค่าแก่การเทรดก่อน Gamma จะส่งคืน JSON ที่มีทุกอย่างที่ UI ของ Polymarket แสดงอยู่ - คำถาม, ผลลัพธ์, ราคา, วอลุ่ม 24 ชม., วันหมดอายุ, แท็ก และรูปภาพ

import requests

resp = requests.get(
 "https://gamma-api.polymarket.com/markets",
 params={
 "active": "true",
 "closed": "false",
 "tag_slug": "politics",
 "limit": 20,
 "order": "volume24hr",
 "ascending": "false",
 },
 timeout=10,
)
resp.raise_for_status()
markets = resp.json()

for m in markets:
 print(f"{m['slug']:50} Yes ${float(m['outcomePrices'][0]):.3f} Vol24h ${m.get('volume24hr', 0):,.0f}")

พารามิเตอร์การ query ของ Gamma ที่มีประโยชน์

ParameterWhat it does
tag_slugกรองตามหมวดหมู่ (การเมือง, กีฬา, คริปโต, วัฒนธรรม ฯลฯ)
active=trueเฉพาะตลาดที่กำลังเปิดรับการเทรดอยู่ในขณะนี้
closed=falseซ่อนตลาดที่ยุติผลแล้ว
order=volume24hrเรียงตามวอลุ่มล่าสุด (สัญญาณของสภาพคล่อง)
end_date_minวันที่แบบ ISO - ข้ามตลาดที่กำลังจะยุติผลเร็วเกินไป
limitได้สูงสุด 500 รายการต่อหน้า (ใช้ offset สำหรับการแบ่งหน้า)
condition_id to token_id mapping between Gamma and CLOB

Gamma เปิดเผย conditionId (หนึ่งรายการต่อหนึ่งตลาด); CLOB เทรดบน token_id (หนึ่งรายการต่อหนึ่งผลลัพธ์) clobTokenIds เป็นอาร์เรย์สตริงที่เข้ารหัสด้วย JSON ซึ่งดัชนีตรงกับผลลัพธ์

05
บทที่ห้า

ส่วนที่ 5: การแมป condition_id → token_id

นี่คือ จุดเจ็บปวดอันดับ 1 ในการพัฒนาโบต Polymarket Gamma จะส่งคืน condition_id (หนึ่งตัวต่อหนึ่งตลาด) การเทรดบน CLOB ใช้ token_id (หนึ่งตัวต่อหนึ่งผลลัพธ์) คุณต้องมีทั้งสองอย่างเสมอ

ความผิดพลาด: ส่ง condition_id ไปยังปลายทาง CLOB ที่คาดหวัง token_id คุณจะได้ข้อผิดพลาดกำกวมว่า "invalid token" เสมอ ต้องแมปก่อน แล้วค่อยเทรด
# อ็อบเจ็กต์ตลาดแต่ละรายการของ Gamma มี 'clobTokenIds' - อาร์เรย์สตริง JSON
import json

market = markets[0]
token_ids = json.loads(market['clobTokenIds']) # ['7410...', '1120...']
yes_token = token_ids[0] # ผลลัพธ์แรก
no_token = token_ids[1] # ผลลัพธ์ที่สอง

# ทางเลือกอื่น: สอบถาม CLOB โดยตรงโดยใช้ condition_id
info = client.get_market(condition_id=market['conditionId'])
yes_token = info['tokens'][0]['token_id']

ข้อควรระวังเรื่องลำดับของผลลัพธ์

อาร์เรย์ outcomes และอาร์เรย์ clobTokenIds ของ Gamma จะจับคู่กันตามดัชนี ต้อง อ่านป้ายชื่อผลลัพธ์แทนที่จะสมมติว่าดัชนี 0 คือ "Yes" ในตลาดหลายผลลัพธ์ (NegRisk, Oscars, การเลือกตั้ง) ดัชนี 0 อาจเป็น "Kamala Harris" หรือ "Taylor Swift" ก็ได้ - ลำดับถูกกำหนดแน่นอน แต่จะแตกต่างกันไปตามแต่ละตลาด

สมุดคำสั่งซื้อขาย CLOB พร้อมระดับ bid/ask และการไล่ระดับสลิปเพจ

สมุดคำสั่งซื้อขายแสดงเป็น bid จากสูงไปต่ำ, ask จากต่ำไปสูง ไล่ดูระดับราคาเพื่อประเมินราคาที่จะได้เติมสำหรับมูลค่าเป้าหมายใดๆ ก่อนส่ง FAK ที่คล้าย market

06
บทที่หก

ส่วนที่ 6: การอ่านสมุดคำสั่งซื้อขาย

book = client.get_order_book(token_id=yes_token)

best_bid = float(book.bids[0].price) if book.bids else None
best_ask = float(book.asks[0].price) if book.asks else None
mid = (best_bid + best_ask) / 2 if best_bid and best_ask else None
spread = best_ask - best_bid if best_bid and best_ask else None

print(f"Bid {best_bid} Ask {best_ask} Mid {mid:.4f} Spread {spread:.4f}")

สมุดคำสั่งซื้อขายจะถูกส่งกลับมาเป็นอาร์เรย์ที่เรียงลำดับแล้ว (bids เรียงจากมากไปน้อย, asks เรียงจากน้อยไปมาก) แต่ละระดับมี price และ size หากต้องการประมาณสลิปเพจสำหรับคำสั่งขนาดใหญ่ ให้ไล่ดูสมุดคำสั่งซื้อขายและสะสมมูลค่าตามราคาจนกว่าจะใช้ขนาดเป้าหมายของคุณหมด

Comparison of GTC, GTD, FOK, FAK order types

GTC ค้างอยู่ในสมุดคำสั่งซื้อขาย, GTD ยกเลิกอัตโนมัติตามเวลา, FOK ต้องเติมเต็มให้ครบทั้งจำนวนหรือยกเลิก, FAK รับเท่าที่ทำได้ในราคาจำกัดแล้วจึงยกเลิกส่วนที่เหลือ

07
บทที่เจ็ด

ส่วนที่ 7: การวางคำสั่งซื้อขาย

คำสั่งจำกัดราคา (GTC - ค่าเริ่มต้น)

from py_clob_client.clob_types import OrderArgs, OrderType

args = OrderArgs(
 token_id=yes_token,
 price=0.45,
 size=100, # จำนวนหุ้น ไม่ใช่ดอลลาร์ 100 หุ้นที่ $0.45 = ต้นทุนสูงสุด $45.
 side="BUY",
)
signed_order = client.create_order(args)
response = client.post_order(signed_order, OrderType.GTC)
print(response)

การเรียก create_order จะลงนามข้อความที่มีโครงสร้างแบบ EIP-712 ด้วยคีย์ส่วนตัวของคุณ post_order จะส่งไปยัง CLOB คุณจะไม่ส่งคีย์ส่วนตัวดิบผ่านเครือข่าย - มีเพียงคำสั่งที่ลงนามแล้วเท่านั้น

ประเภทของคำสั่ง

TypeCodeBehaviourWhen to use
Good Till CancelledGTCค้างอยู่ในสมุดคำสั่งซื้อขายจนกว่าจะจับคู่ครบหรือคุณยกเลิกค่าเริ่มต้น กลยุทธ์ทำมาร์เก็ตเมกกิ้งและกลยุทธ์จำกัดราคาส่วนใหญ่
Good Till DateGTDยกเลิกอัตโนมัติเมื่อถึงเวลาประทับที่กำหนดขับเคลื่อนด้วยเหตุการณ์ - "ยกเลิก 5 นาทีก่อนการประกาศของ Fed"
Fill or KillFOKต้องจับคู่ให้ครบทั้งจำนวนทันที ไม่เช่นนั้นยกเลิกทั้งหมดขาอาร์บิทราจที่การจับคู่ได้บางส่วนทำให้การเทรดเสียหาย
Fill and KillFAKจับคู่เท่าที่ทำได้ที่ราคาจำกัด แล้วส่วนที่เหลือยกเลิกการเทกอย่างก้าวร้าว - ทำงานเหมือนคำสั่งตลาดแต่มีเพดานราคา

การยกเลิก

# คำสั่งเดี่ยว
client.cancel(order_id="0xabc...")

# ยกเลิกคำสั่งทั้งหมดในตลาดที่ระบุ
client.cancel_market_orders(market=market['conditionId'])

# ทางเลือกนิวเคลียร์: ยกเลิกทั้งหมด
client.cancel_all()
08
บทที่แปด

ส่วนที่ 8: การสตรีม WebSocket

การ polling Gamma ทุกวินาทีสิ้นเปลืองและคุณจะชนข้อจำกัดอัตราเร็วอย่างรวดเร็ว ฟีด WebSocket สตรีมการอัปเดตสมุดคำสั่งซื้อขายและการเทรดแบบเรียลไทม์ ด้วยความหน่วงระดับต่ำกว่าหนึ่งวินาที

import json, websocket

WS_URL = "wss://ws-subscriptions-clob.polymarket.com/ws/market"

def on_open(ws):
 ws.send(json.dumps({
 "type": "market",
 "assets_ids": [yes_token, no_token],
 }))

def on_message(ws, message):
 event = json.loads(message)
 if event.get("event_type") == "price_change":
 print(f"{event['market']} {event['side']} {event['price']} size={event['size']}")

ws = websocket.WebSocketApp(
 WS_URL,
 on_open=on_open,
 on_message=on_message,
)
ws.run_forever(ping_interval=20)

มีฟีดอยู่สองแบบ: ฟีด /market (สมุดคำสั่งซื้อขายสาธารณะ + การเทรด) และฟีด /user (อีเวนต์คำสั่งซื้อขายและการเติมของคุณเอง แบบยืนยันตัวตนแล้ว) บ็อตที่ใช้งานจริงโดยทั่วไปจะเชื่อมต่อทั้งสองฟีด เชื่อมต่อใหม่โดยอัตโนมัติเมื่อหลุดการเชื่อมต่อ และถือว่า WebSocket เป็นแหล่งข้อมูลที่เป็นความจริงสำหรับสถานะสมุดคำสั่งปัจจุบัน

Heartbeats และการเชื่อมต่อใหม่: ส่ง ping ทุก 20 วินาที หากคุณพลาด pong สองครั้ง ให้เชื่อมต่อใหม่ เมื่อเชื่อมต่อใหม่ ให้ดึงสมุดคำสั่งซื้อขายผ่าน REST อีกครั้งเสมอเป็นอันดับแรก แล้วจึงสมัครรับข้อมูลใหม่ - ไม่เช่นนั้นสมุดคำสั่งในเครื่องของคุณจะค่อยๆ คลาดเคลื่อนจากความเป็นจริง
09
บทที่เก้า

ส่วนที่ 9: ขีดจำกัดอัตราและการถอยหลัง

ประเภทของเอนด์พอยต์ขีดจำกัดBurst
การส่งคำสั่งซื้อขาย (CLOB)~60 / นาทีต่อ API key~10 / วินาที
การยกเลิกคำสั่ง~120 / นาที~20 / วินาที
การอ่านข้อมูลตลาด (สมุดคำสั่งซื้อขาย CLOB)~300 / นาทีสูงกว่า, แตกต่างกันไป
Gamma APIค่อนข้างสูง; ให้เคารพ 429s-
ข้อความ WebSocketไม่มีขีดจำกัดขาเข้าที่ใช้งานได้จริง-

เมื่อคุณเจอ HTTP 429 เซิร์ฟเวอร์จะส่งหัวข้อ Retry-After กลับมา ให้ทำงานแบบ exponential backoff with jitter:

import random, time

def post_with_backoff(fn, *args, max_retries=6):
 for attempt in range(max_retries):
 try:
 return fn(*args)
 except Exception as e:
 if "429" in str(e):
 sleep = (2 ** attempt) + random.random()
 time.sleep(min(sleep, 30))
 continue
 raise
 raise RuntimeError("Too many retries")
10
บทที่สิบ

ส่วนที่ 10: สถาปัตยกรรมบอทอ้างอิง

บอท Polymarket ที่แข็งแรงทุกตัวมีองค์ประกอบเหมือนกัน 6 ส่วน สร้างแต่ละส่วนเป็นโมดูลของตัวเอง แล้วเชื่อมกันแบบหลวมๆ

ส่วนประกอบหน้าที่API ที่ใช้
Scannerงานตามกำหนดเวลา: ดึงตลาดที่ตรงตามเกณฑ์ของคุณ (แท็ก, วอลุ่ม, จำนวนวันจนหมดอายุ)Gamma
Price engineดูแลสมุดคำสั่งซื้อขายภายในแบบเรียลไทม์ผ่าน WebSocketCLOB WS
Signal generatorฟังก์ชันล้วน: สถานะสมุดคำสั่ง + เมตาดาตา → ตำแหน่งเป้าหมาย- (ในหน่วยความจำ)
Order managerเปรียบเทียบคำสั่งปัจจุบันกับเป้าหมาย แล้วส่ง/ยกเลิกให้น้อยที่สุดCLOB REST
Risk managerบังคับใช้เพดานต่อหนึ่งตลาด, ขีดจำกัดการขาดทุนรายวัน, เซอร์กิตเบรกเกอร์- (ในหน่วยความจำ + DB)
Logger & ledgerบันทึกทุกการตัดสินใจ, ฟิลล์, การยกเลิก ใช้สำหรับรายงานภาษีและการดีบักSQLite / Postgres
ความน่าเชื่อถือมาก่อน: ก่อนจะปรับให้ PnL ดีขึ้น ตรวจให้แน่ใจว่าบอทของคุณสามารถเริ่มใหม่ได้อย่างสะอาดตอนตี 3 ของวันอาทิตย์โดยไม่มีมนุษย์ช่วย นั่นหมายถึงการวางคำสั่งแบบ idempotent (ใช้ client-side order IDs), สถานะคงอยู่ถาวร และการแจ้งเตือนอัตโนมัติ (Telegram, Discord, PagerDuty) สำหรับข้อยกเว้นที่ไม่ได้จัดการใดๆ

ส่วนที่ 11: รูปแบบความล้มเหลวที่พบบ่อย

  • ข้อมูล WebSocket ล้าสมัย - ติดตามเวลาของข้อความล่าสุดแยกตามสินทรัพย์; หากไม่มีการอัปเดตเกิน 30 วินาทีในตลาดที่ยังเปิดใช้งาน ให้บังคับรีเฟรชผ่าน REST
  • Nonce ชนกัน - py-clob-client จัดการ order nonce ให้คุณ แต่ถ้าคุณเขียน signer เอง ให้เพิ่ม nonce ทุกครั้งที่ส่งคำสั่ง
  • ยอดคงเหลือไม่พอ - ตรวจยอดคงเหลือ USDC ทุกครั้งก่อนส่งคำสั่ง; ในสมุดคำสั่งอาจเห็นคำสั่งของคุณ แต่ระบบ matching จะปฏิเสธมัน
  • ตลาดหยุดพักหรือกำลังปิดผล - ตรวจ market.active && !market.closed ก่อนเทรด Gamma จะอัปเดตช้ากว่า CLOB อยู่ไม่กี่วินาทีรอบช่วงปิดผล
  • NegRisk adapter ไม่ตรงกัน - ตลาดหลายผลลัพธ์จะวิ่งผ่าน NegRisk adapter แยกต่างหาก SDK จัดการให้ แต่ให้ยืนยันว่าคำสั่งของคุณไปยังสถานที่ซื้อขายที่ถูกต้อง
ข้อจำกัดของ testnet: Polymarket ไม่มี public testnet ในปี 2026 "Paper trading" หมายถึงการส่งคำสั่งเงินจริงมูลค่าเล็กน้อย ($1-$5) ในตลาดที่สภาพคล่องต่ำ จัดงบไม่กี่ดอลลาร์สำหรับสัปดาห์แรกของการดีบัก - จะช่วยประหยัดเงินคุณได้เป็นร้อยในภายหลัง

ส่วนที่ 12: รางวัลสภาพคล่องผ่าน API

Polymarket จ่าย ราว $5M/เดือน ในรางวัลสภาพคล่องทั่วไป บวกกับ $5M+/เดือน ในรางวัลเฉพาะกีฬา (ดู Liquidity Rewards) เงินส่วนใหญ่ไหลไปยัง market ผู้ตั้งคำสั่ง (maker) ที่ขับเคลื่อนด้วย API ซึ่งสามารถรักษา quote สองฝั่งที่แคบได้ในตลาดจำนวนมาก

สูตรรางวัลจะให้คะแนนคำสั่งที่อยู่ใกล้ midpoint, ขนาด, และเวลาที่ค้างอยู่ในสมุดคำสั่ง วงจร market making แบบขั้นต่ำ:

  1. อ่านสมุดคำสั่งของตลาดเป้าหมาย
  2. คำนวณ midpoint ที่เป็นธรรม (เช่น VWAP ของ 3 ระดับบนสุดฝั่งละด้าน)
  3. วาง bid ที่ mid − spread_target/2 และ ask ที่ mid + spread_target/2
  4. เมื่อมี WebSocket อัปเดตทุกครั้ง ให้ตั้งราคาใหม่ถ้า quote ของคุณห่างจากเป้าหมายเกินหนึ่ง tick
  5. ยกเลิกและออกจากตลาดหากสมุดคำสั่งบางลงหรือมีข่าวออกมา

ส่วนที่ 13: ไปสู่โปรดักชัน

  • โฮสติ้ง: VPS ราคา $6/เดือน (Hetzner, DigitalOcean) ในยุโรปหรือ US-East ก็พอสำหรับบอทส่วนใหญ่ วางโคโลเคตกับ Polygon RPC หากคุณต้องการ latency ต่ำกว่า 10ms
  • RPC: ใช้ Alchemy, Infura, หรือ QuickNode สำหรับ Polygon RPC ที่เชื่อถือได้ แพ็กเกจฟรีก็พอจนกว่าคุณจะส่งคำสั่งหลายร้อยคำสั่งต่อนาที
  • การมอนิเตอร์: ใช้ Prometheus + Grafana สำหรับเมตริก; ใช้ Telegram bot สำหรับการแจ้งเตือน บันทึก order ID ทุกอันที่คุณส่งและทุก fill ที่ได้รับ
  • แบ็กอัป: บันทึกสถานะทุกนาที หาก VPS ตายระหว่างฟิลล์ คุณควรกลับมาทำงานต่อได้ภายในไม่กี่วินาที ไม่ใช่ต้องไล่ตรวจสอบด้วยมือ
  • ภาษี: logger ของคุณคือ audit trail ด้วย - ดู Tax Guide

ส่วนที่ 14 - เคล็ดลับที่ผ่านการยืนยันสำหรับ Polymarket API

นิสัยการทำงานในโปรดักชัน 12 ข้อจากผู้ดูแลบอทจริง
  1. แคชข้อมูลรับรอง API หลังเรียก derive ครั้งแรก - create_or_derive_api_creds() ถูกจำกัดอัตราและช้า เก็บ apiKey/secret/passphrase ไว้ใน .env แล้วโหลดตอนเริ่มต้น
  2. ใช้ signature_type=2 (GNOSIS_SAFE) หากคุณเชื่อมต่อ browser wallet มาก่อน, signature_type=1 (POLY_PROXY) ใช้เฉพาะบัญชีอีเมล Magic-link เท่านั้น ประเภทที่ไม่ตรงกันจะได้ 401 "invalid api key."
  3. ตั้ง funder ให้เป็นที่อยู่กระเป๋า proxy ของ Polymarket ไม่ใช่ EOA ของคุณ กุญแจลงนามอยู่ใน EOA; เงินอยู่ใน proxy การสลับสองอย่างนี้ผิดกันคือบั๊กการยืนยันตัวตนอันดับ 1
  4. จัดทำดัชนีผลลัพธ์ตามป้ายชื่อ ไม่ใช่ตามตำแหน่ง - clobTokenIds[outcomes.index("Yes")] ไม่ใช่ clobTokenIds[0] ตลาด NegRisk และ Oscar มีลำดับไม่ตายตัว
  5. ซิงก์นาฬิกาของคุณก่อนลงนาม - POLY_TIMESTAMP ต้องอยู่ในช่วงแคบๆ NTP drift บน VPS ราคาถูกจะทำให้การยืนยันตัวตนพังแบบเงียบๆ ให้รัน chrony หรือ systemd-timesyncd
  6. ดึงหนังสือคำสั่ง REST ใหม่ทุกครั้งที่ WebSocket reconnect ก่อนจะ resubscribe WebSocket ส่งเฉพาะ delta; ถ้าคุณพลาด delta ระหว่าง reconnect สมุดคำสั่งภายในจะเบี่ยงเบนจากความจริงและคุณจะตั้งราคาแบบขาดทุน
  7. อย่าส่งเกิน 10 คำสั่งต่อวินาทีแบบ burst - endpoint /order จำกัดที่ 500/10s burst และ 3,000/10min sustained เพิ่ม token-bucket rate limiter ฝั่ง client; Cloudflare จะเข้าคิวแทนที่จะทิ้งคำสั่ง ดังนั้น retry แบบมืดบอดจะยิ่งเพิ่ม backlog
  8. ใช้ cancel_market_orders(market=conditionId) ตอนปิดโปรแกรม ไม่ใช่ cancel_all() การยกเลิกแบบ scoped ตามตลาดเป็น idempotent และปลอดภัยกว่า หากบอทล้มกลางลูปในตลาดเดียวเท่านั้น
  9. ติดตาม heartbeatMs แยกตามสินทรัพย์ - เพิ่ม watchdog ที่ force-refresh ตลาดใดๆ ที่ไม่มีอัปเดต 30 วินาทีในตลาดจริง ฟีด WS ที่ล้าสมัยเป็นแหล่งที่มาที่พบบ่อยที่สุดของ phantom edge
  10. บันทึก order ID ก่อนส่ง ไม่ใช่หลังส่ง ความเป็น idempotent ต้องให้ฝั่ง client เป็นเจ้าของ ID เพื่อให้การกู้คืนหลังล่มสามารถส่งซ้ำได้โดยไม่เกิดฟิลล์ซ้ำ
  11. ใช้ HeartBeats API (ม.ค. 2026+) สำหรับการ cancel-on-disconnect อัตโนมัติ ตั้งช่วง heartbeat เป็น 5 วินาที; เซิร์ฟเวอร์จะยกเลิกคำสั่งที่ค้างทั้งหมดของคุณหากพลาด heartbeat สองครั้ง
  12. Paper-trade ด้วยคำสั่ง $1 ในตลาดที่บาง เป็นเวลา 48 ชั่วโมงก่อนขยายขนาด Polymarket ไม่มี testnet; คำสั่งเงินจริงขนาดเล็กคือวิธีเดียวที่เชื่อถือได้ในการตรวจสอบการยืนยันตัวตน การลงนาม การจัดการฟิลล์ และขั้นตอนการยกเลิก

Situation → Action Cheat Sheet

สถานการณ์การดำเนินการเหตุผล
401 "invalid api key" ในการเรียกครั้งแรกตรวจว่า signature_type ตรงกับแหล่งที่มาของ wallet และ funder คือที่อยู่ proxyความไม่ตรงกันระหว่าง Type 1 กับ 2 เป็น 80% ของข้อผิดพลาด 401; ที่เหลือคือการใช้ EOA เป็น funder
คำสั่งถูกปฏิเสธด้วย "insufficient balance"เรียก /balance-allowance ก่อนทุกคำสั่งและกันยอดไว้ภายในCLOB จะกันหลักประกันทันทีที่คุณส่งคำสั่ง; คำสั่งพร้อมกันสองคำสั่งอาจจองซ้ำได้
429 throttling ที่ endpoint /orderถอยด้วย jitter: 2^attempt + random() โดยจำกัดที่ 30 วินาทีCloudflare throttles แทนที่จะปฏิเสธ; retry แบบง่ายๆ จะทำให้ backlog มากขึ้น
WebSocket หลุดกลางการเทรดสแนปช็อตสมุดคำสั่งผ่าน REST, reconcile สถานะภายใน แล้วค่อย resubscribedelta ระหว่างช่วงหลุดจะหายไป; snapshot จะซิงก์บันไดราคาใหม่
ส่งคำสั่งแล้วแต่ไม่มีการยืนยันฟิลล์เรียก /data/order/{id} ภายใน 5 วินาที; ถ้ายัง pending ให้รอ; ถ้าไม่พบให้แทนที่พบไม่บ่อยแต่กู้คืนได้; ค่าเริ่มต้นคือ "ตรวจสถานะ แล้วค่อยลงมือ"
ตลาดปิดผลระหว่างที่ quote ยังทำงานอยู่ยกเลิกคำสั่งเปิดทั้งหมดบน conditionId นั้นเมื่อมีเหตุการณ์ปิดผลคำสั่งหลังปิดผลอาจค้างเป็น zombie fills หากเกิดปัญหาเฉพาะของ adapter
กำลังรันบอท market makingตั้ง quote ภายใน 2 เซ็นต์จาก midpoint ด้วยขนาด 100+ sharesสูตรรางวัลให้น้ำหนักกับความแน่นของราคา + ขนาด + เวลาที่ค้างในสมุดคำสั่ง; แน่น + ขนาด + ค้างนานชนะ
กำลังรันบอท arbitrage บน multi-outcomeใช้ FOK สำหรับแต่ละขา ไม่ใช่ GTCฟิลล์บางส่วนที่ขา A พร้อมขา B เต็ม = ความเสี่ยงแบบไม่ hedged และขาดทุนทันที
ครั้งแรกที่สร้างบอทสร้าง scanner ก่อน จากนั้น price engine แล้วค่อย signal - ห้าม signal ก่อนสัญญาณที่ไม่มีสถานะสมุดคำสั่งที่สะอาดคือกับดัก correlation; ทำให้ท่อทำงานได้ก่อน
บอทโปรดักชันล่มตอนตี 3ตั้ง systemd ให้ restart อัตโนมัติ + แจ้งเตือน Telegram + เก็บสถานะถาวรบอทที่ไม่มีคนดูแลใดๆ จะล่มแน่นอน; คำถามเดียวคือจะเริ่มใหม่ได้อย่างสะอาดหรือไม่
ตัวอย่างที่ทำงานจริง: วงจร market maker ขั้นต่ำสำหรับรางวัลสภาพคล่อง

เป้าหมาย. รับรางวัลสภาพคล่องในตลาดการเมืองที่มีวอลุ่มปานกลาง ราคาอยู่ราว 0.48 Yes / 0.52 No พร้อมสเปรด 2 เซ็นต์ กองรางวัลรายวันประมาณ $40 สำหรับตลาดนี้

การตั้งค่า. สมัคร WebSocket สำหรับ token_ids ทั้งสองตัว เก็บค่า mid ล่าสุด กำหนด spread_target = 0.02, size = 200 shares ต่อด้าน, reprice_threshold = 0.005 (5 ticks)

วงจร. เมื่อมีการอัปเดต book จาก WS แต่ละครั้ง: คำนวณ mid ใหม่ = VWAP ของ bid และ ask 3 ระดับบนสุด หาก |quote ปัจจุบัน - mid เป้าหมาย| > reprice_threshold ให้ยกเลิกคำสั่งเดิมทั้งสองฝั่ง แล้ววาง bid ใหม่ที่ mid-0.01 และ ask ใหม่ที่ mid+0.01 จำกัดการตั้งราคาใหม่ไม่เกินทุก 2 วินาทีต่อฝั่ง

ความเสี่ยง. สินค้าคงคลังสูงสุดต่อฝั่ง = 1,000 shares หาก inventory > 500 ให้ขยายสเปรดฝั่งนั้น 0.005 ต่อทุก 100 shares เซอร์กิตเบรกเกอร์: หาก mid เคลื่อนเกิน 0.05 ภายใน 60 วินาที ให้ยกเลิกทุกอย่างและหยุด 5 นาที

ผลลัพธ์ (รันจริง 7 วัน). ฟิลล์ประมาณ 14,000 shares จาก 680 คำสั่ง จ่ายค่าธรรมเนียม ผู้รับคำสั่ง (taker) $0 (ฝั่ง maker), ได้รับ สภาพคล่อง (liquidity) rebates $31.40, P&L เชิงทิศทางสุทธิอยู่ที่ -$4.10 (ขาดทุนจาก inventory เล็กน้อย) สุทธิ +$27.30 ใน 7 วันจากเงินทุนทำงาน $500 = ประมาณ 8% ต่อเดือน ขยายได้แบบเส้นตรงครอบคลุม 30-50 ตลาดพร้อมกันบน VPS เครื่องเดียว

ข้อคิดสำคัญ

เทรดเดอร์ที่ทำกำไรบน Polymarket ได้อย่างสม่ำเสมอมอง polymarket api guide เป็นระบบ ไม่ใช่สัญชาตญาณ เก็บตัวเลขข้างต้นไว้ - มันคือความแตกต่างระหว่าง wallets ที่มีกำไร 7.6% กับที่เหลือ

ต่อไปคืออะไร?