Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

Différences entre données de carnet d'ordres MBO et MBP

Analyse technique des flux MBO et MBP pour le trading. Comprenez la distinction entre les événements par ordre et l'agrégation par niveau de prix ainsi que leurs coûts.

Les données de carnet d'ordres MBO et MBP constituent une distinction majeure dissimulée derrière une appellation générique. Deux fournisseurs peuvent vous vendre un accès « Level 2 » : le MBP (Market By Price) transmet la taille totale disponible à chaque niveau de prix, tandis que le MBO (Market By Order) transmet chaque ordre individuel comme un événement distinct doté de son propre identifiant. L'un est une synthèse du carnet ; l'autre est le registre à partir duquel le carnet est construit, et son transport nécessite un volume de données nettement plus important.

Ce que contiennent réellement les données de carnet MBP et MBO

Le MBP, ou Market By Price, représente la profondeur agrégée. Chaque mise à jour indique un côté, un niveau de prix, la taille totale affichée à ce niveau et, parfois, le nombre d'ordres sous-jacents. Un produit vendu sous l'appellation MBP-10 vous fournit les dix meilleurs niveaux de prix de chaque côté, soit l'échelle de prix d'une plateforme de trading et la structure de tout graphique de profondeur.

Le MBO, ou Market By Order, est un flux d'événements. Chaque message désigne un ordre unique : son identifiant, son côté, son prix, sa taille affichée et l'événement qui vient de le concerner. Rien n'est pré-agrégé. Si quarante ordres sont placés au même prix, quarante messages distincts les y ont inscrits, et vous devez conserver ces quarante ordres en mémoire pour connaître le total de ce niveau.

Notre guide sur les données de marché Level 1 vs Level 2 détaille la signification de ces catégories pour les investisseurs particuliers. MBO et MBP sont les termes précis désignant le contenu réel lorsqu'un fournisseur mentionne le « Level 2 » ; c'est le nom du schéma qu'il convient d'interroger.

Les actions de messages transmises par un flux MBO

Un flux MBO est une taxonomie d'actions appliquées à des identifiants d'ordres. Quatre d'entre elles génèrent la majeure partie du trafic :

  • Ajout (Add) : un nouvel ordre rejoint le carnet à un prix donné avec un nouvel identifiant.
  • Modification (Modify) : un identifiant existant change de prix ou de taille. Augmenter la taille ou modifier le prix place l'ordre en fin de file d'attente à ce nouveau niveau ; réduire la taille permet généralement de conserver sa position.
  • Annulation (Cancel) : un identifiant quitte le carnet, en totalité ou en partie.
  • Exécution (Trade ou fill) : un ordre agressif s'exécute contre un ou plusieurs identifiants passifs, réduisant ou supprimant ces derniers.

Le MBP ne comporte aucun de ces éléments. Une mise à jour MBP est une déclaration sur un niveau : ce prix contient désormais telle quantité. Que la taille ait diminué suite à une annulation ou à une exécution, la mise à jour est identique. Le panneau ci-dessous illustre cette limite sur le carnet le plus restreint possible, le sommet du carnet consolidé, soit un niveau de prix par côté et MBP-1 dans cette nomenclature.

RequêteÉvolution du top-of-book entre messages consécutifs (AAPL, 10h00 à 10h30 ET, 16 juin 2026)
Le SQL exact derrière chaque chiffre
WITH
    ordered AS
    (
        SELECT
            row_number() OVER (ORDER BY sip_timestamp, sequence_number) AS msg_index,
            bid_price,
            bid_size,
            lagInFrame(bid_price) OVER (ORDER BY sip_timestamp, sequence_number) AS prev_bid_price,
            lagInFrame(bid_size)  OVER (ORDER BY sip_timestamp, sequence_number) AS prev_bid_size
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'AAPL'
          AND sip_timestamp >= '2026-06-16 14:00:00'
          AND sip_timestamp <  '2026-06-16 14:30:00'
          AND bid_price > 0
    ),
    classified AS
    (
        SELECT multiIf(
            bid_price != prev_bid_price, 'best bid price changed',
            bid_size  >  prev_bid_size,  'size joined at the best bid',
            bid_size  <  prev_bid_size,  'size left the best bid',
            'bid untouched, ask side updated') AS message_type
        FROM ordered
        WHERE msg_index > 1
    )
SELECT
    message_type,
    count()                                        AS message_count,
    round(100 * count() / sum(count()) OVER (), 1) AS share_pct
FROM classified
GROUP BY message_type
ORDER BY indexOf(['best bid price changed', 'size joined at the best bid', 'size left the best bid', 'bid untouched, ask side updated'], message_type)
Run this yourself

Sur cette demi-heure, 17.6% des messages ont déplacé la meilleure offre (bid) vers un prix différent, 17.4% ont ajouté de la taille à une offre inchangée, 12% ont retiré de la taille à une offre inchangée, et 53% ont laissé l'offre telle quelle pendant que l'autre côté bougeait. Chaque groupe constitue une déclaration nette sur un niveau de prix. Aucun ne nomme un ordre, et aucun calcul ne permet de retrouver l'identifiant manquant.

Ce que chaque schéma peut et ne peut pas résoudre

Le MBP-10 répond aux questions formulées en termes de « quelle était la taille disponible » : la forme de l'échelle, le déséquilibre du carnet, la liquidité proche du milieu de fourchette, ou le graphique de profondeur lui-même. Les niveaux agrégés suffisent à ces besoins.

Le MBO répond aux questions formulées en termes de « qu'est-il arrivé à cet ordre » : quelle taille se trouvait devant le vôtre lors de votre arrivée, combien de temps les ordres survivent-ils avant d'être annulés, et quelle est la probabilité qu'un ordre passif au meilleur prix soit exécuté avant que le prix ne s'éloigne. Ces quantités n'existent pas sous forme agrégée, et sommer les ordres en un total par niveau détruit la séquence qui les définissait.

La position dans la file d'attente est l'exemple le plus probant, et elle n'a de sens que dans le cadre d'un appariement par priorité prix-temps ou au prorata, où l'ordre d'arrivée détermine qui est servi en premier. Ce qui rend cela crucial, c'est la taille des transactions : un niveau est rempli par de nombreuses petites exécutions, et non par une seule importante.

RequêteRépartition de la taille des trades sur la même période (AAPL, 10h00 à 10h30 ET, 16 juin 2026)
Le SQL exact derrière chaque chiffre
SELECT
    multiIf(size < 100,  '1 to 99 shares',
            size < 200,  '100 to 199 shares',
            size < 500,  '200 to 499 shares',
            size < 1000, '500 to 999 shares',
            '1000 or more shares')                 AS trade_size_bucket,
    count()                                        AS trade_count,
    round(100 * count() / sum(count()) OVER (), 1) AS share_pct,
    round(avg(size))                               AS avg_shares
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
  AND sip_timestamp >= '2026-06-16 14:00:00'
  AND sip_timestamp <  '2026-06-16 14:30:00'
  AND size > 0
GROUP BY trade_size_bucket
ORDER BY min(size)
Run this yourself

Les transactions inférieures à cent actions, soit un « odd lot », ont représenté 92.3% des échanges sur cette période, et le plus grand compartiment présent, 1000 or more shares, a représenté 0.1%. Si vous envoyez ces transactions vers un niveau affichant 4 000 actions, un ordre arrivé en dernier dans la file peut subir des dizaines d'exécutions sans être servi. Le MBP vous montre les 4 000. Le MBO vous montre la file.

Aucun des deux schémas ne montre la taille cachée. Un ordre iceberg affiche une petite partie visible et se rafraîchit avec un nouvel identifiant à chaque fois que cette partie est exécutée ; la réserve n'apparaît donc dans aucun message.

Reconstruire un carnet à partir du MBO est une machine à états

Un flux MBP vous donne le résultat. Un flux MBO vous donne les entrées et exige une précision absolue :

  1. Partez d'un instantané (snapshot) ou d'un carnet vide après le message de réinitialisation de la place boursière.
  2. Appliquez chaque ajout, modification, annulation et exécution dans l'ordre strict, en utilisant l'identifiant d'ordre comme clé.
  3. Maintenez un second index par niveau de prix, car c'est ce que votre stratégie lit.
  4. Surveillez les numéros de séquence et resynchronisez à partir d'un nouvel instantané dès qu'un message manque.

Le mode de défaillance est silencieux. Si vous manquez une annulation, un ordre fantôme reste dans votre carnet pour le reste de la session, gonflant artificiellement ce niveau, sans qu'aucune exception ne soit levée. Le MBP se dégrade de manière beaucoup plus douce : chaque mise à jour réaffirme le total d'un niveau, de sorte qu'une valeur corrompue est écrasée en quelques messages.

Le MBO ne vit également que sur les flux directs des places boursières, un carnet par échange, ce qui implique d'exécuter et de fusionner plusieurs flux. La bande consolidée est une synthèse par construction, une séparation traitée dans SIP versus flux directs des places boursières.

Le coût en bande passante de ce niveau de détail

Le nombre de messages est la méthode honnête pour évaluer la différence de coût. Le panneau ci-dessous compare les messages du sommet du carnet consolidé aux transactions réelles sur la même demi-heure pour cinq valeurs de référence.

RequêteRatio messages top-of-book sur prints, 10h00 à 10h30 ET, 16 juin 2026
Le SQL exact derrière chaque chiffre
WITH
    quote_load AS
    (
        SELECT ticker, count() AS quote_messages
        FROM global_markets.cache_stocks_quotes
        WHERE ticker IN ('SPY', 'AAPL', 'NVDA', 'MSFT', 'KO')
          AND sip_timestamp >= '2026-06-16 14:00:00'
          AND sip_timestamp <  '2026-06-16 14:30:00'
        GROUP BY ticker
    ),
    trade_load AS
    (
        SELECT ticker, count() AS trades
        FROM global_markets.stocks_trades
        WHERE ticker IN ('SPY', 'AAPL', 'NVDA', 'MSFT', 'KO')
          AND sip_timestamp >= '2026-06-16 14:00:00'
          AND sip_timestamp <  '2026-06-16 14:30:00'
        GROUP BY ticker
    )
SELECT
    q.ticker                              AS ticker,
    round(q.quote_messages / 1000, 1)     AS quote_messages_thousands,
    round(t.trades / 1000, 2)             AS trades_thousands,
    round(q.quote_messages / t.trades, 1) AS quotes_per_trade_ratio
FROM quote_load AS q
INNER JOIN trade_load AS t ON t.ticker = q.ticker
ORDER BY quotes_per_trade_ratio DESC
Run this yourself

SPY a généré le trafic de cotation le plus lourd par transaction, avec 9.6 messages pour chaque échange et 510 milliers de messages en trente minutes. L'écart entre les cinq valeurs est important : en bas du panneau, MSFT a enregistré 0.7 messages de cotation par transaction, soit moins d'un message par échange. Rappelez-vous ce que cette colonne compte : un niveau de prix par côté, sur un flux qui a déjà agrégé toutes les places boursières en une seule meilleure offre. Un produit de profondeur à dix niveaux multiplie ce chiffre, et un flux par ordre le multiplie encore, car chaque ordre derrière chaque niveau sur chaque place génère son propre ajout, ses propres modifications et ses propres annulations, qu'il soit exécuté ou non. Le même calcul s'applique à plus grande échelle dans la taille du flux de cotation des options.

De quel flux de carnet d'ordres une stratégie a-t-elle besoin ?

La plupart des travaux s'appuient sur le MBP-10. Les graphiques de profondeur, les indicateurs de déséquilibre, la mesure de la liquidité par prix, les modèles de coût d'exécution et presque toutes les questions de recherche sur la taille disponible à un niveau donné peuvent être résolus à partir de niveaux agrégés, pour une fraction du volume de messages.

Le MBO est requis lorsque la réponse dépend d'un ordre spécifique : position dans la file, durée de vie de l'ordre, comportement d'annulation, probabilité d'exécution passive au meilleur prix. Une stratégie qui dépend du fait d'être à 200 ou 20 000 actions dans la file ne peut pas fonctionner avec des données agrégées, et elle en paie le prix en frais de licence, en bande passante, en stockage et en ingénierie pour maintenir un carnet reconstruit fiable toute la journée.

Comment ces panneaux ont été construits
  • Le flux derrière chaque panneau est le sommet du carnet consolidé, un niveau de prix par côté, plus la bande de transactions. Il ne s'agit pas d'un flux de profondeur ni d'un flux par ordre ; ces panneaux illustrent donc l'argument du volume de messages plutôt que d'échantillonner le MBO lui-même.
  • Les fenêtres sont fixées à une date passée précise, de 10h00 à 10h30 ET le 16 juin 2026, stockées en 14h00 à 14h30 UTC. Les fenêtres fixes assurent la stabilité des chiffres lors des régénérations.
  • Le panneau de classification étiquette chaque message par rapport au précédent dans la séquence. Il ne peut pas distinguer une annulation d'une exécution, ce qui constitue la limite exacte décrite dans cet article.

FAQ

Quelle est la différence entre les données de marché MBO et MBP ?

Le MBP (Market By Price) agrège la taille affichée à chaque niveau de prix et envoie une mise à jour par niveau. Le MBO (Market By Order) envoie chaque ordre individuel avec son propre identifiant, ainsi que les événements d'ajout, de modification, d'annulation et d'exécution qui s'y rapportent.

Les données « Level 2 » sont-elles identiques aux données MBO ?

Généralement non. Le « Level 2 » chez un courtier de détail désigne presque toujours une profondeur agrégée, donc du MBP avec cinq à vingt niveaux de prix. Quelques fournisseurs commercialisent un flux par ordre sous le même nom de catégorie ; c'est donc le nom du schéma, et non celui de la catégorie, qui détermine ce qui arrive sur le terminal.

À quel point un flux MBO est-il plus volumineux qu'un flux MBP ?

De plusieurs ordres de grandeur, selon la place boursière et le symbole. Le sommet du carnet consolidé seul a atteint 9.6 messages par transaction pour la valeur la plus active du panneau ci-dessus. Un flux par ordre ajoute chaque ajout, modification et annulation derrière chaque niveau sur chaque place, incluant la grande majorité des ordres qui ne sont jamais exécutés.

Peut-on reconstruire un carnet MBP à partir de données MBO ?

Oui, et c'est le processus standard : appliquer chaque événement d'ordre à un carnet indexé par identifiant d'ordre, puis publier les totaux par niveau. L'inverse est impossible : une fois que les ordres sont sommés en un total par niveau, les identifiants individuels et leur ordre d'arrivée sont perdus.


Chaque panneau ici est accompagné du code SQL exact qui le génère. Pour compter les mêmes messages sur un symbole ou une session différente, posez la question en anglais simple sur le terminal Strasmore.