nautilus_execution/reports/
position.rs1use std::fmt::{Debug, Display};
17
18use nautilus_core::{UUID4, UnixNanos};
19use nautilus_model::{
20 enums::PositionSide,
21 identifiers::{AccountId, InstrumentId, PositionId},
22 types::Quantity,
23};
24use rust_decimal::Decimal;
25use serde::{Deserialize, Serialize};
26
27#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
29#[serde(tag = "type")]
30#[cfg_attr(
31 feature = "python",
32 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.execution")
33)]
34pub struct PositionStatusReport {
35 pub account_id: AccountId,
37 pub instrument_id: InstrumentId,
39 pub position_side: PositionSide,
41 pub quantity: Quantity,
43 pub signed_decimal_qty: Decimal,
45 pub report_id: UUID4,
47 pub ts_last: UnixNanos,
49 pub ts_init: UnixNanos,
51 pub venue_position_id: Option<PositionId>,
53}
54
55impl PositionStatusReport {
56 #[allow(clippy::too_many_arguments)]
58 #[must_use]
59 pub fn new(
60 account_id: AccountId,
61 instrument_id: InstrumentId,
62 position_side: PositionSide,
63 quantity: Quantity,
64 venue_position_id: Option<PositionId>,
65 ts_last: UnixNanos,
66 ts_init: UnixNanos,
67 report_id: Option<UUID4>,
68 ) -> Self {
69 let signed_decimal_qty = match position_side {
71 PositionSide::Long => quantity.as_decimal(),
72 PositionSide::Short => -quantity.as_decimal(),
73 PositionSide::Flat => Decimal::ZERO,
74 PositionSide::NoPositionSide => Decimal::ZERO, };
76
77 Self {
78 account_id,
79 instrument_id,
80 position_side,
81 quantity,
82 signed_decimal_qty,
83 report_id: report_id.unwrap_or_default(),
84 ts_last,
85 ts_init,
86 venue_position_id,
87 }
88 }
89
90 #[must_use]
92 pub const fn has_venue_position_id(&self) -> bool {
93 self.venue_position_id.is_some()
94 }
95
96 #[must_use]
98 pub const fn is_flat(&self) -> bool {
99 matches!(
100 self.position_side,
101 PositionSide::Flat | PositionSide::NoPositionSide
102 )
103 }
104
105 #[must_use]
107 pub fn is_long(&self) -> bool {
108 self.position_side == PositionSide::Long
109 }
110
111 #[must_use]
113 pub fn is_short(&self) -> bool {
114 self.position_side == PositionSide::Short
115 }
116}
117
118impl Display for PositionStatusReport {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 write!(
121 f,
122 "PositionStatusReport(account={}, instrument={}, side={}, qty={}, venue_pos_id={:?}, ts_last={}, ts_init={})",
123 self.account_id,
124 self.instrument_id,
125 self.position_side,
126 self.signed_decimal_qty,
127 self.venue_position_id,
128 self.ts_last,
129 self.ts_init
130 )
131 }
132}