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