Overview
I built a C++ trading simulator that focuses on **systems fundamentals**: an in-memory order book, a deterministic matching engine,
and fast data structures for price levels and orders. The simulator matches limit/market orders using price/time priority, emits trade
events, updates positions and realized/unrealized P/L, and persists sessions to disk for replay and analysis.
Goals
- Implement a correct, deterministic **matching engine** with price/time priority.
- Maintain **portfolio & P/L** with fills, partial fills, and cancels.
- Provide repeatable runs via **session persistence** and replay.
My Role
- Core engine design (order book, matcher, events, risk checks).
- Performance profiling & concurrency experiments (read/write separation).
- CLI tools, file formats, and unit/integration tests.
Architecture
- Engine Core: Order, OrderId, Side, PriceLevel, OrderBook, MatchingEngine, Trade.
- Order Book: Two maps keyed by price (bids: descending, asks: ascending) → each price level holds a FIFO queue of orders for time priority.
- Matching: New order crosses the spread → generate trades; support **market/limit**, partial fills, and cancels/amends.
- Portfolio: Per-symbol position, VWAP, realized P/L, mark-to-market unrealized P/L (with last trade price).
- Persistence: Append-only binary or CSV log for orders/trades; snapshot of book state for fast restart; replay utility.
- Risk (basic): Max order size, daily loss limit, and reject list; hooks for pre-trade checks.
- Interfaces: CLI commands (
NEW, CXL, AMEND, BOOK, POS, PnL). Optional lightweight HTTP status endpoint via a small embedded server.
- Testing: Unit tests for book operations and matching corner cases (cross/partial, same-price FIFO, cancels at head/tail).
Highlights
Deterministic Matching
Strict price/time priority with FIFO queues per price level — predictable and testable outcomes.
Fast Data Structures
Ordered maps for price levels + intrusive IDs for O(1) cancel/replace within a level.
Replayable Sessions
Append-only logs and snapshots enable run replay, debugging, and profiling on real market-style feeds.
What I Learned
- Designing matching engines and the trade-offs between simplicity and throughput.
- When to use ordered maps vs hash maps for hot paths and why cache locality matters.
- Building testable C++ modules with clear invariants and reproducible runs.
Next Steps
- Add **GTC/IOC/FOK** time-in-force and stop/stop-limit order types.
- Introduce **multithreaded** ingestion (SPSC queues) with a single-threaded matcher for determinism.
- Web dashboard for live book depth and trade tape (consume status endpoint).