Polymarket Bot Tutorial · บทที่ 3 จาก 32
เลือก bot stack สำหรับ Polymarket ของคุณ: Python (py-clob-client 0.34.6), Node.js (@polymarket/clob-client-v2 v1.0.6), หรือ Rust (ไม่มี official SDK, สร้างบน ethers-rs) ข้อดี ข้อเสีย latency และ code samples
บทนี้ครอบคลุมอะไรบ้าง
การเลือกภาษาแทบไม่ได้สำคัญเท่าที่ผู้พัฒนาส่วนใหญ่คิด Polymarket เปิดใช้งาน REST และ WebSocket endpoints เดียวกันสำหรับทุกภาษา; การเลือก SDK ส่วนใหญ่จึงเป็นเรื่องของปริมาณ glue code ที่คุณต้องเขียนเอง Python และ Node มี official SDK ที่ดูแลโดยทีมงานแล้ว; Rust ไม่มี แต่ก็ใช้งานได้สำหรับ hot path บทนี้จะไล่ trade-off ต่างๆ แสดง task เดียวกันคือ "fetch order book" ในแต่ละภาษาเพื่อให้เห็นความต่างชัดเจน และปิดท้ายด้วย mixed-stack pattern ที่บอท production ส่วนใหญ่ลงเอยใช้จริง
- Decision framework
- Python (default choice)
- Node.js (full-stack devs)
- Rust (latency-critical hot path)
- Setup commands per stack
- Code skeleton: fetch order book in 3 languages
- When to mix stacks (Python control plane + Rust hot path)
Decision framework
สามคำถามนี้ช่วยตัดสินการเลือก stack ได้ราว 90%
- คุณมีทักษะเดิมที่แข็งแรงอยู่แล้วไหม? ถ้าคุณเขียน Python ทุกวัน ก็เขียน bot ด้วย Python ถ้าคุณเขียน TypeScript ทุกวัน ก็เขียน bot ด้วย Node ความต่างด้าน SDK quality ด้านล่างเป็นเรื่องจริง แต่เล็กกว่าต้นทุนของการฝืนใช้ภาษาที่ไม่คุ้นเคย
- กลยุทธ์ของคุณต้องการ latency สูงหรือไม่? ถ้า edge ของคุณขึ้นอยู่กับการตอบสนองภายใน 50ms (ตลาด crypto 5 นาที, market-making ระหว่างข่าว) hot path จะได้ประโยชน์จาก Rust หรือ Go กลยุทธ์ส่วนใหญ่ไม่ต้องการระดับนี้
- คุณจะรันมากกว่าหนึ่งกลยุทธ์หรือไม่? Python process เดียวสามารถดูแล 10-20 markets ได้สบายกว่ามาก ถ้าเกินกว่านั้น async Node หรือการแยก process ใน Python จะสเกลได้ดีกว่า
ค่าเริ่มต้นที่ซื่อสัตย์สำหรับ bot ตัวแรกคือ Python เปลี่ยนก็ต่อเมื่อข้อจำกัดที่วัดได้บังคับให้ต้องเปลี่ยน
Python (default choice)
Python เป็น default เพราะ SDK ครบที่สุดและวงจรการ iterate เร็วที่สุด py-clob-client เวอร์ชัน 0.34.6 (พฤษภาคม 2026) ครอบคลุมทุก CLOB v2 endpoint ที่สำคัญ: market และ limit orders, FOK/FAK/GTC variants, การอ่าน order book, การอ่าน balance/allowance และ direct chain operations ผ่าน web3.py
ข้อดี: SDK mature, วิเคราะห์ข้อมูลด้วย pandas ได้ง่าย, community ใหญ่, ใช้ web3.py สำหรับการอ่าน on-chain ได้ ข้อเสีย: async ergonomics ค่อนข้างอึดอัดเมื่อเทียบกับ JavaScript, GIL จำกัดการเร่งความเร็วแบบ multi-core (มักไม่สำคัญสำหรับ bot ที่เป็น I/O-bound), เวลาเริ่มต้นใน cold container ช้า
แนะนำสำหรับ: 80% ของผู้พัฒนา โดยเฉพาะคนที่กลยุทธ์เกี่ยวข้องกับ backtesting, statistical analysis หรือ data work ควบคู่กับ execution
Node.js (full-stack devs)
Node.js เป็น stack ที่รองลงมาที่ support ดีที่สุด @polymarket/clob-client-v2 เวอร์ชัน 1.0.6 ครอบคลุม endpoints เดียวกับ Python SDK พร้อม TypeScript types ครบถ้วน Async เป็น native และเร็ว; การจัดการ WebSocket ทำได้ดีเยี่ยม
ข้อดี: async story ดีที่สุด, native TypeScript types, ecosystem สำหรับ HTTP + WS ใหญ่, deploy บน Node runtime เดียวกับ web dashboard ได้ง่าย ข้อเสีย: ความแม่นยำของตัวเลขต้องใช้ BigInt หรือจัดการเป็น string สำหรับ token ID ขนาดใหญ่ (ERC-1155 IDs มีขนาด 256-bit), data tools ที่เทียบกับ pandas ยังอ่อนกว่า
แนะนำสำหรับ: ผู้พัฒนาที่ดูแล JavaScript stack อยู่แล้วและต้องการ runtime เดียว รวมถึงคนที่สร้าง dashboard ไปพร้อมกับ bot-การแชร์ types ระหว่าง bot core กับ Next.js dashboard จะช่วยตัด bug ได้หลายประเภท
Rust (latency-critical hot path)
Rust ไม่มี official Polymarket SDK คุณต้องสร้างบน V2 REST และ WebSocket APIs โดยตรงด้วย reqwest (HTTP), tokio-tungstenite (WebSocket), และ ethers-rs หรือ alloy สำหรับการ signing งาน setup ประมาณสองวัน เทียบกับ 30 นาทีใน Python
ข้อดี: EIP-712 signing แบบ native โดยไม่ต้องมี JS subprocess, สร้าง order ได้ระดับ sub-millisecond, memory profile คงที่ภายใต้ load, ไม่มี GC pauses ข้อเสีย: ไม่มี SDK หมายความว่าคุณต้อง implement เองในส่วนที่ผู้ใช้ Python ได้ฟรี เช่น การ parse clobToken ID, การ validate response schema, การจัดการ salt/nonce ความได้เปรียบด้าน latency อยู่ที่ประมาณ 20-100ms เมื่อเทียบกับ Python ที่ปรับจูนแล้ว ซึ่งมีความหมายเฉพาะกับกลยุทธ์ sub-second เท่านั้น
แนะนำสำหรับ: hot path ของ market-making bot หรือส่วนยิงเทรดของ news-arb bot แทบไม่ควรใช้ทั้งบอทเป็น Rust ทั้งหมด
Setup commands per stack
คำสั่งขั้นต่ำเพื่อให้ได้ signed order ที่ใช้งานได้กับ mainnet (CLOB v2 endpoint เดียว)
Python:
python -m venv venv && source venv/bin/activate
pip install py-clob-client==0.34.6 web3 python-dotenv
# Set POLYGON_RPC, PRIVATE_KEY, POLY_FUNDER in .env
Node:
npm init -y
npm install @polymarket/[email protected] ethers dotenv
# Set POLYGON_RPC, PRIVATE_KEY, POLY_FUNDER in .env
Rust:
cargo new --bin pmt
cd pmt
cargo add tokio reqwest serde serde_json ethers alloy tungstenite tokio-tungstenite
# Hand-write signer + endpoint client; no SDK shortcut.
Time-to-first-order: ~10 min สำหรับ Python, ~15 min สำหรับ Node, ~4-8 ชั่วโมงสำหรับ Rust
Code skeleton: fetch order book in 3 languages
งานเดียวกัน-ดึง order book สำหรับ Polymarket token-ในแต่ละ stack ทั้งสามแบบจะเรียก CLOB v2 REST endpoint เดียวกัน
Python (py-clob-client):
from py_clob_client.client import ClobClient
client = ClobClient(host="https://clob.polymarket.com", chain_id=137)
book = client.get_order_book("<token_id>")
print(book.bids[:3], book.asks[:3])
Node (@polymarket/clob-client-v2):
import { ClobClient } from "@polymarket/clob-client-v2";
const c = new ClobClient({ host: "https://clob.polymarket.com", chain: 137 });
const book = await c.getOrderBook("<token_id>");
console.log(book.bids.slice(0,3), book.asks.slice(0,3));
Rust (direct HTTP):
let url = format!("https://clob.polymarket.com/book?token_id={}", token);
let book: serde_json::Value = reqwest::get(&url).await?.json().await?;
println!("{:?} {:?}", &book["bids"][..3], &book["asks"][..3]);
รูปแบบ response เหมือนกันทั้งสามแบบ ต้นทุนของ Rust อยู่ตรงส่วนอื่นแทบทั้งหมด-signing, order construction, error handling-ไม่ใช่ใน read path
When to mix stacks (Python control plane + Rust hot path)
pattern ที่ production bots จำนวนมากลงเอยใช้: Python สำหรับทุกอย่างที่เกี่ยวกับการตัดสินใจ และ Rust สำหรับ leg การ execute ระดับมิลลิวินาที
Architecture: Python process อ่าน market state, รัน strategy logic และเขียน small command file (เช่น {"action":"buy","token":"...","size":10,"price":0.45}) ไปยัง Unix socket Rust daemon จะฟัง socket นั้น, sign order, แล้วส่งไปยัง CLOB Python process อาจช้าได้และใช้งานสะดวก ส่วน Rust daemon จะเร็วและเล็ก
จุดสำคัญคือ handoff: เมื่อแยกขั้นตอน signed-order ออกไปแล้ว ก็ได้ประโยชน์จากการรับมือกับ crash budget ของ Python โดยไม่เสีย latency เราใช้ pattern นี้ใน production bots ของเราเอง-Python ส่ง intention, Node daemon บน /tmp/clob.sock จัดการ signing Node version ของ daemon ใช้ได้ดีสำหรับ sub-100ms; Rust จะคุ้มจริงก็ต่ำกว่า 50ms
คำถามที่พบบ่อย
@polymarket/clob-client-v2 มาพร้อม TypeScript types และการจับ type error ตั้งแต่ compile time ช่วยลดการ debug ได้มากเมื่อ EIP-712 signature payload หรือ order types ผิด











