mirror of
https://github.com/floor-licker/polyfill-rs.git
synced 2026-08-15 05:28:07 +00:00
feat: Add EIP-712 signing for L1 authentication (src/auth.rs), HMAC-SHA256 for L2 API authentication, create_api_key(), derive_api_key(), create_or_derive_api_key(), Add set_api_creds() for credential management, Add create_order() and create_market_order() with EIP-712 signing, Add post_order() and create_and_post_order() for order submission, Add cancel(), cancel_orders(), cancel_all() for order management, Add OrderBuilder with proper tick size validation and rounding, Add get_orders() with filtering by ID, asset, market, Add get_trades() with filtering by time range, maker, asset, Add OpenOrderParams and TradeParams for query flexibility, Add balance_allowance() for balance and allowance queries, Add notifications() for push notification setup, Add get_midpoints() for efficient multi-token midpoint queries, Add get_prices() for batch bid/ask/mid price retrieval, Add BatchMidpointRequest/Response and BatchPriceRequest/Response types, Replace Decimal with u32 (Price) and i64 (Qty) on hot paths, Add decimal_to_price() and decimal_to_qty() conversion functions
This commit is contained in:
+35
-12
@@ -8,7 +8,6 @@ use std::collections::BTreeMap; // BTreeMap keeps prices sorted automatically -
|
||||
use std::sync::{Arc, RwLock}; // For thread-safe access across multiple tasks
|
||||
use tracing::{debug, trace, warn}; // Logging for debugging and monitoring
|
||||
use chrono::Utc;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// High-performance order book implementation
|
||||
///
|
||||
@@ -567,26 +566,47 @@ impl OrderBook {
|
||||
/// Get the total liquidity at a given price level
|
||||
/// Tells you how much you can buy/sell at exactly this price
|
||||
pub fn liquidity_at_price(&self, price: Decimal, side: Side) -> Decimal {
|
||||
let price_u32 = decimal_to_price(price).unwrap_or(0);
|
||||
// Convert decimal price to our internal fixed-point representation
|
||||
let price_ticks = match decimal_to_price(price) {
|
||||
Ok(ticks) => ticks,
|
||||
Err(_) => return Decimal::ZERO, // Invalid price
|
||||
};
|
||||
|
||||
match side {
|
||||
Side::BUY => Decimal::from(self.asks.get(&price_u32).copied().unwrap_or_default()), // How much we can buy at this price
|
||||
Side::SELL => Decimal::from(self.bids.get(&price_u32).copied().unwrap_or_default()), // How much we can sell at this price
|
||||
Side::BUY => {
|
||||
// How much we can buy at this price (look at asks)
|
||||
let size_units = self.asks.get(&price_ticks).copied().unwrap_or_default();
|
||||
qty_to_decimal(size_units)
|
||||
},
|
||||
Side::SELL => {
|
||||
// How much we can sell at this price (look at bids)
|
||||
let size_units = self.bids.get(&price_ticks).copied().unwrap_or_default();
|
||||
qty_to_decimal(size_units)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the total liquidity within a price range
|
||||
/// Useful for understanding how much depth exists in a certain price band
|
||||
pub fn liquidity_in_range(&self, min_price: Decimal, max_price: Decimal, side: Side) -> Decimal {
|
||||
let min_price_u32 = decimal_to_price(min_price).unwrap_or(0);
|
||||
let max_price_u32 = decimal_to_price(max_price).unwrap_or(0);
|
||||
// Convert decimal prices to our internal fixed-point representation
|
||||
let min_price_ticks = match decimal_to_price(min_price) {
|
||||
Ok(ticks) => ticks,
|
||||
Err(_) => return Decimal::ZERO, // Invalid price
|
||||
};
|
||||
let max_price_ticks = match decimal_to_price(max_price) {
|
||||
Ok(ticks) => ticks,
|
||||
Err(_) => return Decimal::ZERO, // Invalid price
|
||||
};
|
||||
|
||||
let levels: Vec<_> = match side {
|
||||
Side::BUY => self.asks.range(min_price_u32..=max_price_u32).collect(),
|
||||
Side::SELL => self.bids.range(min_price_u32..=max_price_u32).rev().collect(),
|
||||
Side::BUY => self.asks.range(min_price_ticks..=max_price_ticks).collect(),
|
||||
Side::SELL => self.bids.range(min_price_ticks..=max_price_ticks).rev().collect(),
|
||||
};
|
||||
|
||||
let total: i64 = levels.into_iter().map(|(_, &size)| size).sum();
|
||||
Decimal::from(total)
|
||||
// Sum up the sizes, converting from fixed-point back to Decimal
|
||||
let total_size_units: i64 = levels.into_iter().map(|(_, &size)| size).sum();
|
||||
qty_to_decimal(total_size_units)
|
||||
}
|
||||
|
||||
/// Validate that prices are properly ordered
|
||||
@@ -743,8 +763,11 @@ impl OrderBook {
|
||||
pub fn analytics(&self) -> BookAnalytics {
|
||||
let bid_count = self.bids.len();
|
||||
let ask_count = self.asks.len();
|
||||
let total_bid_size: Decimal = Decimal::from(self.bids.values().sum::<i64>()); // Add up all bid sizes
|
||||
let total_ask_size: Decimal = Decimal::from(self.asks.values().sum::<i64>()); // Add up all ask sizes
|
||||
// Sum up all bid/ask sizes, converting from fixed-point back to Decimal
|
||||
let total_bid_size_units: i64 = self.bids.values().sum();
|
||||
let total_ask_size_units: i64 = self.asks.values().sum();
|
||||
let total_bid_size = qty_to_decimal(total_bid_size_units);
|
||||
let total_ask_size = qty_to_decimal(total_ask_size_units);
|
||||
|
||||
BookAnalytics {
|
||||
token_id: self.token_id.clone(),
|
||||
|
||||
Reference in New Issue
Block a user