Skip to content

Commit 3b59d73

Browse files
Create README.md
1 parent 2d16276 commit 3b59d73

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
# Order Book Implementations
2+
3+
This crate provides different order book data structure implementations optimized for various use cases in cryptocurrency trading systems. Each implementation provides the same interface through the `OrderBook` trait but uses different underlying data structures for optimal performance characteristics.
4+
5+
## Features
6+
7+
- **Multiple Implementations**: BTreeSet, HashMap, AVL Tree, Red-Black Tree
8+
- **Async/Await Support**: All operations are async-compatible
9+
- **Thread Safety**: Built with Arc<RwLock<>> for safe concurrent access
10+
- **Depth Management**: Automatic trimming to configurable maximum depth
11+
- **Exchange Support**: Handle orders from multiple exchanges at same price levels
12+
- **Comprehensive Testing**: Extensive test suite covering edge cases and performance
13+
14+
## Available Implementations
15+
16+
### BTreeSet Implementation (`BTreeOrderBook`)
17+
18+
**Best for**: General purpose use, sorted access patterns
19+
20+
- **Insertion**: O(log n) - Maintains sorted order automatically
21+
- **Lookup**: O(log n) - Binary search through sorted structure
22+
- **Best Price**: O(1) - First element in sorted set
23+
- **Range Queries**: O(log n + k) - Efficient for getting top N orders
24+
- **Memory**: Moderate overhead due to tree structure
25+
26+
```rust
27+
use orderbook_implementations::BTreeOrderBook;
28+
29+
let mut orderbook = BTreeOrderBook::new();
30+
```
31+
32+
### HashMap Implementation (`HashMapOrderBook`)
33+
34+
**Best for**: High-frequency updates, fast lookups
35+
36+
- **Insertion**: O(1) average - Direct hash table access
37+
- **Lookup**: O(1) average - Hash table lookup
38+
- **Best Price**: O(n) - Requires scanning sorted price list
39+
- **Range Queries**: O(n) - Must filter through price levels
40+
- **Memory**: Lower overhead, separate price sorting
41+
42+
```rust
43+
use orderbook_implementations::HashMapOrderBook;
44+
45+
let mut orderbook = HashMapOrderBook::new();
46+
```
47+
48+
### Future Implementations
49+
50+
- **AVL Tree**: Self-balancing binary search tree (placeholder)
51+
- **Red-Black Tree**: Alternative balanced tree implementation (placeholder)
52+
53+
## Usage
54+
55+
### Basic Operations
56+
57+
```rust
58+
use orderbook_implementations::{BTreeOrderBook, OrderBook};
59+
use aggregator_core::{Bid, Ask, Exchange};
60+
use chrono::Utc;
61+
62+
#[tokio::main]
63+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
64+
let mut orderbook = BTreeOrderBook::new();
65+
66+
// Add some bids
67+
let bids = vec![
68+
Bid {
69+
price: 100.0,
70+
quantity: 10.0,
71+
exchange: Exchange::Binance,
72+
timestamp: Utc::now(),
73+
},
74+
Bid {
75+
price: 99.5,
76+
quantity: 5.0,
77+
exchange: Exchange::Coinbase,
78+
timestamp: Utc::now(),
79+
},
80+
];
81+
82+
orderbook.update_bids(bids, 100).await;
83+
84+
// Add some asks
85+
let asks = vec![
86+
Ask {
87+
price: 101.0,
88+
quantity: 8.0,
89+
exchange: Exchange::Binance,
90+
timestamp: Utc::now(),
91+
},
92+
];
93+
94+
orderbook.update_asks(asks, 100).await;
95+
96+
// Get best prices
97+
if let Some(best_bid) = orderbook.get_best_bid().await {
98+
println!("Best bid: {} @ {}", best_bid.quantity, best_bid.price);
99+
}
100+
101+
if let Some(best_ask) = orderbook.get_best_ask().await {
102+
println!("Best ask: {} @ {}", best_ask.quantity, best_ask.price);
103+
}
104+
105+
// Calculate spread
106+
if let Some(spread) = orderbook.get_spread().await {
107+
println!("Spread: {}", spread);
108+
}
109+
110+
// Get top 5 bids and asks
111+
let top_bids = orderbook.get_best_n_bids(5).await;
112+
let top_asks = orderbook.get_best_n_asks(5).await;
113+
114+
println!("Market depth: {} bids, {} asks",
115+
orderbook.bid_depth().await,
116+
orderbook.ask_depth().await);
117+
118+
Ok(())
119+
}
120+
```
121+
122+
### Side-Only Operations
123+
124+
```rust
125+
use orderbook_implementations::{BTreeOrderBook, BuySide, SellSide};
126+
127+
#[tokio::main]
128+
async fn main() {
129+
let orderbook = BTreeOrderBook::new();
130+
131+
// Get side-specific views
132+
let mut bid_side = orderbook.bid_side();
133+
let mut ask_side = orderbook.ask_side();
134+
135+
// Work with bids only
136+
bid_side.update_bids(bids, 100).await;
137+
let best_bid = bid_side.get_best_bid().await;
138+
139+
// Work with asks only
140+
ask_side.update_asks(asks, 100).await;
141+
let best_ask = ask_side.get_best_ask().await;
142+
}
143+
```
144+
145+
### Order Updates and Removal
146+
147+
```rust
148+
// Update existing order (same price + exchange)
149+
let updated_bid = Bid {
150+
price: 100.0,
151+
quantity: 20.0, // New quantity
152+
exchange: Exchange::Binance,
153+
timestamp: Utc::now(),
154+
};
155+
orderbook.update_bids(vec![updated_bid], 100).await;
156+
157+
// Remove order (set quantity to 0)
158+
let remove_bid = Bid {
159+
price: 100.0,
160+
quantity: 0.0, // Zero quantity removes the order
161+
exchange: Exchange::Binance,
162+
timestamp: Utc::now(),
163+
};
164+
orderbook.update_bids(vec![remove_bid], 100).await;
165+
```
166+
167+
### Depth Management
168+
169+
```rust
170+
// Limit to top 50 price levels
171+
let max_depth = 50;
172+
orderbook.update_bids(large_bid_list, max_depth).await;
173+
orderbook.update_asks(large_ask_list, max_depth).await;
174+
175+
// Only the best 50 levels will be kept
176+
assert!(orderbook.bid_depth().await <= max_depth);
177+
assert!(orderbook.ask_depth().await <= max_depth);
178+
```
179+
180+
## Performance Considerations
181+
182+
### Choosing an Implementation
183+
184+
- **BTreeOrderBook**: Choose when you need sorted access and don't mind O(log n) operations
185+
- **HashMapOrderBook**: Choose when you need fastest updates and can tolerate O(n) for best price queries
186+
- **Future implementations**: Will provide specialized performance characteristics
187+
188+
### Optimization Tips
189+
190+
1. **Batch Updates**: Update multiple orders in a single call when possible
191+
2. **Appropriate Depth**: Set `max_depth` to limit memory usage and improve performance
192+
3. **Concurrent Access**: Use the shared Arc<RwLock<>> pattern for multiple readers
193+
4. **Avoid Frequent Clearing**: Prefer selective updates over full clears
194+
195+
## Testing
196+
197+
The crate includes comprehensive tests covering:
198+
199+
- **Integration Tests**: Cross-implementation compatibility
200+
- **Unit Tests**: Implementation-specific behavior
201+
- **Edge Cases**: Extreme values, error conditions
202+
- **Performance Benchmarks**: Comparative performance analysis
203+
204+
### Running Tests
205+
206+
```bash
207+
# Run all tests
208+
cargo test
209+
210+
# Run specific test suite
211+
cargo test --test integration_tests
212+
cargo test --test btree_tests
213+
cargo test --test edge_cases
214+
215+
# Run benchmarks
216+
cargo bench
217+
```
218+
219+
### Test Coverage
220+
221+
- Basic CRUD operations
222+
- Order updates and replacements
223+
- Depth limiting functionality
224+
- Multi-exchange handling
225+
- Concurrent access patterns
226+
- Edge cases (extreme values, empty states)
227+
- Performance under load
228+
229+
## Thread Safety
230+
231+
All implementations are designed for concurrent access:
232+
233+
```rust
234+
use std::sync::Arc;
235+
use tokio::sync::Mutex;
236+
237+
let orderbook = Arc::new(Mutex::new(BTreeOrderBook::new()));
238+
239+
// Multiple tasks can safely access the orderbook
240+
let orderbook_clone = orderbook.clone();
241+
tokio::spawn(async move {
242+
let mut ob = orderbook_clone.lock().await;
243+
ob.update_bids(bids, 100).await;
244+
});
245+
```
246+
247+
## Error Handling
248+
249+
The implementations handle various edge cases gracefully:
250+
251+
- Empty order books return `None` for best price queries
252+
- Zero quantities automatically remove orders
253+
- Depth limiting keeps only the best N levels
254+
- Invalid inputs are handled without panicking
255+
256+
## Contributing
257+
258+
When adding new implementations:
259+
260+
1. Implement the `OrderBook` trait
261+
2. Add comprehensive tests in the `tests/` directory
262+
3. Include benchmarks in `benches/`
263+
4. Update this README with performance characteristics
264+
5. Ensure thread safety with appropriate synchronization
265+
266+
## Dependencies
267+
268+
- `aggregator-core`: Core types (Bid, Ask, Exchange)
269+
- `tokio`: Async runtime and synchronization primitives
270+
- `async-trait`: Async trait support
271+
- `chrono`: Timestamp handling
272+
- `criterion`: Benchmarking framework (dev dependency)
273+
274+
## License
275+
276+
This project is licensed under the same terms as the parent aggregator project.

0 commit comments

Comments
 (0)