บทที่ 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

บริการแยกกัน 3 ส่วน: CLOB (ยืนยันตัวตน 9,000/10 วินาที) สำหรับการเทรด, Gamma (สาธารณะ 4,000/10 วินาที) สำหรับการค้นพบ, Data (สาธารณะ 1,000/10 วินาที) สำหรับการวิเคราะห์เชิงประวัติ
ส่วนที่ 1: API ทั้งสาม
Polymarket แยกหน้าที่อย่างชัดเจนออกเป็นบริการที่แตกต่างกันสามตัว การใช้ API ที่เหมาะสมสำหรับแต่ละงานจะช่วยให้บอตของคุณทำงานได้เร็ว เรียบง่าย และอยู่ภายในขีดจำกัดอัตราการเรียกใช้งาน
| API | Base URL | วัตถุประสงค์ | ต้องยืนยันตัวตน |
|---|---|---|---|
| CLOB API | clob.polymarket.com | วาง ยกเลิก และติดตามคำสั่งซื้อขาย อ่านสมุดคำสั่งซื้อขาย สอบถามสถานะการถือครอง | ใช่ (สำหรับการเทรด) |
| Gamma API | gamma-api.polymarket.com | เรียกดูตลาด ดึงข้อมูลเมตา รูปภาพ ราคาของผลลัพธ์ ปริมาณ วันหมดอายุ แท็ก | ไม่ (สาธารณะ) |
| Data API | data-api.polymarket.com | ประวัติการซื้อขาย ภาพรวมสถานะการถือครอง การวิเคราะห์ผู้ใช้ ข้อมูลลีดเดอร์บอร์ด | ไม่ (สาธารณะ) |
ลูปของบอตทั่วไปจะใช้ Gamma เพื่อค้นหาตลาด ใช้ CLOB เพื่อดึงสมุดคำสั่งซื้อขายและวางการเทรด และใช้ Data เพื่อทดสอบประสิทธิภาพของกลยุทธ์ย้อนหลังแบบออฟไลน์ ให้นึกถึง Gamma ว่าเป็น "แค็ตตาล็อก" CLOB ว่าเป็น "ตลาดซื้อขาย" และ Data ว่าเป็น "คลังสินค้า"
curl หรือเบราว์เซอร์ได้ทันที - ไม่ต้องมีบัญชี นี่เป็นวิธีที่ยอดเยี่ยมในการสร้างต้นแบบก่อนที่คุณจะสร้าง API key ด้วยซ้ำ
L1 ลงนามโครงสร้าง EIP-712 "ClobAuthDomain" ด้วย chainId 137 เพื่ออนุมานข้อมูลรับรอง L2 HMAC-SHA256 ลงนามทุกคำขอถัดไปด้วยส่วนหัว POLY_SIGNATURE
ตอนที่ 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 มาตรฐานสำหรับผู้ใช้รายย่อย)
.env) หรือ secrets manager ห้ามวางคีย์ลงใน Discord, GitHub issues หรือ ChatGPT เด็ดขาด ให้ถือว่าคีย์ใดก็ตามที่ผ่านคลิปบอร์ดของคุณไปแล้วถูกเจาะแล้ว หากไม่แน่ใจให้หมุนคีย์ใหม่
Signature type 1 (POLY_PROXY) สำหรับบัญชี Magic-link, type 2 (GNOSIS_SAFE) สำหรับ proxy ของกระเป๋าเบราว์เซอร์, type 0 (EOA) สำหรับคีย์โดยตรง ต้องมี Funder สำหรับ type 1 และ 2
ส่วนที่ 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 ทุกครั้งที่เริ่มระบบ
POLY_PRIVATE_KEY=0xabc...
POLY_FUNDER=0xdef...
POLY_API_KEY=...
POLY_SECRET=...
POLY_PASSPHRASE=...
Gamma /markets ส่งกลับ outcomePrices, clobTokenIds, volume24hr, tags ใช้ tag_slug + order=volume24hr เป็นคำค้น scanner bot ค่าเริ่มต้น
ส่วนที่ 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 ที่มีประโยชน์
| Parameter | What it does |
|---|---|
tag_slug | กรองตามหมวดหมู่ (การเมือง, กีฬา, คริปโต, วัฒนธรรม ฯลฯ) |
active=true | เฉพาะตลาดที่กำลังเปิดรับการเทรดอยู่ในขณะนี้ |
closed=false | ซ่อนตลาดที่ยุติผลแล้ว |
order=volume24hr | เรียงตามวอลุ่มล่าสุด (สัญญาณของสภาพคล่อง) |
end_date_min | วันที่แบบ ISO - ข้ามตลาดที่กำลังจะยุติผลเร็วเกินไป |
limit | ได้สูงสุด 500 รายการต่อหน้า (ใช้ offset สำหรับการแบ่งหน้า) |

Gamma เปิดเผย conditionId (หนึ่งรายการต่อหนึ่งตลาด); CLOB เทรดบน token_id (หนึ่งรายการต่อหนึ่งผลลัพธ์) clobTokenIds เป็นอาร์เรย์สตริงที่เข้ารหัสด้วย JSON ซึ่งดัชนีตรงกับผลลัพธ์
ส่วนที่ 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" ก็ได้ - ลำดับถูกกำหนดแน่นอน แต่จะแตกต่างกันไปตามแต่ละตลาด

สมุดคำสั่งซื้อขายแสดงเป็น bid จากสูงไปต่ำ, ask จากต่ำไปสูง ไล่ดูระดับราคาเพื่อประเมินราคาที่จะได้เติมสำหรับมูลค่าเป้าหมายใดๆ ก่อนส่ง FAK ที่คล้าย market
ส่วนที่ 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 หากต้องการประมาณสลิปเพจสำหรับคำสั่งขนาดใหญ่ ให้ไล่ดูสมุดคำสั่งซื้อขายและสะสมมูลค่าตามราคาจนกว่าจะใช้ขนาดเป้าหมายของคุณหมด

GTC ค้างอยู่ในสมุดคำสั่งซื้อขาย, GTD ยกเลิกอัตโนมัติตามเวลา, FOK ต้องเติมเต็มให้ครบทั้งจำนวนหรือยกเลิก, FAK รับเท่าที่ทำได้ในราคาจำกัดแล้วจึงยกเลิกส่วนที่เหลือ
ส่วนที่ 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 คุณจะไม่ส่งคีย์ส่วนตัวดิบผ่านเครือข่าย - มีเพียงคำสั่งที่ลงนามแล้วเท่านั้น
ประเภทของคำสั่ง
| Type | Code | Behaviour | When to use |
|---|---|---|---|
| Good Till Cancelled | GTC | ค้างอยู่ในสมุดคำสั่งซื้อขายจนกว่าจะจับคู่ครบหรือคุณยกเลิก | ค่าเริ่มต้น กลยุทธ์ทำมาร์เก็ตเมกกิ้งและกลยุทธ์จำกัดราคาส่วนใหญ่ |
| Good Till Date | GTD | ยกเลิกอัตโนมัติเมื่อถึงเวลาประทับที่กำหนด | ขับเคลื่อนด้วยเหตุการณ์ - "ยกเลิก 5 นาทีก่อนการประกาศของ Fed" |
| Fill or Kill | FOK | ต้องจับคู่ให้ครบทั้งจำนวนทันที ไม่เช่นนั้นยกเลิกทั้งหมด | ขาอาร์บิทราจที่การจับคู่ได้บางส่วนทำให้การเทรดเสียหาย |
| Fill and Kill | FAK | จับคู่เท่าที่ทำได้ที่ราคาจำกัด แล้วส่วนที่เหลือยกเลิก | การเทกอย่างก้าวร้าว - ทำงานเหมือนคำสั่งตลาดแต่มีเพดานราคา |
การยกเลิก
# คำสั่งเดี่ยว
client.cancel(order_id="0xabc...")
# ยกเลิกคำสั่งทั้งหมดในตลาดที่ระบุ
client.cancel_market_orders(market=market['conditionId'])
# ทางเลือกนิวเคลียร์: ยกเลิกทั้งหมด
client.cancel_all()ส่วนที่ 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 เป็นแหล่งข้อมูลที่เป็นความจริงสำหรับสถานะสมุดคำสั่งปัจจุบัน
ส่วนที่ 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: สถาปัตยกรรมบอทอ้างอิง
บอท Polymarket ที่แข็งแรงทุกตัวมีองค์ประกอบเหมือนกัน 6 ส่วน สร้างแต่ละส่วนเป็นโมดูลของตัวเอง แล้วเชื่อมกันแบบหลวมๆ
| ส่วนประกอบ | หน้าที่ | API ที่ใช้ |
|---|---|---|
| Scanner | งานตามกำหนดเวลา: ดึงตลาดที่ตรงตามเกณฑ์ของคุณ (แท็ก, วอลุ่ม, จำนวนวันจนหมดอายุ) | Gamma |
| Price engine | ดูแลสมุดคำสั่งซื้อขายภายในแบบเรียลไทม์ผ่าน WebSocket | CLOB WS |
| Signal generator | ฟังก์ชันล้วน: สถานะสมุดคำสั่ง + เมตาดาตา → ตำแหน่งเป้าหมาย | - (ในหน่วยความจำ) |
| Order manager | เปรียบเทียบคำสั่งปัจจุบันกับเป้าหมาย แล้วส่ง/ยกเลิกให้น้อยที่สุด | CLOB REST |
| Risk manager | บังคับใช้เพดานต่อหนึ่งตลาด, ขีดจำกัดการขาดทุนรายวัน, เซอร์กิตเบรกเกอร์ | - (ในหน่วยความจำ + DB) |
| Logger & ledger | บันทึกทุกการตัดสินใจ, ฟิลล์, การยกเลิก ใช้สำหรับรายงานภาษีและการดีบัก | SQLite / Postgres |
ส่วนที่ 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 จัดการให้ แต่ให้ยืนยันว่าคำสั่งของคุณไปยังสถานที่ซื้อขายที่ถูกต้อง
ส่วนที่ 12: รางวัลสภาพคล่องผ่าน API
Polymarket จ่าย ราว $5M/เดือน ในรางวัลสภาพคล่องทั่วไป บวกกับ $5M+/เดือน ในรางวัลเฉพาะกีฬา (ดู Liquidity Rewards) เงินส่วนใหญ่ไหลไปยัง market ผู้ตั้งคำสั่ง (maker) ที่ขับเคลื่อนด้วย API ซึ่งสามารถรักษา quote สองฝั่งที่แคบได้ในตลาดจำนวนมาก
สูตรรางวัลจะให้คะแนนคำสั่งที่อยู่ใกล้ midpoint, ขนาด, และเวลาที่ค้างอยู่ในสมุดคำสั่ง วงจร market making แบบขั้นต่ำ:
- อ่านสมุดคำสั่งของตลาดเป้าหมาย
- คำนวณ midpoint ที่เป็นธรรม (เช่น VWAP ของ 3 ระดับบนสุดฝั่งละด้าน)
- วาง bid ที่
mid − spread_target/2และ ask ที่mid + spread_target/2 - เมื่อมี WebSocket อัปเดตทุกครั้ง ให้ตั้งราคาใหม่ถ้า quote ของคุณห่างจากเป้าหมายเกินหนึ่ง tick
- ยกเลิกและออกจากตลาดหากสมุดคำสั่งบางลงหรือมีข่าวออกมา
ส่วนที่ 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
- แคชข้อมูลรับรอง API หลังเรียก derive ครั้งแรก -
create_or_derive_api_creds()ถูกจำกัดอัตราและช้า เก็บ apiKey/secret/passphrase ไว้ใน.envแล้วโหลดตอนเริ่มต้น - ใช้ signature_type=2 (GNOSIS_SAFE) หากคุณเชื่อมต่อ browser wallet มาก่อน, signature_type=1 (POLY_PROXY) ใช้เฉพาะบัญชีอีเมล Magic-link เท่านั้น ประเภทที่ไม่ตรงกันจะได้ 401 "invalid api key."
- ตั้ง
funderให้เป็นที่อยู่กระเป๋า proxy ของ Polymarket ไม่ใช่ EOA ของคุณ กุญแจลงนามอยู่ใน EOA; เงินอยู่ใน proxy การสลับสองอย่างนี้ผิดกันคือบั๊กการยืนยันตัวตนอันดับ 1 - จัดทำดัชนีผลลัพธ์ตามป้ายชื่อ ไม่ใช่ตามตำแหน่ง -
clobTokenIds[outcomes.index("Yes")]ไม่ใช่clobTokenIds[0]ตลาด NegRisk และ Oscar มีลำดับไม่ตายตัว - ซิงก์นาฬิกาของคุณก่อนลงนาม - POLY_TIMESTAMP ต้องอยู่ในช่วงแคบๆ NTP drift บน VPS ราคาถูกจะทำให้การยืนยันตัวตนพังแบบเงียบๆ ให้รัน chrony หรือ systemd-timesyncd
- ดึงหนังสือคำสั่ง REST ใหม่ทุกครั้งที่ WebSocket reconnect ก่อนจะ resubscribe WebSocket ส่งเฉพาะ delta; ถ้าคุณพลาด delta ระหว่าง reconnect สมุดคำสั่งภายในจะเบี่ยงเบนจากความจริงและคุณจะตั้งราคาแบบขาดทุน
- อย่าส่งเกิน 10 คำสั่งต่อวินาทีแบบ burst - endpoint /order จำกัดที่ 500/10s burst และ 3,000/10min sustained เพิ่ม token-bucket rate limiter ฝั่ง client; Cloudflare จะเข้าคิวแทนที่จะทิ้งคำสั่ง ดังนั้น retry แบบมืดบอดจะยิ่งเพิ่ม backlog
- ใช้
cancel_market_orders(market=conditionId)ตอนปิดโปรแกรม ไม่ใช่cancel_all()การยกเลิกแบบ scoped ตามตลาดเป็น idempotent และปลอดภัยกว่า หากบอทล้มกลางลูปในตลาดเดียวเท่านั้น - ติดตาม
heartbeatMsแยกตามสินทรัพย์ - เพิ่ม watchdog ที่ force-refresh ตลาดใดๆ ที่ไม่มีอัปเดต 30 วินาทีในตลาดจริง ฟีด WS ที่ล้าสมัยเป็นแหล่งที่มาที่พบบ่อยที่สุดของ phantom edge - บันทึก order ID ก่อนส่ง ไม่ใช่หลังส่ง ความเป็น idempotent ต้องให้ฝั่ง client เป็นเจ้าของ ID เพื่อให้การกู้คืนหลังล่มสามารถส่งซ้ำได้โดยไม่เกิดฟิลล์ซ้ำ
- ใช้ HeartBeats API (ม.ค. 2026+) สำหรับการ cancel-on-disconnect อัตโนมัติ ตั้งช่วง heartbeat เป็น 5 วินาที; เซิร์ฟเวอร์จะยกเลิกคำสั่งที่ค้างทั้งหมดของคุณหากพลาด heartbeat สองครั้ง
- 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 สถานะภายใน แล้วค่อย resubscribe | delta ระหว่างช่วงหลุดจะหายไป; 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 + เก็บสถานะถาวร | บอทที่ไม่มีคนดูแลใดๆ จะล่มแน่นอน; คำถามเดียวคือจะเริ่มใหม่ได้อย่างสะอาดหรือไม่ |
เป้าหมาย. รับรางวัลสภาพคล่องในตลาดการเมืองที่มีวอลุ่มปานกลาง ราคาอยู่ราว 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% กับที่เหลือ
ต่อไปคืออะไร?
- เครื่องมือและแหล่งข้อมูล - แดชบอร์ดของบุคคลที่สาม การวิเคราะห์ และฟีดข้อมูลที่เสริม API
- กลยุทธ์ขั้นสูง - อาร์บิทราจหลายช่วงขาและโครงสร้างคล้ายออปชันที่เหมาะสำหรับบอท
- รางวัลสภาพคล่อง - สูตรที่แม่นยำสำหรับการรับส่วนลดค่าธรรมเนียมการเป็นเมกเกอร์
- คู่มือสมุดคำสั่งซื้อขาย - ความเข้าใจเชิงลึกยิ่งขึ้นสำหรับการอ่านสมุดคำสั่งก่อนที่คุณจะเขียนโค้ดโต้ตอบกับมัน
- อภิธานศัพท์ - คำจำกัดความแบบเข้าใจง่ายของทุกคำศัพท์ในคู่มือนี้
การอ่านที่แนะนำ
เริ่มที่นี่หากคุณเป็นมือใหม่ หรือข้ามไปยังหน้าที่ตรงกับระดับของคุณโดยตรง:











