Sequence/docs

L2Book Structure

The L2Book gives you 20 levels of order book depth:

rust
pub struct L2Book {
    pub bids: [Level; 20],  // Best bid at index 0
    pub asks: [Level; 20],  // Best ask at index 0
    pub bid_ct: u8,         // Number of valid bid levels
    pub ask_ct: u8,         // Number of valid ask levels
    pub symbol_id: u16,     // Symbol identifier
    pub recv_ns: u64,       // When we received this update
}
 
pub struct Level {
    pub px_1e9: u64,        // Price × 10⁹
    pub sz_1e8: u64,        // Size × 10⁸
}
Note

The book is sorted: bids[0] is the highest bid, asks[0] is the lowest ask.

Accessing Levels

rust
fn on_book(&mut self, book: &L2Book, state: &AlgoState, _features: &OnlineFeatures, actions: &mut Actions) {
    // Best bid/ask
    let best_bid = &book.bids[0];
    let best_ask = &book.asks[0];
    
    // Check if valid
    if book.bid_ct > 0 && book.ask_ct > 0 {
        println!("Bid: {} @ {}", best_bid.sz_1e8, best_bid.px_1e9);
        println!("Ask: {} @ {}", best_ask.sz_1e8, best_ask.px_1e9);
    }
    
    // Iterate deeper levels
    for i in 0..book.bid_ct as usize {
        let level = &book.bids[i];
        // ...
    }
}

Helper Methods

Prices

MethodReturnsDescription
best_bid()Option<&Level>Best bid level
best_ask()Option<&Level>Best ask level
mid_px_1e9()u64Mid price (avg of best bid/ask)
spread_1e9()u64Spread in price units
spread_bps()u32Spread in basis points
rust
// Get mid price
let mid = book.mid_px_1e9();
 
// Check if spread is too tight
if book.spread_bps() < 5 {
    return; // Don't trade
}

Depth & Liquidity

MethodReturnsDescription
bid_depth_1e8(n)u64Total bid size for top N levels
ask_depth_1e8(n)u64Total ask size for top N levels
imbalance_bps(n)i32Order imbalance (-10000 to +10000)
rust
// Total liquidity in top 5 levels
let bid_liq = book.bid_depth_1e8(5);
let ask_liq = book.ask_depth_1e8(5);
 
// Order imbalance (positive = more bids)
let imb = book.imbalance_bps(5);
if imb > 2000 {
    // Strong bid-side pressure
}

Example: VWAP Calculation

rust
fn vwap_1e9(book: &L2Book, side: i8, qty_1e8: i64) -> Option<u64> {
    let levels = if side > 0 { &book.asks } else { &book.bids };
    let count = if side > 0 { book.ask_ct } else { book.bid_ct } as usize;
    
    let mut remaining = qty_1e8;
    let mut total_value: u128 = 0;
    let mut total_qty: i64 = 0;
    
    for i in 0..count {
        if remaining <= 0 { break; }
        
        let lvl = &levels[i];
        let fill = remaining.min(lvl.sz_1e8 as i64);
        
        total_value += fill as u128 * lvl.px_1e9 as u128;
        total_qty += fill;
        remaining -= fill;
    }
    
    if total_qty == 0 { return None; }
    Some((total_value / total_qty as u128) as u64)
}

Example: Microprice

rust
fn microprice_1e9(book: &L2Book) -> u64 {
    if book.bid_ct == 0 || book.ask_ct == 0 {
        return 0;
    }
    
    let bid = &book.bids[0];
    let ask = &book.asks[0];
    let total = bid.sz_1e8 + ask.sz_1e8;
    
    if total == 0 {
        return book.mid_px_1e9();
    }
    
    // Size-weighted mid
    ((bid.px_1e9 as u128 * ask.sz_1e8 as u128 
      + ask.px_1e9 as u128 * bid.sz_1e8 as u128) 
      / total as u128) as u64
}

Performance Tips

Tip

The L2Book struct is 688 bytes and fits in L1 cache. Direct array access is faster than method calls for hot loops.

rust
// Fast: direct access
let bid_px = book.bids[0].px_1e9;
 
// Slightly slower: method call
let bid_px = book.best_bid().map(|l| l.px_1e9).unwrap_or(0);