מדוע order book pipeline מאבד נתונים בשיאים
order book pipeline נשבר לא בשוק רגוע, אלא בשניות הראשונות של זינוק: זרם הציטוטים גדל בסדר גודל, וצוואר הבקבוק מתגלה דווקא במקום שאינו נראה בעומס יציב. אובדן עדכונים ברגע כזה אינו נראה כשגיאה — התהליך חי, המדדים ירוקים, רק ספר ההזמנות מפסיק להתאים לבורסה. ניתוק הסשן בשיא הוא היקר מכולם: בזמן ההתחברות מחדש הדלתאות מצטברות בבאפר או אובדות כליל.
הסוג השני של תקלות — snapshots שהוחמצו וחוסר סנכרון בשחזור. אם ה-snapshot לא התיישר לפי מספר הרצף עם זרם הדלתאות, ספר ההזמנות נבנה משכבות שאינן תואמות, ומכאן והלאה שום ולידציה לא תבחין בין הרכבה כזו להרכבה תקינה.
מבחינה הנדסית זה מטופל בהשוואת רצפים, בבקשה חוזרת של snapshot ובחזרה לאחור של חלון, אבל רק אם ה-pipeline תוכנן מתוך הנחה שהעדכונים מגיעים שלא לפי הסדר ועם השהיה שונה ממקורות שונים.
הסוג השלישי, הערמומי מכולם — drift של מאפיינים בין האימון ל-inference. על נתונים היסטוריים ספר ההזמנות נבנה בשיטת נרמול אחת, ובזמן אמת באחרת, והמודל רואה התפלגות שלא פגש מעולם.
השהיית הנתונים מוסיפה לכך היסט: מאפיין שחושב מתמונה מיושנת הוא פורמלית תקין, אבל מתאר שוק שכבר אינו קיים. מבחוץ זה נראה כירידה באיכות החיזויים בלי אף שגיאה ביומנים.
אנחנו מפרקים איך זה נסגר: בקרת שלמות בכל מעבר, שכבה אחידה לחישוב מאפיינים עבור אימון ו-inference, ובקרת השהיית נתונים לאורך כל הנתיב מהמקור ועד המודל.
מה נותן pipeline בנוי היטב של ספר ההזמנות
Pipeline של ספר ההזמנות הוא לא העברת קבצים, אלא חוזה על הנתונים: לכל מערך יש גרסה, סכימה ומערכת בדיקות שבהן הוא נחשב כשיר. להלן מה בדיוק משתנה כשחוזה כזה קבוע.
- יכולת שחזור. כל מערך נבנה לפי גרסה של הרשומות המקוריות וגרסה של כללי הכנת המאפיינים. הרצה חוזרת מניבה את אותם ערכי מדדים, והפער בין אימון לבדיקה מפסיק להיות תעלומה.
- איכות הנתונים בקלט. הבדיקות תופסות snapshots שהוחמצו, כפילויות, קטיעות בטור הזמנים וסידור שכבות פגום. שיעור הסשנים שנפסלו נראה בדוח, ולא מתגלה דרך מדדים חריגים של המודל.
- נתונים היסטוריים. snapshot-ים של הספר נשמרים בפורמט עמודתי Parquet עם חלוקה לפי תאריכים ומכשירים: שליפה לתקופה מבוקשת נקראת בדקות, ולא בשעות של מעבר מלא.
- הכנת המאפיינים. חוסר איזון בין הצדדים, ספרד, עוצמת הביטולים ומהירות ההתאוששות אחרי אימפולס מחושבים במעבר אחד. הכנה ידנית מתקצרת מימים לדקות ומפסיקה להיות תלויה באנליסט מסוים.
- פורמט אחיד. פערים ביחידות, בתוויות זמן ובדיוק בין מקורות מנורמלים בקלט — סוג הכשל "הנתונים הגיעו, אבל לא בצורה הנכונה" נעלם.
- עמידות בזינוקות. באפרינג ולחץ אחורי מחזיקים את הזרם בשיאי פעילות: הודעות לא אובדות, והתור מתרוקן אחרי העומס.
דרכי איסוף ואחסון ציטוטים: השוואה
מצב איסוף הציטוטים קובע מה יקבל המודל: עומק הספר ברגע האירוע, אחידות תוויות הזמן ויכולת שחזור של האימון. האפשרויות שלהלן אינן מתחרות זו בזו — משלבים אותן לפי האופק: היסטוריה נסגרת באצווה, והזרם החי רץ ברציפות.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| טעינת היסטוריה באצווה | קורפוס רטרוספקטיבי גדול לאימון ולבקטסטים | אין נתוני live, קטיעות בין קבצים נתפרות ידנית |
| עיבוד רציף של הזרם | המודל עובד אונליין, השהיית התגובה קריטית | ניתוק החיבור מאבד חלק מהדלתאות ללא חזרה |
| היברידי: snapshots + זרם דלתאות | נדרשים היסטוריה, live וריסטארט תקין | תמיכה מסובכת יותר: סדר האירועים ודה-דופליקציה |
| באפרינג באחסון זמני | שיאי עומס וערוץ לא יציב לאחסון קר | השהיה עד הכתיבה, נדרשת בקרת פינוי באפר |
עבור order book pipeline הקריטריון המרכזי הוא עקביות הזמן. טעינה באצווה נותנת נפח, אבל מאבדת מיקרו-מבנה; הזרם שומר עליו, אבל דורש מנגנון התאוששות אחרי תקלה. סכימה היברידית עם באפר מיישרת את הסתירה: הדלתאות מצטברות באחסון מהיר, snapshots נרשמים לפי טיימר, וריסטארט לא מותיר קטיעות.
בצד האחסון מדובר בקבצים עמודתיים, מחולקים לפי מכשיר ותאריך, ובנוסף יומן דלתאות — ואז שליפה לאימון נבנית במעבר אחד.
איך אנחנו בונים pipeline לעיבוד ציטוטים
סדר השלבים של ההטמעה זהה לכל מקור — API של בורסה, אגרגטור או שער של ברוקר. מתחילים במיפוי מקורות: תדירות העדכונים, פורמט ה-snapshots, ההתנהגות בעת ניתוק חיבור ומספור האירועים. מהפרטים האלה נגזרת סכימת ה-pipeline — האם נדרש יומן ביניים או שמספיק עיבוד זורם.
- מיפוי מקורות. עורכים אינבנטריזציה של הזרמים: ערוצי זמן אמת, snapshots של הספר, עומק, מגבלות חיבורים. בנפרד בודקים שדות שמגיעים לא תמיד, ואיך המקור מסמן החמצה.
- סכימת ה-pipeline. שכבות קליטה, נרמול, דה-דופליקציה, הרכבת הספר מ-snapshot ודלתאות, וכתיבה לאחסון עמודתי. מגדירים נקודות באפרינג כדי לא לאבד אירועים בשיאי עומס.
- איסוף ונרמול. רזולוציית זמן אחידה, ספר מכשירים משותף, יחידות נפח וצד עסקה מתואמים; מזהי הבורסה מרוכזים לטבלת התאמה אחת.
- בדיקת נתונים. הרצה על קטעים היסטוריים עם אנומליות ידועות: רציפות הרצפים, היעדר ספר הפוך, שיעור ההחמצות ששוחזרו. פערים מול תקן מפורקים עד השורש.
- נראות בתוך המערכת. מוני חורים, השהיית מסירה, שיעור אירועים מחוץ לסדר — עם התראות. ה-pipeline מדווח על דעיכה בעצמו, ולא מוסר נתונים פגומים למודל.
- מסירת הפתרון. סכימות זרימה, קונפיגורציות, נוהל הפעלה מחדש והתאוששות אחרי תקלה, והדרכת הצוות — כדי שההפעלה והתיקונים יעברו בלעדינו.
בפלט — order book pipeline שאפשר לשחזר: מהודעות גולמיות ועד מאפיינים למודל. כל שלב מופעל מחדש ומושווה לתקן, ואיכות הנתונים נראית במדדים, ולא בתחושה.
ארטיפקטים: סכימות, נהלים וקונפיגורציות
חבילת המסירה היא לא תיקייה של קבצים "לזכרון", אלא תיעוד עבודה שלפיו צוות הלקוח מרים ומתחזק בעצמו את ה-pipeline לעיבוד ספר ההזמנות. להלן רשימת מה שנשאר אצלכם אחרי המסירה ומה שאתם משתמשים בו בלעדינו.
- סכימת נתונים: תיאור שדות האירועים של הספר — שכבות, צדדים, נפח, תוויות זמן, מזהי מכשיר, כללי נרמול וטיפול בהחמצות.
- קונפיגורציות איסוף: פרמטרי חיבור למקורות, תדירות snapshots, עומק הספר, כללי התחברות מחדש ובאפרינג בעת ניתוקי חיבור.
- סכימת זרימות נתונים: המסלול מקליטת הודעות גולמיות ועד ויטרינת המאפיינים, עם נקודות בקרת איכות ומקומות שאפשר להריץ בהם את הזרם מחדש.
- מדיניות גישה: תפקידי קריאה וכתיבה, הפרדה לפי מכשירים וסביבות, נוהל הנפקה ושלילה של מפתחות.
- נהלי תחזוקה: מה בודקים מדי יום, אילו ספי השהיה ואובדן נחשבים לחריגה, למי ואיך מסלימים.
- ניטור: מערכת מדדים — לאג עיבוד, שיעור קטעים שהוחמצו, חוסר סנכרון בשעונים, גידול בתור — עם הצמדה לכללי התראה.
- תוכנית התאוששות: נקודות שמירה, סדר הפעלה מחדש מהחתך השלם האחרון, בדיקת שלמות הנתונים המשוחזרים.
התיעוד חי באותו אחסון שבו חי הקוד, ולכן הנהלים לא מנותקים מהקונפיגורציה בפועל. כשמתחלף מקור או פורמט הודעה, עדכון תיאור השדות נכנס לאותו מחזור עבודה — אחרת סכימת הנתונים מתיישנת בתוך שבועותיים.
מקרה בוחן: שחזור זרם ציטוטים אחרי תקלה
תקלות בצד מקור הנתונים וניתוקי מנוי שברו את זרם הציטוטים: אחרי התחברות מחדש חלק מהעדכונים הגיעו שוב, וחלק לא הגיעו כלל. שיעור העדכונים שאבדו הגיע ל-5–7% ביום, בספר הופיעו חורים במספרי הרצף, והמנוי החוזר הוסיף כפילויות — לאימון נכנסה היסטוריה שאי אפשר לסמוך עליה.
מה היה לפני
את ההתאוששות אחרי ניתוק עשו ביד: מהנדס הרים את הסשן מחדש, ביקש snapshot מלא של ספר ההזמנות מ-Databento, השווה אותו לזרם שנצבר וניקה את החפיפות. פעולה אחת כזו ארכה 30–40 דקות, ביום הצטברו עד עשר כאלה, והשוואת מערכי הנתונים יצאה לא עקבית בשלוש הרצות מתוך עשר. המודל למד על מדגם מוטה, והדעיכה הייתה בלתי מורגשת: המדדים בוולידציה התנדנדו מהרצה להרצה.
מה עשינו
כל עדכון קיבל מספר סידורי וסכום ביקורת של המצב הקודם, ולכן הקטיעה נראית מיד — לפי אי-רציפות המספרים, ולא לפי סימנים עקיפים.
הבאפר מחזיק חלון של השניות האחרונות, ה-snapshot נטען אוטומטית ומונח על הדלתאות, ורשומות חופפות נזרקות לפי מפתח "מספר + תווית זמן" לפני הכתיבה לאחסון.
מה נהיה
שיעור העדכונים שאבדו — 0.02%, החמצות במספרים הסידוריים נסגרות באותו חלון שבו הן מתגלות. ההתאוששות אחרי ניתוק חיבור אורכת 1.5 דקות לעומת 30–40 דקות של עבודה ידנית, ומספר הפעולות הידניות ביום — אפס.
השוואת מערכי הנתונים הפסיקה לצאת לא עקבית: פערים נתפסים בקלט ולא מגיעים למדגם האימון, ולכן המדדים בוולידציה הפכו לשחזוריים.
סיבת התקלה נראית עכשיו ביומן יחד עם רגע הקטיעה והקטע בזרם — והפירוק אורך דקות, ולא חצי יום. מעגל עמידות כזה אנחנו מניחים בשלב תכנון הזרם, ולא אחרי האירוע הראשון.
במה שונה order book מזרם העסקאות?
Order book הוא מצב של הזמנות לימיט: מחיר, נפח, צד, רגע השינוי. הצבה, ביטול, ביצוע חלקי ומלא יוצרים הודעות נפרדות, ולכן סרט הספר גדול בסדר גודל ומתעדכן בתדירות גבוהה בהרבה מזרם העסקאות.
זרם העסקאות מתעד רק את מה שכבר בוצע, בעוד הספר מציג את עומק השוק: נזילות בשכבות רחוקות, ספרד, חוסר איזון בין ביקוש להיצע. מכאן נובעים סוגי מאפיינים שונים — מהעסקאות רואים יוזמה ואגרסיביות של ביצוע, ומהספר — התנגדות מחיר ומרווח עד להחלקה בכניסה בנפח גדול.
למודלים של מיקרו-מבנה ההבדל הזה הוא העיקר. הספר נותן מאפייני נזילות ולחץ בגבול, וזרם העסקאות — מאפייני ביצוע ואימפולס קצר-טווח. ציטוטים מצטברים, מכווצים לפי שכבות מחיר ומרווחי זמן, מפחיתים את נפח האחסון אבל מוחקים חלק מהמיקרו-מבנה — הבחירה בדיוק היא תמיד פשרה.
בחירת המקור היא שאלה של אופק החיזוי וסוג המאפיינים, ולא של טעם. לחלק מהמשימות נדרשים שני המקורות יחד: עסקה בודדת בלי מצב הספר אינה מוסברת, וספר בלי עסקאות לא מראה מי בדיוק הזיז את המחיר.
לכן את שני הזרמים מסנכרנים לפי זמן, ואת חוסר הסנכרון וההחמצות מטפלים בנפרד — אחרת המאפיינים בפלט מתפצלים.
בקלט שני המקורות נכתבים בנפרד, עם תוויות זמן ומזהי מכשיר, כדי שאפשר יהיה לחשב את המאפיינים מחדש בדיעבד על חלון היסטורי.
ספקות טכניים לפני תחילת העבודה
הספקות לפני ההתחלה הם בדרך כלל אותם ספקות: איך לשלב את המקורות שלנו, מה לעשות עם קטיעות היסטוריות והאם נצטרך לשבור אחסון שעובד. להלן תשובות קצרות לכל נקודה.
ה-pipeline נבנה סביב סכימת אירוע מנורמלת: מכשיר, תווית זמן, צד, שכבות מחיר, נפח. כל מקור מובא אליה באמצעות אדפטר, ולכן בקרת האיכות, שחזור הספר והוויטרינות למודלים עובדים אותו דבר — בלי תלות בכך של מי הנתונים שנכנסים.
אפשר לחבר את המקורות שלנו, ולא רק את שלכם?
כן. נכתוב אדפטר לערוץ או לתצואה שלכם ונקבע את החוזה של הסכימה המנורמלת. מכאן המקור חי בשוויון זכויות עם האחרים: אותן בדיקות שלמות, אותו ניטור טריות, אותן ויטרינות. אם יש לכם ארכיון היסטורי בפורמט משלכם — נפרק אותו במעבר נפרד.
מה עושים עם החמצות בנתונים ישנים?
משחזרים את הספר במעבר אחורה: לוקחים את ה-snapshot השלם הקרוב ומגלגלים עליו דלתאות עד הבא. במקום שבו אי אפשר לשחזר, החלונות מסומנים כלא שלמים ולא נכנסים לאימון — המודל לא לומד על חורים. כל התיקונים נרשמים ביומן, כדי שיהיה ברור איזה קטע היסטוריה הורכב מחדש.
הנתונים לא יוכפלו בעיבוד חוזר?
לא. הכתיבה אידמפוטנטית: המפתח — מקור, מכשיר ותווית זמן של האירוע. מעבר חוזר מעדכן את אותן שורות, ולא מוסיף חדשות, ולכן הוויטרינות לא מתנפחות והמדדים לא "מתנדנדים". זה גם מאפשר להריץ בבטחה קטע מחדש אחרי תקלה.
נצטרך לבנות מחדש את האחסון הקיים?
בדרך כלל לא. ה-pipeline מתחבר לאחסון הקיים וכותב לפרטיציות נפרדות, בלי לגעת בטבלאות העבודה. אם צריך — מרימים ויטרינה מקבילה, משווים תוצאות, ורק אחר כך מחליפים את הצרכנים.
מה עם תמיכה אחרי המסירה?
משאירים ניטור של קטיעות והשהיות, התראות על אנומליות ונוהל להשלמת חלונות שהוחמצו. מוסרים תיעוד וניתוח אירועים, כדי שהצוות יוכל לתחזק את ה-pipeline בעצמו.
נדבר על המשימה שלכם בעיבוד ציטוטים
הערכת היקף העבודה ל-pipeline לעיבוד order book תלויה לא במספר הבורסות, אלא באופן שבו בנויים הנתונים הראשוניים ומה צריך לקבל בפלט. אם נראה מיד דוגמת תצואה ותיאור של מאפיין היעד, נחזור עם פירוט לפי שלבים ודרישות לנתונים, ולא עם טווח "מכאן ועד כאן".
מה כדאי לשלוח מראש:
- מקורות: בורסות, מכשירים, עומק ההיסטוריה והתדירות הנדרשת של snapshots של ספר ההזמנות.
- פורמט הזרם: רק snapshots או snapshots ועדכוני דלתא, איך מסומנות קטיעות וחזרות של רצפים.
- דרישות לנתונים: סכימת אירועים, עבודה עם תוויות זמן, סנכרון, כללי שחזור של קטעים שהוחמצו.
- מאפייני יעד: חוסר איזון בין הצדדים, ספרד, עוצמת הביטולים, פרופיל נזילות — והאופק שבו המודל צריך לעבוד.
- מצב עבודה: שחזור היסטורי, זרם בזמן אמת או שניהם, ואיזו השהיה מותרת.
- תשתית: איפה מארחים את העיבוד, אילו הרשאות ונפחי אחסון יש, והאם נדרשת יכולת שחזור של בניית מערך הנתונים.
את הרכב הצוות מרכיבים לפי פרופיל המשימה: מהנדס עיבוד זורם, מומחה לאחסון ואנליסט שאחראי על תיאום המאפיינים. תארו את המשימה בצורה חופשית — נחזור עם הערכת עבודה, תוכנית הטמעה ושאלות הבהרה.







