كيف تبني بوت تداول على Polymarket
معظم دروس بناء بوتات Polymarket مبنية على حزم SDK لم تعد موجودة. هذا هو المسار الحالي من البداية إلى النهاية — ما الذي تثبّته في 2026، وكيف تعمل المصادقة فعلًا، وأين تقع فجوات البيانات، وأنماط الفشل التي تقتل البوتات في أسبوعها الأول.
معظم دروس بوتات Polymarket قديمة
انتقلت Polymarket إلى حزم SDK موحّدة — polymarket-client للغة Python و@polymarket/client للغة TypeScript. وهي تحل محل py-clob-client و@polymarket/clob-client-v2 و@polymarket/builder-relayer-client و@polymarket/builder-signing-sdk. إذا طلب منك دليلٌ تنفيذ pip install py-clob-client، أو إذا ولّد مساعدك الذكي ذلك الاستيراد، فهو يعمل من مواد قديمة. كل ما يلي يستخدم الحزم الحالية.
بوت Polymarket ست قطع: اكتشاف الأسواق، وقراءة الأسعار، واتخاذ القرار، وتقديم الأوامر، وإدارة المراكز، والبقاء حيًا. الأوليان سهلتان، والرابعة مزعجة التفاصيل، والسادسة هي حيث تموت معظم البوتات فعلًا. يمر هذا الدليل بالمسار كله مع شيفرة متحقَّق منها، ويتحدث بصراحة عن الأجزاء الصعبة حقًا.
الخطوة 0: حدّد ما يتداوله بوتك
يستحق القيام بذلك قبل أن تكتب سطرًا واحدًا، لأنه يحدد كل ما يليه. تنقسم أسواق Polymarket إلى عائلتين لا يجمعهما شيء تقريبًا:
| أسواق الأحداث | أسواق Up/Down للعملات المشفرة | |
|---|---|---|
| أمثلة | الانتخابات، والرياضة، والجوائز | btc-updown-5m، eth-updown-15m |
| العمر | من أسابيع إلى أشهر | من 5 دقائق إلى 24 ساعة |
| ما يحرّك السعر | الأخبار، والمعلومات، والمعنويات | البنية الدقيقة للسوق وتدفق الأوامر |
| مصدر الأفضلية | أن تكون أفضل اطلاعًا | أن تكون أسرع أو أفضل تسعيرًا |
| الصفقات يوميًا | بضع صفقات | المئات |
| الحساسية لزمن الاستجابة | منخفضة | عالية |
إذا كنت تؤتمت، فأنت مهتم على الأرجح بالعائلة الثانية — عالية التردد، ومتواصلة، وآلية بما يكفي لترميزها. وهي مغطاة بالتفصيل في شرح أسواق Up/Down.
الخطوة 1: ثبّت حزمة SDK الحالية
تمنحك كلتا الحزمتين واجهة عميل واحدة لكل واجهات API الخاصة بـ Polymarket، ونماذج ذات أنواع محددة، وترقيمًا متسقًا للصفحات، وتوقيعًا مدمجًا — وهذا قدر كبير من العمل المزعج الذي لا تريد إعادة تنفيذه.
pip install polymarket-client
# or: uv add polymarket-client / poetry add polymarket-clientهناك أربعة عملاء في Python، واختيار الصحيح منها أهم مما يبدو:
| العميل | البيانات العامة | التداول | الوقت الفعلي |
|---|---|---|---|
AsyncPublicClient | نعم | لا | نعم |
AsyncSecureClient | نعم | نعم | نعم |
PublicClient | نعم | لا | لا |
SecureClient | نعم | نعم | لا |
subscribe(). البوتات تحتاج إلى النسخ غير المتزامنة؛ أما المتزامنة فهي للسكربتات ودفاتر Jupyter.ابدأ بالعميل العام
يمكنك بناء واختبار الاكتشاف وقراءة الأسعار وتوليد الإشارات ومسار بياناتك بالكامل باستخدام AsyncPublicClient — بلا مفاتيح، ولا محفظة، ولا مخاطرة. ولا تنتقل إلى AsyncSecureClient إلا عندما تكون مستعدًا لتقديم أمر. معظم الأخطاء تظهر قبل تلك النقطة بكثير.
الخطوة 2: اعثر على الأسواق
اكتشاف الأسواق العامة لا يتطلب أي بيانات اعتماد. أداة الترقيم في SDK متسقة عبر كل دوال السرد، لذا يمكن تعميم هذا النمط.
import asyncio
from polymarket import AsyncPublicClient
async def main() -> None:
async with AsyncPublicClient() as client:
pages = client.list_markets(closed=False, page_size=50)
# Iterate items directly when page boundaries do not matter.
async for market in pages.iter_items():
if "updown" in (market.slug or ""):
print(market.slug, market.condition_id)
asyncio.run(main())أمران يجب استيعابهما هنا. أولًا، page.next_cursor مؤشر معتم — خزّنه حرفيًا إذا أردت استئناف المسح لاحقًا، ولا تحاول تحليله أو تكوينه. ثانيًا، تحمل /markets أضيق حد معدل في المنصة كلها عند 300 طلب / 10 ثوانٍ، لذا خزّن البيانات الوصفية للأسواق مؤقتًا بدلًا من إعادة سردها في حلقة ساخنة. الأرقام الكاملة في مرجع حدود المعدل.
الخطوة 3: المصادقة
التداول يتطلب محفظة. تبني حزمة Python SDK الموقِّع من مفتاح خاص محلي:
import os
from polymarket import AsyncSecureClient
client = await AsyncSecureClient.create(
private_key=os.environ["POLYMARKET_PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
)في العمق، تستخدم Polymarket طبقتي مصادقة: L1 توقيع محفظة EIP-712 يثبت أنك تتحكم في العنوان ويتيح لك إنشاء بيانات اعتماد API أو اشتقاقها؛ وL2 توقّع كل طلب خاص بتلك البيانات باستخدام HMAC-SHA256. تتولى SDK كلتيهما، وهذا هو السبب الرئيسي لاستخدامها.
فشلا المصادقة اللذان ستواجههما
بيانات اعتماد ناقصة — تحتاج L2 إلى المفتاح والسر وعبارة المرور. اثنان من ثلاثة ينتجان طلبًا سليم الشكل بتوقيع لا يمكن التحقق منه. انحراف الساعة — يتضمن التوقيع طابعًا زمنيًا، لذا تُرفض الحاوية التي تنحرف ساعتها بضع ثوانٍ. وكلاهما يظهر بالرسالة غير المفيدة نفسها Unauthorized/Invalid api key. الشرح الكامل في مرجع الأخطاء.
التعامل مع المفاتيح
ذلك المفتاح الخاص يستطيع نقل الأموال. احفظه في متغيرات البيئة أو في مدير أسرار — لا في الشيفرة المصدرية أبدًا، ولا في صورة حاوية، ولا في المستودع الذي توشك على دفعه. استخدم محفظة مخصصة لا تحتوي إلا على ما يُسمح للبوت بخسارته، ليكون أي خطأ محدودًا بالرصيد لا بحكمك في الثالثة فجرًا.
الخطوة 4: احصل على الأسعار الآنية
الخطأ المعماري الأكثر شيوعًا في أول بوت هو استطلاع /book على مؤقت. فهذا يستهلك ميزانية حد المعدل، ويضيف تأخيرًا، ويتوسع بشكل سيئ. اشترك بدلًا من ذلك — تدمج SDK عدة تغذيات في تدفق أحداث واحد.
from polymarket.streams import MarketSpec
async with await client.subscribe([MarketSpec(token_ids=[token_id])]) as stream:
async for event in stream:
# MarketBookEvent | MarketPriceChangeEvent | MarketLastTradePriceEvent
# | MarketTickSizeChangeEvent | MarketBestBidAskEvent
# | NewMarketEvent | MarketResolvedEvent
handle(event)إذا اتصلت بـ WebSocket الخام بدلًا من استخدام SDK، فيجب أن ترسل PING كل 10 ثوانٍ وإلا يُقطع الاتصال، وتحتاج إلى custom_feature_enabled: true لتلقي أحداث best_bid_ask وnew_market وmarket_resolved أصلًا. هذه الأمور وأنماط إعادة الاتصال مشروحة في دليل WebSocket. وبشكل منفصل، انتقلت الأسعار المرجعية إلى PolyBolt في 15 سبتمبر 2026 — إذا كان بوتك يبث الأسعار الفورية، فراجع دليل الانتقال.
الخطوة 5: قدّم أمرًا
أمر السوق هو أبسط شيء يعمل، وamount مقوّم بعملة pUSD التي أنت مستعد لإنفاقها لا بالأسهم:
market = await client.get_market(slug="<market-slug>")
token_id = market.outcomes.yes.token_id
assert token_id is not None
response = await client.place_market_order(
token_id=token_id,
side="BUY",
amount="10", # spend up to 10 pUSD
)
if not response.ok:
raise RuntimeError(response.message)
# Settlement is on-chain and asynchronous — this waits for it.
hashes = await client.wait_for_order_fill_settlement(response)بالنسبة لأوامر الحد القائمة، ستلدغك قاعدتان قبل أي شيء آخر. يجب أن تقع الأسعار على شبكة التيك الخاصة بالسوق — استدعِ GET /tick-size لكل سوق بدلًا من افتراض 0.01، لأن حجم التيك يختلف وقد يضيق مع نضج السوق. والأوامر التي تقل عن الحد الأدنى للحجم في السوق تُرفض مباشرة. وكلاهما يعود كأخطاء 400 برسائل محددة، مدرجة في مرجع الأخطاء.
الرمز 200 على دفعة أوامر لا يعني النجاح
عندما ترسل عدة أوامر، تُرجع حالات فشل الأوامر الفردية داخل مصفوفة استجابة 200 كحقول errorMsg منفصلة. مرّ على المصفوفة وتحقق من كل عنصر. البوتات التي لا تتحقق إلا من حالة HTTP تعتقد بصمت أن لديها مراكز ليست لديها — وهذه فئة خطيرة حقًا من الأخطاء.
الخطوة 6: اعرف ما إذا كانت الاستراتيجية تنجح
كل ما سبق توصيلات، والتوصيلات هي النصف السهل. السؤال الصعب هو ما إذا كانت استراتيجيتك تجني المال — وهنا يفترق بناء بوتات Polymarket بحدة عن بناء بوتات العملات المشفرة الفورية.
لا توجد شبكة اختبار. لا sandbox، ولا API تجريبية، ولا نقطة نهاية للتداول الورقي. هذه الكلمات لا تظهر في أي مكان من وثائق Polymarket. أول أمر حقيقي لك هو أموال حقيقية مقابل أطراف مقابلة حقيقية. راجع هل لدى Polymarket شبكة اختبار للبدائل الأربعة.
ولا يوجد دفتر أوامر تاريخي. بمجرد حسم السوق، يُرجع دفتره 404. وتحتفظ بسلسلة أسعار بمعدل نقطة واحدة تقريبًا في الدقيقة، وفقط إذا طلبتها ببداية ونهاية صريحتين:
TOK=<token_id_of_a_resolved_market>
START=<epoch seconds the window opened>
END=$((START + 300))
curl -s "https://clob.polymarket.com/book?token_id=$TOK"
# {"error":"No orderbook exists for the requested token id"} HTTP 404
curl -s "https://clob.polymarket.com/prices-history?market=$TOK&startTs=$START&endTs=$END&fidelity=1"
# about 6 points for a 5-minute market; interval=max returns [] for older onesلذا لا يمكنك إجراء اختبار رجعي من Polymarket. تحتاج إلى لقطات عند لحظات زمنية محددة سجّلها أحدهم أثناء تشغيل الأسواق. وهذا ما توفره PolyTest لأسواق Up/Down للعملات المشفرة — 240M+ لقطة، و8 مستويات من عمق الدفتر لكل جانب، وطوابع زمنية بدقة أقل من الثانية، مع الاحتفاظ بالأسواق المحسومة:
import os, requests
BASE = "https://api.polytest.io/api/v1"
H = {"X-API-Key": os.environ["POLYTEST_KEY"]}
markets = requests.get(f"{BASE}/markets",
params={"coin": "btc", "market_type": "5m", "limit": 50},
headers=H).json()["markets"]
snaps = requests.get(f"{BASE}/markets/{markets[0]['id']}/snapshots",
params={"include_orderbook": "true"},
headers=H).json()["snapshots"]
def simulate_fill(levels, qty):
"""Walk the ladder. Mid-price is not a price you can trade at."""
filled = cost = 0.0
for lvl in levels:
take = min(lvl["size"], qty - filled)
cost += take * lvl["price"]
filled += take
if filled >= qty:
break
return cost / filled if filled >= qty else None
print(simulate_fill(snaps[0]["orderbook"]["asks"], 500))الخطأ الذي يجعل الاختبار الرجعي بلا قيمة
إذا أجريت الاختبار الرجعي مقابل السعر الأوسط فأنت تختبر متطابقة حسابية، لا استراتيجية. فوارق أسواق Up/Down تبلغ عادةً 2–5 سنتات على عقد يُسوّى عند $1 — وكثيرًا ما تكون أوسع من الأفضلية المدّعاة. امشِ عبر الدفتر وخذ التنفيذ الذي كنت ستحصل عليه حقًا. هذا التغيير الوحيد يقتل معظم الاستراتيجيات، وهذا بالضبط ما تريده منه أن يفعل، بتكلفة زهيدة، قبل تمويلها.
الخطوة 7: اصمد أمام بيئة الإنتاج
البوت الذي يتداول بشكل صحيح لساعة ثم يتعطل أسوأ من عدم وجود بوت. هذه هي أنماط الفشل التي تحدث فعلًا، مرتبة تقريبًا حسب تكرار حدوثها:
| الفشل | ما تراه | المعالجة |
|---|---|---|
| تجاوز حد المعدل | ارتفاع زمن الاستجابة، لا أخطاء | تقوم Cloudflare بالإبطاء بدلًا من الرفض — راقب p99، لا معدل الأخطاء |
| إعادة تشغيل محرك المطابقة | 425 Too Early | أعد المحاولة مع التراجع؛ لا تطلق تنبيهًا لحالات فردية |
| إيقاف المنصة مؤقتًا | 503 | توقف عن فتح المراكز. ألغِ إن كان مسموحًا |
| وضع الإلغاء فقط | 503 على الأوامر الجديدة | يجب أن يعمل مسار الإلغاء بشكل مستقل عن مسار الدخول |
| وضع النشر فقط | 503 + retry_after_seconds | انتظر تلك المدة بالضبط، ثم أعد المحاولة |
| عدم تطابق الموقّع | خطأ 400 في موقّع الأمر | بيانات اعتماد قديمة من محفظة أخرى — أعد الاشتقاق |
| انقطاع WebSocket | صمت | غياب البيانات لا يعني غياب التغيير — تتبّع عمر آخر رسالة |
| انحراف الساعة | 401 على بوت كان يعمل بالأمس | شغّل NTP؛ هذا الخطأ يهدر أكبر قدر من الوقت |
الصمت هو الحالة الخطرة
انقطاع WebSocket لا يطلق استثناءً — بل يتوقف ببساطة عن توصيل الرسائل. البوت الذي يحمل مركزًا ولا يتلقى تحديثات سيعتقد بكل سرور أن السوق متجمد عند آخر سعر رآه. تتبّع عمر آخر رسالة وتعامل مع التقادم كحالة خطأ، لا كهدوء.
- اختبر مسار الإلغاء قبل مسار الدخول. العجز عن الخروج أسوأ بكثير من العجز عن الدخول.
- ضع سقفًا للتعرض في الشيفرة، لا في ذهنك. حد صارم للمركز يحوّل الخطأ المنطقي إلى خسارة صغيرة بدلًا من خسارة غير محدودة.
- ابنِ مفتاح إيقاف طارئ واختبره فعلًا. مفتاح الإيقاف غير المختبَر مجرد تعليق.
- أضف تذبذبًا عشوائيًا إلى المهام المجدولة. العمّال الذين يستيقظون في الثانية نفسها بالضبط يخلقون ذروة متزامنة أعلى بكثير من معدلك المتوسط.
- سجّل كل طلب واستجابة في الأسبوع الأول. ستحتاج إليها، ولا يمكنك إعادة بنائها لاحقًا.
- أطلق التنبيهات حسب الفئات، لا حسب الرسائل. تُضمّن Polymarket معرّفات الأوامر والأسعار في نصوص الأخطاء، لذا فالتنبيه حسب النص الخام مجرد ضوضاء.
ترتيب بناء واقعي
التسلسل الذي يهدر أقل قدر من الوقت والمال:
- تكامل للقراءة فقط، بالعميل العام، بلا مفاتيح. أثبت الاكتشاف والتحليل وترقيم الصفحات والتراجع. يوم واحد، مجانًا.
- أجرِ اختبارًا رجعيًا للاستراتيجية على دفاتر تاريخية مع محاكاة صادقة للتنفيذ. معظم الأفكار تموت هنا. وهذا هو المقصود.
- تداول ورقيًا مباشرة لمدة أسبوع على الأقل — سجّل الأوامر المقصودة بدلًا من إرسالها. يثبت ذلك وقت التشغيل وإعادة الاتصال والتوقيت.
- ابدأ مباشرة بالحد الأدنى للحجم مع سقف صارم للتعرض ومفتاح إيقاف طارئ مختبَر.
- لا توسّع إلا حين تطابق الأرقام المباشرة الأرقام الورقية. إذا تباعدت، فنموذج التنفيذ لديك كان خاطئًا — عُد إلى الخطوة 2.
الخطوات 1 و3 و4 يمكنك بناؤها في بضعة أيام. أما الخطوة 2 فتحتاج إلى بيانات لا تحتفظ بها Polymarket، وهي أيضًا الخطوة الأكثر موثوقية في توفير المال. ابدأ فترة تجريبية مجانية على PolyTest — تكفي لتعرف ما إذا كانت فكرتك تصمد أمام الفارق.
الأسئلة الشائعة
- كيف أبني بوت تداول على Polymarket؟
- ثبّت حزمة SDK الموحّدة الحالية — polymarket-client للغة Python أو @polymarket/client للغة TypeScript. استخدم AsyncPublicClient لاكتشاف الأسواق وقراءة الأسعار دون بيانات اعتماد، ثم AsyncSecureClient مع مفتاح خاص للتداول. اشترك في قناة السوق عبر WebSocket بدلًا من استطلاع الأسعار، وقدّم الأوامر باستخدام place_market_order، وتعامل مع الاستجابات 425 و429 و503 بالتراجع. وقبل التشغيل المباشر، أجرِ اختبارًا رجعيًا على لقطات دفتر الأوامر التاريخية مع محاكاة واقعية للتنفيذ، إذ لا تملك Polymarket شبكة اختبار ولا تحتفظ بسجل لدفاتر الأوامر.
- ما حزمة SDK التي يجب أن أستخدمها لبوت Polymarket في 2026؟
- استخدم حزم SDK الموحّدة: polymarket-client للغة Python أو @polymarket/client للغة TypeScript. وهي تحل محل الحزم الأقدم py-clob-client و@polymarket/clob-client-v2 و@polymarket/builder-relayer-client و@polymarket/builder-signing-sdk. وحزمة Rust SDK موحّدة قيد التطوير. لا تزال معظم الدروس والشيفرات المولّدة بالذكاء الاصطناعي تشير إلى الحزم المهجورة، لذا تحقّق من الاستيرادات قبل الوثوق بأي مقتطف.
- هل يمكنني التداول ورقيًا على Polymarket قبل المخاطرة بأموال حقيقية؟
- ليس عبر Polymarket — فلا توجد شبكة اختبار ولا sandbox ولا API تجريبية. يمكنك بناء طبقة تداول ورقي بنفسك بتشغيل حلقة استراتيجيتك المباشرة مقابل بيانات الأسواق الإنتاجية وتسجيل الأوامر المقصودة مع حالة الدفتر في تلك اللحظة بدلًا من إرسالها. يثبت ذلك أن بوتك سليم تشغيليًا، لكنه يفترض التنفيذ، لذا لن يعلّمك شيئًا عن الموقع في الطابور أو أثر السوق.
- كيف أجري اختبارًا رجعيًا لبوت تداول على Polymarket؟
- تحتاج إلى لقطات تاريخية لدفتر الأوامر من طرف ثالث، لأن API الخاصة بـ Polymarket تُرجع 404 لدفتر السوق المحسوم ولا تحتفظ إلا بنقطة واحدة تقريبًا في الدقيقة من سجل الأسعار. اسحب لقطات عند لحظات زمنية محددة بعمق كامل، وأعد تشغيلها بترتيب زمني دون النظر إلى الأمام، وحاكِ التنفيذ بالمشي عبر مستويات الدفتر بدلًا من افتراض السعر الأوسط. فوارق Up/Down البالغة 2-5 سنتات على عقد قيمته $1 تكون عادةً أكبر من الأفضلية المدّعاة، لذا فالاختبارات الرجعية بالسعر الأوسط مضللة.
- لماذا يتلقى بوتي على Polymarket الخطأ Unauthorized/Invalid api key؟
- غالبًا لأحد سببين. إما أن مجموعة بيانات اعتمادك ناقصة — فمصادقة L2 تحتاج إلى مفتاح API والسر وعبارة المرور معًا — أو أن ساعة نظامك قد انحرفت، إذ يتضمن توقيع الطلب طابعًا زمنيًا وانحراف بضع ثوانٍ يبطله. وبشكل أقل شيوعًا، تكون قد اشتققت بيانات الاعتماد لمحفظة غير التي تتداول منها.
- هل أحتاج إلى WebSocket لبوت Polymarket أم يمكنني الاستطلاع؟
- استخدم WebSocket. استطلاع /book على مؤقت يستهلك ميزانية حد المعدل، ويضيف تأخيرًا، ويتوسع بشكل سيئ. اشترك في قناة السوق في CLOB لتحديثات الدفتر والأسعار العامة، وفي قناة المستخدم لتحديثات أوامرك وصفقاتك. وإذا اتصلت بـ WebSocket الخام بدلًا من المرور عبر SDK، فأرسل PING كل 10 ثوانٍ لإبقاء الاتصال حيًا.
احصل على البيانات التاريخية التي لا تحتفظ بها Polymarket
يسجّل PolyTest أسواق Up/Down للعملات المشفرة على Polymarket أثناء تشغيلها — 240M+ لقطة مع 8 مستويات من عمق دفتر الأوامر، وطوابع زمنية بدقة أقل من الثانية، مع الاحتفاظ بالأسواق المحسومة. ابدأ بفترة تجريبية مجانية لمدة 3 أيام.
تابع القراءة
أفضلية تأخر السعر الفوري على Polymarket حقيقية. وعمقها نحو $100 أيضًا.
اشترِ الجانب الذي أكده السعر الفوري بالفعل، قبل أن تعيد Polymarket التسعير. خلافًا لمعظم الاستراتيجيات التي يدّعيها الناس، تصمد هذه أمام البيانات — بدرجة z قدرها 15. والسبب في أنها لم تُغنِ الجميع قابع في دفتر الأوامر.
WebSockets في Polymarket: بيانات آنية لا تنقطع
استطلاع دفتر الأوامر هو الطريقة الأكثر شيوعًا لاستنزاف ميزانية حد المعدل بلا فائدة. إليك التدفقات الأربعة، وخيارات الاشتراك التي لا يوثقها أحد، ونمط الفشل الذي يتلقى فيه بوتك الصمت فيظنه هدوءًا.
حزمة Polymarket Python SDK في 2026 (والانتقال من py-clob-client)
إذا كانت شيفرتك لا تزال تستورد ClobClient من py_clob_client، فهي مبنية على حزمة حلّت محلها أخرى — وكذلك معظم شيفرات Polymarket التي سيكتبها لك مساعد الذكاء الاصطناعي. إليك حزمة SDK الحالية وكيف تنتقل إليها.