Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

做市商為何虧損?理解交易中的逆向選擇

了解做市商如何因逆向選擇虧損,掌握 markout 曲線的衡量方法,以及庫存風險與排隊位置成本如何侵蝕買賣價差收益。

做市商會因逆向選擇而虧損:主動買進賣方報價的交易者,往往早已知道該報價已經過時。每筆成交一開始都會帶來一小筆信用,約為買賣價差的一半;接下來幾秒鐘,決定這筆信用能保留多少。衡量工具是 markout,也就是成交後固定時間點的帶方向價格變化;下方各圖則根據成交與報價紀錄,建立實際的 markout 曲線。我們另有文章 做市商如何獲利,說明同一筆帳上的收入面。

交易中的逆向選擇是什麼?

做市商會同時掛出兩個價格:買進的買方報價與賣出的賣方報價,各自對應明確的數量。兩者之間的差距就是 買賣價差,而這項業務的計算方式很直接。在買方報價買進、在賣方報價賣出,每天重複數萬次,平均每次往返交易取得的金額大致接近買賣價差。

這種計算建立在買賣兩邊的成交量均衡之上。但實際並不均衡。掛在市場上的報價是一項任何人都能在自己選擇的時點執行的待定選擇權,而最密切關注市場的交易者會挑選最有利的時機。一檔基金執行大型母單時,只要賣方報價仍偏低,就會持續買進。某個系統若已觀察到相關工具上漲,就會交易尚未重新定價的一方。

逆向選擇就是用來描述這種成交結構偏斜的概念:做市商收到的成交,較集中於最想完成交易的交易者。其結果是,做市商掛出的價差與實際保留下來的價差之間出現落差。

做市中的 markout 是什麼?

markout 回答的是每筆成交後的一個問題:以我所處的一方為基準,固定幾秒後的價格在哪裡?假設做市商以 50.02 美元賣出 100 股,而中間價為 50.00 美元。這筆成交一開始每股帶來 2 美分的信用,以交易台慣用單位計為 20 mils;其中 1 mil 是 0.1 美分。若 60 秒後中間價上升至 50.04 美元,60 秒 markout 就是負 20 mils。原先的信用已經消失,並且又多出同等金額的損失。

將某段期間的每筆成交取平均,再對照不同時間區間繪圖,就會得到 markout 曲線。下圖以 2026年5月14日星期四中午時段的 3 小時資料,建立 AAPL 的 markout 曲線。每筆成交都以該成交所在秒的中間價判定方向:高於中間價的成交,視為買方主動買進,做市商則處於賣方。

查詢價差存續幅度:AAPL markout 曲線,1 秒至 5 分鐘
每個數據背後的精確 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
Run this yourself

第一條序列是成交當下的信用,也就是成交價與中間價之間的距離,平均為每股 19.66 mils。第二條序列是相同成交在中間價經過一段時間變動後的價值:1 秒後為 20.5 mils,5 分鐘後為 9.81 mils。任何時間區間下兩條序列之間的距離,就是 markout;這筆成本來自做市商所報出的價差。

曲線快速下滑後趨於平坦,表示做市商承擔了即時重新定價的成本,但保留了剩餘信用。曲線在每個時間區間都維持相同方向的斜率,則表示成交持續落在價格延續變動的不利一側。前一種形狀是業務成本;後一種則表示報價需要調整。

哪些成交屬於有毒流量?

這裡的「有毒」具有技術上的特定含義。當一大批成交的 markout 曲線在所有時間區間都朝不利於成交做市商的方向傾斜時,這類流量就具有毒性。交易台會依據所有可觀察的標籤對成交分類,包括成交量、交易場所、訂單類型及交易對手識別碼。公開交易紀錄所帶有的標籤就是成交量。

查詢依成交量分組的 AAPL 成交:成交時的 credit 與 60 秒後的價值
每個數據背後的精確 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)
Run this yourself

低於 100 股的成交,起始時每股帶來 19.47 mils 的信用,1 分鐘後價值為 15.22 mils。1,000 股以上的成交,起始時帶來 36.26 mils,在相同時間區間後價值為 21.34 mils。同一檔工具、同樣的 3 小時,每股經濟效益卻不同。最大筆訂單往往完全避開公開佇列,這正是 大宗交易 所要達成的目的。

庫存風險:無法及時避險的部位

markout 的時間區間同時也是一個時鐘。做市商以買方報價買進 5,000 股後,就持有 5,000 股;在部位完成避險或賣出前,必須承擔價格下一步變動的風險。避險很少能即時完成:單一股票部位可以用相關 ETF 或選擇權部位抵銷,而每一種工具都會產生需要支付的買賣價差。庫存風險就是在這段時間內可能發生的價格變動幅度,所有標的都以相同方式衡量。價格在下一分鐘、下一小時通常會移動多遠?

查詢部位等待期間的價格變動幅度:SPY 與 NVDA,2026年5月
每個數據背後的精確 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
Run this yourself

在 2026年5月期間,SPY 1 分鐘的平均絕對變動為 1.9 個基點;其中 1 個基點是百分之一個百分點。NVDA 在相同 1 分鐘期間為 5.5。將時間拉長至 1 小時後,兩項數值分別變為 14.140.4。能在 1 分鐘內平倉的做市商,承擔的是第一組風險。持有 1 小時的做市商,承擔的是第二組風險;但兩者在成交時收取的信用完全相同。

為什麼做市商在佇列後端會虧損?

交易所會按照訂單抵達的順序,以同一價格撮合掛單:先比價格,再比時間。買方報價上有一個 40,000 股的佇列,排在最後的訂單必須等待前方 40,000 股成交;估算佇列位置 本身就是一門專業。

困難在於如何定義佇列被清空。佇列有兩種清空方式。賣方持續打到買方報價,直到該價位的數量耗盡;或者價格下跌穿過該價位,將該價位留在身後。排在前方的訂單會參與這兩種情況。排在後方的訂單,則多半在第二種情況下成交,也就是該價位即將成為舊價格的時刻。兩名做市商可以在同一工具、同一價格交易,卻保留不同的利潤。佇列位置不會出現在報價的買賣價差中,因為兩名做市商報出的價格相同;它會出現在 markout 曲線中。

為什麼擴大報價不是免費解方?

面對不佳的 markout 曲線,最直接的做法是擴大報價。較寬的報價每筆成交賺取更多,但成交筆數也會減少。這項取捨的兩個面向,都會出現在同一天的成交紀錄中,並依每筆成交距離中間價的幅度分類。

查詢依距離中間價的幅度分組之 AAPL 成交:成交量占比與 60 秒 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.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

距離中間價半美分以內的成交,占該時段股數的 27.58%,1 分鐘後價值為每股 0.95 mils。距離中間價超過 2 美分的成交,占股數的 33.19%,價值為 46.86 mils。距離中間價更遠的報價,只會被當日較少比例的成交量觸及。

成交率是退到較遠價格後承擔的第一項成本。交易所回饋是第二項,因為許多交易場所會按成交股數向做市商支付回饋,而這項收入取決於成交股數,不取決於報價寬度。決定回饋率的成交量級距按月計算,因此某個月份交易清淡,會重新影響下一個月的每筆成交。放棄佇列位置是最後一項成本:離場時要付出一次,重新進場排到佇列後端時又要再付出一次。每個做市商都位於這條曲線上的某個位置;能最精確衡量自身 markout 的做市商,才能更接近最優報價並保留信用。這項衡量能力,正是 最大型做市商 所守住的優勢。

常見問題

做市商會在個別交易中虧損嗎?

經常會。做市帳簿由許多小額獲利與小額損失構成,而虧損成交會集中在價格即將變動的時刻。這項業務仰賴數百萬筆成交的平均結果。

交易中的 markout 是什麼?

markout 是成交後固定時間區間內的市場價格變化,並從其中一方的角度標示方向;正值表示該方獲利。股票交易台以每股 mils 報價 markout,選擇權交易台則以每張合約的 ticks 表示。

有毒訂單流量是什麼意思?

它描述的是一種訂單流量:其 markout 曲線持續朝不利於成交做市商的方向傾斜,表示每筆成交後價格都持續遠離做市商。這個標籤是訂單流量的統計特徵,不代表對任何單一交易者的評價。

為什麼做市商會擴大買賣價差,而不是撤掉報價?

較寬的報價讓做市商能繼續留在市場中,並以足以補償較差 markout 曲線的價格交易。撤掉報價不會帶來收入,也會一併放棄佇列位置。交易台兩種做法都會採用,取決於報價預期會維持過時狀態多久。

如何衡量逆向選擇?

使用 markout。先依做市商所處的一方為每筆成交標示方向,再計算成交後固定時間區間內的中間價變化平均值。成交時的信用與各時間區間價值之間的差距,就是以與價差相同單位表示的逆向選擇成本。

這些數字如何建立

每個 AAPL 圖表都讀取兩項公開紀錄:成交紀錄與報價紀錄。2026年5月14日 14:00 至 17:00 UTC 之間的每筆成交,會配對至成交所在秒的全國最佳買價與賣價中間價平均值 national best bid and offer,再標示交易方向。高於該中間價的成交,視為主動買進,做市商則處於賣方。剛好等於中間價的成交不帶有交易方向,會予以剔除;距離中間價超過 2% 的成交也會剔除。買方報價等於或高於賣方報價的報價紀錄會排除,因為 鎖定或交叉市場 沒有可用的中間價。

以秒為層級的第二層配對,可近似成交微秒時點的有效報價,並平滑最快速的更新。各時間區間的價格來自相同的秒級中間價。庫存圖表使用 1 分鐘 K 線,且只保留至少包含 50 筆成交的 K 線,使樣本集中在每日交易最活躍的時段。

此處每個圖表都附有產生該圖表的 SQL,因此 markout 計算可以逐行檢視。若要在其他標的或其他日期重建曲線,可在 Strasmore terminal 以自然語言提出要求。