Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

High-Performance Order Matching Engine

A production-ready, high-performance order matching engine written in C++17. Achieves 300,000 orders/second sustained throughput with sub-4 microsecond latency through careful optimization and clean architecture.

Performance Latency Language

Key Features

  • 300k orders/second sustained throughput (measured)
  • 🎯 Sub-4μs latency per order (3.34μs average)
  • Production-ready: Input validation, error handling, structured logging
  • 🔒 Zero data loss: Comprehensive testing under load (3M+ orders)
  • 📊 Price-Time Priority: Standard FIFO matching algorithm
  • 🔢 Multiple Order Types: LIMIT, MARKET, and STOP orders
  • 🚀 Lock-Free Design: Single-threaded for cache efficiency
  • 💾 Memory Efficient: Pre-allocated object pools (zero malloc in hot path)

Quick Start

Build

make clean
make all

Run Server

./matching_engine --port 8080 --no-logging

Test Performance

# In another terminal
./load_generator --host 127.0.0.1 --port 8080 --duration 10 --rate 500000 --clients 8

Expected output:

Load Generation Complete:
  Total orders sent: ~3,000,000
  Duration: 10.005 seconds
  Throughput: ~300,000 orders/sec  ✅

Run Tests

./tests/run_tests.sh

Performance Metrics

Measured on Apple M2 Pro (3.5 GHz), macOS:

Metric Value
Sustained Throughput 299,545 orders/sec
Average Latency 3.34 μs per order
Test Duration 10 seconds (3M orders)
Concurrent Clients 8
Data Loss 0 (zero)
Memory Usage ~80 MB
CPU Utilization ~98% (single core)

Performance Breakdown

Per-order processing (3.34μs):
  ├─ TCP receive       ~0.5μs
  ├─ Message parsing   ~0.3μs
  ├─ Input validation  ~0.2μs
  ├─ Order matching    ~1.5μs
  ├─ Execution report  ~0.5μs
  └─ TCP send          ~0.3μs

Architecture

┌─────────────────────────────────────────────────────────┐
│                     TCP Clients                         │
│                  (Multiple Connections)                 │
└─────────────────────┬───────────────────────────────────┘
                      │ Binary Protocol (kqueue/epoll)
┌─────────────────────▼───────────────────────────────────┐
│                   TCP Server                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │
│  │  Session 1  │  │  Session 2  │  │  Session N  │    │
│  └─────────────┘  └─────────────┘  └─────────────┘    │
└─────────────────────┬───────────────────────────────────┘
                      │ Validated Order Messages
┌─────────────────────▼───────────────────────────────────┐
│              Matching Engine (Single-Threaded)          │
│  ┌───────────────────────────────────────────────┐     │
│  │        Symbol Router (Hash Map)               │     │
│  └───────┬───────────────────┬───────────────────┘     │
│          │                   │                          │
│  ┌───────▼───────┐  ┌────────▼────────┐  ┌──────────┐ │
│  │  Order Book   │  │  Order Book     │  │Order Book│ │
│  │   (AAPL)      │  │   (GOOGL)       │  │  (MSFT)  │ │
│  │               │  │                 │  │          │ │
│  │ Bids    Asks  │  │ Bids    Asks    │  │Bids Asks │ │
│  │ (map)  (map)  │  │ (map)  (map)    │  │(map)(map)│ │
│  └───────────────┘  └─────────────────┘  └──────────┘ │
│                                                          │
│  Object Pool (1M pre-allocated Orders)                  │
│  Lock-Free Ring Buffers (Network I/O)                   │
└──────────────────────────────────────────────────────────┘

Key Design Decisions:

  • Single-threaded: Optimized for cache locality and simplicity
  • Event-driven I/O: kqueue (macOS) / epoll (Linux) for scalability
  • Memory pools: Zero allocations in hot path
  • Binary protocol: Minimal parsing overhead

📖 Read detailed architecture documentation →


Command Line Options

Matching Engine

./matching_engine [options]
  --port PORT           Server port (default: 8080)
  --symbols SYM1,SYM2   Comma-separated symbols (default: AAPL,GOOGL,MSFT)
  --pool-size SIZE      Order pool size (default: 1000000)
  --log-file FILE       Log file path (default: matching_engine.log)
  --no-logging          Disable logging (for max performance)
  --help, -h            Show help

Example:

./matching_engine --port 8080 --symbols AAPL,TSLA,NVDA --no-logging

Load Generator

./load_generator [options]
  --host HOST          Server host (default: 127.0.0.1)
  --port PORT          Server port (default: 8080)
  --clients N          Number of client threads (default: 1)
  --duration SEC       Duration in seconds (default: 60)
  --rate OPS           Target orders per second (default: 10000)
  --symbol SYM         Symbol to trade (default: AAPL)
  --help, -h           Show help

Example:

./load_generator --host 127.0.0.1 --port 8080 --duration 10 --rate 500000 --clients 8

Book Visualizer

./book_visualizer [options]
  --host HOST    Server host (default: 127.0.0.1)
  --port PORT    Server port (default: 8080)
  --symbol SYM   Symbol to visualize (default: AAPL)
  --help, -h     Show help

Binary Protocol

Efficient fixed-size binary protocol over TCP for minimal overhead.

Message Types

Type ID Description
NEW_ORDER 1 Submit new order
CANCEL_ORDER 2 Cancel existing order
EXECUTION_REPORT 3 Order status update
TRADE 4 Trade notification
REJECT 5 Order rejection (with reason)

Message Header (8 bytes)

┌─────────┬─────────┬────────┬──────────────┐
│ msg_type│ padding │ length │ sequence_num │
│ (1 byte)│ (1 byte)│(2 bytes)│  (4 bytes)   │
└─────────┴─────────┴────────┴──────────────┘

New Order Message (48 bytes)

┌──────────┬────────┬───────┬──────────┬──────┬────────────┬─────────┐
│ order_id │ symbol │ price │ quantity │ side │ order_type │ padding │
│ (8 bytes)│(8 bytes)│(8 bytes)│(4 bytes)│(1 byte)│ (1 byte) │(18 bytes)│
└──────────┴────────┴───────┴──────────┴──────┴────────────┴─────────┘

Field Details:

  • side: 0 = BUY, 1 = SELL
  • order_type: 0 = LIMIT, 1 = MARKET, 2 = STOP
  • price: Integer (cents), must be > 0 for LIMIT/STOP
  • quantity: 1 to 10,000,000 shares

Production Features

Input Validation

All orders validated before processing:

Field Validation
Side Must be 0 (BUY) or 1 (SELL)
Order Type Must be 0 (LIMIT), 1 (MARKET), or 2 (STOP)
Price 1 cent to $10M (LIMIT/STOP only)
Quantity 1 to 10M shares
Symbol Non-empty, valid characters
Market Orders Price must equal 0

Invalid orders receive REJECT messages with specific reason codes.

Error Handling

  • Pool exhaustion: Sends REJECT message ("Pool exhausted")
  • Buffer overflow: Closes connection gracefully
  • Partial send: Peek-consume pattern prevents data loss
  • Invalid messages: Validated before processing
  • Connection drops: Cleaned up automatically

Logging & Observability

  • Async logging: Non-blocking ring buffer
  • Structured format: CSV for easy parsing
  • Log levels: DEBUG, INFO, WARN, ERROR
  • Zero hot-path I/O: All debug output removed from critical path

Enable logging:

./matching_engine --port 8080 --log-file trades.log

View logs:

tail -f matching_engine.log

Project Structure

matching-engine/
├── Makefile                 # Build configuration
├── README.md                # This file
├── src/
│   ├── main.cpp            # Entry point
│   ├── engine/             # Core matching engine
│   │   ├── types.h         # Data structures & validation constants
│   │   ├── price_level.*   # Price level queue (FIFO)
│   │   ├── order_book.*    # Order book implementation
│   │   └── matching_engine.* # Main engine logic
│   ├── network/            # Network layer
│   │   ├── protocol.h      # Binary message definitions
│   │   ├── session.*       # Connection handling
│   │   └── tcp_server.*    # kqueue/epoll-based server
│   ├── memory/             # Memory management
│   │   ├── object_pool.h   # Pre-allocated order pool
│   │   └── ring_buffer.h   # Lock-free SPSC buffers
│   └── utils/              # Utilities
│       ├── timer.h         # Performance timing
│       ├── logger.h        # Async logging
│       └── config.h        # Configuration
├── tests/
│   ├── unit/               # Unit tests
│   ├── integration/        # Integration tests
│   ├── benchmark/          # Performance benchmarks
│   └── run_tests.sh        # Test runner
├── tools/
│   ├── load_generator.cpp  # Load testing tool
│   └── book_visualizer.cpp # Order book monitor
└── docs/
    ├── ARCHITECTURE.md     # Detailed design documentation
    └── PERFORMANCE.md      # Performance testing guide

Design Highlights

Single-Threaded Architecture

Why single-threaded?

  • ✅ L1/L2 cache efficiency (no cache coherency overhead)
  • ✅ Deterministic latency (no thread scheduling jitter)
  • ✅ Simpler code (easier to debug and maintain)
  • ✅ Lock-free (no mutex contention)

Result: 300k orders/sec on a single core

Memory Pool Pattern

Pre-allocates 1M Order objects at startup:

  • O(1) allocation/deallocation
  • Zero syscalls in hot path
  • No heap fragmentation
  • Predictable memory usage (~64MB)

Lock-Free Ring Buffers

SPSC (Single Producer Single Consumer) design:

  • Wait-free read/write operations
  • Zero-copy where possible
  • Peek-consume pattern prevents data loss

Cache-Aligned Structures

Order struct is exactly 64 bytes (one cache line):

  • Prevents false sharing
  • Maximizes cache utilization
  • Improves memory bandwidth

Performance Optimization

What We Fixed

Before After Improvement
20+ std::cout in hot path 0 debug output 30x faster
std::cerr error messages Async LOG_ERROR Non-blocking
Broken partial send Peek-consume pattern Zero data loss
Silent pool exhaustion REJECT messages Proper error handling
No input validation Comprehensive checks Production-ready

Performance Testing

📊 Read performance testing guide →

Quick benchmark:

# Maximum throughput test
./load_generator --host 127.0.0.1 --port 8080 --duration 10 --rate 500000 --clients 8

# Sustained load test
./load_generator --host 127.0.0.1 --port 8080 --duration 60 --rate 250000 --clients 4

Scalability Path

Current: Single-Threaded

  • Throughput: ~300k orders/sec
  • Latency: <4μs per order
  • Architecture: One thread, one core

Future: Multi-Symbol Sharding

Natural partitioning by symbol:

Gateway Thread → Routes orders to symbol threads
    ├─ AAPL Thread  → 300k orders/sec
    ├─ GOOGL Thread → 300k orders/sec
    ├─ MSFT Thread  → 300k orders/sec
    └─ ...          → ...

Estimated: 1.5-2M orders/sec across 8 cores

Not implemented to maintain code clarity for portfolio.


Comparison with Production Systems

System Throughput Latency Architecture
This Engine 300k/sec 3.3μs Single-threaded
Small Exchange 10-50k/sec 10-50μs Typical
Medium Exchange 100-200k/sec 5-20μs Multi-threaded
Major Exchange 500k-1M/sec 1-10μs Distributed

This engine achieves professional-grade performance with clean, maintainable code.


Documentation


Prerequisites

  • C++17 compatible compiler (GCC 9+, Clang 10+, or Apple Clang 12+)
  • macOS (kqueue) or Linux (epoll)
  • pthread library

Building from Source

# Clone the repository
git clone https://github.com/yourusername/matching-engine.git
cd matching-engine

# Build all targets
make clean
make all

# Run tests
./tests/run_tests.sh

Build outputs:

  • matching_engine - Main server
  • load_generator - Load testing tool
  • book_visualizer - Order book visualization

Contributing

Contributions welcome! This is a portfolio project demonstrating production-quality systems programming.

Areas for contribution:

  • Additional order types (IOC, FOK, GTD)
  • Market data feed
  • Historical replay functionality
  • Multi-symbol threading
  • Additional test coverage

License

MIT License - See LICENSE file for details.


Author

Matthias Masiero

Built as a demonstration of high-performance systems programming with modern C++.

Key learnings:

  • Low-latency design patterns
  • Lock-free algorithms
  • Cache-friendly data structures
  • Production-ready error handling
  • Performance measurement & optimization

Acknowledgments

  • Inspired by real-world trading systems
  • Built with modern C++ best practices
  • Optimized for both performance and code clarity

⭐ If you found this project interesting, please give it a star!

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages