BOOT_PORTFOLIO.BATv1.0

systems project // active development

Order Book [ Phase 05 // Cancellation & Order Lifecycle ]

I am building a correctness-first electronic limit order book in modern C++ because apparently my idea of a relaxing side project is asking, "what if a queue had opinions about fairness, latency, and the memory hierarchy?"

This is explicitly a current work in progress. It is not done, not polished, and not pretending to be a production exchange. The goal is to understand the infrastructure underneath modern markets: matching orders, preserving price-time priority, and designing data structures that do not make the CPU file a formal complaint.

As it grows, I am planning to add benchmarking, profiling, unit tests, market data feeds, replay tools, and progressively more performance-focused experiments. Less "hot stock tip," more "let me build the tiny engine room where the market plumbing lives."

C:\MARKET\LOB>matching_engine.exe

[DONE] define orders and price levels

[DONE] store bids and asks in price priority

[DONE] preserve FIFO within each price level

[DONE] index active orders by ID

[DONE] match by price-time priority across price levels

[DONE] execute at the resting (maker) price

[DONE] rest any remainder at its own limit

[ACTIVE] cancellation and the complete order lifecycle

[QUEUED] replay, benchmark, and profile (before bragging about speed)

awaiting next commit

SIM_DEPTHprice-time priority
BEST BID 101.24SPREAD 0.01BEST ASK 101.25
Bid SizeBidAskAsk Size
420 101.24 101.25 180
310 101.23 101.26 260
780 101.22 101.27 640
150 101.21 101.28 390
900 101.20 101.29 710
MATCHING ENGINE // WORKINGPHASE 04 // WORKED EXAMPLE

The engine now does the one thing an engine is contractually obligated to do: when a buyer and a seller agree on a price, it makes them trade. Here is one order walking into the book, start to finish.

BEFORE

WhoSidePriceQty
STOP Dee SELL101.28200
#3 Cam SELL101.26100
#2 Ben SELL101.2530
#1 Ana SELL101.2550
Eli BUY101.20100

Sellers on top, buyers below, best prices meet in the middle. Ana got in line before Ben.

AFTER

WhoSidePriceQty
Dee SELL101.28200
NEW You BUY101.2720
Eli BUY101.20100

180 bought, 20 still waiting. Ana, Ben, and Cam are done for the day.

INCOMING

FILLED 180 / 200

BUY 200 // PAY UP TO $101.27

  1. #1
    BUY 50 @ $101.25 from Ana

    Cheapest seller, and she got in line first. Fills completely.

  2. #2
    BUY 30 @ $101.25 from Ben

    Same price as Ana, but he showed up after her. At equal prices, whoever arrived first trades first.

  3. #3
    BUY 100 @ $101.26 from Cam

    $101.25 is cleaned out, so the engine moves one level up. Still under the $101.27 limit.

  4. STOP
    Dee wants $101.28

    One cent over the limit. 20 shares are still wanted, but nobody left is willing to sell at that price.

  5. REST
    BID 20 @ $101.27 joins the book

    The leftover waits at its original limit, not at $101.26 (the last price it traded at).

WHY YOU PAID $101.25 AND NOT $101.27

Trades happen at the price of the order that was already waiting. Ana posted "I'll sell at $101.25" and gets exactly that. Your $101.27 was a ceiling, not a target, so the difference stays with you. Nobody walks up to a $20 price tag at a garage sale and insists on paying $25.

In market terms, the order that was already waiting is the MAKERAn order that was already sitting on the book. It made a price available for someone else to take. Ana, Ben, and Cam were the makers here. (it made the price available) and the order that shows up and trades against it is the TAKERThe order that shows up and trades right away against what is already waiting. Your buy order was the taker. Real exchanges often charge takers higher fees than makers, as a small tax on impatience.. The trade always happens at the maker's price. Across the three fills here, that works out to $2.60 saved. Please do not spend it all in one place.

SOURCE AVAILABLEGITHUB_REMOTE

Browse the C++ implementation, tests, benchmarks, and build setup.

[ OPEN GITHUB REPOSITORY ]