Alt text

From Fascination to Code

I’ve always been fascinated by the stock market — not just the graphs and tickers, but the invisible machinery underneath. How do prices move? What determines whether an order gets filled? And how do systems that process billions of dollars every day stay reliable, precise, and fast?

This curiosity led me deep into the world of electronic trading and high-frequency trading (HFT). I started watching videos and reading articles about how firms operate at microsecond (or even nanosecond) latencies, squeezing tiny profits out of large volumes using techniques like arbitrage and spread capture.

Eventually, my YouTube algorithm served me a video of someone building a Limit Order Book (LOB) in C++. I didn’t fully understand what I was watching at first — but I quickly realized: this is the heart of an exchange. Every single trade goes through the LOB. It applies price-time priority, matches buyers and sellers, and handles tremendous throughput with virtually no room for error.

I had to build one myself.


The Challenge: Real-Time, Not Just Backtests

Most trading projects online focus on backtesting — loading data, running a strategy, printing results. But I wanted something closer to reality — a real-time simulation of how markets operate, complete with the delays, throughput, and concurrency challenges of real systems.

To do that, I found LOBSTER, a fantastic data source that provides nanosecond-resolution limit order book data. I pulled a full day of trading data for AAPL and set out to build a matching engine that could:

  • Simulate order flow in real time
  • Match orders correctly using price-time priority
  • Handle the volume and speed of real market data
  • Display the order book live in a terminal UI

And most importantly: it had to keep up.


The Architecture: A Journey in Three Phases

What started as a curiosity quickly turned into a deep dive into low-latency systems, multithreading, and performance-critical design. The project evolved in phases:

Phase 1: Building the Core Engine

The first component was the OrderBook class. I used two main STL data structures:

  • std::map — to maintain sorted price levels (bids and asks)
  • std::unordered_map — for fast O(1) access to individual orders via their IDs

With this, I could parse the LOBSTER data and simulate how orders were placed, matched, and canceled.

At this stage, the simulation was functional — but static. It processed the file and printed logs. There was no interactivity, and no sense of flow.


Phase 2: Real-Time Simulation and Visualization

To simulate a live market, I added a timing mechanism: the engine reads the timestamps from the data and uses std::this_thread::sleep_for() to simulate real-time delay between events — sometimes just microseconds apart. This made the engine feel alive.

Then I integrated the FTXUI library to build a real-time Terminal User Interface that shows the current order book and trade log dynamically.

But… this created a new problem.


Phase 3: Hitting Concurrency Bottlenecks — and Solving Them

With both the simulation and UI running, the app hit performance issues. The fast simulation thread was being blocked by the slower UI thread due to std::mutex contention. CPU usage spiked. The system stuttered.

This was a real-world concurrency bug — and a turning point.

The fix was to fully decouple the simulation and UI using a Producer-Consumer architecture:

  • Producer Thread: Processes events, owns the OrderBook, and periodically publishes a ViewModel (a lightweight snapshot of the book).
  • Consumer Thread: Renders the UI, reading from a thread-safe queue of ViewModels.

Now, the simulation runs full speed, and the UI updates independently — no blocking, no stutter.


Testing the Engine

A matching engine must be correct. To ensure this, I wrote unit tests using GoogleTest to verify order matching logic, cancellations, and post-trade book state. These tests prevent regressions and give confidence that the engine behaves as expected under all scenarios.


What I Learned

This project pushed me into areas of software engineering that are easy to read about, but hard to master without building something:

  • Modern C++: From STL containers to memory management and multithreading primitives
  • Systems Design: Designing decoupled, concurrent systems that are both performant and maintainable
  • Concurrency: Handling race conditions, lock contention, and building thread-safe communication patterns
  • Real-Time Simulation: Making a backtest feel like a real exchange
  • Testing for Correctness: Using unit tests not just to check behavior, but to trust your logic under stress

Final Thoughts

This project started as a question: How does a real exchange work under the hood?

Answering that took me through papers, videos, blogs, and thousands of lines of C++. It gave me a much deeper appreciation for how modern financial systems are built — and the engineering challenges behind every market tick.

If you’re curious, you can check out the code, demo, and documentation here:
👉 GitHub Repository


Tech Stack

  • C++
  • FTXUI (Terminal UI library)
  • GoogleTest
  • LOBSTER Data (for real market simulation)