Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

Perché i market maker perdono: adverse selection

Perché i market maker perdono denaro? L’adverse selection è il canale principale: scopri markout, rischio inventario e costi di queue position con esempi pratici.

I market maker perdono denaro per adverse selection: il trader che colpisce un offer è spesso quello che sa già che quell’offer è obsoleto. Ogni eseguito si apre con un piccolo credito, pari grosso modo a metà dello spread, e i secondi successivi determinano quanta parte di quel credito rimane. Lo strumento di misurazione è il markout, una variazione di prezzo con segno calcolata a un orizzonte fisso dopo un eseguito; i pannelli qui sotto costruiscono curve di markout reali a partire da prints di trade e quote. Il nostro articolo collegato su come guadagnano i market maker esamina il lato dei ricavi dello stesso conto economico.

Che cos’è l’adverse selection nel trading?

Un market maker espone contemporaneamente due prezzi: un bid a cui comprare e un offer a cui vendere, ciascuno valido per una quantità specificata. La differenza tra i due è il bid ask spread e l’attività si basa sull’aritmetica. Comprare al bid, vendere all’offer, ripetere l’operazione decine di migliaia di volte al giorno: il round trip medio incassa una somma vicina allo spread.

Questa aritmetica presuppone che i due lati arrivino in equilibrio. Non accade. Una quote resting è un’opzione sempre disponibile che chiunque può esercitare nel momento che preferisce, e i trader più attenti scelgono i momenti migliori. Un fondo che esegue un parent order di grandi dimensioni continua a comprare mentre l’offer resta conveniente. Un sistema che ha già rilevato un movimento in uno strumento correlato colpisce il lato che non si è ancora adeguato.

Adverse selection è il nome dato allo squilibrio di questo mix: gli eseguiti ricevuti dal market maker sono maggiormente concentrati tra i trader che li desideravano di più. Il sintomo è la differenza tra lo spread quotato dal market maker e quello che riesce effettivamente a mantenere.

Che cos’è un markout nel market making?

Il markout risponde a una domanda posta dopo ogni eseguito: dove si trovava il prezzo dopo un numero fisso di secondi, misurato dal lato in cui mi trovavo? Supponiamo che un market maker venda 100 azioni a $50.02 mentre il midpoint è a $50.00. L’eseguito si apre con un credito di due centesimi per azione, pari a 20 mils nelle unità usate dal desk, dove un mil è un decimo di centesimo. Se 60 secondi dopo il midpoint è salito a $50.04, il markout a 60 secondi è pari a meno 20 mils. Il credito iniziale è svanito, insieme a un importo uguale.

Calcolando la media su tutti gli eseguiti di una finestra temporale e rappresentandola in funzione dell’orizzonte, si ottiene una curva di markout. Il pannello qui sotto ne costruisce una per AAPL su una finestra intraday di tre ore, nella fascia centrale della seduta di giovedì 14 maggio 2026. Ogni print viene classificato rispetto al midpoint del secondo in cui è stato eseguito: un print sopra il midpoint indica un acquisto da parte del taker e colloca il market maker sul lato sell.

QueryQuanto dello spread sopravvive: curva di markout di AAPL, da 1 secondo a 5 minuti
L'esatto SQL dietro ogni numero
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

La prima serie è il credito al momento dell’eseguito, cioè la distanza tra il print e il midpoint, pari in media a 19.66 mils per azione. La seconda serie mostra quanto valgono quegli stessi eseguiti dopo che il midpoint ha avuto il tempo di muoversi: 20.5 mils dopo un secondo e 9.81 mils dopo cinque minuti. La distanza tra le due serie a ciascun orizzonte è il markout e viene sottratta allo spread quotato dal market maker.

Una curva che scende rapidamente e poi si appiattisce descrive un market maker che paga il repricing immediato e conserva il resto. Una curva che continua a inclinarsi nella stessa direzione a ogni orizzonte descrive eseguiti che si verificano dal lato sbagliato di un prezzo in continuo movimento. La prima forma è un costo dell’attività. La seconda indica che la quote deve cambiare.

Quali eseguiti rappresentano toxic flow?

Qui la parola toxic ha un significato tecnico. Il flow è toxic quando la sua curva di markout si inclina contro il market maker che ha eseguito l’ordine, a ogni orizzonte e su un campione ampio. I desk classificano gli eseguiti in base a ogni variabile disponibile: dimensione del print, venue, tipo di ordine, identificativo della controparte. La dimensione è la variabile visibile nel tape pubblico.

QueryEsecuzioni AAPL per dimensione del print: credito all’esecuzione e valore dopo 60 secondi
L'esatto SQL dietro ogni numero
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

Gli eseguiti inferiori a 100 azioni si aprono con un credito di 19.47 mils per azione e valgono 15.22 mils un minuto dopo. I prints da 1.000 azioni in su si aprono con 36.26 mils e valgono 21.34 mils allo stesso orizzonte. Stesso strumento, stesse tre ore, economia diversa per azione. Gli ordini più grandi spesso evitano del tutto la coda pubblica, che è proprio ciò che un block trade è strutturato per fare.

Il rischio di inventory, la posizione che non può essere coperta in tempo

Un orizzonte di markout è anche un orologio. Un market maker che compra 5.000 azioni al bid detiene 5.000 azioni e, finché la posizione non viene coperta o venduta, è esposto a ciò che farà il prezzo. L’hedging raramente è istantaneo: una posizione su una singola azione può essere compensata con un ETF correlato o con una posizione in opzioni, e ciascuno di questi strumenti comporta il proprio spread da attraversare. Il rischio di inventory è l’ampiezza del movimento che può verificarsi durante quella finestra ed è misurato nello stesso modo per ogni titolo. Quanto si muove normalmente il prezzo nel minuto successivo e nell’ora successiva?

QueryQuanto si muove il prezzo mentre una posizione è in attesa: SPY e NVDA, maggio 2026
L'esatto SQL dietro ogni numero
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

Nel corso di maggio 2026, il movimento assoluto medio di SPY su un minuto è stato di 1.9 basis points, dove un basis point equivale a un centesimo di punto percentuale. Su NVDA è stato di 5.5 nello stesso intervallo. Estendendo l’orizzonte a un’ora, i due valori diventano 14.1 e 40.4. Un market maker che riesce a portare la posizione in pareggio entro un minuto vive con la prima coppia. Un market maker che mantiene la posizione per un’ora vive con la seconda, mentre il credito incassato sull’eseguito è identico in entrambi i casi.

Perché i market maker perdono denaro in fondo alla coda

Le borse abbinano gli ordini resting allo stesso prezzo nell’ordine di arrivo: prima il prezzo, poi il tempo. Un ordine in fondo a una coda di 40.000 azioni al bid deve attendere che vengano eseguite le 40.000 azioni davanti a lui, e stimare la posizione nella coda è una disciplina a sé.

La parte complessa riguarda il significato di esaurimento della coda. Una coda si svuota in due modi. I venditori continuano a colpire il bid finché il livello non si esaurisce, oppure il prezzo scende attraverso quel livello e lo lascia indietro. Un ordine vicino alla testa partecipa a entrambi i percorsi. Un ordine in fondo si esegue soprattutto nel secondo caso, nel momento in cui il livello sta per diventare il vecchio prezzo. Due market maker possono negoziare lo stesso strumento allo stesso prezzo e conservarne quantità diverse. La posizione nella coda non compare nello spread quotato, perché entrambi i market maker hanno quotato lo stesso prezzo. Compare nella curva di markout.

Perché allargare la quote non è una soluzione gratuita

La risposta più ovvia a una curva di markout sfavorevole è quotare uno spread più ampio. Una quote più ampia guadagna di più per ogni eseguito, ma riceve meno eseguiti. Entrambi gli aspetti della scelta compaiono nei prints della stessa giornata, ordinati in base alla distanza di ciascun print dal midpoint.

QueryPrint di AAPL per distanza dal midpoint: quota del volume e markout a 60 secondi
L'esatto SQL dietro ogni numero
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

I prints entro mezzo centesimo dal midpoint rappresentavano 27.58 percento delle azioni nella finestra e valevano 0.95 mils per azione un minuto dopo. I prints a più di due centesimi dal midpoint rappresentavano 33.19 percento delle azioni, con un valore di 46.86 mils. Una quote esposta più lontano dal midpoint viene raggiunta da una quota minore del volume giornaliero.

Il primo costo dell’arretramento è il fill rate. Il secondo sono i rebate delle borse, poiché molte venue pagano il market maker per ogni azione eseguita e questo ricavo dipende dal numero di azioni, non dall’ampiezza della quote. Le fasce di volume che determinano il rebate vengono calcolate su base mensile; un mese poco attivo modifica quindi il valore di ogni eseguito nel mese successivo. Rinunciare alla posizione nella coda è l’ultimo costo: si paga all’uscita e di nuovo, in fondo alla fila, al rientro. Ogni market maker si trova in un punto di questa curva, e quelli che misurano i propri markout con maggiore precisione possono restare vicini al touch e conservare comunque il credito. Questa misurazione è il vantaggio difeso dai market maker più grandi.

FAQ

I market maker perdono denaro sulle singole operazioni?

Regolarmente. Un book di market making è una distribuzione di piccoli guadagni e piccole perdite, e gli eseguiti in perdita si concentrano nei momenti immediatamente precedenti a un movimento del prezzo. L’attività si basa sulla media di milioni di eseguiti.

Che cos’è un markout nel trading?

Un markout è la variazione del prezzo di mercato a un orizzonte fisso dopo un eseguito, con segno determinato dal punto di vista di uno dei due lati; un valore positivo indica che quel lato ha guadagnato. I desk azionari esprimono i markout in mils per azione, mentre i desk di opzioni li esprimono in ticks per contratto.

Che cosa significa toxic order flow?

Descrive un order flow la cui curva di markout si inclina persistentemente contro il market maker che lo esegue: il prezzo continua ad allontanarsi dopo ogni eseguito. L’etichetta è una proprietà statistica di un flusso di ordini e non esprime alcun giudizio su un singolo trader.

Perché i market maker allargano gli spread invece di ritirare le quote?

Una quote più ampia consente al market maker di restare sul mercato a un prezzo che compensa una curva di markout peggiore. Ritirare la quote non genera ricavi e comporta la perdita della posizione nella coda. I desk adottano entrambe le soluzioni; la scelta dipende dal tempo previsto prima che la quote diventi obsoleta.

Come si misura l’adverse selection?

Con i markout. Si assegna un segno a ogni eseguito in base al lato occupato dal market maker e poi si calcola la variazione media del midpoint a orizzonti fissi successivi. La differenza tra il credito al momento dell’eseguito e il valore a ciascun orizzonte è il costo dell’adverse selection, espresso nelle stesse unità dello spread.

Come sono stati costruiti questi numeri

Ogni pannello su AAPL utilizza due fonti pubbliche: il trade tape e il quote tape. Ogni print tra le 14:00 e le 17:00 UTC del 14 maggio 2026 viene associato al midpoint medio del national best bid and offer nel secondo in cui è stato eseguito e poi classificato con un segno. Un print sopra quel midpoint indica un acquisto da parte del taker e colloca il market maker sul lato sell. I prints esattamente al midpoint non hanno un lato e vengono esclusi, così come ogni print distante più del 2 percento dal midpoint. Vengono esclusi anche i record di quote in cui il bid è pari o superiore all’offer, perché un mercato locked o crossed non ha un midpoint utilizzabile.

L’abbinamento al livello del secondo approssima la quote vigente al microsecondo dell’eseguito e attenua gli aggiornamenti più rapidi. I prezzi agli orizzonti provengono dagli stessi midpoint al livello del secondo. Il pannello sull’inventory utilizza barre a un minuto e conserva solo quelle con almeno 50 prints, concentrando il campione nelle ore più attive della giornata.


Ogni pannello qui include l’SQL che lo ha prodotto, così la matematica del markout può essere verificata riga per riga. Per ricostruire la curva su un altro titolo o in un’altra giornata, è sufficiente richiederla in inglese semplice sul terminale Strasmore.