1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
1516use indexmap::IndexMap;
17use nautilus_core::{UUID4, UnixNanos};
18use rust_decimal::Decimal;
19use serde::{Deserialize, Serialize};
20use ustr::Ustr;
2122use crate::{
23 enums::{
24 ContingencyType, LiquiditySide, OrderSide, OrderStatus, OrderType, TimeInForce,
25 TrailingOffsetType, TriggerType,
26 },
27 identifiers::{
28 AccountId, ClientOrderId, ExecAlgorithmId, InstrumentId, OrderListId, PositionId,
29 StrategyId, TradeId, TraderId, VenueOrderId,
30 },
31 orders::{Order, OrderAny},
32 types::{Money, Price, Quantity},
33};
3435/// Represents an order state snapshot as a certain instant.
36#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
37#[cfg_attr(
38 feature = "python",
39 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model")
40)]
41pub struct OrderSnapshot {
42/// The trader ID associated with the order.
43pub trader_id: TraderId,
44/// The strategy ID associated with the order.
45pub strategy_id: StrategyId,
46/// The order instrument ID.
47pub instrument_id: InstrumentId,
48/// The client order ID.
49pub client_order_id: ClientOrderId,
50/// The venue assigned order ID.
51pub venue_order_id: Option<VenueOrderId>,
52/// The position ID associated with the order.
53pub position_id: Option<PositionId>,
54/// The account ID associated with the order.
55pub account_id: Option<AccountId>,
56/// The orders last trade match ID.
57pub last_trade_id: Option<TradeId>,
58/// The order type.
59pub order_type: OrderType,
60/// The order side.
61pub order_side: OrderSide,
62/// The order quantity.
63pub quantity: Quantity,
64/// The order price (LIMIT).
65pub price: Option<Price>,
66/// The order trigger price (STOP).
67pub trigger_price: Option<Price>,
68/// The trigger type for the order.
69pub trigger_type: Option<TriggerType>,
70/// The trailing offset for the orders limit price.
71pub limit_offset: Option<Decimal>,
72/// The trailing offset for the orders trigger price (STOP).
73pub trailing_offset: Option<Decimal>,
74/// The trailing offset type.
75pub trailing_offset_type: Option<TrailingOffsetType>,
76/// The order time in force.
77pub time_in_force: TimeInForce,
78/// The order expiration (UNIX epoch nanoseconds), zero for no expiration.
79pub expire_time: Option<UnixNanos>,
80/// The order total filled quantity.
81pub filled_qty: Quantity,
82/// The order liquidity side.
83pub liquidity_side: Option<LiquiditySide>,
84/// The order average fill price.
85pub avg_px: Option<f64>,
86/// The order total price slippage.
87pub slippage: Option<f64>,
88/// The commissions for the order.
89pub commissions: Vec<Money>,
90/// The order status.
91pub status: OrderStatus,
92/// If the order will only provide liquidity (make a market).
93pub is_post_only: bool,
94/// If the order carries the 'reduce-only' execution instruction.
95pub is_reduce_only: bool,
96/// If the order quantity is denominated in the quote currency.
97pub is_quote_quantity: bool,
98/// The quantity of the `LIMIT` order to display on the public book (iceberg).
99pub display_qty: Option<Quantity>,
100/// The order emulation trigger type.
101pub emulation_trigger: Option<TriggerType>,
102/// The order emulation trigger instrument ID (will be `instrument_id` if `None`).
103pub trigger_instrument_id: Option<InstrumentId>,
104/// The orders contingency type.
105pub contingency_type: Option<ContingencyType>,
106/// The order list ID associated with the order.
107pub order_list_id: Option<OrderListId>,
108/// The orders linked client order ID(s).
109pub linked_order_ids: Option<Vec<ClientOrderId>>,
110/// The parent client order ID.
111pub parent_order_id: Option<ClientOrderId>,
112/// The execution algorithm ID for the order.
113pub exec_algorithm_id: Option<ExecAlgorithmId>,
114/// The execution algorithm parameters for the order.
115pub exec_algorithm_params: Option<IndexMap<Ustr, Ustr>>,
116/// The execution algorithm spawning client order ID.
117pub exec_spawn_id: Option<ClientOrderId>,
118/// The order custom user tags.
119pub tags: Option<Vec<Ustr>>,
120/// The event ID of the `OrderInitialized` event.
121pub init_id: UUID4,
122/// UNIX timestamp (nanoseconds) when the object was initialized.
123pub ts_init: UnixNanos,
124/// UNIX timestamp (nanoseconds) when the last event occurred.
125pub ts_last: UnixNanos,
126}
127128impl From<OrderAny> for OrderSnapshot {
129fn from(order: OrderAny) -> Self {
130Self {
131 trader_id: order.trader_id(),
132 strategy_id: order.strategy_id(),
133 instrument_id: order.instrument_id(),
134 client_order_id: order.client_order_id(),
135 venue_order_id: order.venue_order_id(),
136 position_id: order.position_id(),
137 account_id: order.account_id(),
138 last_trade_id: order.last_trade_id(),
139 order_type: order.order_type(),
140 order_side: order.order_side(),
141 quantity: order.quantity(),
142 price: order.price(),
143 trigger_price: order.trigger_price(),
144 trigger_type: order.trigger_type(),
145 limit_offset: order.limit_offset(),
146 trailing_offset: order.trailing_offset(),
147 trailing_offset_type: order.trailing_offset_type(),
148 time_in_force: order.time_in_force(),
149 expire_time: order.expire_time(),
150 filled_qty: order.filled_qty(),
151 liquidity_side: order.liquidity_side(),
152 avg_px: order.avg_px(),
153 slippage: order.slippage(),
154 commissions: order.commissions().values().cloned().collect(),
155 status: order.status(),
156 is_post_only: order.is_post_only(),
157 is_reduce_only: order.is_reduce_only(),
158 is_quote_quantity: order.is_quote_quantity(),
159 display_qty: order.display_qty(),
160 emulation_trigger: order.emulation_trigger(),
161 trigger_instrument_id: order.trigger_instrument_id(),
162 contingency_type: order.contingency_type(),
163 order_list_id: order.order_list_id(),
164 linked_order_ids: order.linked_order_ids().map(Vec::from),
165 parent_order_id: order.parent_order_id(),
166 exec_algorithm_id: order.exec_algorithm_id(),
167 exec_algorithm_params: order.exec_algorithm_params().cloned(),
168 exec_spawn_id: order.exec_spawn_id(),
169 tags: order.tags().map(Vec::from),
170 init_id: order.init_id(),
171 ts_init: order.ts_init(),
172 ts_last: order.ts_last(),
173 }
174 }
175}