Use this file to discover all available pages before exploring further.
The nano-lob crate provides comprehensive feature extraction from order book snapshots for machine learning models. These features capture market microstructure signals used to predict short-term price movements.
for i in 0..levels { let weight = 1.0 / (i as f64 + 1.0); if let Some(level) = book.bid_level(i) { let qty = f64::from(level.quantity.value()); bid_sum += level.price.as_f64() * qty * weight; bid_weight_sum += qty * weight; } // ... same for ask side}weighted_mid = (bid_sum + ask_sum) / (bid_weight_sum + ask_weight_sum)
OFI tracks changes in order flow between consecutive book states:
let prev_book = /* previous book snapshot */;let curr_book = /* current book snapshot */;let ofi = extractor.order_flow_imbalance(&prev_book, &curr_book);
OFI Calculation Logic:
Bid side:
If bid price improved (higher): +new_bid_qty
If bid price worsened (lower): -old_bid_qty
If same price: delta_qty
Ask side:
If ask price improved (lower): -new_ask_qty
If ask price worsened (higher): +old_ask_qty
If same price: -delta_qty
Implementation:
pub fn order_flow_imbalance( &self, prev_book: &OrderBook, curr_book: &OrderBook,) -> f64 { let mut ofi = 0.0; // Bid side OFI if let (Some((prev_bp, prev_bq)), Some((curr_bp, curr_bq))) = (prev_book.best_bid(), curr_book.best_bid()) { if curr_bp > prev_bp { ofi += f64::from(curr_bq.value()); } else if curr_bp < prev_bp { ofi -= f64::from(prev_bq.value()); } else { ofi += (i64::from(curr_bq.value()) - i64::from(prev_bq.value())) as f64; } } // Ask side OFI (similar logic) // ... ofi / self.qty_scale}
VPIN (Volume-Synchronized Probability of Informed Trading)
VPIN estimates the probability of informed trading by analyzing volume buckets:
use nano_lob::features::VpinCalculator;let mut vpin = VpinCalculator::new( 1000, // bucket_size: complete bucket after 1000 contracts traded 50, // num_buckets: use last 50 buckets for calculation);// Add trades as they occurvpin.add_trade(Quantity::new(10), true); // buyvpin.add_trade(Quantity::new(5), false); // sell// Calculate VPIN (0 to 1)let vpin_value = vpin.calculate();// High VPIN (>0.7) suggests high probability of informed trading// Low VPIN (<0.3) suggests more random trading
use nano_lob::snapshot::SnapshotRingBuffer;let mut history = SnapshotRingBuffer::new(100); // Keep last 100 snapshotslet extractor = LobFeatureExtractor::new();// After each book updatelet snapshot = book.to_snapshot(timestamp);history.push(snapshot);// Calculate OFI over last N snapshotsif let (Some(prev), Some(curr)) = (history.get(history.len() - 2), history.latest()) { let prev_book = OrderBook::from_snapshot(prev); let curr_book = OrderBook::from_snapshot(curr); let ofi = extractor.order_flow_imbalance(&prev_book, &curr_book); println!("OFI: {:.3}", ofi);}