1pub mod account;
19pub mod funding;
20pub mod order;
21pub mod portfolio;
22pub mod position;
23
24use nautilus_core::UnixNanos;
25
26use crate::data::HasTsInit;
27pub use crate::events::{
29 account::state::AccountState,
30 funding::settlement::FundingSettlement,
31 order::{
32 OrderEvent, OrderEventType,
33 accepted::OrderAccepted,
34 accepted_batch::OrderAcceptedBatch,
35 any::OrderEventAny,
36 cancel_rejected::OrderCancelRejected,
37 canceled::OrderCanceled,
38 canceled_batch::OrderCanceledBatch,
39 denied::OrderDenied,
40 denied_reason::{OrderDeniedCode, OrderDeniedReason, OrderPriceField},
41 emulated::OrderEmulated,
42 expired::OrderExpired,
43 fill_voided::OrderFillVoided,
44 filled::OrderFilled,
45 initialized::OrderInitialized,
46 modify_rejected::OrderModifyRejected,
47 pending_cancel::OrderPendingCancel,
48 pending_update::OrderPendingUpdate,
49 rejected::OrderRejected,
50 released::OrderReleased,
51 snapshot::OrderSnapshot,
52 submitted::OrderSubmitted,
53 submitted_batch::OrderSubmittedBatch,
54 triggered::OrderTriggered,
55 updated::OrderUpdated,
56 },
57 portfolio::snapshot::PortfolioSnapshot,
58 position::{
59 PositionEvent, adjusted::PositionAdjusted, changed::PositionChanged,
60 closed::PositionClosed, opened::PositionOpened, snapshot::PositionSnapshot,
61 },
62};
63
64impl HasTsInit for AccountState {
65 fn ts_init(&self) -> UnixNanos {
66 self.ts_init
67 }
68}
69
70impl HasTsInit for FundingSettlement {
71 fn ts_init(&self) -> UnixNanos {
72 self.ts_init
73 }
74}
75
76impl HasTsInit for OrderInitialized {
77 fn ts_init(&self) -> UnixNanos {
78 self.ts_init
79 }
80}
81
82impl HasTsInit for OrderDenied {
83 fn ts_init(&self) -> UnixNanos {
84 self.ts_init
85 }
86}
87
88impl HasTsInit for OrderEmulated {
89 fn ts_init(&self) -> UnixNanos {
90 self.ts_init
91 }
92}
93
94impl HasTsInit for OrderSubmitted {
95 fn ts_init(&self) -> UnixNanos {
96 self.ts_init
97 }
98}
99
100impl HasTsInit for OrderAccepted {
101 fn ts_init(&self) -> UnixNanos {
102 self.ts_init
103 }
104}
105
106impl HasTsInit for OrderRejected {
107 fn ts_init(&self) -> UnixNanos {
108 self.ts_init
109 }
110}
111
112impl HasTsInit for OrderPendingCancel {
113 fn ts_init(&self) -> UnixNanos {
114 self.ts_init
115 }
116}
117
118impl HasTsInit for OrderCanceled {
119 fn ts_init(&self) -> UnixNanos {
120 self.ts_init
121 }
122}
123
124impl HasTsInit for OrderCancelRejected {
125 fn ts_init(&self) -> UnixNanos {
126 self.ts_init
127 }
128}
129
130impl HasTsInit for OrderExpired {
131 fn ts_init(&self) -> UnixNanos {
132 self.ts_init
133 }
134}
135
136impl HasTsInit for OrderTriggered {
137 fn ts_init(&self) -> UnixNanos {
138 self.ts_init
139 }
140}
141
142impl HasTsInit for OrderPendingUpdate {
143 fn ts_init(&self) -> UnixNanos {
144 self.ts_init
145 }
146}
147
148impl HasTsInit for OrderReleased {
149 fn ts_init(&self) -> UnixNanos {
150 self.ts_init
151 }
152}
153
154impl HasTsInit for OrderModifyRejected {
155 fn ts_init(&self) -> UnixNanos {
156 self.ts_init
157 }
158}
159
160impl HasTsInit for OrderUpdated {
161 fn ts_init(&self) -> UnixNanos {
162 self.ts_init
163 }
164}
165
166impl HasTsInit for OrderFilled {
167 fn ts_init(&self) -> UnixNanos {
168 self.ts_init
169 }
170}
171
172impl HasTsInit for OrderFillVoided {
173 fn ts_init(&self) -> UnixNanos {
174 self.ts_init
175 }
176}
177
178impl HasTsInit for OrderSnapshot {
179 fn ts_init(&self) -> UnixNanos {
180 self.ts_init
181 }
182}
183
184impl HasTsInit for PositionOpened {
185 fn ts_init(&self) -> UnixNanos {
186 self.ts_init
187 }
188}
189
190impl HasTsInit for PositionChanged {
191 fn ts_init(&self) -> UnixNanos {
192 self.ts_init
193 }
194}
195
196impl HasTsInit for PositionClosed {
197 fn ts_init(&self) -> UnixNanos {
198 self.ts_init
199 }
200}
201
202impl HasTsInit for PositionAdjusted {
203 fn ts_init(&self) -> UnixNanos {
204 self.ts_init
205 }
206}
207
208impl HasTsInit for PositionSnapshot {
209 fn ts_init(&self) -> UnixNanos {
210 self.ts_init
211 }
212}
213
214impl HasTsInit for PortfolioSnapshot {
215 fn ts_init(&self) -> UnixNanos {
216 self.ts_init
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use nautilus_core::UUID4;
223 use rstest::rstest;
224 use rust_decimal_macros::dec;
225
226 use super::*;
227 use crate::{
228 enums::{AccountType, OrderSide, OrderType, PositionAdjustmentType},
229 events::order::spec::{
230 OrderAcceptedSpec, OrderCancelRejectedSpec, OrderCanceledSpec, OrderDeniedSpec,
231 OrderEmulatedSpec, OrderExpiredSpec, OrderFillVoidedSpec, OrderFilledSpec,
232 OrderInitializedSpec, OrderModifyRejectedSpec, OrderPendingCancelSpec,
233 OrderPendingUpdateSpec, OrderRejectedSpec, OrderReleasedSpec, OrderSubmittedSpec,
234 OrderTriggeredSpec, OrderUpdatedSpec,
235 },
236 identifiers::{AccountId, InstrumentId, PositionId, StrategyId, TraderId},
237 orders::builder::OrderTestBuilder,
238 position::Position,
239 stubs::stub_position_long,
240 types::{Currency, Money, Price, Quantity},
241 };
242
243 #[rstest]
244 fn test_order_lifecycle_event_ts_init() {
245 let ts_init = UnixNanos::from(1);
246
247 assert_eq!(
248 HasTsInit::ts_init(&OrderInitializedSpec::builder().ts_init(ts_init).build()),
249 ts_init
250 );
251 assert_eq!(
252 HasTsInit::ts_init(&OrderDeniedSpec::builder().ts_init(ts_init).build()),
253 ts_init
254 );
255 assert_eq!(
256 HasTsInit::ts_init(&OrderEmulatedSpec::builder().ts_init(ts_init).build()),
257 ts_init
258 );
259 assert_eq!(
260 HasTsInit::ts_init(&OrderReleasedSpec::builder().ts_init(ts_init).build()),
261 ts_init
262 );
263 assert_eq!(
264 HasTsInit::ts_init(&OrderSubmittedSpec::builder().ts_init(ts_init).build()),
265 ts_init
266 );
267 assert_eq!(
268 HasTsInit::ts_init(&OrderAcceptedSpec::builder().ts_init(ts_init).build()),
269 ts_init
270 );
271 assert_eq!(
272 HasTsInit::ts_init(&OrderRejectedSpec::builder().ts_init(ts_init).build()),
273 ts_init
274 );
275 assert_eq!(
276 HasTsInit::ts_init(&OrderTriggeredSpec::builder().ts_init(ts_init).build()),
277 ts_init
278 );
279 assert_eq!(
280 HasTsInit::ts_init(&OrderExpiredSpec::builder().ts_init(ts_init).build()),
281 ts_init
282 );
283 assert_eq!(
284 HasTsInit::ts_init(&OrderCanceledSpec::builder().ts_init(ts_init).build()),
285 ts_init
286 );
287 }
288
289 #[rstest]
290 fn test_order_amendment_event_ts_init() {
291 let ts_init = UnixNanos::from(2);
292
293 assert_eq!(
294 HasTsInit::ts_init(&OrderPendingUpdateSpec::builder().ts_init(ts_init).build()),
295 ts_init
296 );
297 assert_eq!(
298 HasTsInit::ts_init(&OrderPendingCancelSpec::builder().ts_init(ts_init).build()),
299 ts_init
300 );
301 assert_eq!(
302 HasTsInit::ts_init(&OrderModifyRejectedSpec::builder().ts_init(ts_init).build()),
303 ts_init
304 );
305 assert_eq!(
306 HasTsInit::ts_init(&OrderCancelRejectedSpec::builder().ts_init(ts_init).build()),
307 ts_init
308 );
309 assert_eq!(
310 HasTsInit::ts_init(&OrderUpdatedSpec::builder().ts_init(ts_init).build()),
311 ts_init
312 );
313 }
314
315 #[rstest]
316 fn test_order_fill_event_ts_init() {
317 let ts_init = UnixNanos::from(3);
318
319 assert_eq!(
320 HasTsInit::ts_init(&OrderFilledSpec::builder().ts_init(ts_init).build()),
321 ts_init
322 );
323 assert_eq!(
324 HasTsInit::ts_init(&OrderFillVoidedSpec::builder().ts_init(ts_init).build()),
325 ts_init
326 );
327 }
328
329 #[rstest]
330 fn test_order_snapshot_ts_init() {
331 let ts_init = UnixNanos::from(4);
332 let order = OrderTestBuilder::new(OrderType::Market)
333 .instrument_id(InstrumentId::from("AUD/USD.SIM"))
334 .side(OrderSide::Buy)
335 .quantity(Quantity::from(1))
336 .build();
337 let mut snapshot = OrderSnapshot::from(order);
338 snapshot.ts_init = ts_init;
339
340 assert_eq!(HasTsInit::ts_init(&snapshot), ts_init);
341 }
342
343 #[rstest]
344 fn test_position_event_ts_init(mut stub_position_long: Position) {
345 let ts_init = UnixNanos::from(5);
346 let event_id = UUID4::default();
347 let fill = stub_position_long.last_event().unwrap();
348
349 assert_eq!(
350 HasTsInit::ts_init(&PositionOpened::create(
351 &stub_position_long,
352 &fill,
353 event_id,
354 ts_init
355 )),
356 ts_init
357 );
358 assert_eq!(
359 HasTsInit::ts_init(&PositionChanged::create(
360 &stub_position_long,
361 &fill,
362 event_id,
363 ts_init
364 )),
365 ts_init
366 );
367 assert_eq!(
368 HasTsInit::ts_init(&PositionClosed::create(
369 &stub_position_long,
370 &fill,
371 event_id,
372 ts_init
373 )),
374 ts_init
375 );
376
377 stub_position_long.ts_init = ts_init;
378
379 assert_eq!(
380 HasTsInit::ts_init(&PositionSnapshot::from(&stub_position_long, None)),
381 ts_init
382 );
383 }
384
385 #[rstest]
386 fn test_position_adjusted_ts_init() {
387 let ts_init = UnixNanos::from(6);
388
389 let event = PositionAdjusted::new(
390 TraderId::from("TRADER-001"),
391 StrategyId::from("EMA-CROSS"),
392 InstrumentId::from("AUD/USD.SIM"),
393 PositionId::from("P-001"),
394 AccountId::from("SIM-001"),
395 PositionAdjustmentType::Funding,
396 None,
397 Some(Money::new(1.0, Currency::USD())),
398 None,
399 UUID4::default(),
400 UnixNanos::from(5),
401 ts_init,
402 );
403
404 assert_eq!(HasTsInit::ts_init(&event), ts_init);
405 }
406
407 #[rstest]
408 fn test_account_state_ts_init() {
409 let ts_init = UnixNanos::from(7);
410
411 let event = AccountState::new(
412 AccountId::from("SIM-001"),
413 AccountType::Cash,
414 vec![],
415 vec![],
416 true,
417 UUID4::default(),
418 UnixNanos::from(6),
419 ts_init,
420 Some(Currency::USD()),
421 );
422
423 assert_eq!(HasTsInit::ts_init(&event), ts_init);
424 }
425
426 #[rstest]
427 fn test_portfolio_snapshot_ts_init() {
428 let ts_init = UnixNanos::from(8);
429
430 let event = PortfolioSnapshot::new(
431 AccountId::from("SIM-001"),
432 AccountType::Cash,
433 Some(Currency::USD()),
434 vec![],
435 vec![],
436 vec![],
437 vec![],
438 vec![],
439 None,
440 false,
441 vec![],
442 vec![],
443 vec![],
444 UUID4::default(),
445 UnixNanos::from(7),
446 ts_init,
447 );
448
449 assert_eq!(HasTsInit::ts_init(&event), ts_init);
450 }
451
452 #[rstest]
453 fn test_funding_settlement_ts_init() {
454 let ts_init = UnixNanos::from(9);
455
456 let event = FundingSettlement::new(
457 TraderId::from("TRADER-001"),
458 InstrumentId::from("AUD/USD.SIM"),
459 AccountId::from("SIM-001"),
460 dec!(0.0001),
461 Price::from("1.00000"),
462 Currency::USD(),
463 UUID4::default(),
464 UnixNanos::from(8),
465 ts_init,
466 );
467
468 assert_eq!(HasTsInit::ts_init(&event), ts_init);
469 }
470}