use fastnum::UD64;
use super::BuilderAttribution;
#[derive(Clone, derive_more::Debug)]
pub struct MakerFill {
pub log_index: u64,
pub maker_account_id: super::AccountId,
pub maker_order_id: super::OrderId,
pub maker_client_order_id: Option<super::RequestId>,
#[debug("{price}")]
pub price: UD64,
#[debug("{size}")]
pub size: UD64,
#[debug("{fee}")]
pub fee: UD64,
pub builder: Option<super::BuilderAttribution>,
#[debug("{builder_fee}")]
pub builder_fee: UD64,
}
#[derive(Clone, derive_more::Debug)]
pub struct Trade {
pub perpetual_id: super::PerpetualId,
pub taker_account_id: super::AccountId,
pub taker_request_id: super::RequestId,
pub taker_side: super::OrderSide,
#[debug("{taker_fee}")]
pub taker_fee: UD64,
pub taker_builder: Option<BuilderAttribution>,
#[debug("{taker_builder_fee}")]
pub taker_builder_fee: UD64,
pub maker_fills: Vec<MakerFill>,
}
impl Trade {
pub fn total_size(&self) -> UD64 { self.maker_fills.iter().map(|f| f.size).sum() }
pub fn avg_price(&self) -> Option<UD64> {
if self.maker_fills.is_empty() {
return None;
}
let total_value: UD64 = self.maker_fills.iter().map(|f| f.price * f.size).sum();
let total_size = self.total_size();
if total_size == UD64::ZERO {
return None;
}
Some(total_value / total_size)
}
pub fn total_maker_fees(&self) -> UD64 { self.maker_fills.iter().map(|f| f.fee).sum() }
pub fn total_builder_fees(&self) -> UD64 {
self.taker_builder_fee + self.maker_fills.iter().map(|f| f.builder_fee).sum::<UD64>()
}
pub fn builder_total(&self, builder_id: super::BuilderId) -> UD64 {
let taker = self
.taker_builder
.filter(|b| b.builder_id() == builder_id)
.map(|_| self.taker_builder_fee)
.unwrap_or(UD64::ZERO);
taker
+ self
.maker_fills
.iter()
.filter(|f| f.builder.is_some_and(|b| b.builder_id() == builder_id))
.map(|f| f.builder_fee)
.sum::<UD64>()
}
pub fn maker_total(&self, account_id: super::AccountId) -> Option<(UD64, UD64, UD64)> {
let mut total_value = UD64::ZERO;
let mut total_size = UD64::ZERO;
let mut total_fee = UD64::ZERO;
for fill in self
.maker_fills
.iter()
.filter(|f| f.maker_account_id == account_id)
{
total_value += fill.price * fill.size;
total_size += fill.size;
total_fee += fill.fee
}
if total_size == UD64::ZERO {
return None;
}
Some((total_value / total_size, total_size, total_fee))
}
}