מדריך 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 מאומתים בייצור עבור הקטגוריות הנפוצות ביותר:

TagIDTagID
Sports1NBA745
Crypto21NFL450
Politics2Tennis864
Bitcoin100196Esports702
Ethereum100383Soccer1059
Election3EPL739
Middle East1432UCL2186

סננו לפי 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 במקום זאת.

שאלות נפוצות

מהו Polymarket Gamma API?
Gamma הוא ה־API למטא־דאטה ולגילוי של Polymarket. הוא מספק רשימות events/markets, כותרות, תיאורים, תאריכי סיום, tags, ונפח מצטבר. הוא לא מספק נתוני order book בזמן אמת - אלו נמצאים ב־CLOB API. עבור רוב מקרי השימוש של גילוי ואנליטיקה, מתחילים ב־Gamma.
מה ההבדל בין event ל־market ב־Polymarket?
event מקבץ one or more markets שחולקים נושא שאלה. market הוא תוצאה ספציפית של Yes/No עם order book ומזהי token משלו. Event של "2026 NBA Champion" מכיל 30 markets (אחד לכל קבוצה). עבור events בינאריים של Yes/No, ל־event יש market בסיסי אחד.
איך מוצאים מזהי tag של Polymarket?
Tags נחשפים דרך נקודת הקצה gamma /tags. מזהים מאומתים שבהם אנו משתמשים בייצור: 864 Tennis, 745 NBA. slugs של tag ב־URL ‏(?tag_slug=tennis) ושאילתת טקסט חופשי ‏(?q=tennis) אינם אמינים - השתמשו רק ב־tag_id מספרי. בדקו את /tags לפני שאתם מסתמכים על slug.
איך ממיינים events של Polymarket לפי נפח 24 שעות?
/events?order=volume24hr&ascending=false - זה מה שמניע את רוב הווידג'טים של "trending markets". שלבו עם active=true&closed=false כדי לסנן markets שפג תוקפם או הושהו. Limit ברירת המחדל הוא 25; המקסימום הוא 500 לקריאה.
האם יש מגבלות pagination ב־Gamma?
כן. נקודות הקצה /events ו־/markets מקבלות limit (מקסימום 500 לקריאה) ו־offset עבור pagination. רוב הספריות לא מבצעות pagination אוטומטית - אם אתם צריכים את כל המרחב, הריצו לולאה עם offset עד שמתקבל דף עם פחות תוצאות מ־`limit`.
האם Gamma תומך ב־WebSocket?
לא. Gamma הוא REST בלבד. לעדכונים בזמן אמת (שינויי מחיר, markets חדשים, order book) השתמשו ב־CLOB WebSocket - מכוסה בפרק 8 של הסדרה הזו.