A high-performance, low-latency C++ library for managing financial market order books. Optimized for microsecond-level performance in high-frequency trading systems.
- π 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.)
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 |
- C++23 compiler: GCC 14+, Clang 18+, or MSVC 2022+ (17.6+)
- CMake: 3.20 or higher
- Git: For cloning the repository
# 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 .#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
#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;
}#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;
}#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;
}- Examples - Usage examples
- Benchmarks - Performance benchmarking and profiling guides
- 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
- 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
# 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)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)# In your CMakeLists.txt
add_compile_definitions(SLICK_ORDERBOOK_HEADER_ONLY)
target_include_directories(your_target PRIVATE /path/to/slick-orderbook/include)# 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# 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=jsonThis project is licensed under the MIT License - see the LICENSE file for details.
- Built with modern C++23 features
- Powered by Google Benchmark for performance testing
- Inspired by high-frequency trading systems and exchange matching engines
- Organization: Slick Quant
- GitHub Issues: For bug reports and feature requests
Made with β‘ by Slick Quant