Polymarket Bot Tutorial · Chapter 7 of 32
شرح معمّق لواجهة Polymarket Gamma API: نهايتا /events و /markets، الترقيم الصفحي pagination، معرّفات الوسوم tag IDs (864 Tennis، 745 NBA، إلخ)، التصفية حسب حجم التداول خلال 24 ساعة، حدود المعدّل rate limits، وأمثلة كود Python وNode.
ما الذي يغطيه هذا الفصل
Gamma هي واجهة API الخاصة بكتالوج Polymarket - فهي تعرض كل event، وكل market، وكل tag، والصورة، والنتيجة المحسومة التي تُظهرها الواجهة الأمامية. واجهة CLOB API مخصّصة للتداول؛ أما Gamma فتصف ما يمكن تداوله. معظم أخطاء البوتات في طبقة الاكتشاف discovery تأتي من الخلط بينهما، أو من تجاهل عقد pagination. هذا الفصل هو المرجع الميداني للنهايات الرئيسية في Gamma مع السلوك الدقيق للمعاملات التي تعتمد عليها أدوات الجلب في الإنتاج لدينا.
- Gamma مقابل CLOB: متى تستخدم كلًا منهما
- بنية /events
- بنية /markets
- الوسوم tag IDs (قائمة موثقة)
- التصفية: active، closed، وترتيب volume24hr
- pagination والحدود
- Rate limits وcaching
- Code: جلب أعلى markets من حيث حجم تداول 24 ساعة
Gamma مقابل CLOB: متى تستخدم كلًا منهما
خدمتان مختلفتان لمهمتين مختلفتين.
Gamma (gamma-api.polymarket.com): الكتالوج. تعرض الأحداث، الأسواق، الوسوم، الأوصاف، الصور، النتائج المحسومة، حجم التداول خلال 24 ساعة، الحجم الإجمالي، وتواريخ الانتهاء. HTTP للقراءة فقط. لا تتطلب مصادقة في معظم عمليات القراءة. يتم تحديثها باستمرار ولكنها eventually consistent - قد يظهر market أغلق للتو على أنه closed: false لبضع ثوانٍ.
CLOB (clob.polymarket.com): التداول + order book. تعرض أفضل bid/ask الحالي، وعمق book حتى أعلى N، وآخر الصفقات. تتطلب مصادقة لنهايات الكتابة (وضع الأوامر، الإلغاء). تتوفر قنوات WebSocket في الوقت الحقيقي لتحديثات book.
قاعدة عملية: استخدم Gamma لمعرفة ما الذي ستتداول عليه؛ واستخدم CLOB للتداول نفسه. البوت الذي يقرأ الأسعار من Gamma يستخدم بيانات متأخرة - حقول الأسعار في Gamma تُحدَّث بوتيرة أقل من order book في CLOB. والبوت الذي يقرأ بيانات تعريف السوق من 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للأحداث الحية.volume،volume24hr: إجماليات بالدولار الأمريكي.tags: مصفوفة من كائنات الوسوم (راجع قسم الوسوم أدناه).markets: مصفوفة من كائنات market التابعة (راجع بنية/markets).
أكثر نمط شائع للاكتشاف: GET /events?active=true&closed=false&order=volume24hr&ascending=false&limit=100. يعيد أعلى 100 event حي من حيث الحجم.
بنية /markets
GET /markets يعيد بيانات على مستوى market. الـ market هو عقدة Yes/No أو متعددة النتائج؛ ويعيش داخل event.
الحقول الأساسية:
slug: معرّف صالح للـ URL.question: العنوان المعروض في صفحة التداول (مثلًا "Will Trump be president on January 1, 2027?").outcomes: سلسلة JSON لأسماء النتائج، مثل'["Yes","No"]'. تكون دائمًا عنصرين في الأسواق الثنائية؛ وأكثر من ذلك في NegRisk.outcomePrices: سلسلة JSON للأسعار الحالية بوصفها أعدادًا عشرية، مثل'["0.62","0.38"]'. مجموع الجانبين يساوي تقريبًا 1.0 ناقص spread.clobTokenIds: سلسلة JSON لمعرّفات ERC-1155 المرتبطة بالنتائج. هذه هي الرموز التي تشتريها/تبيعها فعليًا.negRisk: قيمة منطقية؛ true للأسواق متعددة النتائج التي مجموعها يساوي 1. يهم هذا عند وضع الأوامر (الفصل 11).
الحقول outcomes / outcomePrices / clobTokenIds تأتي كسلاسل JSON، وليس كمصفوفات محللة - لذا يجب فك JSON قبل استخدامها.
الوسوم وtag IDs (قائمة موثقة)
الوسوم هي تسميات تصنيفية (Sports، Crypto، Tennis، NBA، إلخ). فيما يلي tag IDs الموثقة في الإنتاج لأكثر الفئات استخدامًا:
| 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_id=745 لوسم محدد، أو ?tag_slug=nba باستخدام الـ slug. التصفية بالـ slug أكثر وضوحًا في الكود لكنها أبطأ قليلًا؛ أما التصفية بالـ ID فهي الافتراضية في الإنتاج.
التصفية: active، closed، وترتيب volume24hr
أبعاد التصفية الأربعة التي ستستخدمها 95% من الوقت.
active=true|false: القيمةtrueتستبعد الأسواق التي أخفاها فريق Polymarket من الواجهة.closed=true|false: القيمةfalseتستبعد الأسواق المحسومة. الجمعactive=true&closed=falseهو أكثر فلتر حي شيوعًا.order=volume24hr،order=volume،order=endDate: مفتاح الترتيب. الأكثر فائدة هوvolume24hrللعثور على الأسواق النشطة حاليًا.ascending=true|false: القيمة الافتراضية true في معظم النهايات؛ وغالبًا ما تريدfalseعند الترتيب حسب الحجم.
تنبيه: التصفية باستخدام tag_id مع order=volume24hr وascending=false قد تعطي أحيانًا صفحة فارغة عندما يكون للوسم عدد قليل جدًا من الأسواق الحية. لذا يجب دائمًا over-fetch (اطلب أكثر مما تعرضه) ثم قم بالتصفية اللاحقة post-filter لمعالجة ذلك.
pagination والحدود
معامل limit يقبل من 1 إلى 500 لكل طلب. القيمة الافتراضية 100 إذا لم تُحدَّد. إذا تجاوزت 500 فإن الخادم يقيّدها بصمت - ستحصل على 500 لكن الاستجابة لا تشير إلى وجود المزيد.
pagination يعتمد على offset: ?limit=500&offset=500 للصفحة الثانية. لا يوجد pagination قائم على cursor، لذا قد تؤدي الإضافات المتزامنة إلى تغيّر حدود الصفحات بين الطلبات. بالنسبة لمعظم أغراض اكتشاف البوتات فهذا مقبول؛ أما في عمليات scraping للأرشيف، فرتّب حسب حقل ثابت (endDate أو createdAt) واكشف التداخل بواسطة slug.
النمط العملي لـ "كل الأسواق الحية": اجلب limit=500&order=volume24hr&ascending=false. هذا يغطي أعلى 500 سوقًا حسب الحجم، وهو عمليًا كل سوق لديه نشاط غير هامشي. تجاوز الصفحة الأولى نادرًا ما يكون مفيدًا - فالأسواق في ذيل توزيع الحجم ليست، بحكم التعريف، حيث يوجد الزخم.
Rate limits وcaching
Gamma خلف Cloudflare ولديها rate limits مرنة لكل IP. العتبات التجريبية المرصودة تحت حمل الإنتاج:
- حتى نحو 30 طلب/ثانية من IP واحد بشكل مستمر: جيد.
- دفعات من 100+ طلب/ثانية: قد تظهر أحيانًا 429s، وتنجح الإعادات retries.
- نحو 500 طلب/ثانية بشكل مستمر: صفحة rate-limit أو حظر مؤقت (10-60 ثانية).
تتضمن رؤوس الاستجابة المنشورة قيم Cache-Control من 30 إلى 60 ثانية لمعظم النهايات. التزم بها - لا توجد فائدة من إعادة جلب نفس event عشر مرات في الدقيقة. نمط caching في الإنتاج: LRU داخل العملية + TTL مفهرسة على كامل الـ URL، مع TTL لمدة 30 ثانية. هذا يوفر عدد الطلبات ويقلل زمن الاستجابة.
للاستراتيجيات عالية التردد، انسخ بيانات Gamma إلى مخزن محلي يتم تحديثه بواسطة عملية fetcher واحدة؛ ثم دع عدة مستهلكين يقرؤون من ذلك المخزن. fetcher واحد × عدة مستهلكين > عدة fetchers × Gamma.
Code: جلب أعلى markets من حيث حجم تداول 24 ساعة
مرجع fetcher بثلاث لغات، يعيد أعلى 50 market حيًا حسب حجم التداول خلال 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'
نهاية Polymarket gamma /events لا تدعم معامل بحث نصي حر - إضافة ?q=foo أو ?search=foo تعيد بصمت الترتيب الافتراضي. استخدم slug أو tag بدلًا من ذلك.










