pub struct OrderBook {
pub token_id: String,
pub token_id_hash: u64,
pub sequence: u64,
pub last_delta_sequence: u64,
pub last_snapshot_timestamp_ms: u64,
pub timestamp: DateTime<Utc>,
/* private fields */
}Expand description
High-performance order book implementation
This is the core data structure that holds all the live buy/sell orders for a token. The efficiency of this code is critical as the order book is constantly being updated as orders are added and removed.
PERFORMANCE OPTIMIZATION: This struct now uses fixed-point integers internally instead of Decimal for maximum speed. The performance difference is dramatic:
Before (Decimal): ~100ns per operation + memory allocation After (fixed-point): ~5ns per operation, zero allocations
Fields§
§token_id: StringToken ID this book represents (like “123456” for a specific prediction market outcome)
token_id_hash: u64Hash of token_id for fast lookups (avoids string comparisons in hot path)
sequence: u64Legacy delta sequence number.
Kept as a compatibility alias for Self::last_delta_sequence. WebSocket
snapshot timestamps are tracked separately in Self::last_snapshot_timestamp_ms.
last_delta_sequence: u64Last accepted legacy/incremental delta sequence number.
Delta sequences are a different clock from WebSocket snapshot timestamps and must not be compared against millisecond timestamps.
last_snapshot_timestamp_ms: u64Last accepted full-book snapshot timestamp in milliseconds.
Used for WebSocket book snapshots and serde BookUpdate snapshots.
timestamp: DateTime<Utc>Last update timestamp - when we last got new data for this book
Implementations§
Source§impl OrderBook
impl OrderBook
Sourcepub fn new(token_id: String, max_depth: usize) -> Self
pub fn new(token_id: String, max_depth: usize) -> Self
Create a new order book Just sets up empty bid/ask maps and basic metadata
Sourcepub fn set_tick_size(&mut self, tick_size: Decimal) -> Result<()>
pub fn set_tick_size(&mut self, tick_size: Decimal) -> Result<()>
Set the tick size for this book This tells us the minimum price increment allowed We store it in ticks for fast validation without conversion overhead
Sourcepub fn set_tick_size_ticks(&mut self, tick_size_ticks: Price)
pub fn set_tick_size_ticks(&mut self, tick_size_ticks: Price)
Set the tick size directly in ticks (even faster) Use this when you already have the tick size in our internal format
Sourcepub fn best_bid(&self) -> Option<BookLevel>
pub fn best_bid(&self) -> Option<BookLevel>
Get the current best bid (highest price someone is willing to pay) Bids are stored highest price first.
PERFORMANCE: Now returns data in external format but internally uses fast lookups
Sourcepub fn best_ask(&self) -> Option<BookLevel>
pub fn best_ask(&self) -> Option<BookLevel>
Get the current best ask (lowest price someone is willing to sell at) Asks are stored lowest price first.
PERFORMANCE: Now returns data in external format but internally uses fast lookups
Sourcepub fn best_bid_fast(&self) -> Option<FastBookLevel>
pub fn best_bid_fast(&self) -> Option<FastBookLevel>
Get the current best bid in fast internal format Use this for internal calculations to avoid conversion overhead
Sourcepub fn best_ask_fast(&self) -> Option<FastBookLevel>
pub fn best_ask_fast(&self) -> Option<FastBookLevel>
Get the current best ask in fast internal format Use this for internal calculations to avoid conversion overhead
Sourcepub fn spread(&self) -> Option<Decimal>
pub fn spread(&self) -> Option<Decimal>
Get the current spread (difference between best ask and best bid) This tells us how “tight” the market is - smaller spread = more liquid market
PERFORMANCE: Now uses fast internal calculations, only converts to Decimal at the end
Sourcepub fn mid_price(&self) -> Option<Decimal>
pub fn mid_price(&self) -> Option<Decimal>
Get the current mid price (halfway between best bid and ask) This is often used as the “fair value” of the market
PERFORMANCE: Now uses fast internal calculations, only converts to Decimal at the end
Sourcepub fn spread_pct(&self) -> Option<Decimal>
pub fn spread_pct(&self) -> Option<Decimal>
Get the spread as a percentage (relative to the bid price) Useful for comparing spreads across different price levels
PERFORMANCE: Now uses fast internal calculations and returns basis points
Sourcepub fn spread_fast(&self) -> Option<Price>
pub fn spread_fast(&self) -> Option<Price>
Get the current spread in fast internal format (PERFORMANCE OPTIMIZED) Returns spread in ticks - use this for internal calculations
Sourcepub fn mid_price_fast(&self) -> Option<Price>
pub fn mid_price_fast(&self) -> Option<Price>
Get the current mid price in fast internal format (PERFORMANCE OPTIMIZED) Returns mid price in ticks - use this for internal calculations
Sourcepub fn bids(&self, depth: Option<usize>) -> Vec<BookLevel>
pub fn bids(&self, depth: Option<usize>) -> Vec<BookLevel>
Get all bids up to a certain depth (top N price levels) Returns them in descending price order (best bids first)
PERFORMANCE: Converts from internal fixed-point to external Decimal format Only call this when you need to return data to external APIs
Sourcepub fn asks(&self, depth: Option<usize>) -> Vec<BookLevel>
pub fn asks(&self, depth: Option<usize>) -> Vec<BookLevel>
Get all asks up to a certain depth (top N price levels) Returns them in ascending price order (best asks first)
PERFORMANCE: Converts from internal fixed-point to external Decimal format Only call this when you need to return data to external APIs
Sourcepub fn bids_fast(&self, depth: Option<usize>) -> Vec<FastBookLevel>
pub fn bids_fast(&self, depth: Option<usize>) -> Vec<FastBookLevel>
Get all bids in fast internal format Use this for internal calculations to avoid conversion overhead
Sourcepub fn asks_fast(&self, depth: Option<usize>) -> Vec<FastBookLevel>
pub fn asks_fast(&self, depth: Option<usize>) -> Vec<FastBookLevel>
Get all asks in fast internal format (PERFORMANCE OPTIMIZED) Use this for internal calculations to avoid conversion overhead
Sourcepub fn snapshot(&self) -> OrderBook
pub fn snapshot(&self) -> OrderBook
Get the full book snapshot Creates a copy of the current state that can be safely passed around without worrying about the original book changing
Sourcepub fn apply_delta(&mut self, delta: OrderDelta) -> Result<()>
pub fn apply_delta(&mut self, delta: OrderDelta) -> Result<()>
Apply a delta update to the book (LEGACY VERSION - for external API compatibility) A “delta” is an incremental change - like “add 100 tokens at $0.65” or “remove all at $0.70”
This method converts the external Decimal delta to our internal fixed-point format and then calls the fast version. Use apply_delta_fast() directly when possible.
Sourcepub fn apply_delta_fast(&mut self, delta: FastOrderDelta) -> Result<()>
pub fn apply_delta_fast(&mut self, delta: FastOrderDelta) -> Result<()>
Apply a delta update to the book
This is the high-performance version that works directly with fixed-point data. It includes tick alignment validation and is much faster than the Decimal version.
Performance improvement: ~50x faster than the old Decimal version!
- No Decimal conversions in the hot path
- Integer comparisons instead of Decimal comparisons
- No memory allocations for price/size operations
Sourcepub fn apply_book_update(&mut self, update: &BookUpdate) -> Result<()>
pub fn apply_book_update(&mut self, update: &BookUpdate) -> Result<()>
Apply a WebSocket book update for this token.
The official Polymarket CLOB WebSocket book event is a full snapshot.
Unlike apply_delta_fast, this method can apply many levels that share
the same message timestamp.
Notes:
- This replaces the snapshot for both sides.
- Levels omitted from the message are removed.
- Insertions of new price levels may allocate or shift vector entries.
Sourcepub fn calculate_market_impact(
&self,
side: Side,
size: Decimal,
) -> Option<MarketImpact>
pub fn calculate_market_impact( &self, side: Side, size: Decimal, ) -> Option<MarketImpact>
Calculate the market impact for a given order size This is exactly why we don’t need deep levels - if your order would require hitting prices way off the current market (like $0.95 when best ask is $0.67), you’d never actually place that order. You’d either:
- Break it into smaller pieces over time
- Use a different trading strategy
- Accept that there’s not enough liquidity right now
Sourcepub fn is_stale(&self, max_age: Duration) -> bool
pub fn is_stale(&self, max_age: Duration) -> bool
Check if the book is stale (no recent updates) Useful for detecting when we’ve lost connection to live data
Sourcepub fn liquidity_at_price(&self, price: Decimal, side: Side) -> Decimal
pub fn liquidity_at_price(&self, price: Decimal, side: Side) -> Decimal
Get the total liquidity at a given price level Tells you how much you can buy/sell at exactly this price
Trait Implementations§
Auto Trait Implementations§
impl Freeze for OrderBook
impl RefUnwindSafe for OrderBook
impl Send for OrderBook
impl Sync for OrderBook
impl Unpin for OrderBook
impl UnsafeUnpin for OrderBook
impl UnwindSafe for OrderBook
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more