Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PMR Market Simulator (C++17)

C++17 License Platform Build Arena Performance Storage Export

Plain-language summary (please read first)

This repository is a personal, non-commercial systems/performance engineering project. It implements a deterministic, event-driven simulator with a limit-order-book data structure so I can learn and benchmark:

  • cache locality, memory allocation patterns (std::pmr), and hot-path design
  • determinism/replay (seeded PRNG + replayable event streams)
  • correctness invariants for a non-trivial state machine under load

It is NOT a trading system.

  • No live trading: no order routing, no broker/exchange connectivity
  • No live market feeds: no live exchange connectivity; no proprietary/paid data feeds
  • No strategies/signals: does not implement alpha, execution logic, or investment advice
  • No proprietary employer resources: built on personal time/equipment; not affiliated with any employer
  • Synthetic data: default simulation uses generated events and synthetic prices (e.g., around a baseline mid such as $100)

If you’re here to evaluate engineering work: thank you. This repo is intended to be unambiguous about scope and usage so it’s easy to review and understand.


A high-performance, allocator-aware event simulator with per-symbol arenas, CPU pinning, and a fast per-symbol limit order book implementation. Designed for repeatable benchmarking, correctness, and maintainable hot-path code.

Current performance (Windows / MSVC / Ryzen 7 5800X, 6 pinned threads):

  • Best: 42.4M events/sec
  • Avg: 41.2M events/sec
    (6 symbols, 2,000,000 events, sigma=0.001, 1 MiB arena per symbol, --no-log)

Results vary by CPU, compiler, and flags. Logging / I/O will reduce throughput drastically.


What’s in here

  • Limit Order Book (LOB)

    • Strict price-time priority
    • Internal tick-based prices (int32_t tick) for determinism and speed
    • Flat hash price levels + pooled level reuse (avoids std::map<double> pointer chasing)
    • Cancel index maintained for correctness (filled resting orders removed from index)
  • Simulation Engine

    • Multi-threaded event generation and application (one symbol per thread by default)
    • Deterministic ID + timestamp generation in benchmark mode (no realtime clock in hot loop)
  • Performance / Memory

    • Per-symbol std::pmr::monotonic_buffer_resource arenas
    • CPU pinning support (best-effort on Windows/Linux)
    • Bounded SPSC ring buffer implementation + unit tests (building block for future pipelining)
  • Persistence / Export (optional)

    • LMDB-backed persistence + replay mode
    • Optional Protobuf/gRPC export for local observability/visualization
      • Off by default
      • Intended for telemetry/inspection, not for production pipelines
      • Recommended in single-thread mode unless otherwise stated in docs

Repo layout (high level)

  • include/msim/
    • order_book.hpp — core order book API + structures
    • flat_hash.hpp — fixed-capacity flat hash with tombstone compaction
    • spsc_ring.hpp — bounded SPSC ring buffer
    • simulator.hpp — simulation engine interface
  • src/
    • order_book.cpp — LOB implementation
    • simulator.cpp / main.cpp — harness + CLI
    • storage/ — LMDB + optional export plumbing (not required for benchmark mode)
  • tests/
    • spsc_ring_test.cpp
    • order_book_test.cpp
  • scripts/
    • bench.sh — repeatable benchmark runner (multi-config MSVC aware)

Build

Windows (Visual Studio 2022 / MSVC)

cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DMSIM_WITH_GRPC=OFF -DMSIM_BUILD_TESTS=ON
cmake --build build --config Release -j
ctest --test-dir build -C Release --output-on-failure

Linux / single-config generators (example)

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DMSIM_WITH_GRPC=OFF -DMSIM_BUILD_TESTS=ON
cmake --build build -j
ctest --test-dir build --output-on-failure

Benchmark (recommended)

Use the included script (handles MSVC multi-config correctly and runs multiple reps):

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DMSIM_WITH_GRPC=OFF -DMSIM_BUILD_TESTS=ON
cmake --build build -j
ctest --test-dir build --output-on-failure

# then:
scripts/bench.sh

Default config (override via env):

  • SYMBOLS=SYM1,SYM2,SYM3,SYM4,SYM5,SYM6
  • EVENTS=2000000
  • THREADS=6
  • SIGMA=0.001
  • ARENA_BYTES=1048576
  • REPS=5

Example override:

THREADS=1 EVENTS=3000000 REPS=3 scripts/bench.sh

Note: Symbols are placeholders for per-instrument workloads; they are not intended to imply usage of any real security or dataset.

Latest benchmark numbers

Best: 42,404,684 ev/s
Avg: 41,163,937 ev/s

(Windows 11, MSVC 19.44, Ryzen 7 5800X, 6 pinned threads, --no-log)


CLI (common flags)

Flag Meaning Default
--events N total simulated iterations/events 100000
--symbols CSV comma-separated symbol identifiers SYM1,SYM2,SYM3
--threads N worker threads (typically = symbols) auto
--sigma X gaussian sigma (fraction of mid) 0.001
--arena-bytes BYTES arena size per symbol 1048576
--no-log disable persistence entirely off
--log PATH persist to LMDB off
--read PATH replay from LMDB off
--dump N when reading, print first N per symbol off
--print-arena show allocator telemetry off
--grpc HOST:PORT export events to collector off

Benchmarking tip: always use --no-log unless you're explicitly measuring persistence/export.


Why it's fast (short version)

  • Tick-based prices avoid floating-key ordering issues and enable tight hashing.
  • Flat hash maps + pooling reduce allocations and pointer chasing vs. trees.
  • Tombstone compaction keeps open-addressing delete-heavy workloads stable.
  • Benchmark harness avoids:
    • contended global atomics in hot loops
    • realtime clock calls per event
    • string hashing/lookup per event

More docs

  • docs/architecture.md — core architecture + invariants (LOB / harness / arenas)
  • docs/export.md — optional export path (e.g., gRPC/Protobuf), batching, and expected overhead
  • docs/persistence.md — LMDB log format + replay mode

Disclaimer (explicit)

This is a personal, non-commercial performance engineering project for educational purposes. It is not used for live trading, does not connect to brokers/exchanges, does not ingest proprietary or paid market data, and does not implement trading strategies, signals, or investment advice. Built on personal time/equipment; not affiliated with or endorsed by any employer.

About

High-performance C++17 market simulator with NUMA-aware PMR arenas, zero-allocation order books, LMDB persistence, and real-time gRPC streaming.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages