Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Concurrent Matching Engine

A multi-threaded limit-order matching engine in C++20, built as a Unix-socket client/server. Multiple clients connect concurrently and submit buy/sell/cancel orders; the engine matches them against a per-instrument order book using price-time priority.

Features

  • Price-time priority matching — orders are matched at the best available price first, and by arrival time within the same price level.

  • Fine-grained locking — rather than a single global lock on the whole book, the engine uses a layered locking scheme:

    • a shared_mutex per instrument book (readers can match concurrently; writers get exclusive access when resting a new order),
    • a shared_mutex per side (buy/sell) of the book,
    • a mutex per price level,
    • a mutex per individual order.

    This lets unrelated instruments, and even unrelated price levels within the same instrument, be touched by different threads at the same time.

  • Lazy cancellation — cancelling an order just flags it (cancelled = true); it's removed from the book the next time it's encountered during matching, avoiding an expensive in-place list removal on the cancel path.

  • One thread per client connection, detached and independent, reading commands off a Unix domain socket.

Building

make

This produces two binaries:

  • engine — the matching engine server
  • client — a simple CLI client that reads commands from stdin and forwards them over a Unix socket

Requires clang/clang++ with C++20 support (see the Makefile for flags).

Running

Start the engine, giving it a path for the Unix domain socket:

./engine /tmp/exchange.sock

In another terminal, connect a client and feed it commands:

./client /tmp/exchange.sock < commands.txt

Command format

Each line is one command:

Command Format Example
Buy B <order_id> <instrument> <price> <count> B 125 GOOG 2705 30
Sell S <order_id> <instrument> <price> <count> S 126 GOOG 2705 30
Cancel C <order_id> C 125

Lines starting with # and blank lines are ignored.

Output format

The engine prints one line per event to stdout:

Event Format
Order resting on the book B/S <order_id> <instrument> <price> <count> <timestamp>
Order executed (fill) E <resting_id> <new_id> <exec_id> <price> <count> <timestamp>
Order cancelled/rejected X <order_id> A/R <timestamp>

Design notes / known limitations

  • Locks are always acquired in a consistent order (book → side → price level → order) to avoid deadlock.
  • Matching happens under a shared lock on the book, so multiple orders can be matched concurrently; only resting a new order (when it isn't fully filled) requires the exclusive book lock.
  • This is a learning/portfolio project, not a production trading system — there's no persistence, no risk checks, and no networked (TCP) transport.

About

Multi-threaded limit-order matching engine in C++20 with fine-grained (per-instrument, per-side, per-price-level, per-order) locking and price-time priority matching over Unix sockets

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages