From 0a1d185a473cd84ee4f4365ae2ad613b18cef3e0 Mon Sep 17 00:00:00 2001 From: Filip Macek Date: Mon, 15 Apr 2024 01:00:41 +0200 Subject: [PATCH] Refactor OrderCore in Rust to use only OrderInitialized (#1592) --- nautilus_core/model/src/orders/base.rs | 85 +++++++------------ nautilus_core/model/src/orders/limit.rs | 60 ++++++++----- .../model/src/orders/limit_if_touched.rs | 60 ++++++++----- nautilus_core/model/src/orders/market.rs | 60 ++++++++----- .../model/src/orders/market_if_touched.rs | 60 ++++++++----- .../model/src/orders/market_to_limit.rs | 60 ++++++++----- nautilus_core/model/src/orders/stop_limit.rs | 60 ++++++++----- nautilus_core/model/src/orders/stop_market.rs | 60 ++++++++----- .../model/src/orders/trailing_stop_limit.rs | 60 ++++++++----- .../model/src/orders/trailing_stop_market.rs | 60 ++++++++----- 10 files changed, 365 insertions(+), 260 deletions(-) diff --git a/nautilus_core/model/src/orders/base.rs b/nautilus_core/model/src/orders/base.rs index b7cd5b0a6202..1f79481fa74c 100644 --- a/nautilus_core/model/src/orders/base.rs +++ b/nautilus_core/model/src/orders/base.rs @@ -843,70 +843,49 @@ pub struct OrderCore { } impl OrderCore { - #[must_use] - #[allow(clippy::too_many_arguments)] - pub fn new( - trader_id: TraderId, - strategy_id: StrategyId, - instrument_id: InstrumentId, - client_order_id: ClientOrderId, - order_side: OrderSide, - order_type: OrderType, - quantity: Quantity, - time_in_force: TimeInForce, - reduce_only: bool, - quote_quantity: bool, - emulation_trigger: Option, - contingency_type: Option, - order_list_id: Option, - linked_order_ids: Option>, - parent_order_id: Option, - exec_algorithm_id: Option, - exec_algorithm_params: Option>, - exec_spawn_id: Option, - tags: Option, - init_id: UUID4, - ts_init: UnixNanos, - ) -> Self { - Self { - events: Vec::new(), + pub fn new(init: OrderInitialized) -> anyhow::Result { + let events: Vec = vec![OrderEvent::OrderInitialized(init.clone())]; + Ok(OrderCore { + events, commissions: HashMap::new(), venue_order_ids: Vec::new(), trade_ids: Vec::new(), previous_status: None, status: OrderStatus::Initialized, - trader_id, - strategy_id, - instrument_id, - client_order_id, + trader_id: init.trader_id, + strategy_id: init.strategy_id, + instrument_id: init.instrument_id, + client_order_id: init.client_order_id, venue_order_id: None, position_id: None, account_id: None, last_trade_id: None, - side: order_side, - order_type, - quantity, - time_in_force, + side: init.order_side, + order_type: init.order_type, + quantity: init.quantity, + time_in_force: init.time_in_force, liquidity_side: Some(LiquiditySide::NoLiquiditySide), - is_reduce_only: reduce_only, - is_quote_quantity: quote_quantity, - emulation_trigger: emulation_trigger.or(Some(TriggerType::NoTrigger)), - contingency_type: contingency_type.or(Some(ContingencyType::NoContingency)), - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - filled_qty: Quantity::zero(quantity.precision), - leaves_qty: quantity, + is_reduce_only: init.reduce_only, + is_quote_quantity: init.quote_quantity, + emulation_trigger: init.emulation_trigger.or(Some(TriggerType::NoTrigger)), + contingency_type: init + .contingency_type + .or(Some(ContingencyType::NoContingency)), + order_list_id: init.order_list_id, + linked_order_ids: init.linked_order_ids, + parent_order_id: init.parent_order_id, + exec_algorithm_id: init.exec_algorithm_id, + exec_algorithm_params: init.exec_algorithm_params, + exec_spawn_id: init.exec_spawn_id, + tags: init.tags, + filled_qty: Quantity::zero(init.quantity.precision), + leaves_qty: init.quantity, avg_px: None, slippage: None, - init_id, - ts_init, - ts_last: ts_init, - } + init_id: init.event_id, + ts_init: init.ts_event, + ts_last: init.ts_event, + }) } pub fn apply(&mut self, event: OrderEvent) -> Result<(), OrderError> { @@ -1202,7 +1181,7 @@ mod tests { assert_eq!(order.status, OrderStatus::Denied); assert!(order.is_closed()); assert!(!order.is_open()); - assert_eq!(order.event_count(), 1); + assert_eq!(order.event_count(), 2); assert_eq!(order.last_event(), &event); } diff --git a/nautilus_core/model/src/orders/limit.rs b/nautilus_core/model/src/orders/limit.rs index 394bf5047f76..a0d730247794 100644 --- a/nautilus_core/model/src/orders/limit.rs +++ b/nautilus_core/model/src/orders/limit.rs @@ -97,31 +97,45 @@ impl LimitOrder { } } } + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::Limit, + quantity, + time_in_force, + post_only, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, // ts_event timestamp identical to ts_init + ts_init, + Some(price), + None, + None, + None, + None, + None, + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::Limit, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), price, expire_time: expire_time.or(Some(UnixNanos::default())), is_post_only: post_only, diff --git a/nautilus_core/model/src/orders/limit_if_touched.rs b/nautilus_core/model/src/orders/limit_if_touched.rs index ca24d7339544..c3e5e84c44f3 100644 --- a/nautilus_core/model/src/orders/limit_if_touched.rs +++ b/nautilus_core/model/src/orders/limit_if_touched.rs @@ -87,30 +87,44 @@ impl LimitIfTouchedOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::LimitIfTouched, + quantity, + time_in_force, + post_only, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + Some(price), + Some(trigger_price), + Some(trigger_type), + None, + None, + None, + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::LimitIfTouched, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), price, trigger_price, trigger_type, diff --git a/nautilus_core/model/src/orders/market.rs b/nautilus_core/model/src/orders/market.rs index 7352f93673ba..455f4bfec34f 100644 --- a/nautilus_core/model/src/orders/market.rs +++ b/nautilus_core/model/src/orders/market.rs @@ -79,31 +79,45 @@ impl MarketOrder { if time_in_force == TimeInForce::Gtd { anyhow::bail!("{}", "GTD not supported for Market orders"); } + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::Market, + quantity, + time_in_force, + false, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + None, + None, + Some(TriggerType::NoTrigger), + None, + None, + None, + None, + None, + None, + None, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::Market, - quantity, - time_in_force, - reduce_only, - quote_quantity, - None, // Emulation trigger - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), }) } } diff --git a/nautilus_core/model/src/orders/market_if_touched.rs b/nautilus_core/model/src/orders/market_if_touched.rs index a67994ece45f..36537180a935 100644 --- a/nautilus_core/model/src/orders/market_if_touched.rs +++ b/nautilus_core/model/src/orders/market_if_touched.rs @@ -83,30 +83,44 @@ impl MarketIfTouchedOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::MarketIfTouched, + quantity, + time_in_force, + false, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + None, + Some(trigger_price), + Some(trigger_type), + None, + None, + None, + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::MarketIfTouched, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), trigger_price, trigger_type, expire_time, diff --git a/nautilus_core/model/src/orders/market_to_limit.rs b/nautilus_core/model/src/orders/market_to_limit.rs index 70c1809ebbe2..06c3d79b66bd 100644 --- a/nautilus_core/model/src/orders/market_to_limit.rs +++ b/nautilus_core/model/src/orders/market_to_limit.rs @@ -78,30 +78,44 @@ impl MarketToLimitOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::MarketToLimit, + quantity, + time_in_force, + post_only, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + None, + None, + None, + None, + None, + None, + expire_time, + display_qty, + Some(TriggerType::NoTrigger), + None, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::MarketToLimit, - quantity, - time_in_force, - reduce_only, - quote_quantity, - None, // Emulation trigger - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), price: None, // Price will be determined on fill expire_time, is_post_only: post_only, diff --git a/nautilus_core/model/src/orders/stop_limit.rs b/nautilus_core/model/src/orders/stop_limit.rs index 1e136e3404cb..579a3280d9c5 100644 --- a/nautilus_core/model/src/orders/stop_limit.rs +++ b/nautilus_core/model/src/orders/stop_limit.rs @@ -88,30 +88,44 @@ impl StopLimitOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::StopLimit, + quantity, + time_in_force, + post_only, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + Some(price), + Some(trigger_price), + Some(trigger_type), + None, + None, + None, + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::StopLimit, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), price, trigger_price, trigger_type, diff --git a/nautilus_core/model/src/orders/stop_market.rs b/nautilus_core/model/src/orders/stop_market.rs index 91f70d47823d..32d43cc69b3a 100644 --- a/nautilus_core/model/src/orders/stop_market.rs +++ b/nautilus_core/model/src/orders/stop_market.rs @@ -84,30 +84,44 @@ impl StopMarketOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::StopMarket, + quantity, + time_in_force, + false, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + None, + Some(trigger_price), + Some(trigger_type), + None, + None, + None, + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::StopMarket, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), trigger_price, trigger_type, expire_time, diff --git a/nautilus_core/model/src/orders/trailing_stop_limit.rs b/nautilus_core/model/src/orders/trailing_stop_limit.rs index b650323db54e..451be0fee930 100644 --- a/nautilus_core/model/src/orders/trailing_stop_limit.rs +++ b/nautilus_core/model/src/orders/trailing_stop_limit.rs @@ -93,30 +93,44 @@ impl TrailingStopLimitOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::TrailingStopLimit, + quantity, + time_in_force, + post_only, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + Some(price), + Some(trigger_price), + Some(trigger_type), + Some(limit_offset), + Some(trailing_offset), + Some(trailing_offset_type), + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::TrailingStopLimit, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), price, trigger_price, trigger_type, diff --git a/nautilus_core/model/src/orders/trailing_stop_market.rs b/nautilus_core/model/src/orders/trailing_stop_market.rs index ea3e593d0bff..8862a2242c09 100644 --- a/nautilus_core/model/src/orders/trailing_stop_market.rs +++ b/nautilus_core/model/src/orders/trailing_stop_market.rs @@ -88,30 +88,44 @@ impl TrailingStopMarketOrder { init_id: UUID4, ts_init: UnixNanos, ) -> anyhow::Result { + let init_order = OrderInitialized::new( + trader_id, + strategy_id, + instrument_id, + client_order_id, + order_side, + OrderType::TrailingStopMarket, + quantity, + time_in_force, + false, + reduce_only, + quote_quantity, + false, + init_id, + ts_init, + ts_init, + None, + Some(trigger_price), + Some(trigger_type), + None, + Some(trailing_offset), + Some(trailing_offset_type), + expire_time, + display_qty, + emulation_trigger, + trigger_instrument_id, + contingency_type, + order_list_id, + linked_order_ids, + parent_order_id, + exec_algorithm_id, + exec_algorithm_params, + exec_spawn_id, + tags, + ) + .unwrap(); Ok(Self { - core: OrderCore::new( - trader_id, - strategy_id, - instrument_id, - client_order_id, - order_side, - OrderType::TrailingStopMarket, - quantity, - time_in_force, - reduce_only, - quote_quantity, - emulation_trigger, - contingency_type, - order_list_id, - linked_order_ids, - parent_order_id, - exec_algorithm_id, - exec_algorithm_params, - exec_spawn_id, - tags, - init_id, - ts_init, - ), + core: OrderCore::new(init_order).unwrap(), trigger_price, trigger_type, trailing_offset,