Skip to content

nickjohnsondls/matchingengine

Repository files navigation

MicroMatch - Solving Sub-Microsecond Market Data Jitter and A/B Feed Arbitrage

A C++ matching engine implementation that demonstrates how to handle the 500ΞΌs+ latency differences between redundant market data feeds and the 100x jitter spikes that occur during market volatility - problems that cost trading firms millions in missed opportunities.

🎯 The Specific Problem We're Solving

Real-world challenge: Major exchanges like Nasdaq and CME publish duplicate A/B feeds where:

  • Feed latency differences exceed 500ΞΌs (enough to lose every trade)
  • Jitter increases 100-1000x during volatility (50ΞΌs β†’ 50ms)
  • 17% of trades are now modified within 1 millisecond
  • Wrong feed selection negates millions in infrastructure investment

This project demonstrates practical solutions to these exact problems.

πŸ›  Tech Stack

Core Technologies

  • C++20 - Modern C++ for high-performance, zero-cost abstractions
  • CMake 3.20+ - Build system and dependency management
  • Conan 2.0 - C++ package manager for dependencies

Networking & Messaging

  • ASIO (standalone) - Asynchronous I/O for networking
  • ZeroMQ - High-performance messaging library
  • Protocol Buffers - Efficient binary serialization
  • tcpdump/libpcap - Packet capture for latency analysis

Data Structures & Algorithms

  • Intel TBB - Threading Building Blocks for parallel algorithms
  • Boost.Intrusive - Zero-allocation intrusive containers
  • SPSC/MPMC Queues - Lock-free queues for order flow

Monitoring & Metrics

  • Prometheus C++ Client - Metrics collection
  • Grafana - Real-time dashboards
  • spdlog - High-performance logging

Testing & Benchmarking

  • Google Test - Unit testing framework
  • Google Benchmark - Microbenchmarking
  • Catch2 - BDD-style testing

Development Tools

  • Docker - Containerization
  • docker-compose - Multi-container orchestration
  • Valgrind/Perf - Performance profiling
  • GDB - Debugging

πŸ“Š Performance Targets

Metric Target Stretch Goal
Order Processing Latency < 1 ΞΌs < 500 ns
Throughput 1M orders/sec 5M orders/sec
Market Data Distribution < 10 ΞΌs < 5 ΞΌs
Memory Usage < 1 GB < 500 MB
Jitter (99th percentile) < 100 ΞΌs < 10 ΞΌs

πŸ— Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Order Entry   │────▢│ Matching Engine │────▢│  Market Data    β”‚
β”‚    Gateway      β”‚     β”‚      Core       β”‚     β”‚  Distribution   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                       β”‚                        β”‚
         β”‚                       β”‚                        β”œβ”€β”€β–Ά Feed A (50ΞΌs base)
         β”‚                       β”‚                        β”‚
         β–Ό                       β–Ό                        └──▢ Feed B (150ΞΌs base)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚   Order Queue   β”‚     β”‚   Order Book    β”‚              β–Ό
β”‚   (Lock-free)   β”‚     β”‚  (Price-Time)   β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚ Arbitrage Detectorβ”‚
                                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”‘ What This Project Demonstrates

1. The Jitter Problem

  • Normal Market: 50-100ΞΌs latency with Β±10ΞΌs jitter
  • Volatility Spike: 1-10ms latency with Β±1ms jitter (100x increase!)
  • Implementation: Realistic jitter injection based on market conditions

2. A/B Feed Arbitrage

  • Problem: 500ΞΌs+ difference between "redundant" feeds
  • Solution: Dynamic feed selection with latency tracking
  • Measurement: Real-time arbitrage opportunity detection

3. Burst Handling

  • Challenge: 100x message rate spikes during announcements
  • Solution: Adaptive buffering without adding base latency
  • Demo: Configurable burst injection with performance monitoring

πŸš€ Quick Start

Prerequisites

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y \
    build-essential \
    cmake \
    ninja-build \
    libboost-all-dev \
    libzmq3-dev \
    protobuf-compiler \
    libprotobuf-dev \
    libtbb-dev

# Install Conan
pip install conan

Build and Run

# Clone repository
git clone https://github.com/yourusername/matchingengine.git
cd matchingengine

# Create build directory
mkdir build && cd build

# Configure with CMake
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..

# Build
ninja

# Run tests
ctest --output-on-failure

# Run the matching engine
./bin/matching_engine --symbols AAPL,GOOGL,MSFT --order-rate 1000000

Docker Setup

# Build and run with Docker Compose
docker-compose up --build

# Access monitoring dashboards
# Grafana: http://localhost:3000 (admin/admin)
# Prometheus: http://localhost:9090

πŸ“ Project Structure

matchingengine/
β”œβ”€β”€ CMakeLists.txt           # Root CMake configuration
β”œβ”€β”€ conanfile.txt            # Conan dependencies
β”œβ”€β”€ docker-compose.yml       # Container orchestration
β”œβ”€β”€ Dockerfile              # Container definition
β”œβ”€β”€ README.md              # This file
β”œβ”€β”€ benchmarks/            # Performance benchmarks
β”‚   β”œβ”€β”€ orderbook_bench.cpp
β”‚   └── latency_bench.cpp
β”œβ”€β”€ cmake/                 # CMake modules
β”‚   └── FindTBB.cmake
β”œβ”€β”€ config/               # Configuration files
β”‚   β”œβ”€β”€ prometheus.yml
β”‚   └── grafana/
β”œβ”€β”€ docs/                # Documentation
β”‚   β”œβ”€β”€ architecture.md
β”‚   └── performance.md
β”œβ”€β”€ include/             # Public headers
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ order.hpp
β”‚   β”‚   β”œβ”€β”€ orderbook.hpp
β”‚   β”‚   └── matching_engine.hpp
β”‚   β”œβ”€β”€ network/
β”‚   β”‚   β”œβ”€β”€ feed_handler.hpp
β”‚   β”‚   └── market_data.hpp
β”‚   └── utils/
β”‚       β”œβ”€β”€ lockfree_queue.hpp
β”‚       └── time_utils.hpp
β”œβ”€β”€ src/                # Implementation files
β”‚   β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ network/
β”‚   β”œβ”€β”€ monitoring/
β”‚   └── main.cpp
β”œβ”€β”€ tests/             # Unit tests
β”‚   β”œβ”€β”€ test_orderbook.cpp
β”‚   β”œβ”€β”€ test_latency.cpp
β”‚   └── test_feed_arbitrage.cpp
└── scripts/          # Utility scripts
    β”œβ”€β”€ generate_orders.py
    └── analyze_latency.py

πŸ“ˆ Real-World Performance Characteristics

Latency Breakdown (What Actually Happens)

Normal Conditions:
Order Receipt      β†’  Gateway:        50 ns  (Β±5 ns)
Gateway           β†’  Queue:          20 ns  (Β±2 ns)
Queue             β†’  Matching:       30 ns  (Β±3 ns)
Matching          β†’  Execution:     100 ns  (Β±10 ns)
Execution         β†’  Market Data:    50 ns  (Β±5 ns)
Market Data       β†’  Network:       200 ns  (Β±20 ns)
─────────────────────────────────────────────────
Total:                              450 ns  (Β±45 ns)

During Volatility (Fed Announcement):
Order Receipt      β†’  Gateway:       500 ns  (Β±200 ns)
Gateway           β†’  Queue:         200 ns  (Β±100 ns)
Queue             β†’  Matching:     5000 ns  (Β±2000 ns)
Matching          β†’  Execution:   10000 ns  (Β±5000 ns)
Execution         β†’  Market Data:  5000 ns  (Β±2000 ns)
Market Data       β†’  Network:     20000 ns  (Β±10000 ns)
─────────────────────────────────────────────────
Total:                           40700 ns  (Β±19300 ns)

A/B Feed Latency Arbitrage Example

12:00:00.000000 - Normal Trading
Feed A: 52ΞΌs latency (Β±8ΞΌs jitter)
Feed B: 148ΞΌs latency (Β±12ΞΌs jitter)
Arbitrage Window: 96ΞΌs

12:30:00.000000 - Economic Data Release
Feed A: 2,847ΞΌs latency (Β±892ΞΌs jitter)
Feed B: 156ΞΌs latency (Β±45ΞΌs jitter)
Arbitrage Window: 2,691ΞΌs (Feed B now faster!)

πŸ§ͺ Testing Strategy

Unit Tests

  • Order book correctness under concurrent access
  • Jitter injection validation
  • Feed arbitrage detection accuracy

Integration Tests

  • End-to-end latency measurement with hardware timestamps
  • A/B feed synchronization verification
  • Burst handling without packet loss

Performance Tests

  • Sustained 1M orders/second for 60 seconds
  • Latency percentiles during burst injection
  • Memory usage under extreme load

Chaos Tests

  • Random feed latency flips
  • Sudden 1000x jitter increase
  • Packet loss simulation

πŸŽ“ Key Insights from Real Trading Systems

From the Research

  • CME Finding: Internal latency varies 100x between products
  • Nasdaq Data: B-feed consistently 500ΞΌs+ behind A-feed
  • Industry Stats: 17% of DAX futures modified within 1ms (2024)

From the Field

  • "We lost $2M in one day from listening to the wrong feed" - Anonymous Trader
  • "Jitter prediction is worth more than raw speed" - HFT Developer
  • "Most firms don't even measure feed arbitrage" - Exchange Engineer

πŸ“„ License

MIT License - See LICENSE file for details

πŸ™ Acknowledgments

  • Inspired by real incidents at CME, Nasdaq, and Eurex
  • Based on techniques from Jane Street, Jump Trading, and Citadel
  • Data from Databento's analysis of exchange feed behavior

Note: This is a simplified educational implementation. Production trading systems require additional features like risk management, regulatory compliance, and fault tolerance.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages