Skip to content

timothim/matching-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Low-Latency Limit Order Book & Matching Engine

A high-performance trading engine featuring a C++20 matching engine core, Python FastAPI gateway, and React/Next.js frontend. Implements price-time priority matching with fixed-point arithmetic and sub-10μs order processing latency.

C++20 Python Next.js TypeScript License


Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                              Frontend                                   │
│                        Next.js 14 + TypeScript                         │
│                                                                         │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  │
│   │  OrderBook  │  │ DepthChart  │  │  OrderForm  │  │TradeHistory │  │
│   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘  │
│          └────────────────┴────────┬───────┴────────────────┘          │
│                                    │                                    │
│                        WebSocket / Simulation                           │
└────────────────────────────────────┼────────────────────────────────────┘
                                     │
┌────────────────────────────────────┼────────────────────────────────────┐
│                              Gateway                                    │
│                         Python + FastAPI                                │
│                                                                         │
│   ┌──────────────┐    ┌───────────────┐    ┌───────────────────────┐   │
│   │  REST API    │    │  WebSocket    │    │  Connection Manager   │   │
│   │  /orders     │    │  Broadcast    │    │  (Multi-client)       │   │
│   └──────┬───────┘    └───────┬───────┘    └───────────┬───────────┘   │
│          └────────────────────┼────────────────────────┘               │
│                               │                                         │
│                          pybind11                                       │
└───────────────────────────────┼─────────────────────────────────────────┘
                                │
┌───────────────────────────────┼─────────────────────────────────────────┐
│                         Core Engine                                     │
│                          C++20                                          │
│                                                                         │
│   ┌─────────────────┐   ┌─────────────────┐   ┌─────────────────────┐ │
│   │ MatchingEngine  │──▶│   OrderBook     │──▶│    ObjectPool       │ │
│   │ (Price-Time     │   │ (std::map +     │   │ (Zero-alloc hot     │ │
│   │  Priority)      │   │  std::deque)    │   │  path, 100K pool)   │ │
│   └─────────────────┘   └─────────────────┘   └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘

Features

Core Engine (C++20)

  • Price-Time Priority Matching — Orders matched by best price first, then by arrival time (FIFO)
  • O(log N) Operations — Red-black tree (std::map) for price levels, O(1) queue operations within levels
  • Zero-Allocation Hot Path — Pre-allocated object pool (100,000 orders) eliminates heap allocations during matching
  • Fixed-Point Arithmetic — Integer prices (1 unit = $0.01) eliminate floating-point errors entirely
  • Sub-10μs Latency — Benchmarked at <10 microseconds per order on standard hardware

Gateway (Python + FastAPI)

  • Native C++ Bindings — pybind11 for near-native matching performance
  • Python Fallback — Pure Python mock engine when C++ isn't compiled (cross-platform)
  • Real-time WebSocket — Full-duplex broadcast of trades and book updates to all connected clients
  • RESTful API — Standard HTTP endpoints for order submission, cancellation, and book queries
  • Async Architecture — FastAPI with asyncio for high concurrency

Frontend (Next.js + TypeScript)

  • Dual Environment Mode — Simulation mode with synthetic market data, or Live mode connected to the real backend
  • Real-time Order Book — Live bid/ask display with depth visualization bars
  • Canvas Depth Chart — GPU-accelerated market depth rendering with gradient fills
  • Order Feedback — Detailed result banners showing fills, partial fills, and resting orders
  • Zustand State Management — Efficient state updates without unnecessary re-renders

Simulation Mode

The frontend includes a built-in simulation engine that generates realistic market activity without requiring the backend:

  • Dynamic order book with 15 bid/ask price levels
  • Random price drift, quantity fluctuations, and simulated trades
  • Full order matching — place limit/market buy/sell orders and see them execute against the simulated book
  • Instant feedback with trade details, average fill prices, and remaining quantities

Quick Start

Prerequisites

  • C++ Engine: GCC 11+ / Clang 14+ / MSVC 2022+, CMake 3.18+
  • Gateway: Python 3.10+
  • Frontend: Node.js 18+

Option 1: Docker

git clone <repo-url>
cd matching-engine

cd docker
docker-compose up --build

# Frontend: http://localhost:3000
# API:      http://localhost:8000
# Docs:     http://localhost:8000/docs

Option 2: Local Development

1. Build the C++ Engine

cd cpp_core
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

# Run unit tests
./trading_engine_tests

If the C++ build fails (e.g. toolchain issues on macOS), the gateway will automatically fall back to the Python mock engine.

2. Start the Gateway

cd gateway
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -r requirements.txt

uvicorn main:app --reload --host 0.0.0.0 --port 8000

3. Start the Frontend

cd frontend
npm install
npm run dev

Open http://localhost:3000. Switch between Simulation and Live API modes from the environment selector.

API Reference

REST Endpoints

Method Endpoint Description
POST /orders Submit a new order
DELETE /orders/{id} Cancel an order
GET /orders/{id} Get order details
GET /orderbook?depth=20 Get order book snapshot
GET /stats Engine statistics
GET /health Health check
POST /reset Reset the engine

Submit Order Example

curl -X POST http://localhost:8000/orders \
  -H "Content-Type: application/json" \
  -d '{
    "side": "buy",
    "type": "limit",
    "price": 10050,
    "quantity": 100
  }'
{
  "order_id": 1,
  "status": "new",
  "resting": true,
  "trades": [],
  "updates": [...]
}

WebSocket

Connect to ws://localhost:8000/ws for real-time market data.

Server broadcasts:

{ "type": "book_update", "data": { "bids": [[10050, 100]], "asks": [[10060, 150]] } }
{ "type": "trade", "data": { "price": 10050, "quantity": 50, "taker_side": "buy" } }

Client messages:

{ "type": "submit_order", "data": { "side": "buy", "type": "limit", "price": 10050, "quantity": 100 } }
{ "type": "cancel_order", "data": { "order_id": 1 } }

Technical Deep Dive

Order Book Data Structure

// Bids sorted by highest price first (buy side wants maximum)
std::map<Price, std::deque<Order*>, std::greater<Price>> bids_;

// Asks sorted by lowest price first (sell side wants minimum)
std::map<Price, std::deque<Order*>, std::less<Price>> asks_;

// O(1) order lookup by ID for cancellations
std::unordered_map<OrderId, Order*> orders_;

Matching Algorithm

Incoming BUY @ price P:
  WHILE best_ask ≤ P AND remaining_qty > 0:
    MATCH against oldest order at best_ask (FIFO)
    EMIT Trade { maker, taker, price, quantity }
  IF remaining_qty > 0:
    INSERT into bids at price P

Incoming SELL @ price P:
  WHILE best_bid ≥ P AND remaining_qty > 0:
    MATCH against oldest order at best_bid (FIFO)
    EMIT Trade { maker, taker, price, quantity }
  IF remaining_qty > 0:
    INSERT into asks at price P

Market orders: same logic, but skip the price check (match at any price).

Memory Management

ObjectPool<Order> pool_(100'000);  // Pre-allocate at startup

Order* order = pool_.allocate();   // O(1) — no malloc
pool_.deallocate(order);           // O(1) — return to free list

Zero heap allocations on the hot path prevents latency spikes from memory allocation and GC pressure.

Fixed-Point Pricing

All prices are stored as integers in cents: $100.50 → 10050. This eliminates IEEE 754 floating-point rounding errors that cause real issues in financial systems (e.g. 0.1 + 0.2 ≠ 0.3).

using Price = int64_t;
constexpr int64_t PRICE_MULTIPLIER = 100;  // 2 decimal places

Benchmarks

cd benchmarks
python benchmark.py
Benchmark Orders Avg Latency P99 Latency Throughput
Standard (1M orders) 1,000,000 3.2 μs 8.5 μs 312,500/sec
Heavy Matching 500,000 4.1 μs 11.2 μs 243,902/sec
Market Orders (50%) 500,000 2.8 μs 7.3 μs 357,143/sec

Measured on Apple M1 Pro. Results vary by hardware.

Project Structure

matching-engine/
├── cpp_core/                    # C++20 matching engine
│   ├── CMakeLists.txt
│   ├── include/
│   │   ├── types.hpp            # Price, Quantity, OrderId, Side, OrderType
│   │   ├── order.hpp            # Order struct, Trade struct, MatchResult
│   │   ├── order_book.hpp       # Bid/ask book with std::map + std::deque
│   │   ├── matching_engine.hpp  # Top-level engine interface
│   │   └── object_pool.hpp      # Lock-free memory pool (100K pre-alloc)
│   ├── src/
│   │   ├── order_book.cpp
│   │   └── matching_engine.cpp
│   ├── bindings/
│   │   └── python_bindings.cpp  # pybind11 → Python interop
│   └── tests/
│       └── test_matching.cpp    # Google Test suite
│
├── gateway/                     # Python FastAPI server
│   ├── main.py                  # REST + WebSocket endpoints
│   ├── models.py                # Pydantic request/response models
│   ├── connection_manager.py    # WebSocket client management
│   ├── mock_engine.py           # Pure Python engine fallback
│   └── requirements.txt
│
├── frontend/                    # Next.js 14 React app
│   ├── src/
│   │   ├── app/
│   │   │   ├── page.tsx         # Main dashboard with environment selector
│   │   │   ├── layout.tsx
│   │   │   └── globals.css
│   │   ├── components/
│   │   │   ├── OrderBook/       # Real-time bid/ask depth display
│   │   │   ├── DepthChart/      # Canvas-based depth visualization
│   │   │   ├── OrderForm/       # Buy/sell form with result feedback
│   │   │   ├── TradeHistory/    # Live trade feed
│   │   │   └── MarketStats/     # Price, spread, volume stats
│   │   ├── hooks/
│   │   │   └── useWebSocket.ts  # Dual-mode: simulation + live WebSocket
│   │   ├── lib/
│   │   │   ├── api.ts           # REST API client
│   │   │   ├── simulation.ts    # Client-side simulation engine
│   │   │   └── utils.ts         # Formatting utilities
│   │   ├── store/
│   │   │   └── useMarketStore.ts # Zustand state (order book, trades, env)
│   │   └── types/
│   │       └── index.ts         # Shared TypeScript types
│   └── package.json
│
├── benchmarks/
│   └── benchmark.py             # 1M order throughput & latency tests
│
├── docker/
│   ├── Dockerfile.engine        # Multi-stage: build C++ → Python runtime
│   ├── Dockerfile.frontend      # Build Next.js → serve with nginx
│   └── docker-compose.yml       # Full stack orchestration
│
├── docs/
│   └── DEPLOYMENT.md            # Deployment guide (Vercel + Railway)
│
├── .gitignore
├── LICENSE                      # MIT
└── README.md

Deployment

See docs/DEPLOYMENT.md for detailed deployment instructions using Vercel (frontend) and Railway (backend).

License

MIT — see LICENSE.

About

High-performance trading engine with C++20 matching core (<10μs latency), Python FastAPI gateway, and React frontend. Features price-time priority matching, zero-allocation hot path, and real-time WebSocket updates.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors