Skip to content

High-performance C++23 orderbook library for financial trading systems - exceeds all performance targets by 2-40x

License

Notifications You must be signed in to change notification settings

SlickQuant/slick-orderbook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

54 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Slick OrderBook

CI Documentation License: MIT C++23 Platform Release

A high-performance, low-latency C++ library for managing financial market order books. Optimized for microsecond-level performance in high-frequency trading systems.

✨ Features

  • πŸš€ Blazing Fast: Sub-100ns L2 operations, sub-200ns L3 operations (p99)
  • πŸ“Š Dual Market Data: Level 2 (aggregated) and Level 3 (order-by-order) support
  • 🎯 Multi-Symbol: Efficient management of thousands of instruments
  • πŸ”§ Flexible Build: Compiled library (default) or header-only mode
  • 🧩 Protocol Agnostic: Generic design works with any exchange feed
  • ⚑ Zero Allocations: Object pooling eliminates runtime allocations in hot paths
  • πŸ“¦ C++23: Leverages modern C++ features (std::flat_map, concepts, etc.)

πŸ“ˆ Performance

All performance targets exceeded by 2-40x:

Operation Target Actual (p99) Status
L2 Add/Modify/Delete <100ns 21-33ns βœ… 3-5x faster
L3 Add/Modify/Delete <200ns 59-490ns βœ… 2-3x faster
Best Bid/Ask Query <10ns 0.25-0.33ns βœ… 30-40x faster
Observer Notification <50ns/observer 2-3ns βœ… 16-25x faster
Memory Footprint (L2) <1KB/symbol <1KB βœ… Meets target
Memory Footprint (L3) <10KB/1000 orders <10KB βœ… Meets target

πŸš€ Quick Start

Prerequisites

  • C++23 compiler: GCC 14+, Clang 18+, or MSVC 2022+ (17.6+)
  • CMake: 3.20 or higher
  • Git: For cloning the repository

Installation

# Clone the repository
git clone https://github.com/SlickQuant/slick-orderbook.git
cd slick-orderbook

# Build (Release mode)
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . -j

# Run tests
ctest --output-on-failure

# Install (optional)
sudo cmake --install .

Basic Usage - Level 2 OrderBook

#include <slick/orderbook/orderbook.hpp>
#include <iostream>

using namespace slick::orderbook;

int main() {
    // Create L2 orderbook for symbol ID 1
    OrderBookL2 book(1);

    // Add price levels
    book.updateLevel(Side::Buy, 10000, 100, 0, 0);   // Bid: $100.00, qty 100
    book.updateLevel(Side::Buy, 9950, 50, 0, 0);     // Bid: $99.50, qty 50
    book.updateLevel(Side::Sell, 10050, 75, 0, 0);   // Ask: $100.50, qty 75
    book.updateLevel(Side::Sell, 10100, 100, 0, 0);  // Ask: $101.00, qty 100

    // Query top of book
    auto tob = book.getTopOfBook();
    std::cout << "Best Bid: " << tob.best_bid_price << " x " << tob.best_bid_quantity << "\n";
    std::cout << "Best Ask: " << tob.best_ask_price << " x " << tob.best_ask_quantity << "\n";
    std::cout << "Spread: " << tob.getSpread() << "\n";
    std::cout << "Mid Price: " << tob.getMidPrice() << "\n";

    return 0;
}

Output:

Best Bid: 10000 x 100
Best Ask: 10050 x 75
Spread: 50
Mid Price: 10025

Basic Usage - Level 3 OrderBook

#include <slick/orderbook/orderbook.hpp>

using namespace slick::orderbook;

int main() {
    // Create L3 orderbook for symbol ID 1
    OrderBookL3 book(1);

    // Add individual orders
    book.addOrModifyOrder(1001, Side::Buy, 10000, 100, 0, 0, 0);  // Order #1001
    book.addOrModifyOrder(1002, Side::Buy, 10000, 50, 0, 1, 0);   // Order #1002 (lower priority)
    book.addOrModifyOrder(2001, Side::Sell, 10050, 75, 0, 0, 0);  // Order #2001

    // Modify order quantity
    book.addOrModifyOrder(1001, Side::Buy, 10000, 150, 0, 0, 0);  // Increase qty to 150

    // Execute partial order
    book.executeOrder(2001, 25, 0);  // Execute 25 of order #2001

    // Delete order
    book.deleteOrder(1002, 0);  // Cancel order #1002

    // Query aggregated L2 view
    const auto& bids = book.getLevelsL2(Side::Buy);
    const auto& asks = book.getLevelsL2(Side::Sell);

    return 0;
}

Multi-Symbol Management

#include <slick/orderbook/orderbook.hpp>

using namespace slick::orderbook;

int main() {
    // Create multi-symbol manager
    OrderBookManager<OrderBookL2> manager;

    // Get or create orderbooks for different symbols
    auto* btc_book = manager.getOrCreateOrderBook(1);  // BTC
    auto* eth_book = manager.getOrCreateOrderBook(2);  // ETH
    auto* sol_book = manager.getOrCreateOrderBook(3);  // SOL

    // Update each orderbook
    btc_book->updateLevel(Side::Buy, 4500000, 1000, 0, 0);  // BTC: $45,000
    eth_book->updateLevel(Side::Buy, 250000, 5000, 0, 0);   // ETH: $2,500
    sol_book->updateLevel(Side::Buy, 10000, 10000, 0, 0);   // SOL: $100

    // Query all symbols
    manager.forEachOrderBook([](SymbolId symbol_id, OrderBookL2* book) {
        auto tob = book->getTopOfBook();
        std::cout << "Symbol " << symbol_id
                  << ": Best Bid=" << tob.best_bid_price << "\n";
    });

    return 0;
}

Observer Pattern - Real-Time Notifications

#include <slick/orderbook/orderbook.hpp>
#include <iostream>

using namespace slick::orderbook;

// Implement observer interface
class MyObserver : public IOrderBookObserver {
public:
    void onPriceLevelUpdate(const PriceLevelUpdate& update) override {
        std::cout << "Level updated: "
                  << (update.side == Side::Buy ? "BID" : "ASK")
                  << " @ " << update.price
                  << " qty=" << update.quantity << "\n";
    }

    void onTopOfBookUpdate(const TopOfBook& tob) override {
        std::cout << "ToB: " << tob.best_bid_price
                  << " / " << tob.best_ask_price << "\n";
    }

    // Implement other required callbacks...
    void onOrderUpdate(const OrderUpdate& update) override {}
    void onTrade(const Trade& trade) override {}
    void onSnapshotBegin(SymbolId, uint64_t, Timestamp) override {}
    void onSnapshotEnd(SymbolId, uint64_t, Timestamp) override {}
};

int main() {
    OrderBookL2 book(1);
    auto observer = std::make_shared<MyObserver>();

    // Register observer
    book.registerObserver(observer);

    // Updates will trigger notifications
    book.updateLevel(Side::Buy, 10000, 100, 0, 0);
    // Output: Level updated: BID @ 10000 qty=100
    //         ToB: 10000 / 0

    return 0;
}

πŸ“š Documentation

πŸ—οΈ Architecture Highlights

Cache-Optimized Data Structures

  • FlatMap: Uses std::flat_map (C++23) for cache-friendly sorted price level storage
  • Intrusive List: Zero-allocation doubly-linked list for order queues
  • Object Pool: Pre-allocated memory eliminates runtime allocations
  • Cache Alignment: 64-byte alignment prevents false sharing in multi-symbol scenarios

Zero-Cost Abstractions

  • Template-Based: No virtual dispatch in hot paths
  • Concepts: C++23 concepts for compile-time type checking
  • Inline Everything: Aggressive inlining for sub-nanosecond operations

πŸ”§ CMake Options

# Build options
-DCMAKE_BUILD_TYPE=Release          # Release, Debug, RelWithDebInfo
-DSLICK_ORDERBOOK_HEADER_ONLY=ON    # Enable header-only mode (default: OFF)
-DSLICK_ORDERBOOK_BUILD_SHARED=ON   # Build shared library (default: OFF)
-DSLICK_ORDERBOOK_BUILD_TESTS=ON    # Build tests (default: ON)
-DSLICK_ORDERBOOK_BUILD_BENCHMARKS=ON  # Build benchmarks (default: OFF)
-DSLICK_ORDERBOOK_BUILD_EXAMPLES=ON    # Build examples (default: ON)

πŸ“¦ Integration

CMake FetchContent

include(FetchContent)

FetchContent_Declare(
    slick-orderbook
    GIT_REPOSITORY https://github.com/SlickQuant/slick-orderbook.git
    GIT_TAG        main
)

FetchContent_MakeAvailable(slick-orderbook)

target_link_libraries(your_target PRIVATE slick::orderbook)

Header-Only Mode

# In your CMakeLists.txt
add_compile_definitions(SLICK_ORDERBOOK_HEADER_ONLY)
target_include_directories(your_target PRIVATE /path/to/slick-orderbook/include)

πŸ§ͺ Testing

# Build and run all tests
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DSLICK_ORDERBOOK_BUILD_TESTS=ON
cmake --build build -j
cd build && ctest --output-on-failure

# Run specific test
./build/tests/unit/test_orderbook_l2

# With sanitizers
cmake -B build-asan -DCMAKE_CXX_FLAGS="-fsanitize=address -g"
cmake --build build-asan
cd build-asan && ctest

πŸ“Š Benchmarking

# Build benchmarks
cmake -B build -DCMAKE_BUILD_TYPE=Release -DSLICK_ORDERBOOK_BUILD_BENCHMARKS=ON
cmake --build build -j

# Run all benchmarks
cd build/benchmarks
./bench_orderbook_l2
./bench_orderbook_l3
./bench_market_replay

# Run specific benchmark with filter
./bench_orderbook_l2 --benchmark_filter="AddNewLevel/100"

# Output results to JSON
./bench_orderbook_l2 --benchmark_out=results.json --benchmark_out_format=json

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built with modern C++23 features
  • Powered by Google Benchmark for performance testing
  • Inspired by high-frequency trading systems and exchange matching engines

πŸ“§ Contact

  • Organization: Slick Quant
  • GitHub Issues: For bug reports and feature requests

Made with ⚑ by Slick Quant