A high-performance Level 2 (L2) order book implementation in Rust that streams real-time cryptocurrency market data from multiple exchanges via WebSocket connections.
- Overview
- Features
- Supported Exchanges
- Installation
- Configuration
- Usage
- Testing
- Implementation Details
- API Documentation
- Contributing
- License
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
✅ 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
| 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)
- Rust 1.70+ (Edition 2021)
- Cargo (comes with Rust)
-
Clone the repository:
git clone https://github.com/your-username/l2_order_book.git cd l2_order_book -
Build the project:
cargo build --release
-
Run the application:
cargo run --release
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.
| 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.
Create a config.toml file in the project root directory:
[exchange]
depth_limit = 20
instrument = "BTC-USD"
[provider]
name = "Bitstamp"Environment variables override TOML file settings:
export EXCHANGE_DEPTH_LIMIT=10
export EXCHANGE_INSTRUMENT=BTC-USD
export PROVIDER_NAME=BitstampCLI 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 BitstampAvailable 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) |
1. Run with default configuration (from config.toml):
cargo run2. 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 Bitstamp3. Using environment variables:
EXCHANGE_DEPTH_LIMIT=20 EXCHANGE_INSTRUMENT=BTC-PERPETUAL PROVIDER_NAME=Deribit cargo runBy default, the application launches an interactive terminal UI built with Ratatui:
cargo run -- --instrument BTC-USD --provider BitstampUI 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
Escorqto gracefully exit
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 runAvailable Log Levels: error, warn, info, debug, trace
Deribit BTC Perpetual (Depth 10):
cargo run -- -d 10 -i BTC-PERPETUAL -p DeribitBitstamp BTC/USD (Depth 20):
cargo run -- -d 20 -i BTC-USD -p BitstampUsing config.toml:
[exchange]
depth_limit = 10
instrument = "BTC-PERPETUAL"
[provider]
name = "Deribit"cargo runThe 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_orderTest Coverage:
- ✅ Order book operations (add, remove, update)
- ✅ Depth limit enforcement
- ✅ Snapshot processing
- ✅ Configuration merging
- ✅ CLI argument parsing
- ✅ Configuration validation
# Run clippy for linting
cargo clippy --all-targets --all-features
# Check code formatting
cargo fmt -- --check
# Apply code formatting
cargo fmtThe 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
- The
OrderBookstruct 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
SharedOrderBookstruct provides a thread-safe wrapper usingArc<RwLock<OrderBook>>
- Deribit: Uses the official
deribitcrate for WebSocket communication - Bitstamp: Custom implementation using
tokio-tungstenitefor WebSocket connections - Incoming messages are parsed using
serde_jsonand processed to update the order book in real-time - Graceful shutdown via
tokio::select!and cancellation channels
- Built on Tokio async runtime for high-performance I/O
- Uses
async/awaitsyntax throughout - Concurrent tasks for WebSocket streaming, UI rendering, and user input handling
- Proper cancellation and cleanup on shutdown
Arc<RwLock<OrderBook>>pattern for shared mutable state- Multiple readers or single writer access pattern
- No data races or deadlocks
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,
}- Deribit API: https://docs.deribit.com/#book-instrument_name-group-depth-interval
- Bitstamp WebSocket: https://www.bitstamp.net/websocket/v2/ (see Channels section)
- Bitstamp Order Book Example: Order Book V2 Example
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
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
cargo test) - Run clippy (
cargo clippy) - Format code (
cargo fmt) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ using Rust