מדריך בוט Polymarket · פרק 18 מתוך 32
בוטים לחיזוי מחלוקות UMA ב־Polymarket: זיהוי הצעות של Optimistic Oracle, חיזוי סבירות למחלוקת, ניצול אסימטריית מחירים לפני ואחרי מחלוקת, והימנעות מספירלות מוות של שוק במחלוקת.
מה מכוסה בפרק זה
ה־Optimistic Oracle של UMA הוא זה שמכריע את שווקי Polymarket, ומחלוקות יוצרות אנומליות במחיר לפני ואחרי שהן מתרחשות. דפוסים שניתן למסחר קיימים בשני צדי המחלוקת, אבל האסטרטגיה מורכבת תפעולית ושרפה יותר בוטים ממה שהיא האכילה. הפרק הזה הוא המדריך הכנה והישיר.
- איך UMA Optimistic Oracle עובד
- זיהוי proposal on-chain
- מנבאי מחלוקת (נפח, עמימות, היסטוריה)
- אסימטריית מחיר לפני מחלוקת
- סטאפים למסחר אחרי מחלוקת
- מתי לא לסחור בשווקים במחלוקת
- קוד: subscribe לאירועי UMA proposed/disputed
How UMA Optimistic Oracle works
ה־Optimistic Oracle (OO) של UMA הוא שכבת יישוב המחלוקות עבור Polymarket. כל סגירת שוק עוברת דרך OO; רוב המקרים אינם שנויים במחלוקת ונחתמים אוטומטית. אלה שבמחלוקת - disputes - מפעילים חלון הצבעה של 24-72 שעות, שבמהלכו מחזיקי טוקני UMA מחליטים על התוצאה.
מחזור החיים: ה־resolver של Polymarket מציע מחיר (0 = NO ניצח, 1 = YES ניצח). לאחר חלון ערעור של שעתיים, אם אף אחד לא מגיש מחלוקת, המחיר מתקבע וחוזה ה־CTF מחלק את התשלומים. אם מישהו מגיש מחלוקת, השוק נכנס לחלון הצבעה; מחזיקי UMA מצביעים, והרוב מנצח.
עבור בוט, האירועים הרלוונטיים הם ProposePrice (הצעה נכנסה, חלון הערעור נפתח) ו־DisputePrice (הוגשה מחלוקת, תקופת ההצבעה מתחילה). יש לבצע subscribe לאירועים האלה כדי לעקוב בזמן אמת אחר מצב היישוב של השוק.
Detecting a proposal 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 מקודד בהקס שמציג את שאלת השוק. פענוח שלו נותן לך את מזהה השוק, שאפשר לבצע אליו cross-reference מול הפוזיציות הפתוחות שלך.
Dispute predictors (volume, ambiguity, history)
שלושה אותות לפני מחלוקת מתואמים עם מחלוקות בפועל שמגיעות בהמשך.
- Total volume: שווקים עם נפח חיים של יותר מ־$1M שנויים במחלוקת בשיעור הגבוה פי 4 משווקים קטנים. ככל שיש יותר הון על הכף = כך יש יותר תמריץ לערער.
- Ambiguous wording: כל שוק עם "or similar," "officially confirmed," או תנאים מורכבים (תאריך AND תוצאה ספציפית) מציג שיעורי מחלוקת גבוהים יותר.
- Past disputes on the same event: אם הצעה קודמת כבר הייתה במחלוקת והוגשה מחדש, ההצעה השנייה נתקפת במחלוקת בקצב הגבוה פי 2-3 מהרגיל.
בוט יכול לחשב ציון של "סבירות למחלוקת" על בסיס המאפיינים האלה ולהימנע מלקיחת פוזיציות בשווקים שעוברים סף מסוים סמוך ליישוב.
Pre-dispute price asymmetry
בשעות שלפני מחלוקת סבירה, מחיר השוק מראה לעיתים קרובות תנועה אסימטרית: הצד שה־proposer סימן כ־YES נסחף מטה (כי סוחרים חוששים שמחלוקת תהפוך אותו), והצד השני נסחף מעלה.
אם יש לך דעה כיוונית לגבי איך המחלוקת תיפתר, זהו חלון שניתן לסחור בו. הסיכון: אם המחלוקת לא מתרחשת, האסימטריה מתהפכת כשהחלון נסגר בלי אירועים מיוחדים, והמחירים קופצים חזרה לכיוון המוצע.
באופן כן: רוב העסקאות של אסימטריית טרום־מחלוקת הן עסקאות מפסידות, כי רוב האתגרים מסתיימים לטובת ההצעה המקורית. האסטרטגיה עובדת רק כשיש לך מידע ספציפי על למה סביר שהמחלוקת תישאר בעינה.
Post-dispute trade setups
אחרי שמוגשת מחלוקת, השוק נסחר במשך 24-72 שעות ב"שטח ביניים" - ידוע שנמצא במחלוקת, והתוצאה אמורה להיות מוכרעת בהצבעה. יש שני סטאפים.
התכנסות לקונצנזוס של UMA: אם רואים מוקדם את כיוון יישוב המחלוקת (למשל, מצביע בולט ב־UMA נוקט עמדה בפומבי), המחיר נע לכיוון היישוב הזה. בוט שעוקב אחרי אותות מ־UMA Discord / Twitter יחד עם תנועת המחיר יכול לתפוס את זה ב־30-60% מהמקרים.
חקירת תנודתיות: תקופות הביניים האלה מגיעות עם מרווחים רחבים. market maker סבלני יכול להרוויח את מס ה־spread על פני כמה סוחרים שנכנסים ויוצאים במהלך חלון ההצבעה. סיכון המלאי גבוה; יש להתאים את הגודל בהתאם.
שני הסוגים דורשים נוחות עם האפשרות הממשית שהיישוב יפעל נגד הפוזיציה שלך. התייחסו למלאי בתקופת מחלוקת כאל חצי גודל לכל היותר.
When NOT to trade disputed markets
שלושה מצבים שבהם עסקת המחלוקת שגויה כברירת מחדל.
- אין לך עמדה ספציפית ל־UMA. אם היתרון היחיד שלך הוא "נראה לי שההצעה המקורית נכונה", אין לך יתרון על פני המציע המקורי - ומגיש המחלוקת חושב בדיוק ההפך. תוצאת ההצבעה היא הטלת מטבע שאי אפשר לחזות.
- המחלוקת היא על ניסוח עמום. מצביעי UMA בדרך כלל נוטים לפרשנות מילולית קפדנית של השאלה. אם השוק אמר "עד 31 בינואר" והאירוע התרחש ב־1 בפברואר, UMA יכריע NO בלי קשר לאינטואיציה של קהל הסוחרים.
- יש לך מלאי שנצבר לפני המחלוקת. הוספה לפוזיציה קיימת כדי "להוריד ממוצע" בזמן השהייה היא דפוס קלאסי של הרס הון. או להחזיק או לצאת, לעולם לא להוסיף.
Code: subscribe to UMA proposed/disputed events
Reference: subscribe ב־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)
הדפוס: subscribe, decode, alert. פעולה אלגוריתמית על מחלוקות היא בסיכון גבוה; התפקיד של הבוט הוא בדרך כלל להעלות את האירוע לבודק אנושי.





