פיתוח מנוע מסחר (מנוע התאמות)

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

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1375
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1349
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    794
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1087
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1032
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1129

פיתוח matching engine: היכן זה נשבר תחת עומס

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

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

הכשל האופייני הראשון — דִּיסִינְכְּרוֹן של ספר ההזמנות. הליבה מעדכנת את הספר ומפיצה אותו ללקוחות בשני מסלולים שונים, ואם התקלה מתרחשת באמצע החבילה, תמונת המצב מתרחקת מיומן האירועים.

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

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

ברגע שהעיבוד מתפצל "לפי העין", והנעילות נלקחות נקודתית, ההתנהגות במסחר בשיא הופכת לבלתי צפויה — זו שאלה של סכימה, לא של מרווח כוח. נבחן כיצד בנויה פיתוח matching engine שמחזיקה שיא לפי חישוב.

מה נותנת ליבה מכוילת: תפוקה והשהיות

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

  • תפוקה של ליבת מסחר (matching engine) — עשרות אלפי הזמנות בשנייה לכל מכשיר; הוספת צומת נותנת גידול, ולא חלוקה מחדש של אותו תור.
  • זמן תגובה להזמנה — p50 ו-p99 נשמרים בטווח המוסכם כאשר הזרם הממוצע עולה פי עשרה: התור גדל, לא הזנב של ההתפלגות.
  • מחלקות כשל שהוסרו — מרוצים בעת התאמת הזמנות מנוגדות, אובדן פקודה בעת התחברות מחדש של לקוח, כפילויות לאחר שליחה חוזרת, תקיעת ספר ההזמנות בביצוע חלקי. כל מחלקה סגורה בבדיקה נפרדת, ולא בהבטחה "אנחנו כותבים בקפידה".
  • עמידות במסחר בשיא — בפתיחה ובתנועות חדות המערכת נכנסת לדעיכה צפויה: מגבלות תורים, עדיפויות לפי סוגי הוראות, שגיאה מפורשת במקום אובדן שקט של הזמנה.
  • שחזור ונראות — מצב ספר ההזמנות והפוזיציות מתכנס מיומן הפעולות תוך דקות, וההשהיה לפי שלבים (קליטה, ולידציה, התאמה, פרסום) נראית בלוח הניטור.

בדיקת קבלה — תרחיש אחד על הליבה הישנה והחדשה עם השוואת התפלגויות, לא ממוצעים: ממוצעים מסתירים זנבות שבגללם סוחרים עוברים למתחרה. הרצות עומס ב-k6 מתבצעות לפני שחרור, לא אחרי התקרית הראשונה.

Matching engine: אפשרויות בניית הליבה

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

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

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

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

שלבי הטמעה: מביקורת ועד מסירה

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

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

  1. ביקורת מערכת המסחר: אוספים מפת זרימות הזמנות וחישובים, מודדים השהיות נוכחיות ונקודות כשל, מתעדים אי-התאמות בין הליבה למערך החשבונאי.
  2. תכנון הליבה: מגדירים את מודל ספר ההזמנות, כללי ההתאמה, העדיפויות וההתנהגות בביצוע חלקי — במפרט, ולא בהסכמות בעל פה.
  3. תיאום החלפה: מתארים פורמטים של הודעות, קודי שגיאה ותרחיש שחזור לאחר ניתוק הקשר עם המערך החיצוני.
  4. מימוש והגדרה: בונים את הליבה בתצורה היעד, מגדירים תורים, תיעוד יומן ומגבלות, ומקימים סטנד בדיקה לצד הסביבה הפרודוקטיבית.
  5. בדיקת עומס לליבה: מריצים פרופילי שיא — פרץ הזמנות, ביטולים המוניים, נטילת נזילות — ומסתכלים לא על הממוצע, אלא על המקרה הגרוע והזנב של ההשהיות.
  6. מסירת הפרויקט ללקוח: מוסרים תיעוד, סכימות, נהל פריסה וחזרה לאחור, מעבירים הדרכה לצוות ונשארים בקשר בתקופת השחרורים הראשונים.

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

הרכב האספקה: תצורות, סכימות, נהלים

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

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

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

מקרה בוחן: ליבת מסחר תחת עומס שיא בימי חישובים

מה היה

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

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

מה שינו

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

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

מדדים לפני ואחרי

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

במה שונה מנוע בורסאי מתור הזמנות במסד נתונים?

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

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

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

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

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

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

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

ספקות טכניים: עמידות בכשלים וחישובים

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

מה יקרה אם צומת המנוע ייפול באמצע סשן?

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

האם המנוע ישתלב בפלטפורמה שכבר עובדת?

המנוע מותקן מאחורי מתאם לשער ההזמנות שלכם ולמערכת החשבונאות, ומסנכרן יתרות עם שלכם. אנחנו מחליפים בשלבים — תחילה מכשיר אחד תחת עומס אמיתי.

כיצד מאושרת תקינות החישובים בין המשתתפים?

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

כיצד נמנעת כפילות הזמנות בעת ניתוק קשר?

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

נדון במשימה: ממה מתחיל הפרויקט

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

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

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

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

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