شرح Polymarket Bot · الفصل 18 من 32
بوتات التنبؤ بنزاعات UMA على Polymarket: اكتشف مقترحات Optimistic Oracle، وتنبأ باحتمال النزاع، واستفد من عدم تماثل السعر قبل النزاع وبعده، وتجنب دوامات الموت في الأسواق المتنازع عليها.
ما الذي يغطيه هذا الفصل
Optimistic Oracle من UMA هو الذي يحسم أسواق Polymarket، والنزاعات تخلق شذوذات سعرية قبل حدوثها وبعدها. توجد أنماط قابلة للتداول على جانبي النزاع، لكن الاستراتيجية معقدة تشغيليًا وقد أحرقت عددًا من البوتات أكثر مما غذّته. هذا الفصل هو دليل التشغيل الصريح.
- كيف يعمل UMA Optimistic Oracle
- اكتشاف المقترح on-chain
- المؤشرات التنبؤية للنزاع (volume، والغموض، والسجل السابق)
- عدم تماثل السعر قبل النزاع
- إعدادات التداول بعد النزاع
- متى لا تتداول الأسواق المتنازع عليها
- الكود: الاشتراك في أحداث UMA proposed/disputed
كيف يعمل UMA Optimistic Oracle
Optimistic Oracle (OO) من UMA هو طبقة تسوية النزاعات في Polymarket. كل عملية حسم سوق تمر عبر OO؛ ومعظمها لا يواجه اعتراضًا ويتم تسويته تلقائيًا. أما الحالات المتنازع عليها - النزاعات - فتفعّل فترة تصويت تتراوح بين 24 و72 ساعة يقرر خلالها حاملو توكنات UMA النتيجة.
دورة الحياة: يقوم resolver الخاص بـ Polymarket باقتراح سعر (0 = فازت NO، 1 = فازت YES). بعد نافذة اعتراض مدتها ساعتان، إذا لم يعترض أحد، يُعتمد السعر نهائيًا ويقوم عقد CTF بتوزيع المدفوعات. إذا اعترض أحدهم، يدخل السوق في نافذة تصويت؛ ويصوّت حاملو UMA، وتفوز الأغلبية.
بالنسبة إلى bot، الأحداث ذات الصلة هي ProposePrice (تم إدخال المقترح وفتح نافذة الاعتراض) وDisputePrice (تم رفع النزاع وبدأت فترة التصويت). اشترك في هذه الأحداث لتتبع حالة تسوية السوق في الوقت الحقيقي.
اكتشاف المقترح on-chain
عقد UMA OO على Polygon يصدر حدث ProposePrice مع المعاملات (requester, identifier, timestamp, ancillaryData, proposer, proposedPrice). قم بالتصفية باستخدام عنوان requester المعروف لـ Polymarket لتقليل المقترحات ذات الصلة فقط.
POLY_REQUESTER = "0x..." # Polymarket Adjudicator
filt = oo_contract.events.ProposePrice.create_filter(
fromBlock="latest",
argument_filters={"requester": POLY_REQUESTER}
)
for event in filt.get_new_entries():
market_id = decode_ancillary(event.args.ancillaryData)
proposed = "YES" if event.args.proposedPrice == 1e18 else "NO"
print(f"PROPOSE: market {market_id} → {proposed}")
الحقل ancillaryData هو JSON مشفّر بصيغة hex يصف سؤال السوق. يمنحك فك ترميزه معرّف السوق الذي يمكنك ربطه بمراكزك المفتوحة.
المؤشرات التنبؤية للنزاع (volume، والغموض، والسجل السابق)
ثلاث إشارات قبل النزاع ترتبط بالنزاعات الفعلية اللاحقة.
- إجمالي volume: الأسواق التي يتجاوز volume التراكمي فيها $1M تتعرض للنزاع بمعدل أعلى 4 مرات من الأسواق الصغيرة. كلما زاد رأس المال على المحك، زادت الحوافز للطعن.
- صياغة غامضة: أي سوق يحتوي على "or similar" أو "officially confirmed" أو شروط مركبة (تاريخ AND نتيجة محددة) يكون لديه معدل نزاع أعلى.
- نزاعات سابقة على الحدث نفسه: إذا كان مقترح سابق قد تعرّض للنزاع ثم أُعيد تقديمه، فإن المقترح الثاني يتعرض للنزاع بمعدل 2-3 مرات المعدل الطبيعي.
يمكن لـ bot حساب درجة "احتمال النزاع" من هذه السمات وتجنب فتح مراكز في الأسواق التي تتجاوز عتبة معينة عند الاقتراب من التسوية.
عدم تماثل السعر قبل النزاع
في الساعات التي تسبق نزاعًا محتملًا، غالبًا ما يُظهر سعر السوق حركة غير متماثلة: الجانب الذي سمّاه المقترح على أنه YES يميل للهبوط (لأن المتداولين يخشون أن يقلبه النزاع)، بينما يرتفع الجانب الآخر.
إذا كانت لديك رؤية اتجاهية حول الجهة التي سيُحسم لصالحها النزاع، فهذه نافذة قابلة للتداول. المخاطرة: إذا لم يحدث النزاع، ينعكس هذا الاختلال عندما تُغلق نافذة الاعتراض دون شيء، وتعود الأسعار سريعًا إلى اتجاه المقترح.
بصراحة: معظم صفقات عدم التماثل قبل النزاع خاسرة، لأن معظم الاعتراضات تُحسم لصالح المقترح الأصلي. هذه الاستراتيجية تنجح فقط عندما تكون لديك معلومات محددة عن سبب احتمال أن يُحافَظ على هذا النزاع.
إعدادات التداول بعد النزاع
بعد رفع النزاع، يتداول السوق لمدة 24-72 ساعة في حالة "تعليق" - معروف أنه متنازع عليه، والنتيجة ستُحسم بالتصويت. توجد إعدادتان.
الاقتراب من إجماع UMA: إذا ظهرت إشارة مبكرة على تسوية النزاع (مثلًا، يتخذ أحد كبار المصوتين في UMA موقفًا علنيًا)، يتحرك السعر نحو تلك التسوية. يمكن لـ bot يراقب إشارات UMA Discord / Twitter + حركة السعر أن يلتقط ذلك في 30-60% من الحالات.
اصطياد التقلب: فترات التعليق تكون فيها spreads واسعة. يمكن لـ market maker صبور أن يربح spread tax عبر عدة متداولين يدخلون ويخرجون خلال نافذة التصويت. مخاطر inventory مرتفعة؛ لذا اضبط الحجم وفقًا لذلك.
كلاهما يتطلب راحةً مع الاحتمال الحقيقي أن تُحسم النتيجة ضد مركزك. تعامل مع inventory خلال فترة النزاع على أنه نصف الحجم كحد أقصى.
متى لا تتداول الأسواق المتنازع عليها
ثلاث حالات يكون فيها تداول النزاع خاطئًا افتراضيًا.
- ليس لديك رؤية خاصة بـ UMA. إذا كانت ميزتك الوحيدة هي "المقترح الأصلي يبدو صحيحًا بالنسبة لي"، فلا توجد لديك أفضلية على المقترح الأصلي - ورفع النزاع نفسه يعتقد العكس. نتيجة التصويت تصبح أشبه برمية عملة لا يمكنك التنبؤ بها.
- النزاع مبني على صياغة غامضة. عادةً ما ينحاز مصوّتوا UMA إلى القراءة الحرفية للسؤال. إذا نص السوق على "by January 31" وحدث الحدث في February 1، فسوف تسوّي UMA النتيجة NO بغض النظر عن حدس مجتمع المتداولين.
- لديك inventory من قبل النزاع. إضافة مركز قائم لـ "متوسط التكلفة" خلال فترة التعليق هي النمط الكلاسيكي لتدمير رأس المال. احتفظ أو اخرج، ولا تضف أبدًا.
الكود: الاشتراك في أحداث UMA proposed/disputed
مرجع: اشتراك WebSocket في أحداث UMA OO، مع التصفية بحسب requester الخاص بـ Polymarket.
from web3 import Web3
w3 = Web3(Web3.WebsocketProvider(POLYGON_WSS))
oo = w3.eth.contract(address=UMA_OO_ADDR, abi=UMA_OO_ABI)
POLY = "0x...".lower()
dispute_filter = oo.events.DisputePrice.create_filter(fromBlock="latest")
propose_filter = oo.events.ProposePrice.create_filter(fromBlock="latest")
while True:
for event in dispute_filter.get_new_entries():
if event.args.requester.lower() == POLY:
on_dispute(event)
for event in propose_filter.get_new_entries():
if event.args.requester.lower() == POLY:
on_propose(event)
time.sleep(2)
def on_dispute(event):
market_q = decode_ancillary_to_question(event.args.ancillaryData)
send_telegram(f"DISPUTE: {market_q}")
# If we hold a position in this market, alert + consider exit
if market_q in our_positions:
flag_position_for_review(market_q)
النمط: اشترك، فك الترميز، أطلق التنبيه. اتخاذ إجراءات خوارزمية على النزاعات يحمل مخاطرة عالية؛ وغالبًا ما تكون مهمة bot هي فقط عرض الحدث على مراجع بشري.





