Skip to content

numados/l2-order-book

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

L2 Order Book

Rust License Build Status

A high-performance Level 2 (L2) order book implementation in Rust that streams real-time cryptocurrency market data from multiple exchanges via WebSocket connections.

Table of Contents

Overview

This project implements a Level 2 (L2) order book that streams real-time market data from cryptocurrency exchanges using WebSocket connections. The order book maintains the best bid and offer prices and enforces a configurable depth limit.

Key Capabilities:

  • Real-time order book updates via WebSocket
  • Multi-exchange support (Deribit, Bitstamp)
  • Thread-safe order book implementation using Arc<RwLock<T>>
  • Interactive terminal UI with Ratatui
  • Flexible configuration system (TOML, Environment Variables, CLI)
  • Comprehensive unit test coverage
  • Async/await architecture with Tokio

Features

Real-time Market Data - WebSocket streaming from multiple exchanges
Multi-Exchange Support - Deribit and Bitstamp providers
Configurable Depth Limit - Control order book depth (1, 10, or 20 levels)
Interactive TUI - Beautiful terminal UI with Ratatui
Flexible Configuration - TOML file, environment variables, or CLI arguments
Thread-Safe - Concurrent access using Arc<RwLock<T>> pattern
Comprehensive Testing - Unit tests for core components
Async Architecture - Built on Tokio async runtime
Graceful Shutdown - Clean WebSocket disconnection on exit

Supported Exchanges

Exchange Instrument Example Public Access Implementation
Deribit BTC-PERPETUAL ✅ Yes External crate (deribit-rs)
Bitstamp BTC-USD ✅ Yes Custom WebSocket implementation

Note: The test instruments differ between providers:

  • Deribit: Uses BTC-PERPETUAL (not available on Bitstamp)
  • Bitstamp: Uses BTC-USD (not available on Deribit)

Installation

Prerequisites

  • Rust 1.70+ (Edition 2021)
  • Cargo (comes with Rust)

Steps

  1. Clone the repository:

    git clone https://github.com/your-username/l2_order_book.git
    cd l2_order_book
  2. Build the project:

    cargo build --release
  3. Run the application:

    cargo run --release

Configuration

The application supports a three-tier configuration system with the following priority order:

TOML File < Environment Variables < Command-Line Arguments

Priority: CLI arguments have the highest priority, followed by environment variables, then the TOML file.

Configuration Options

Parameter Valid Values Description Required
depth_limit 1, 10, 20 Order book depth level ✅ Yes
instrument e.g., BTC-USD, BTC-PERPETUAL Trading pair/instrument ✅ Yes
provider Deribit, Bitstamp Exchange provider ✅ Yes

Note: Depth limit values are restricted to [1, 10, 20] because Deribit only supports these specific levels.

1. TOML Configuration File (Lowest Priority)

Create a config.toml file in the project root directory:

[exchange]
depth_limit = 20
instrument = "BTC-USD"

[provider]
name = "Bitstamp"

2. Environment Variables (Medium Priority)

Environment variables override TOML file settings:

export EXCHANGE_DEPTH_LIMIT=10
export EXCHANGE_INSTRUMENT=BTC-USD
export PROVIDER_NAME=Bitstamp

3. Command-Line Arguments (Highest Priority)

CLI arguments override all other configuration sources:

# Full syntax
cargo run -- --depth_limit 10 --instrument BTC-USD --provider Bitstamp

# Short flags
cargo run -- -d 10 -i BTC-USD -p Bitstamp

Available CLI Arguments:

Flag Short Long Description
-d --depth_limit Order book depth (1, 10, or 20)
-i --instrument Trading instrument (e.g., BTC-USD)
-p --provider Exchange provider (Deribit or Bitstamp)

Usage

Basic Usage

1. Run with default configuration (from config.toml):

cargo run

2. Override specific parameters:

# Change instrument only
cargo run -- --instrument BTC-PERPETUAL

# Change provider and instrument
cargo run -- --provider Deribit --instrument BTC-PERPETUAL

# Full configuration via CLI
cargo run -- -d 10 -i BTC-USD -p Bitstamp

3. Using environment variables:

EXCHANGE_DEPTH_LIMIT=20 EXCHANGE_INSTRUMENT=BTC-PERPETUAL PROVIDER_NAME=Deribit cargo run

Interactive UI Mode

By default, the application launches an interactive terminal UI built with Ratatui:

cargo run -- --instrument BTC-USD --provider Bitstamp

UI Features:

  • 📊 Best Prices Display - Shows best bid and ask prices in real-time
  • 📈 Order Book Table - Displays all bids and asks up to the configured depth
  • 🎨 Color-Coded - Green for asks, red for bids, blue for quantities
  • ⌨️ Exit Keys - Press Esc or q to gracefully exit

Debug/Logging Mode

To disable the UI and view raw log output, set the RUST_LOG environment variable:

# Info level logging
RUST_LOG=info cargo run -- --instrument BTC-USD

# Debug level logging
RUST_LOG=debug cargo run -- --instrument BTC-PERPETUAL --provider Deribit

# Trace level logging (very verbose)
RUST_LOG=trace cargo run

Available Log Levels: error, warn, info, debug, trace

Example Configurations

Deribit BTC Perpetual (Depth 10):

cargo run -- -d 10 -i BTC-PERPETUAL -p Deribit

Bitstamp BTC/USD (Depth 20):

cargo run -- -d 20 -i BTC-USD -p Bitstamp

Using config.toml:

[exchange]
depth_limit = 10
instrument = "BTC-PERPETUAL"

[provider]
name = "Deribit"
cargo run

Testing

Unit Tests

The project includes comprehensive unit tests for core components:

# Run all tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Run specific test
cargo test test_add_order

Test Coverage:

  • ✅ Order book operations (add, remove, update)
  • ✅ Depth limit enforcement
  • ✅ Snapshot processing
  • ✅ Configuration merging
  • ✅ CLI argument parsing
  • ✅ Configuration validation

Code Quality

# Run clippy for linting
cargo clippy --all-targets --all-features

# Check code formatting
cargo fmt -- --check

# Apply code formatting
cargo fmt

Implementation Details

Architecture

The project follows a clean, modular architecture:

src/
├── main.rs              # Application entry point
├── lib.rs               # Library root
├── cli/                 # Command-line interface
│   ├── mod.rs
│   └── commands.rs      # CLI argument parsing
├── console/             # Terminal UI
│   ├── mod.rs           # UI initialization
│   └── ui.rs            # Ratatui rendering
├── core/                # Core business logic
│   ├── mod.rs           # SharedOrderBook wrapper
│   ├── order_book.rs    # OrderBook implementation
│   └── messages.rs      # Message types
├── providers/           # Exchange integrations
│   ├── mod.rs           # Provider dispatcher
│   ├── deribit.rs       # Deribit implementation
│   └── bitstamp.rs      # Bitstamp implementation
└── utils/               # Utilities
    └── config.rs        # Configuration management

Order Book

  • The OrderBook struct maintains the state of the order book, including bids, asks, best bid, and best ask prices
  • Uses BTreeMap<OrderedFloat<f64>, f64> for efficient price-level storage and ordering
  • Enforces a configurable depth limit to maintain only the top N bids and asks
  • The SharedOrderBook struct provides a thread-safe wrapper using Arc<RwLock<OrderBook>>

WebSocket Connection

  • Deribit: Uses the official deribit crate for WebSocket communication
  • Bitstamp: Custom implementation using tokio-tungstenite for WebSocket connections
  • Incoming messages are parsed using serde_json and processed to update the order book in real-time
  • Graceful shutdown via tokio::select! and cancellation channels

Async Architecture

  • Built on Tokio async runtime for high-performance I/O
  • Uses async/await syntax throughout
  • Concurrent tasks for WebSocket streaming, UI rendering, and user input handling
  • Proper cancellation and cleanup on shutdown

Thread Safety

  • Arc<RwLock<OrderBook>> pattern for shared mutable state
  • Multiple readers or single writer access pattern
  • No data races or deadlocks

API Documentation

Key Types

OrderBook - Core order book data structure

pub struct OrderBook {
    pub bids: BTreeMap<OrderedFloat<f64>, f64>,
    pub asks: BTreeMap<OrderedFloat<f64>, f64>,
    pub best_bid: Option<f64>,
    pub best_ask: Option<f64>,
    pub depth_limit: usize,
}

SharedOrderBook - Thread-safe wrapper

pub struct SharedOrderBook {
    inner: Arc<RwLock<OrderBook>>,
}

Provider - Exchange provider enum

pub enum Provider {
    None,
    Deribit,
    Bitstamp,
}

Resources

Exchange Documentation

Dependencies

Key dependencies used in this project:

  • tokio - Async runtime
  • tokio-tungstenite - WebSocket client
  • serde / serde_json - Serialization
  • ratatui - Terminal UI framework
  • clap - CLI argument parsing
  • anyhow - Error handling
  • log / env_logger - Logging
  • deribit - Deribit API client

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (cargo test)
  5. Run clippy (cargo clippy)
  6. Format code (cargo fmt)
  7. Commit your changes (git commit -m 'Add amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

License

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


Built with ❤️ using Rust

About

L2 Order Book implementation example

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages