use indexmap::{IndexMap, IndexSet};
use nautilus_model::{
enums::{AvgPxReconciliation, OrderSide, PositionSide},
identifiers::{AccountId, InstrumentId, TradeId, VenueOrderId},
reports::{FillReport, OrderStatusReport},
};
use rust_decimal::Decimal;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct FillSnapshot {
pub venue_order_id: VenueOrderId,
pub side: OrderSide,
pub qty: Decimal,
pub px: Decimal,
pub ts_event: u64,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct VenuePositionSnapshot {
pub side: PositionSide,
pub qty: Decimal,
pub avg_px: Decimal,
pub avg_px_reconciliation: AvgPxReconciliation,
pub avg_px_precision: Option<u8>,
}
impl VenuePositionSnapshot {
pub(super) fn signed_qty(&self) -> Decimal {
match self.side {
PositionSide::Long => self.qty,
PositionSide::Short => -self.qty,
PositionSide::Flat => Decimal::ZERO,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub(super) enum FillAdjustmentResult {
NoAdjustment,
AddSyntheticOpening {
synthetic_fill: FillSnapshot,
existing_fills: Vec<FillSnapshot>,
},
ReplaceCurrentLifecycle {
synthetic_fill: FillSnapshot,
},
FilterToCurrentLifecycle {
last_zero_crossing_ts: u64,
current_lifecycle_fills: Vec<FillSnapshot>,
},
}
impl FillSnapshot {
#[must_use]
pub(super) fn new(
venue_order_id: VenueOrderId,
side: OrderSide,
qty: Decimal,
px: Decimal,
ts_event: u64,
) -> Self {
Self {
venue_order_id,
side,
qty,
px,
ts_event,
}
}
#[must_use]
pub(super) fn direction(&self) -> i8 {
match self.side {
OrderSide::Buy => 1,
OrderSide::Sell => -1,
}
}
}
#[derive(Debug, Clone)]
pub struct ReconciliationResult {
pub orders: IndexMap<VenueOrderId, OrderStatusReport>,
pub fills: IndexMap<VenueOrderId, Vec<FillReport>>,
pub order_only_ids: IndexSet<VenueOrderId>,
pub order_only_fill_keys: IndexSet<(AccountId, InstrumentId, TradeId)>,
}