מדריך Bot של Polymarket · פרק 7 מתוך 32
צלילה עמוקה ל־Polymarket Gamma API: נקודות הקצה /events ו־/markets, pagination, מזהי תגיות (864 Tennis, 745 NBA, וכו׳), סינון לפי נפח 24 שעות, rate limits, ודוגמאות קוד ב־Python וב־Node.
מה הפרק הזה מכסה
Gamma הוא ה־API הקטלוגי של Polymarket - הוא מציג כל event, כל market, כל tag, תמונה, ותוצאה שהוחלטה שה־front-end מציג. ה־CLOB API מבצע מסחר; Gamma מתאר מה ניתן למסחר. רוב ה־bugs של bot בשכבת הגילוי נובעים מבלבול בין השניים, או מחוסר הבנה של חוזה ה־pagination. הפרק הזה הוא מדריך שטח לנקודות הקצה המרכזיות של Gamma, עם התנהגות הפרמטרים המדויקת שעליה מסתמכים תהליכי השליפה שלנו בייצור.
- Gamma מול CLOB: מתי להשתמש בכל אחד
- מבנה נקודת הקצה /events
- מבנה נקודת הקצה /markets
- Tags ומזהי tag (רשימה מאומתת)
- סינון: active, closed, מיון לפי volume24hr
- pagination ומגבלות
- rate limits ו־caching
- קוד: שליפת markets בעלי נפח 24 שעות הגבוה ביותר
Gamma מול CLOB: מתי להשתמש בכל אחד
שני שירותים שונים לשני תפקידים שונים.
Gamma (gamma-api.polymarket.com): קטלוג. מציג events, markets, tags, תיאורים, תמונות, תוצאות שהוחלטו, נפח 24 שעות, נפח כולל, ותאריכי סיום. HTTP לקריאה בלבד. ברוב פעולות הקריאה אין צורך באימות. מתעדכן ברציפות אבל בצורה eventually consistent - market שרק נסגר עשוי עדיין להופיע כ־closed: false במשך כמה שניות.
CLOB (clob.polymarket.com): מסחר + order book. מציג bid/ask הטוב ביותר כרגע, עומק ספר פקודות top-N, ועסקאות אחרונות. דורש אימות עבור נקודות קצה לכתיבה (הצבת order, ביטול). ערוצי WebSocket בזמן אמת זמינים לעדכוני ספר הפקודות.
כלל אצבע: השתמשו ב־Gamma כדי למצוא מה לסחור; השתמשו ב־CLOB כדי לסחור בו. Bot שקורא מחירים מ־Gamma משתמש בנתונים לא עדכניים - שדות המחיר של Gamma מתעדכנים פחות בתדירות מאשר order book של CLOB. Bot שקורא מטא־דאטה של market מ־CLOB מבצע יותר בקשות מהנדרש.
מבנה נקודת הקצה /events
GET /events מחזיר נתונים ברמת event. "event" הוא עמוד Polymarket; event אחד עשוי להכיל כמה markets (למשל, event הבחירות לנשיאות 2024 כולל market נפרד לכל מועמד).
שדות מרכזיים:
slug: מזהה בטוח ל־URL, יציב לאורך חיי ה־event.title,description: תצוגה לבני אדם.endDate(ISO 8601): מתי ה־event נסגר.active,closed: בוליאנים; שלבו אותם בשאילתה עם?active=true&closed=falseעבור events פעילים.volume,volume24hr: סכומים בדולרים.tags: מערך של אובייקטי tag (ראו סעיף tags בהמשך).markets: מערך של אובייקטי market צאצאים (ראו מבנה/markets).
תבנית הגילוי הנפוצה ביותר: GET /events?active=true&closed=false&order=volume24hr&ascending=false&limit=100. מחזיר את 100 ה־events הפעילים בעלי הנפח הגבוה ביותר.
מבנה נקודת הקצה /markets
GET /markets מחזיר נתונים ברמת market. market הוא חוזה Yes/No או רב־תוצאתי; הוא חי בתוך event.
שדות מרכזיים:
slug: מזהה בטוח ל־URL.question: הכותרת שמוצגת בעמוד המסחר (למשל "Will Trump be president on January 1, 2027?").outcomes: מחרוזת JSON של שמות התוצאות, למשל'["Yes","No"]'. תמיד שני איברים עבור binary; יותר עבור NegRisk.outcomePrices: מחרוזת JSON של המחירים הנוכחיים כמספרים עשרוניים, למשל'["0.62","0.38"]'. שני הצדדים יחד מסתכמים לכ־1.0 פחות spread.clobTokenIds: מחרוזת JSON של מזהי ERC-1155 token המותאמים לתוצאות. אלו ה־tokens שאתם באמת קונים/מוכרים.negRisk: בוליאני; true עבור markets רב־תוצאתיים שמסתכמים ל־1. חשוב להצבת orders (פרק 11).
השדות outcomes / outcomePrices / clobTokenIds מגיעים כמחרוזות JSON, לא כמערכים מפוענחים - יש לבצע JSON-decode לפני השימוש.
Tags ומזהי tag (רשימה מאומתת)
Tags הם תוויות קטגוריות (Sports, Crypto, Tennis, NBA, וכו׳). מזהי tag מאומתים בייצור עבור הקטגוריות הנפוצות ביותר:
| Tag | ID | Tag | ID |
|---|---|---|---|
| Sports | 1 | NBA | 745 |
| Crypto | 21 | NFL | 450 |
| Politics | 2 | Tennis | 864 |
| Bitcoin | 100196 | Esports | 702 |
| Ethereum | 100383 | Soccer | 1059 |
| Election | 3 | EPL | 739 |
| Middle East | 1432 | UCL | 2186 |
סננו לפי tag באמצעות ?tag_id=745 עבור tag מסוים, או ?tag_slug=nba באמצעות ה־slug. סינון מבוסס slug קריא יותר בקוד אך מעט איטי יותר; סינון מבוסס ID הוא ברירת המחדל בייצור.
סינון: active, closed, מיון לפי volume24hr
ארבעת ממדי הסינון שבהם תשתמשו ב־95% מהמקרים.
active=true|false:trueמוציא משימוש markets שהצוות של Polymarket הסתיר מה־UI.closed=true|false:falseמוציא משימוש markets שהוכרעו. השילובactive=true&closed=falseהוא סינון ה־live הנפוץ ביותר.order=volume24hr,order=volume,order=endDate: מפתח מיון. השימושי ביותר הואvolume24hrלמציאת markets פעילים כרגע.ascending=true|false: ברירת המחדל ברוב נקודות הקצה היא true; כמעט תמיד תרצוfalseעבור מיון לפי נפח.
אזהרה: סינון באמצעות tag_id בשילוב order=volume24hr ו־ascending=false מחזיר לפעמים דף ריק כאשר ל־tag יש מעט מאוד markets פעילים. תמיד שלפו יותר מהנדרש (requestו יותר ממה שאתם מציגים) ואז בצעו post-filter כדי להתמודד עם זה.
pagination ומגבלות
הפרמטר limit מקבל 1-500 בכל קריאה. ברירת המחדל היא 100 אם לא מציינים. מעל 500 השרת מגביל בשקט - תקבלו 500 אבל אין אינדיקציה בתגובה שיש עוד.
pagination מבוסס offset: ?limit=500&offset=500 עבור הדף השני. אין pagination מבוסס cursor, ולכן הוספות מקבילות עלולות לגרום לגבולות העמוד לזוז בין קריאות. עבור רוב צרכי הגילוי של bot זה מקובל; עבור שליפות ארכיון, מיינו לפי שדה יציב (endDate או createdAt) וזיהו חפיפה לפי slug.
תבנית מעשית עבור "כל ה־markets הפעילים": שלפו limit=500&order=volume24hr&ascending=false. זה מכסה את 500 המובילים לפי נפח, שהם למעשה כל market בעל פעילות לא זניחה. מעבר לדף 1 לעיתים רחוקות מועיל - markets בזנב התפלגות הנפח הם, בהגדרה, לא המקום שבו נמצאת הפעילות.
rate limits ו־caching
Gamma יושב מאחורי Cloudflare ויש לו rate limits רכים לכל IP. ספי ביצועים שנצפו תחת עומס ייצור:
- עד כ־30 בקשות לשנייה מ־IP אחד באופן מתמשך: בסדר.
- התפרצויות של 100+ בקשות לשנייה: לעיתים 429, ניסיונות חוזרים מצליחים.
- כ־500 בקשות לשנייה באופן מתמשך: עמוד rate-limit או חסימה זמנית (10-60 שניות).
כותרות התגובה שפורסמו כוללות ערכי Cache-Control של 30-60 שניות עבור רוב נקודות הקצה. כבדו אותם - אין תועלת בשליפה מחדש של אותו event 10 פעמים בדקה. תבנית caching בייצור: LRU בתוך התהליך + TTL לפי ה־URL המלא, TTL של 30 שניות. חוסך מספר בקשות ומפחית latency.
עבור אסטרטגיות בתדירות גבוהה, שיקפו את נתוני Gamma לתוך אחסון מקומי המתעדכן על ידי תהליך fetcher יחיד; תנו למספר צרכנים לקרוא מאותו אחסון. fetcher אחד × צרכנים רבים > הרבה fetchers × Gamma.
קוד: שליפת markets בעלי נפח 24 שעות הגבוה ביותר
fetcher ייחוס בשלוש שפות, המחזיר את 50 ה־markets הפעילים המובילים לפי נפח 24 שעות.
Python:
import requests
r = requests.get("https://gamma-api.polymarket.com/events",
params={"active":"true","closed":"false",
"order":"volume24hr","ascending":"false","limit":50},
timeout=10)
for ev in r.json()[:50]:
print(ev["slug"], ev.get("volume24hr"))
Node:
const url = "https://gamma-api.polymarket.com/events?active=true&closed=false" +
"&order=volume24hr&ascending=false&limit=50";
const events = await fetch(url).then(r => r.json());
for (const ev of events) console.log(ev.slug, ev.volume24hr);
Curl:
curl -s "https://gamma-api.polymarket.com/events?active=true&closed=false&order=volume24hr&ascending=false&limit=50" \
| jq '.[].slug'
נקודת הקצה /events של Polymarket gamma אינה תומכת בפרמטר חיפוש טקסט חופשי - הוספת ?q=foo או ?search=foo תחזיר בשקט את המיון ברירת המחדל. סננו לפי slug או tag במקום זאת.










