Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

Adverse selection khiến market maker thua lỗ

Tìm hiểu vì sao market maker thua lỗ do adverse selection, cách markout đo lường tác động, cùng rủi ro tồn kho và chi phí queue position.

Market makers chịu lỗ do adverse selection: trader thực hiện mua tại offer thường là người đã biết offer đó không còn cập nhật. Mỗi lần khớp lệnh bắt đầu với một khoản credit nhỏ, xấp xỉ một nửa spread, và vài giây tiếp theo sẽ quyết định bao nhiêu phần credit còn lại. Công cụ đo lường là markout, tức mức thay đổi giá có dấu tại một khoảng thời gian cố định sau khi khớp lệnh. Các biểu đồ dưới đây xây dựng đường cong markout thực tế từ dữ liệu trade và quote. Bài viết đi kèm về cách market makers kiếm tiền trình bày phía doanh thu của cùng bảng cân đối đó.

Adverse selection trong giao dịch là gì?

Market maker niêm yết đồng thời hai mức giá: bid để mua và offer để bán, mỗi mức áp dụng cho một khối lượng cụ thể. Khoảng cách giữa hai mức giá là bid ask spread, và hoạt động kinh doanh dựa trên phép tính đơn giản. Mua tại bid, bán tại offer, lặp lại hàng chục nghìn lần mỗi ngày, rồi thu về trung bình một khoản gần bằng spread cho mỗi vòng giao dịch.

Phép tính đó giả định hai phía xuất hiện cân bằng. Thực tế không như vậy. Một quote đang chờ khớp là một quyền chọn có thể được bất kỳ ai thực hiện vào thời điểm họ lựa chọn. Những trader theo dõi thị trường sát sao sẽ chọn đúng thời điểm có lợi nhất. Một quỹ đang thực hiện một parent order lớn sẽ tiếp tục mua khi offer vẫn còn rẻ. Một hệ thống đã phát hiện một công cụ tương quan biến động sẽ giao dịch ở phía chưa kịp điều chỉnh giá.

Adverse selection là tên gọi của sự lệch trong cơ cấu đó: các lệnh được khớp với market maker tập trung nhiều hơn ở những trader thực sự muốn giao dịch. Dấu hiệu là khoảng cách giữa spread mà market maker niêm yết và phần spread mà họ thực sự giữ lại.

Markout trong hoạt động market making là gì?

Markout trả lời một câu hỏi sau mỗi lần khớp lệnh: giá nằm ở đâu sau một khoảng thời gian cố định, tính từ phía mà tôi đang đứng? Giả sử một market maker bán 100 cổ phiếu ở mức $50.02 trong khi midpoint là $50.00. Lệnh khớp đó bắt đầu với credit hai cent trên mỗi cổ phiếu, tương đương 20 mil theo đơn vị của trading desk, trong đó một mil bằng một phần mười cent. Nếu midpoint tăng lên $50.04 sau 60 giây, markout 60 giây là âm 20 mil. Credit ban đầu đã biến mất, cùng với thêm một khoản tương đương.

Lấy trung bình kết quả của mọi lần khớp trong một khoảng thời gian rồi biểu diễn theo các mốc thời gian, ta có đường cong markout. Biểu đồ dưới đây xây dựng đường cong cho AAPL trong khoảng ba giờ giữa phiên vào thứ Năm, ngày 14 tháng 5 năm 2026. Mỗi print được xác định dấu dựa trên midpoint của giây mà giao dịch được thực hiện: print cao hơn midpoint được tính là taker mua, khiến market maker đứng ở phía bán.

Truy vấnMức spread còn lại: đường cong markout của AAPL, từ 1 giây đến 5 phút
Câu lệnh SQL chính xác đằng sau mỗi con số
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
Run this yourself

Chuỗi thứ nhất là credit tại thời điểm khớp lệnh, tức khoảng cách giữa print và midpoint, với mức trung bình 19.66 mil trên mỗi cổ phiếu. Chuỗi thứ hai cho biết giá trị của chính các lệnh khớp đó sau khi midpoint có thời gian biến động: 20.5 mil sau một giây và 9.81 mil sau năm phút. Khoảng cách giữa hai chuỗi tại mỗi mốc thời gian chính là markout, và khoản này được trừ vào spread mà market maker đã niêm yết.

Đường cong giảm nhanh rồi đi ngang cho thấy market maker phải chịu chi phí do giá điều chỉnh ngay lập tức nhưng vẫn giữ được phần còn lại. Đường cong tiếp tục dốc theo cùng hướng ở mọi mốc thời gian cho thấy các lệnh khớp liên tục rơi vào phía bất lợi của một mức giá vẫn đang tiếp tục di chuyển. Hình dạng thứ nhất là chi phí kinh doanh. Hình dạng thứ hai cho thấy quote cần được điều chỉnh.

Dòng lệnh nào là toxic flow?

Từ toxic ở đây có ý nghĩa kỹ thuật. Flow là toxic khi đường cong markout của nó dốc ngược lại phía market maker đã khớp lệnh, tại mọi mốc thời gian và trong một mẫu đủ lớn. Các trading desk phân loại lệnh khớp theo mọi nhãn có thể quan sát: quy mô print, venue, loại lệnh và mã nhận diện đối tác. Quy mô là nhãn được thể hiện trên public tape.

Truy vấnCác lệnh khớp AAPL theo quy mô giao dịch: credit tại thời điểm khớp và giá trị sau 60 giây
Câu lệnh SQL chính xác đằng sau mỗi con số
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)
Run this yourself

Các lệnh khớp dưới 100 cổ phiếu bắt đầu với 19.47 mil trên mỗi cổ phiếu và chỉ còn giá trị 15.22 mil sau một phút. Các print từ 1.000 cổ phiếu trở lên bắt đầu với 36.26 mil và có giá trị 21.34 mil trong cùng khoảng thời gian. Cùng một công cụ, cùng ba giờ giao dịch, nhưng economics trên mỗi cổ phiếu khác nhau. Các lệnh lớn nhất thường tránh hoàn toàn hàng đợi công khai, đúng với mục đích của block trade.

Rủi ro tồn kho: vị thế không thể hedge kịp thời

Khoảng thời gian của markout cũng là một chiếc đồng hồ đo lường. Market maker mua 5.000 cổ phiếu tại bid sẽ nắm giữ 5.000 cổ phiếu. Cho đến khi vị thế được hedge hoặc bán ra, vị thế đó chịu rủi ro từ mọi biến động tiếp theo của giá. Việc hedge hiếm khi diễn ra ngay lập tức: một vị thế cổ phiếu riêng lẻ có thể được bù trừ bằng ETF tương quan hoặc vị thế quyền chọn, và mỗi công cụ đều có spread riêng cần vượt qua. Rủi ro tồn kho là quy mô biến động có thể xảy ra trong khoảng thời gian đó, và được đo lường theo cùng cách với mọi mã. Giá thường di chuyển bao xa trong một phút tiếp theo và trong một giờ tiếp theo?

Truy vấnGiá di chuyển bao xa trong khi vị thế chờ: SPY và NVDA, tháng 5/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
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
Run this yourself

Trong tháng 5 năm 2026, mức biến động tuyệt đối trung bình của SPY trong một phút là 1.9 basis points, trong đó một basis point bằng một phần một trăm của một phần trăm. Mức tương ứng của NVDA là 5.5 trong cùng một phút. Kéo dài khoảng thời gian lên một giờ, hai con số lần lượt là 14.140.4. Market maker có thể đưa vị thế về trạng thái trung hòa trong một phút sẽ chịu cặp rủi ro thứ nhất. Market maker nắm giữ vị thế trong một giờ sẽ chịu cặp rủi ro thứ hai, trong khi credit thu được tại thời điểm khớp là như nhau.

Vì sao market makers chịu lỗ ở cuối hàng đợi?

Các sàn giao dịch khớp các lệnh đang chờ tại cùng một mức giá theo thứ tự đến trước: ưu tiên giá trước, rồi đến thời gian. Một lệnh ở cuối hàng đợi 40.000 cổ phiếu tại bid phải chờ 40.000 cổ phiếu phía trước được khớp hết. Ước tính vị trí trong hàng đợi là một nghiệp vụ riêng.

Điểm phức tạp nằm ở ý nghĩa của việc hàng đợi được giải phóng. Một hàng đợi cạn theo hai cách. Người bán tiếp tục đánh vào bid cho đến khi mức giá đó hết khối lượng, hoặc giá giảm xuyên qua mức đó và bỏ lại lệnh phía sau. Lệnh ở gần đầu hàng đợi tham gia vào cả hai trường hợp. Lệnh ở cuối hàng đợi chủ yếu được khớp theo trường hợp thứ hai, đúng lúc mức giá sắp trở thành mức giá cũ. Hai market maker có thể giao dịch cùng một công cụ tại cùng một mức giá nhưng giữ lại các khoản khác nhau. Vị trí trong hàng đợi không xuất hiện trong spread được niêm yết vì cả hai market maker niêm yết cùng một mức giá. Nó thể hiện trong đường cong markout.

Vì sao nới rộng quote không phải là giải pháp miễn phí?

Phản ứng hiển nhiên trước một đường cong markout bất lợi là niêm yết spread rộng hơn. Quote rộng hơn mang lại nhiều hơn trên mỗi lần khớp nhưng dẫn đến ít lần khớp hơn. Cả hai mặt của sự đánh đổi này đều xuất hiện trong các print của cùng một ngày, được phân loại theo khoảng cách mỗi print so với midpoint.

Truy vấnCác giao dịch AAPL theo khoảng cách đến midpoint: tỷ trọng volume và markout sau 60 giây
Câu lệnh SQL chính xác đằng sau mỗi con số
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)
Run this yourself

Các print nằm trong phạm vi nửa cent so với midpoint chiếm 27.58 phần trăm số cổ phiếu trong khoảng thời gian, với giá trị 0.95 mil trên mỗi cổ phiếu sau một phút. Các print cách midpoint hơn hai cent chiếm 33.19 phần trăm số cổ phiếu, với giá trị 46.86 mil. Quote được đặt xa midpoint hơn sẽ chỉ được một phần nhỏ hơn của khối lượng trong ngày tiếp cận.

Tỷ lệ khớp là chi phí đầu tiên của việc lùi quote. Chi phí thứ hai là rebate từ sàn, vì nhiều venue trả cho market maker theo mỗi cổ phiếu được khớp và khoản thu này tăng theo số cổ phiếu thay vì độ rộng của quote. Các ngưỡng khối lượng quyết định mức rebate được tính theo tháng, nên một tháng có thanh khoản thấp sẽ làm thay đổi giá trị của mọi lần khớp trong tháng tiếp theo. Từ bỏ vị trí trong hàng đợi là chi phí cuối cùng: market maker chịu chi phí khi rời hàng và lại chịu thêm một lần khi quay lại cuối hàng. Mỗi market maker đều có một vị trí trên đường cong này. Những bên đo lường markout của chính mình chính xác nhất có thể đứng gần touch nhất mà vẫn giữ được credit. Việc đo lường đó là lợi thế mà các market makers lớn nhất bảo vệ.

FAQ

Market makers có chịu lỗ trong từng giao dịch riêng lẻ không?

Thường xuyên. Sổ lệnh market making là một phân phối gồm các khoản lãi nhỏ và lỗ nhỏ. Các lần khớp thua lỗ tập trung vào những thời điểm ngay trước khi giá biến động. Hoạt động kinh doanh dựa trên mức trung bình của hàng triệu lần khớp.

Markout trong giao dịch là gì?

Markout là mức thay đổi của giá thị trường tại một khoảng thời gian cố định sau khi khớp lệnh, được xác định dấu từ góc nhìn của một phía. Số dương nghĩa là phía đó có lợi. Các trading desk cổ phiếu niêm yết markout theo mil trên mỗi cổ phiếu, còn trading desk quyền chọn niêm yết theo tick trên mỗi hợp đồng.

Toxic order flow nghĩa là gì?

Toxic order flow là dòng lệnh có đường cong markout liên tục dốc ngược lại phía market maker khớp lệnh đó. Điều này có nghĩa là giá tiếp tục di chuyển bất lợi sau mỗi lần khớp. Đây là một đặc tính thống kê của một dòng lệnh, không phải nhận định về bất kỳ trader riêng lẻ nào.

Vì sao market makers nới rộng spread thay vì rút quote?

Quote rộng hơn giúp market maker tiếp tục tham gia thị trường ở mức giá đủ bù đắp cho đường cong markout bất lợi hơn. Rút quote không tạo ra doanh thu và đồng thời làm mất vị trí trong hàng đợi. Các trading desk sử dụng cả hai cách. Lựa chọn phụ thuộc vào thời gian dự kiến quote sẽ bị lỗi thời.

Adverse selection được đo lường như thế nào?

Bằng markout. Xác định dấu cho mỗi lần khớp dựa trên phía mà market maker đứng, sau đó tính trung bình thay đổi của midpoint tại các mốc thời gian cố định. Khoảng cách giữa credit tại thời điểm khớp và giá trị tại từng mốc thời gian là chi phí adverse selection, được đo bằng cùng đơn vị với spread.

Cách xây dựng các con số này

Mỗi biểu đồ AAPL sử dụng hai nguồn dữ liệu công khai: trade tape và quote tape. Mỗi print trong khoảng từ 14:00 đến 17:00 UTC ngày 14 tháng 5 năm 2026 được ghép với midpoint trung bình của national best bid and offer trong giây mà giao dịch được thực hiện, sau đó được xác định dấu. Print cao hơn midpoint được tính là taker mua, khiến market maker đứng ở phía bán. Các print đúng bằng midpoint không có phía giao dịch và bị loại bỏ. Những print cách midpoint hơn 2 phần trăm cũng bị loại bỏ. Các bản ghi quote trong đó bid bằng hoặc vượt offer bị loại, vì locked or crossed market không có midpoint có thể sử dụng.

Việc ghép ở cấp độ giây giúp xấp xỉ quote hiện hành tại microsecond khi lệnh được khớp và làm mượt các cập nhật nhanh nhất. Giá tại các mốc thời gian được lấy từ midpoint ở cùng cấp độ giây. Biểu đồ tồn kho sử dụng các thanh dữ liệu một phút và chỉ giữ lại những thanh có ít nhất 50 print, qua đó tập trung mẫu vào các giờ giao dịch sôi động nhất trong ngày.


Mỗi biểu đồ tại đây đều kèm theo SQL đã tạo ra nó, nên có thể kiểm tra từng bước tính toán markout. Để dựng lại đường cong cho một mã khác hoặc một ngày khác, hãy yêu cầu bằng tiếng Anh tự nhiên trên terminal Strasmore.