מדריך בוט Polymarket · פרק 30 מתוך 32

קוד ניהול סיכונים ברמת Production עבור בוטים של Polymarket: מגבלות פוזיציה, מגבלות הפסד יומי, סנטינלים לעצירה, מעקב אחר שיעור מילויים, reconcile בעת אתחול מחדש, retry-ים idempotent. דפוסי קוד מסוחר Production אמיתי.

מה מכוסה בפרק זה

קוד סיכון הוא רובו של בוט מסחר ברמת Production. לוגיקת האסטרטגיה היא החלק הקל; המגבלות, העצירות, מנגנוני המעקב וה-reconcile שמקיפים אותה הם מה שקובע אם הבוט ישרוד את השבוע הרע הראשון שלו. הפרק הזה הוא תבנית הסיכון ברמת Production.

  • למה קוד סיכון הוא רובו של בוט מסחר אמיתי
  • מגבלות פוזיציה (לכל שוק, לכל אסטרטגיה, לכלל המערכת)
  • מתג כיבוי להפסד יומי
  • סנטינלים לעצירה (עצירת חירום מבוססת קובץ)
  • Watchdog לשיעור מילויים
  • Reconcile בין היומן ל-on-chain בעת אתחול מחדש
  • קוד: לולאה ברמת Production עם מודעות לעצירה

Why risk code is most of a real trading bot

מדידה שעשינו על בסיס הקוד של הבוט שלנו: 60% משורות הקוד הן קוד סיכון (מגבלות, עצירות, watchdogs, reconciliation). 30% הן אסטרטגיה. 10% הם glue.

היחס הזה נכון. אסטרטגיה היא החלק הקל - להסביר מתי להיכנס ומתי לצאת אפשר בכמה עשרות שורות. קוד הסיכון הוא כל השאר: מה עושים כשהמחיר נע נגדך מהר מהצפוי, מה עושים כשהמילויים מפסיקים להיכנס, מה עושים כשה-WebSocket נופל, מה עושים כשהאסטרטגיה מתבררת כלא רווחית.

רוב סיפורי הכישלון של בונים חולקים אותה צורה: האסטרטגיה עבדה, אבל הבוט המשיך לסחור דרך שינוי משטר כי לא הופעלה עצירה. כתבו את מנגנוני העצירה לפני שאתם כותבים את האסטרטגיה.

Position caps (per-market, per-strategy, total)

שלוש מגבלות, נאכפות בקוד.

  • מגבלת per-market: מקסימום $X לכל שוק בלי קשר לרמת הביטחון באפסייד. טיפוסי: $25-100 לבוטים קטנים, $200-500 ל-Production. מגביל את גודל הנזק של טעות בשוק יחיד.
  • מגבלת per-strategy: אם אתם מריצים כמה אסטרטגיות, כל אחת מקבלת נתח מההון הכולל. טיפוסי: 30-50% לכל אסטרטגיה. מונע מיום רע של אסטרטגיה אחת לבלוע את ההון של האחרות.
  • מגבלה כוללת: אחוז מקסימלי מיתרת ה-wallet שנפרס בו-זמנית. טיפוסי: 50-70%. משאיר הון להזדמנויות לא צפויות או כדי לתפוס באגים בחשבונאות של הבוט עצמו.

את שלוש המגבלות צריך לאכוף בתוך פונקציית הצבת ההזמנה, ולא רק בלוגיקת האסטרטגיה. יכול להיות באג באסטרטגיה; השער של הצבת ההזמנה הוא קו ההגנה האחרון.

Daily loss kill switch

מנגנון הבקרה החשוב ביותר: מתג כיבוי להפסד יומי.

הכלל: אם PnL ממומש + לא ממומש מאז חצות UTC יורד מתחת ל--X% מיתרת הפתיחה היומית, הבוט מפסיק לפתוח פוזיציות חדשות ו-(אופציונלית) מאפס את הקיימות. X טיפוסי: 5-10%.

המתמטיקה: לבוט עם שיעור ניצחון צפוי של 60% יש אולי סיכוי של 5% לרצף הפסדים של 10 טריידים. בלי מתג הכיבוי, הרצף הזה מצטבר: הפסד של $200 → הבוט ממשיך לסחור → עוד הפסד של $200 → ה-wallet יורד ב-40%. כשהמתג פועל ב--10%, היום הרע מוגבל ל-$200, ומחר הבוט מתחיל מחדש.

את המתג אוכפים בצד השרת: כותבים קובץ halt או מגדירים דגל במסד הנתונים שלולאת המסחר בודקת בכל איטרציה. מפעילים מחדש רק אחרי בדיקה ידנית.

Halt sentinels (file-based emergency stop)

מנגנון העצירה הפשוט ביותר האפשרי: הבוט בודק אם קובץ קיים (למשל /opt/pmt/HALT) בכל איטרציה של הלולאה ועוצר מסחר אם הקובץ קיים.

def trading_loop():
    while True:
        if os.path.exists("/opt/pmt/HALT"):
            log("HALT file detected, sleeping")
            time.sleep(30)
            continue
        run_one_iteration()
        time.sleep(5)

כדי לעצור מיד מכל מקום (SSH, בוט Telegram, מערכת ניטור): touch /opt/pmt/HALT. כדי להמשיך: rm /opt/pmt/HALT.

הגישה מבוססת-הקובץ היא במכוון low-tech כי היא עובדת בתנאים שבהם מנגנוני עצירה מתוחכמים יותר נכשלים: כשהבוט קרס חלקית, כשה-database לא זמין, כשה-API key מוגבל בקצב. גישה ל-file system תמיד זמינה.

Fill-rate watchdog

האסטרטגיה מניחה שהזמנות FOK יתמלאו בשיעור מסוים (לרוב 60-80%). כשהשיעור יורד משמעותית, משהו השתנה: market makers נסוגו, האסטרטגיה שלכם זוהתה, או שיש outage ב-API. תהיה הסיבה אשר תהיה, ההנחה שהובילה את מתמטיקת ה-PnL של האסטרטגיה נשברה.

לוגיקת ה-watchdog: ספירת fill-rate נעה של 24 שעות. אם היא < 30% (או 50% מהמצופה), שולחים alert + מבצעים auto-halt. ממשיכים רק אחרי בדיקה ידנית.

ה-watchdog שימושי גם ככלי אבחוני. ירידה פתאומית ב-fill-rate בדרך כלל מתואמת לאירוע חיצוני (פריסת Polymarket, עומס ב-Polygon, ה-IP שלכם מקבל rate limit) שכדאי לדעת עליו בלי קשר להשפעה על המסחר.

Reconcile diary vs on-chain on restart

הבוט מחזיק יומן של הפוזיציות שהוא חושב שיש לו. ה-chain מחזיק את האמת. הם צריכים תמיד להסכים; כשהם לא, הבוט פועל על אמונה שגויה ויבצע מסחר שגוי.

לוגיקת reconciliation: בכל אתחול מחדש ופעם בשעה בזמן פעילות רגילה, מביאים balances on-chain עבור כל טוקן שהבוט נגע בו. משווים מול היומן; שולחים alert + עוצרים אם ה-balance של טוקן כלשהו שונה מהיומן ביותר מטולרנס עיגול.

הסיבה הנפוצה ביותר לסטייה היא הזמנה מוצלחת שהקריאה ל-API של הבוט פספסה (timeout, retry שלא נרשם). ה-chain מחזיק את הפוזיציה; הבוט חושב שלא. בלי reconciliation, הבוט לא יפרסם את יציאת ה-take-profit והפוזיציה תיסחב עד לפתרון.

Code: production-grade halt-aware loop

Reference: לולאת המסחר ב-Production עם כל בקרות הסיכון מחוברות.

def production_loop():
    while True:
        # Halt checks
        if os.path.exists("/opt/pmt/HALT"):
            sleep_with_log(30); continue
        if daily_pnl_below_threshold():
            create_halt("daily PnL kill"); continue

        # Reconcile every hour
        if now() - last_reconcile > 3600:
            ok = reconcile_diary_vs_chain()
            last_reconcile = now()
            if not ok: create_halt("reconciliation failed"); continue

        # Fill-rate watchdog
        if recent_fill_rate() < 0.30:
            create_halt("fill rate collapse"); continue

        # Strategy
        try:
            run_strategy_once()
        except Exception as e:
            log_exception(e)
            if consecutive_exceptions >= 5:
                create_halt(f"exceptions: {e}"); continue
        time.sleep(5)

הדפוס: כל איטרציה עוברת דרך השער. באגים באסטרטגיה לא יכולים לעקוף את הבקרות, מעצם התכנון.

שאלות נפוצות

מהו halt sentinel?
קובץ (למשל, data/halt_autobuy) שהבוט בודק לפני כל הזמנה. אם הקובץ קיים, הבוט מסרב להציב הזמנות גם אם האסטרטגיה אומרת שכן. זה מאפשר לעצור את הבוט באמצע אירוע עם פקודת touch אחת. הוספנו את הדפוס המדויק הזה לבוט ה-Production שלנו אחרי אירוע מילוי תקוע באפריל 2026.
אילו מגבלות פוזיציה כדאי לי להגדיר?
לכל שוק: 1-5% מה-bankroll. לכל אסטרטגיה: 10-20%. חשיפה פתוחה כוללת: 50-70% מה-bankroll (להשאיר buffer במזומן). הגבילו הזמנה בודדת ל-1-2% מה-bankroll בלי קשר לאסטרטגיה - אף הזמנה אחת עם טעות הקלדה לא צריכה להיות בגודל של החשבון.
איך מיישמים מתג כיבוי להפסד יומי?
עוקבים אחרי PnL ממומש + לא ממומש לכל יום UTC. אם ה-PnL היומי יורד מתחת ל--3 עד -5% מה-bankroll, מגדירים את ה-halt sentinel ומודיעים לעצמכם. הבוט מפסיק הזמנות חדשות; פוזיציות קיימות מנוהלות ידנית. מאפסים ב-00:00 UTC בכל יום.
מה הבוט צריך לעשות באתחול מחדש אחרי קריסה?
שלושה שלבים: (1) לבצע reconcile להזמנות פתוחות דרך SDK מול היומן המקומי. (2) לבדוק פוזיציות פתוחות on-chain מול המצב המקומי. (3) אם יש אי-התאמה, לעצור את הבוט ולדרוש בדיקה ידנית. לעולם לא ממשיכים אוטומטית למצב לא עקבי.
איך מונעים מבאג יחיד לרוקן לי את החשבון?
מגבלות בשכבות: מגבלת פוזיציה ברמת הקוד, מגבלת גודל הזמנה ברמת הקוד, halt sentinel ברמת הקובץ, מגבלות מינימום/מקסימום מובלעות ברמת הבורסה (Polymarket), התראות ניטור שמקפיצות אתכם על קצב הזמנות חריג. אף שכבה אחת לא מספיקה - הן פועלות במכפלה.
האם הבוט צריך לסחור אם הלוגים שלי נכשלו?
לא. אם הבוט לא מסוגל לכתוב ליומן שלו, הוא לא יכול לבצע reconcile באתחול מחדש, כלומר קריסה תוביל למצב לא עקבי. יש לגרום לבוט להיכשל בצורה קשיחה אם ה-logging נכשל. בוטי Production בריאים הם פרנואידים לגבי ה-observability שלהם.