use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct DepthStats {
pub total_volume: u64,
pub levels_count: usize,
pub avg_level_size: f64,
pub weighted_avg_price: f64,
pub min_level_size: u64,
pub max_level_size: u64,
pub std_dev_level_size: f64,
}
impl DepthStats {
#[must_use]
pub fn zero() -> Self {
Self {
total_volume: 0,
levels_count: 0,
avg_level_size: 0.0,
weighted_avg_price: 0.0,
min_level_size: 0,
max_level_size: 0,
std_dev_level_size: 0.0,
}
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.levels_count == 0 || self.total_volume == 0
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct DistributionBin {
pub min_price: u128,
pub max_price: u128,
pub volume: u64,
pub level_count: usize,
}
impl DistributionBin {
#[must_use]
pub fn midpoint(&self) -> u128 {
(self.min_price + self.max_price) / 2
}
#[must_use]
pub fn width(&self) -> u128 {
self.max_price.saturating_sub(self.min_price)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_depth_stats_zero() {
let stats = DepthStats::zero();
assert_eq!(stats.total_volume, 0);
assert_eq!(stats.levels_count, 0);
assert_eq!(stats.avg_level_size, 0.0);
assert!(stats.is_empty());
}
#[test]
fn test_depth_stats_not_empty() {
let stats = DepthStats {
total_volume: 100,
levels_count: 5,
avg_level_size: 20.0,
weighted_avg_price: 50000.0,
min_level_size: 10,
max_level_size: 30,
std_dev_level_size: 5.0,
};
assert!(!stats.is_empty());
}
#[test]
fn test_distribution_bin_midpoint() {
let bin = DistributionBin {
min_price: 100,
max_price: 200,
volume: 50,
level_count: 3,
};
assert_eq!(bin.midpoint(), 150);
assert_eq!(bin.width(), 100);
}
}