27 באוגוסט 2026 · הנדסת נתונים

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

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

שלחת לי את המחברת ביום ראשון בלילה, והיא פתוחה אצלי מאז במסך השני. מומנטום רוחבי, 150 חוזי Binance USDⓈ-M התמידיים המובילים לפי נפח דולרי ל-30 יום, איזון שבועי מחדש, לונג בעשירון העליון ושורט בעשירון התחתון, מ-2021-01 עד 2026-06. Sharpe של 2.31, ירידה מרבית של 14.2%, ומודל עלויות שנראה לי הגון: taker בכניסה וביציאה, מימון נצבר בכל מרווח, ורכיב החלקה שגדל בהתאם לגודל הפקודה שלך מול ספר הפקודות. עשית נכון את הדברים הקשים. ואז שאלת למה שישה שבועות של מסחר מדומה הסתיימו ללא שינוי, והאם היתרון נשחק.

הוא לא נשחק. הוא מעולם לא היה בבדיקת העבר. תסתכל בתא 4:

info = requests.get(BASE + "/fapi/v1/exchangeInfo").json()
symbols = [s["symbol"] for s in info["symbols"]
           if s["status"] == "TRADING" and s["quoteAsset"] == "USDT"]

קראת לנקודת הקצה הזאת ביוני 2026 והשתמשת בתשובה כדי להגדיר מה היה סחיר במרץ 2021. כל סמל ברשימה הזאת שרד עד יוני 2026, מעצם הגדרתה. זה כל הבאג, וההשפעה שלו גדולה מההשפעה של יתר מודל העלויות שלך גם יחד.

2.31 → 0.74Sharpe, רשימת שורדים לעומת נתונים לנקודת זמן
~1 מכל 5מהנכסים ביקום שלך ב-2021 כבר לא קיימים
380 KBתמונת מצב יומית של exchangeInfo, דחוסה ב-gzip

מה נקודת הקצה לא מספרת לך

אין היסטוריה ב-exchangeInfo. אין פרמטר asOf, אין ארכיון, אין יומן שינויים. זו תמונת מצב של עכשיו, ו-Binance מעולם לא הבטיחה לך דבר אחר. כשחוזה מוסר מהמסחר, הרשומה שלו נמחקת מהתשובה והטיקר מפסיק להתקיים מבחינת ה-API. Binance רשמה למסחר יותר מ-600 חוזים תמידיים של USDⓈ-M מאז 2019, והוציאה מהמסחר הרבה יותר ממאה מהם. BTS, COCOS, TOMO, RAY, FTT, SC, ועוד שובל ארוך של חוזים מעונת האלטים של 2021 שהיו להם רבעון זוהר אחד ואז דעכו עד שהזירה הסירה אותם.

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

בניתי מחדש את ההרצה שלך מול ארכיון התמונות שלנו, עם יקום לנקודת זמן, אותו איתות ואותן עלויות, והתקבל Sharpe של 0.74 עם ירידה של 31%. בערך שתי חמישיות מהפער נובעות מנכסים שהוסרו מהמסחר ושמעולם לא הורשית להחזיק. עוד רבע נובע מהבעיה ההפוכה, שהיא עדינה יותר, ואני חושד שתמצא חן בעיניך פחות.

הקצה השני של מכונת הזמן: סמלים שעדיין לא היו קיימים

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

אפשר לטעון שהחלק הזה לגיטימי. הנה מה שלא לגיטימי: ספק הנתונים שלך השלים לאחור חלק מהסמלים האלה עם נתוני ספוט או מדד מתקופה שלפני שהחוזה התמידי שלהם היה קיים, ולכן לכמה חוזים יש היסטוריית kline שמקדימה את onboardDate שלהם. אפשר לבדוק את זה בתוך דקה בערך. חבר את טבלת המחירים שלך לתאריכי הרישום וספור שורות שמקדימות את הרישום. בנתונים שלך יש 41 סמלים עם נרות מלפני הרישום, ואחד מהם, בקיץ 2023, מוסיף 6% בשבוע אחד לעקומת ההון מפוזיציה בחוזה שלא יהיה קיים במשך תשעה ימים נוספים.

מחרוזת טיקר היא לא מזהה. היא תווית שהזירה משאילה, לפעמים פעמיים.

וכאן מגיעים שינויי השמות. MATICUSDT הפך ל-POLUSDT. FTMUSDT הפך ל-SUSDT בהמרה של 1:1. המצב של LUNA במאי 2022 הותיר את LUNCUSDT, ובהמשך גם LUNAUSDT חדש לגמרי, שחולק שורש טיקר עם משהו שאיבד כמעט את כל ערכו. אם הטוען שלך משתמש במחרוזת הסמל כמפתח ומשרשר כל קובץ שהוא מוצא, יש לך לפחות סדרה אחת עם קפיצה שאינה תנועת מחיר, ומאפיין המומנטום שלך יקרא את הקפיצה הזאת כאיתות החזק ביותר בחתך הרוחבי.

כל שאר הדברים שמשתנים לך מתחת לאף

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

שדהאיך הוא משתנהמה נפגע
statusTRADING → SETTLING → הוסרהטיית הישרדות; יציאות מדומות במחיר סגירה שמעולם לא נסחר
onboardDateרישומים חדשים מדי שבוע; לא קיים בסמלים שנמחקומסחר בחוזים לפני שהיו קיימים
tickSize / stepSizeמותאמים מחדש עם שינוי רמות המחירעיגול פקודות, ומחירי לימיט שהיו נדחים
minNotionalמועלה עם הזמן בספרי פקודות דליםרגליים קטנות שהנתב שלך במסחר חי היה מסרב לבצע
fundingIntervalHours8h במשך שנים, ואז 4h או 1h בסמלים רביםחישוב מימון שגוי פי 2–3 דווקא באלטים שהמסנן שלך מחזיק
מדרגות מינוףהמדרגות ודרישת הביטחונות לתחזוקה עודכנומודל חיסול ויכולת העמדת בטחונות

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

הסרה מהמסחר היא אירוע, ואתה לא מדמה אותו

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

אם מעולם לא שמרת בארכיון את exchangeInfo, עוד לא אבוד לך. המזבלה הציבורית ב-data.binance.vision/data/futures/um/monthly/klines/ עדיין שומרת תיקיות של סמלים שהוסרו מהמסחר זמן רב אחרי שה-API שכח אותם. סרוק את רשימת התיקיות, והקובץ החודשי הראשון והאחרון לכל סמל יתנו לך חלון רישום והסרה סביר, בלי ספק נתונים. זו שחזור, לא תיעוד, והיא לא תוכל לשחזר גדלי תקתוק או מרווחי מימון. אבל היא תגיד לך מי היה קיים ומתי, וזה 80% ממה שאתה צריך עד יום שני.

מה הייתי בונה לפני שנוגעים שוב באיתות

  1. משימת cron ששואבת exchangeInfo מכל זירה שאתה חוקר, מדי יום, ושומרת אותו באחסון אובייקטים כשהמפתח הוא התאריך. דחוס ב-gzip, הקובץ קטן מחצי מגה־בייט. עשר שנים יעלו לך סכום זניח ב-S3 ויקנו לך יכולת מחקר שלא תוכל לרכוש מאוחר יותר.
  2. מאסטר נכסים שנגזר מהתמונות האלה: שורה אחת לכל (venue, symbol, valid_from, valid_to), עם כל השדות. השווה תמונות עוקבות כדי ליצור אותו, והתייחס לכל שינוי בשדה כאל שורה חדשה.
  3. פונקציית יקום עם ארגומנט חותמת זמן חובה. universe(ts), לעולם לא universe(). קבע ברירת מחדל שאי אפשר לעקוף, כדי שאף אחד, כולל אתה בעתיד ב-1am, לא יוכל לבחור בטעות ברשימת השורדים.
  4. בדיקת תקינות לפני הרישום בטוען הנתונים: אסור שיופיע נר לפני onboard_ts פחות יום אחד. עצור את ההרצה, אל תסתפק באזהרה.
  5. מזהה מכשיר פנימי יציב ששורד שינויי שם, כשהטיקר יורד למעמד של מאפיין. מַפֶּה את POL ואת MATIC למזהה אחד, וסמן שינויי ערך נקוב מחדש כדי שלוגיקת הרציפות תוכל לסרב לחבר ביניהם.

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

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

הטיית הישרדותנתונים לנקודת זמןחוזים עתידיים בקריפטובדיקות עברהנדסת נתונים
← כל הפוסטים