nautilus_common/clients/execution.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2026 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// -------------------------------------------------------------------------------------------------
15
16//! Execution client trait definition.
17
18use async_trait::async_trait;
19use nautilus_core::UnixNanos;
20use nautilus_model::{
21 accounts::AccountAny,
22 enums::OmsType,
23 identifiers::{
24 AccountId, ClientId, ClientOrderId, InstrumentId, StrategyId, Venue, VenueOrderId,
25 },
26 reports::{ExecutionMassStatus, FillReport, OrderStatusReport, PositionStatusReport},
27 types::{AccountBalance, MarginBalance},
28};
29
30use super::log_not_implemented;
31use crate::messages::execution::{
32 BatchCancelOrders, CancelAllOrders, CancelOrder, GenerateFillReports,
33 GenerateOrderStatusReport, GenerateOrderStatusReports, GeneratePositionStatusReports,
34 ModifyOrder, QueryAccount, QueryOrder, SubmitOrder, SubmitOrderList,
35};
36
37/// Defines the interface for an execution client managing order operations.
38///
39/// # Thread Safety
40///
41/// Client instances are not intended to be sent across threads. The `?Send` bound
42/// allows implementations to hold non-Send state for any Python interop.
43#[async_trait(?Send)]
44pub trait ExecutionClient {
45 fn is_connected(&self) -> bool;
46 fn client_id(&self) -> ClientId;
47 fn account_id(&self) -> AccountId;
48 fn venue(&self) -> Venue;
49 fn oms_type(&self) -> OmsType;
50 fn get_account(&self) -> Option<AccountAny>;
51
52 /// Generates and publishes the account state event.
53 ///
54 /// # Errors
55 ///
56 /// Returns an error if generating the account state fails.
57 fn generate_account_state(
58 &self,
59 balances: Vec<AccountBalance>,
60 margins: Vec<MarginBalance>,
61 reported: bool,
62 ts_event: UnixNanos,
63 ) -> anyhow::Result<()>;
64
65 /// Starts the execution client.
66 ///
67 /// # Errors
68 ///
69 /// Returns an error if the client fails to start.
70 fn start(&mut self) -> anyhow::Result<()>;
71
72 /// Stops the execution client.
73 ///
74 /// # Errors
75 ///
76 /// Returns an error if the client fails to stop.
77 fn stop(&mut self) -> anyhow::Result<()>;
78
79 /// Connects the client to the execution venue.
80 ///
81 /// # Errors
82 ///
83 /// Returns an error if connection fails.
84 async fn connect(&mut self) -> anyhow::Result<()> {
85 Ok(())
86 }
87
88 /// Disconnects the client from the execution venue.
89 ///
90 /// # Errors
91 ///
92 /// Returns an error if disconnection fails.
93 async fn disconnect(&mut self) -> anyhow::Result<()> {
94 Ok(())
95 }
96
97 /// Submits a single order command to the execution venue.
98 ///
99 /// # Errors
100 ///
101 /// Returns an error if submission fails.
102 fn submit_order(&self, cmd: &SubmitOrder) -> anyhow::Result<()> {
103 log_not_implemented(cmd);
104 Ok(())
105 }
106
107 /// Submits a list of orders to the execution venue.
108 ///
109 /// # Errors
110 ///
111 /// Returns an error if submission fails.
112 fn submit_order_list(&self, cmd: &SubmitOrderList) -> anyhow::Result<()> {
113 log_not_implemented(cmd);
114 Ok(())
115 }
116
117 /// Modifies an existing order.
118 ///
119 /// # Errors
120 ///
121 /// Returns an error if modification fails.
122 fn modify_order(&self, cmd: &ModifyOrder) -> anyhow::Result<()> {
123 log_not_implemented(cmd);
124 Ok(())
125 }
126
127 /// Cancels a specific order.
128 ///
129 /// # Errors
130 ///
131 /// Returns an error if cancellation fails.
132 fn cancel_order(&self, cmd: &CancelOrder) -> anyhow::Result<()> {
133 log_not_implemented(cmd);
134 Ok(())
135 }
136
137 /// Cancels all orders.
138 ///
139 /// # Errors
140 ///
141 /// Returns an error if cancellation fails.
142 fn cancel_all_orders(&self, cmd: &CancelAllOrders) -> anyhow::Result<()> {
143 log_not_implemented(cmd);
144 Ok(())
145 }
146
147 /// Cancels a batch of orders.
148 ///
149 /// # Errors
150 ///
151 /// Returns an error if batch cancellation fails.
152 fn batch_cancel_orders(&self, cmd: &BatchCancelOrders) -> anyhow::Result<()> {
153 log_not_implemented(cmd);
154 Ok(())
155 }
156
157 /// Queries the status of an account.
158 ///
159 /// # Errors
160 ///
161 /// Returns an error if the query fails.
162 fn query_account(&self, cmd: &QueryAccount) -> anyhow::Result<()> {
163 log_not_implemented(cmd);
164 Ok(())
165 }
166
167 /// Queries the status of an order.
168 ///
169 /// # Errors
170 ///
171 /// Returns an error if the query fails.
172 fn query_order(&self, cmd: &QueryOrder) -> anyhow::Result<()> {
173 log_not_implemented(cmd);
174 Ok(())
175 }
176
177 /// Generates a single order status report.
178 ///
179 /// # Errors
180 ///
181 /// Returns an error if report generation fails.
182 async fn generate_order_status_report(
183 &self,
184 cmd: &GenerateOrderStatusReport,
185 ) -> anyhow::Result<Option<OrderStatusReport>> {
186 log_not_implemented(cmd);
187 Ok(None)
188 }
189
190 /// Generates multiple order status reports.
191 ///
192 /// # Errors
193 ///
194 /// Returns an error if report generation fails.
195 async fn generate_order_status_reports(
196 &self,
197 cmd: &GenerateOrderStatusReports,
198 ) -> anyhow::Result<Vec<OrderStatusReport>> {
199 log_not_implemented(cmd);
200 Ok(Vec::new())
201 }
202
203 /// Generates fill reports based on execution results.
204 ///
205 /// # Errors
206 ///
207 /// Returns an error if fill report generation fails.
208 async fn generate_fill_reports(
209 &self,
210 cmd: GenerateFillReports,
211 ) -> anyhow::Result<Vec<FillReport>> {
212 log_not_implemented(&cmd);
213 Ok(Vec::new())
214 }
215
216 /// Generates position status reports.
217 ///
218 /// # Errors
219 ///
220 /// Returns an error if generation fails.
221 async fn generate_position_status_reports(
222 &self,
223 cmd: &GeneratePositionStatusReports,
224 ) -> anyhow::Result<Vec<PositionStatusReport>> {
225 log_not_implemented(cmd);
226 Ok(Vec::new())
227 }
228
229 /// Generates mass status for executions.
230 ///
231 /// # Errors
232 ///
233 /// Returns an error if status generation fails.
234 async fn generate_mass_status(
235 &self,
236 lookback_mins: Option<u64>,
237 ) -> anyhow::Result<Option<ExecutionMassStatus>> {
238 log_not_implemented(&lookback_mins);
239 Ok(None)
240 }
241
242 /// Registers an external order for tracking by the execution client.
243 ///
244 /// This is called after reconciliation creates an external order, allowing the
245 /// execution client to track it for subsequent events (e.g., cancellations).
246 fn register_external_order(
247 &self,
248 _client_order_id: ClientOrderId,
249 _venue_order_id: VenueOrderId,
250 _instrument_id: InstrumentId,
251 _strategy_id: StrategyId,
252 _ts_init: UnixNanos,
253 ) {
254 // Default no-op implementation
255 }
256}