מדוע עושי שוק מפסידים כסף: ברירה שלילית והסבר על markout
מהי ברירה שלילית במסחר וכיצד היא משפיעה על רווחי עושי שוק. המדריך מסביר את השימוש בעקומות markout למדידת הפסדים, לצד השפעות של סיכון מלאי ועלויות מיקום בתור.
עושי שוק מפסידים כסף כתוצאה מברירה שלילית (adverse selection): הסוחר ש"מרים" הצעה הוא לעיתים קרובות זה שכבר יודע שההצעה אינה מעודכנת. כל ביצוע (fill) נפתח עם קרדיט קטן, בערך מחצית מה-spread, והשניות שלאחר מכן קובעות כמה מאותו קרדיט יישאר. כלי המדידה הוא ה-markout, שינוי מחיר חתום בטווח זמן קבוע לאחר הביצוע, והפאנלים להלן בונים עקומות markout אמיתיות מתוך נתוני מסחר וציטוטים. המאמר המשלים שלנו בנושא כיצד עושי שוק מרוויחים כסף מכסה את צד ההכנסות של אותו דף חשבון.
מהי ברירה שלילית במסחר?
עושה שוק מפרסם שני מחירים בו-זמנית: מחיר קנייה (bid) ומחיר מכירה (offer), כל אחד עבור כמות מוצהרת. הפער ביניהם הוא ה-bid ask spread, והעסק הוא אריתמטי. קנה ב-bid, מכור ב-offer, חזור על כך עשרות אלפי פעמים ביום, והסיבוב הממוצע יניב משהו שקרוב ל-spread.
האריתמטיקה הזו מניחה ששני הצדדים מגיעים באיזון. הם לא. ציטוט פעיל הוא אופציה עומדת שכל אחד יכול לממש ברגע שיבחר, והסוחרים שנותנים את מירב תשומת הלב בוחרים את הרגעים הטובים ביותר. קרן שמבצעת הוראת הורה (parent order) גדולה ממשיכה לקנות כל עוד ה-offer נותר זול. מערכת שכבר ראתה נכס מתואם זז, לוקחת את הצד שטרם תמחר את עצמו מחדש.
ברירה שלילית היא השם לנטייה בתמהיל הזה: הביצועים שעושה שוק מקבל מוטים לטובת הסוחרים שרצו אותם ביותר. הסימפטום הוא פער בין ה-spread שעושה השוק מצטט לבין ה-spread שהוא שומר לעצמו.
מהו markout בעשיית שוק?
ה-markout עונה על שאלה אחת, שנשאלת לאחר כל ביצוע: היכן היה המחיר מספר שניות קבוע לאחר מכן, במדידה מהצד שבו הייתי? נניח שעושה שוק מוכר 100 מניות ב-50.02 דולר בזמן שה-midpoint עומד על 50.00 דולר. הביצוע הזה נפתח עם קרדיט של שני סנט למניה, 20 mils ביחידות של דסק מסחר (כאשר mil הוא עשירית הסנט). אם ה-midpoint זז ל-50.04 דולר שישים שניות לאחר מכן, ה-markout של 60 שניות הוא מינוס 20 mils. הקרדיט ההתחלתי נעלם, ואיתו סכום זהה נוסף.
בצע ממוצע על פני כל ביצוע בחלון זמן ושרטט אותו מול טווח הזמן, והתוצאה היא עקומת markout. הפאנל להלן בונה עקומה כזו עבור AAPL במהלך חלון זמן של שלוש שעות בצהרי יום חמישי, ה-14 במאי 2026. כל ביצוע חתום מול ה-midpoint של השנייה שבה הוא בוצע: ביצוע מעל ה-midpoint נחשב לקונה (taker), מה שמציב את עושה השוק בצד המכירה.
ה-SQL המדויק מאחורי כל מספר
WITH
qs AS (
SELECT toUnixTimestamp(toDateTime(sip_timestamp)) AS ts,
avg((toFloat64(bid_price) + toFloat64(ask_price)) / 2) AS mid
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-05-14 14:00:00'
AND sip_timestamp < '2026-05-14 17:06:00'
AND bid_price > 0 AND ask_price > bid_price
GROUP BY ts
),
fills AS (
SELECT t.ts AS ts, t.px AS px, t.shares AS shares, q.mid AS mid_at_fill,
if(t.px > q.mid, 1, -1) AS taker_side
FROM (
SELECT toUnixTimestamp(toDateTime(sip_timestamp)) AS ts,
toFloat64(price) AS px, toUInt64(size) AS shares
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-05-14 14:00:00'
AND sip_timestamp < '2026-05-14 17:00:00'
AND size > 0
) AS t
INNER JOIN qs AS q ON q.ts = t.ts
WHERE t.px != q.mid AND abs(t.px / q.mid - 1) < 0.02
)
SELECT
concat('+', toString(e.secs), 's') AS horizon,
round(1000 * avg(e.taker_side * (e.px - e.mid_at_fill)), 2) AS edge_at_fill_mils,
round(1000 * avg(e.taker_side * (e.px - f.mid)), 2) AS edge_after_mils
FROM (
SELECT toUInt32(ts + secs) AS future_ts, secs, px, mid_at_fill, taker_side
FROM (SELECT *, arrayJoin([1, 5, 15, 30, 60, 300]) AS secs FROM fills)
) AS e
INNER JOIN qs AS f ON f.ts = e.future_ts
GROUP BY e.secs
ORDER BY e.secsהסדרה הראשונה היא הקרדיט ברגע הביצוע, המרחק בין הביצוע ל-midpoint, בממוצע של 19.66 mils למניה. הסדרה השנייה היא השווי של אותם ביצועים לאחר של-midpoint היה זמן לזוז: 20.5 mils לאחר שנייה אחת, ו-9.81 mils לאחר חמש דקות. המרחק בין שתי הסדרות בכל טווח זמן הוא ה-markout, והוא נגרע מה-spread שעושה השוק ציטט.
עקומה שיורדת במהירות ואז מתייצבת מתארת עושה שוק שמשלם על התמחור מחדש המיידי ושומר את היתרה. עקומה שממשיכה בשיפוע באותו כיוון בכל טווח זמן מתארת ביצועים שנוחתים בצד הלא נכון של מחיר שממשיך לנוע. הצורה הראשונה היא עלות עשיית עסקים. השנייה היא ציטוט שצריך להשתנות.
אילו ביצועים הם זרם רעיל (toxic flow)?
המילה "רעיל" מבצעת כאן תפקיד טכני. זרם הוא רעיל כאשר עקומת ה-markout שלו משופעת נגד עושה השוק שביצע אותו, בכל טווח זמן, על פני מדגם גדול. דסקים ממיינים ביצועים לפי כל תווית שהם יכולים לראות: גודל ביצוע, זירה, סוג הוראה, מזהה צד נגדי. גודל הוא התווית הנישאת בסרט המסחר הציבורי.
ה-SQL המדויק מאחורי כל מספר
WITH
qs AS (
SELECT toUnixTimestamp(toDateTime(sip_timestamp)) AS ts,
avg((toFloat64(bid_price) + toFloat64(ask_price)) / 2) AS mid
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-05-14 14:00:00'
AND sip_timestamp < '2026-05-14 17:06:00'
AND bid_price > 0 AND ask_price > bid_price
GROUP BY ts
),
fills AS (
SELECT t.ts AS ts, t.px AS px, t.shares AS shares, q.mid AS mid_at_fill,
if(t.px > q.mid, 1, -1) AS taker_side
FROM (
SELECT toUnixTimestamp(toDateTime(sip_timestamp)) AS ts,
toFloat64(price) AS px, toUInt64(size) AS shares
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-05-14 14:00:00'
AND sip_timestamp < '2026-05-14 17:00:00'
AND size > 0
) AS t
INNER JOIN qs AS q ON q.ts = t.ts
WHERE t.px != q.mid AND abs(t.px / q.mid - 1) < 0.02
)
SELECT
multiIf(s.shares < 100, 'under 100 shares',
s.shares < 500, '100 to 499',
s.shares < 1000, '500 to 999',
'1,000 or more') AS size_bucket,
count() AS fills_count,
round(1000 * avg(s.taker_side * (s.px - s.mid_at_fill)), 2) AS edge_at_fill_mils,
round(1000 * avg(s.taker_side * (s.px - f.mid)), 2) AS edge_after_60s_mils
FROM (SELECT *, toUInt32(ts + 60) AS future_ts FROM fills) AS s
INNER JOIN qs AS f ON f.ts = s.future_ts
GROUP BY size_bucket
ORDER BY min(s.shares)ביצועים של פחות מ-100 מניות נפתחים עם 19.47 mils למניה של קרדיט ושווים 15.22 mils דקה לאחר מכן. ביצועים של 1,000 מניות ומעלה נפתחים עם 36.26 mils ושווים 21.34 mils באותו טווח זמן. אותו נכס, אותן שלוש שעות, כלכלה שונה למניה. ההוראות הגדולות ביותר נמנעות לעיתים קרובות מהתור הציבורי לחלוטין, וזה מה ש-block trade נועד לעשות.
סיכון מלאי, הפוזיציה שלא ניתן לגדר בזמן
טווח זמן של markout הוא גם שעון. עושה שוק שקונה 5,000 מניות ב-bid מחזיק 5,000 מניות, ועד שהפוזיציה מגודרת או נמכרת היא חשופה לכל מה שהמחיר יעשה בהמשך. גידור הוא לעיתים רחוקות מיידי: פוזיציה במניה בודדת יכולה להיות מקוזזת עם ETF מתואם או פוזיציית אופציות, וכל אחד מאלה נושא spread משלו שצריך לחצות. סיכון מלאי הוא גודל התנועה שנכנסת בתוך אותו חלון זמן, והוא נמדד באותה דרך עבור כל נייר. כמה רחוק המחיר בדרך כלל נע במהלך הדקה הבאה, ובמהלך השעה הבאה?
ה-SQL המדויק מאחורי כל מספר
WITH
bars AS (
SELECT ticker, window_start,
toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
toFloat64(close) AS px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'NVDA')
AND window_start >= '2026-05-01 00:00:00'
AND window_start < '2026-06-01 00:00:00'
AND transactions >= 50
AND close > 0
),
starts AS (
SELECT ticker, et_date, px, mins,
window_start + toIntervalMinute(mins) AS future_start
FROM (SELECT *, arrayJoin([1, 2, 5, 15, 30, 60]) AS mins FROM bars)
)
SELECT
concat(toString(s.mins), ' min') AS hold_horizon,
round(avgIf(abs(f.px / s.px - 1) * 10000, s.ticker = 'SPY'), 1) AS spy_drift_bps,
round(avgIf(abs(f.px / s.px - 1) * 10000, s.ticker = 'NVDA'), 1) AS nvda_drift_bps
FROM starts AS s
INNER JOIN bars AS f
ON f.ticker = s.ticker AND f.et_date = s.et_date AND f.window_start = s.future_start
GROUP BY s.mins
HAVING countIf(s.ticker = 'SPY') > 0 AND countIf(s.ticker = 'NVDA') > 0
ORDER BY s.minsבמהלך מאי 2026, התנועה המוחלטת הממוצעת ב-SPY במהלך דקה אחת מדדה 1.9 נקודות בסיס (basis points), כאשר נקודת בסיס היא מאית האחוז. NVDA מדדה 5.5 במהלך אותה דקה. אם נמתח את השעון לשעה, שני הנתונים הופכים ל-14.1 ו-40.4. עושה שוק שיכול להתייצב בתוך דקה חי עם הזוג הראשון. עושה שוק שמחזיק שעה חי עם הזוג השני, והקרדיט שנאסף בביצוע זהה בשני המקרים.
מדוע עושי שוק מפסידים כסף בסוף התור
בורסות מתאימות הוראות עומדות במחיר אחד לפי סדר הגעתן: קודם מחיר, אחר כך זמן. הוראה בסוף תור של 40,000 מניות ב-bid מחכה ש-40,000 המניות שלפניה יתנקו, ו-הערכת מיקום בתור היא דיסציפלינה בפני עצמה.
החלק המביך הוא מה פירוש "להתנקות". תור מתרוקן בשתי דרכים. מוכרים ממשיכים להכות ב-bid עד שהרמה ממוצה, או שהמחיר יורד מתחת לרמה ומשאיר אותה מאחור. הוראה קרוב להתחלה משתתפת בשני התהליכים. הוראה בסוף התור מתבצעת בעיקר בדרך השנייה, ברגע שהרמה עומדת להפוך למחיר הישן. שני עושי שוק יכולים לסחור באותו נכס באותו מחיר ולשמור כמויות שונות ממנו. המיקום בתור לעולם לא מופיע ב-spread המצוטט, שכן שני עושי השוק ציטטו את אותו מחיר בדיוק. הוא מופיע בעקומת ה-markout.
מדוע הרחבת הציטוט אינה פתרון חינמי
התשובה הברורה לעקומת markout גרועה היא לצטט רחב יותר. ציטוט רחב יותר מרוויח יותר לכל ביצוע ומגיע לפחות ביצועים. שני חצאי העסקה הזו יושבים בביצועי אותו יום, ממוינים לפי המרחק של כל ביצוע מה-midpoint.
ה-SQL המדויק מאחורי כל מספר
WITH
qs AS (
SELECT toUnixTimestamp(toDateTime(sip_timestamp)) AS ts,
avg((toFloat64(bid_price) + toFloat64(ask_price)) / 2) AS mid
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-05-14 14:00:00'
AND sip_timestamp < '2026-05-14 17:06:00'
AND bid_price > 0 AND ask_price > bid_price
GROUP BY ts
),
fills AS (
SELECT t.ts AS ts, t.px AS px, t.shares AS shares, q.mid AS mid_at_fill,
if(t.px > q.mid, 1, -1) AS taker_side
FROM (
SELECT toUnixTimestamp(toDateTime(sip_timestamp)) AS ts,
toFloat64(price) AS px, toUInt64(size) AS shares
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-05-14 14:00:00'
AND sip_timestamp < '2026-05-14 17:00:00'
AND size > 0
) AS t
INNER JOIN qs AS q ON q.ts = t.ts
WHERE t.px != q.mid AND abs(t.px / q.mid - 1) < 0.02
)
SELECT
multiIf(s.cents <= 0.5, '0.5 cents or less',
s.cents <= 1.0, '0.5 to 1 cent',
s.cents <= 2.0, '1 to 2 cents',
'over 2 cents') AS distance_from_mid,
round(100 * sum(s.shares) / sum(sum(s.shares)) OVER (), 2) AS share_of_volume_pct,
round(1000 * avg(s.taker_side * (s.px - f.mid)), 2) AS edge_after_60s_mils
FROM (
SELECT *, toUInt32(ts + 60) AS future_ts, abs(px - mid_at_fill) * 100 AS cents
FROM fills
) AS s
INNER JOIN qs AS f ON f.ts = s.future_ts
GROUP BY distance_from_mid
ORDER BY min(s.cents)ביצועים בטווח של חצי סנט מה-midpoint היוו 27.58 אחוז מהמניות בחלון הזמן, והיו שווים 0.95 mils למניה דקה לאחר מכן. ביצועים שנחתו יותר משני סנט רחוק היוו 33.19 אחוז מהמניות, ב-46.86 mils. ציטוט שמפורסם רחוק יותר מה-midpoint מגיע לחלק קטן יותר מנפח המסחר היומי.
שיעור הביצוע (fill rate) הוא העלות הראשונה של נסיגה לאחור. החזרי בורסה (rebates) הם השנייה, שכן זירות רבות משלמות לעושה שוק עבור כל מניה שבוצעה, והכנסה זו גדלה עם כמות המניות ולא עם רוחב הציטוט. מדרגות הנפח שקובעות את שיעור ההחזר נספרות מדי חודש, כך שחודש שקט מתמחר מחדש כל ביצוע בחודש הבא. ויתור על המיקום בתור הוא העלות האחרונה, שמשולמת בדרך החוצה ומשולמת שוב בסוף התור בדרך פנימה. כל עושה שוק יושב איפשהו על העקומה הזו, ואלו שמודדים את ה-markouts שלהם בצורה המדויקת ביותר יכולים לשבת הכי קרוב ל-touch ועדיין לשמור על הקרדיט. המדידה הזו היא היתרון ש-עושי השוק הגדולים ביותר מגנים עליו.
שאלות נפוצות
האם עושי שוק מפסידים כסף בעסקאות בודדות?
באופן שגרתי. ספר מסחר של עושה שוק הוא התפלגות של רווחים קטנים והפסדים קטנים, והביצועים המפסידים מתקבצים ברגעים שלפני תנועת מחיר. העסק נשען על הממוצע על פני מיליוני ביצועים.
מהו markout במסחר?
markout הוא השינוי במחיר השוק בטווח זמן קבוע לאחר ביצוע, חתום מנקודת המבט של צד אחד, כאשר מספר חיובי אומר שאותו צד הרוויח. דסקים של מניות מצטטים markouts ב-mils למניה, ודסקים של אופציות ב-ticks לחוזה.
מה המשמעות של זרם הוראות רעיל (toxic order flow)?
זה מתאר זרם הוראות שעקומת ה-markout שלו משופעת בעקביות נגד עושה השוק שמבצע אותו, כלומר המחיר ממשיך להתרחק לאחר כל ביצוע. התווית היא תכונה סטטיסטית של זרם הוראות, והיא אינה נושאת שיפוט לגבי סוחר בודד.
מדוע עושי שוק מרחיבים spreads במקום למשוך את הציטוטים שלהם?
ציטוט רחב יותר משאיר את עושה השוק בשוק במחיר שמשלם על עקומת markout גרועה. משיכת הציטוט לא מרוויחה דבר ומוותרת על המיקום בתור יחד איתו. דסקים עושים את שניהם, והבחירה תלויה בכמה זמן הציטוט צפוי להישאר לא מעודכן.
כיצד נמדדת ברירה שלילית?
באמצעות markouts. חתום כל ביצוע לפי הצד שבו היה עושה השוק, לאחר מכן בצע ממוצע של שינוי ה-midpoint בטווחים קבועים לאחר מכן. הפער בין הקרדיט בביצוע לבין השווי בכל טווח זמן הוא עלות הברירה השלילית, באותן יחידות כמו ה-spread.
כיצד נבנו הנתונים הללו
כל פאנל AAPL קורא שני רשומות ציבוריות: סרט המסחר (trade tape) וסרט הציטוטים (quote tape). כל ביצוע בין 14:00 ל-17:00 UTC ב-14 במאי 2026 מותאם ל-national best bid and offer הממוצע של השנייה שבה הוא בוצע, ולאחר מכן נחתם. ביצוע מעל ה-midpoint ההוא נחשב לקנייה, מה שמציב את עושה השוק בצד המכירה. ביצועים בדיוק ב-midpoint אינם נושאים צד ומושמטים, יחד עם כל ביצוע שרחוק יותר מ-2 אחוזים מה-midpoint. רשומות ציטוט שבהן ה-bid פוגש או חוצה את ה-offer מוחרגות, שכן ל-locked or crossed market אין midpoint שמיש.
התאמת רמה שנייה מקרבת את הציטוט ששרר במיקרו-שנייה של הביצוע, והיא מחליקה את העדכונים המהירים ביותר. מחירי הטווח מגיעים מאותם midpoints של רמה שנייה. פאנל המלאי משתמש בנרות של דקה אחת ושומר רק נרות הנושאים לפחות 50 ביצועים, מה שמרכז את המדגם בשעות העמוסות ביותר של היום.
כל פאנל כאן נושא את ה-SQL שיצר אותו, כך שמתמטיקת ה-markout פתוחה לבדיקה שורה אחר שורה. כדי לבנות מחדש את העקומה על שם אחר או יום אחר, בקש זאת באנגלית פשוטה בטרמינל של Strasmore.