Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LOB-Sim-CPP

A high-performance limit order book (LOB) simulator and ML backtesting engine built in C++17 with LibTorch integration.

⚠️ Note: This project is under active development. Built for personal LOB research and microstructure experiments. Feel free to fork and adapt!

C++17 MIT CMake LibTorch

What is this?

A fast C++ toolkit for streaming order book data, running ML inference (DeepLOB-style), and backtesting execution strategies with minimal overhead.

Data Flow:  CSV → [L2Streamer] → [Ring40] → [TorchModel] → [Trader] → PnL
                       ↓              ↓            ↓            ↓
                  Parse LOB     History      Inference    Execute
                  Snapshots      Buffer       (0.1ms)      Orders

Architecture

┌──────────────────────────────────────────────────────────────────┐
│                         LOB-Sim-CPP                              │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌────────────┐    ┌──────────┐    ┌────────────┐              │
│   │ L2Streamer │───▶│  Snap    │───▶│  Ring40<H> │              │
│   │  (CSV I/O) │    │ (10-lvl) │    │ (H×40 buf) │              │
│   └────────────┘    └──────────┘    └─────┬──────┘              │
│                                           │                      │
│         ┌─────────────────────────────────┘                      │
│         ▼                                                        │
│   ┌────────────┐    ┌──────────┐    ┌────────────┐              │
│   │ TorchModel │───▶│ Predict  │───▶│   Trader   │              │
│   │ (DeepLOB)  │    │  -1/0/+1 │    │  (PnL/Pos) │              │
│   └────────────┘    └──────────┘    └────────────┘              │
│                                                                  │
│   ┌─────────────────────────────────────────────────┐           │
│   │                  Utilities                       │           │
│   │  LOBDay • LatencyQueue • mid() • spread()       │           │
│   └─────────────────────────────────────────────────┘           │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

Features

Component Description
L2Streamer Streams paired orderbook + message CSVs (LOBSTER format)
Snap Compact 10-level LOB snapshot (40 floats: ask/bid price & size)
Ring40<H> Lock-free circular buffer maintaining H×40 contiguous history
TorchModel TorchScript wrapper for DeepLOB inference
Trader Simple market order executor with position & PnL tracking
LOBDay Bulk loader for full-day orderbook data

Data Format (LOBSTER-style)

Orderbook CSV (10 levels × 4 columns = 40 values per row):
───────────────────────────────────────────────────────────
ask_p1, ask_s1, bid_p1, bid_s1, ask_p2, ask_s2, ...

Message CSV (timestamps):
───────────────────────────────────────────────────────────
timestamp_sec, event_type, order_id, size, price, direction

Quick Start

#include "lob/L2Streamer.hpp"
#include "lob/Ring40.hpp"
#include "lob/Trader.hpp"
#include "lob/TorchModel.hpp"

int main() {
    // Stream LOBSTER data
    lob::L2Streamer stream("AAPL", "2023-01-03", 10, "data/raw");
    lob::Ring40<100> ring;  // 100-snapshot history
    Trader trader;
    TorchModel model("models/deeplob_ts.pt");

    lob::Snap snap;
    std::uint64_t ts_us;

    while (stream.next(snap, ts_us)) {
        if (!ring.push(snap)) continue;  // warm-up

        double mid = 0.5 * (snap.askPrice[0] + snap.bidPrice[0]);
        
        // ML inference → direction prediction
        auto [side, prob] = model.infer(ring.contiguous(), 100);
        
        if (prob > 0.8f && side != 0) {
            trader.market(mid, side, 100);
        }
    }

    std::cout << "Final PnL: $" << trader.pnl(mid) << std::endl;
}

Build

git clone https://github.com/YOUR_USERNAME/lob-sim-cpp.git
cd lob-sim-cpp
mkdir build && cd build

# Point to your LibTorch installation
cmake -DCMAKE_PREFIX_PATH="$HOME/Downloads/libtorch" ..
cmake --build . --config Release

Requirements

  • CMake ≥ 3.16
  • C++17 compiler (clang++ / g++)
  • LibTorch (PyTorch C++ distribution)

Run

# Demo: load and inspect order book data
./demo AAPL 2023-01-03 10

# Backtest: run DeepLOB strategy
./backtest AAPL 2023-01-03 data/raw

Example Output

=== DeepLOB Backtesting System ===
Symbol: AAPL, Date: 2023-01-03, Depth: 10

Opening CSV streamer...          ✓ (12ms)
Initializing ring buffer...      ✓ (3μs)
Loading ML model...              ✓ (847ms)

=== Starting main processing loop ===
Processed: 50000 rows, Rate: 142,857 rows/sec
Processed: 100000 rows, Rate: 138,462 rows/sec

=== Performance Report ===
Total rows processed: 234,521
Processing rate: 140,234 rows/sec

=== Timing Breakdown ===
Avg inference latency: 89 μs
Total trades executed: 1,247
Trade rate: 0.53% of rows

=== Trading Results ===
Final PnL: $2,341.87

Project Structure

lob-sim-cpp/
├── include/
│   └── lob/
│       ├── L2Streamer.hpp    # CSV streaming
│       ├── Snap.hpp          # LOB snapshot struct
│       ├── Ring40.hpp        # Circular history buffer
│       ├── TorchModel.hpp    # TorchScript wrapper
│       ├── Trader.hpp        # Position & PnL tracker
│       ├── LOBDay.hpp        # Bulk day loader
│       ├── LatencyQueue.hpp  # Latency simulation
│       └── utils.hpp         # mid(), spread(), etc.
├── src/
│   ├── LOBDay.cpp
│   └── main.cpp
├── app/
│   ├── main.cpp              # Demo executable
│   ├── backtest.cpp          # ML backtest
│   └── deeplob_backtest.cpp  # Enhanced backtest
├── models/
│   └── deeplob_ts.pt         # TorchScript model
├── data/
│   └── raw/                  # LOBSTER CSV files
├── CMakeLists.txt
└── README.md

How It Works

1. Data Ingestion
   CSV → L2Streamer → Snap{askPrice[10], askSize[10], bidPrice[10], bidSize[10]}
                           │
                           ▼
2. History Buffer (Ring40<100>)
   ┌─────────────────────────────────────────┐
   │ t-99 │ t-98 │ ... │ t-1 │ t-0 │ (head) │  → [100 × 40] float array
   └─────────────────────────────────────────┘

3. ML Inference
   [100 × 40] → TorchModel(DeepLOB) → softmax → argmax → {-1, 0, +1}
                                                              │
4. Execution                                                  ▼
   side = -1 (sell) │ side = 0 (hold) │ side = +1 (buy)
         │                                    │
         └──────────► Trader.market() ◄──────┘
                            │
                            ▼
                    Update pos, cash, PnL

Design Principles

Principle Implementation
Zero-copy where possible Ring buffer returns pointer to contiguous memory
Minimal allocations Fixed-size arrays, stack allocation in hot path
Inference-only ML Models trained in Python, exported as TorchScript
Modular components Swap data source, model, or execution logic independently

Roadmap

  • LOBSTER CSV streaming
  • Ring buffer for ML input
  • TorchScript integration
  • Basic market order execution
  • PnL tracking
  • Limit order support
  • Latency simulation modes
  • Multi-asset support
  • Live data feed adapters
  • GPU inference optimization

Inspired By

License

MIT License - see LICENSE for details.

Author

Angelo - GitHub

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors