nautilus_execution/client/mod.rs
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// -------------------------------------------------------------------------------------------------
15
16//! Execution client implementations for trading venue connectivity.
17
18use std::fmt::Debug;
19
20use async_trait::async_trait;
21use nautilus_common::messages::execution::{
22 BatchCancelOrders, CancelAllOrders, CancelOrder, GenerateFillReports,
23 GenerateOrderStatusReport, GeneratePositionReports, ModifyOrder, QueryAccount, QueryOrder,
24 SubmitOrder, SubmitOrderList,
25};
26use nautilus_core::UnixNanos;
27use nautilus_model::{
28 accounts::AccountAny,
29 enums::OmsType,
30 identifiers::{AccountId, ClientId, Venue},
31 reports::{ExecutionMassStatus, FillReport, OrderStatusReport, PositionStatusReport},
32 types::{AccountBalance, MarginBalance},
33};
34
35pub mod base;
36
37pub trait ExecutionClient {
38 fn is_connected(&self) -> bool;
39 fn client_id(&self) -> ClientId;
40 fn account_id(&self) -> AccountId;
41 fn venue(&self) -> Venue;
42 fn oms_type(&self) -> OmsType;
43 fn get_account(&self) -> Option<AccountAny>;
44
45 /// Generates and publishes the account state event.
46 ///
47 /// # Errors
48 ///
49 /// Returns an error if generating the account state fails.
50 fn generate_account_state(
51 &self,
52 balances: Vec<AccountBalance>,
53 margins: Vec<MarginBalance>,
54 reported: bool,
55 ts_event: UnixNanos,
56 ) -> anyhow::Result<()>;
57
58 /// Starts the execution client.
59 ///
60 /// # Errors
61 ///
62 /// Returns an error if the client fails to start.
63 fn start(&mut self) -> anyhow::Result<()>;
64
65 /// Stops the execution client.
66 ///
67 /// # Errors
68 ///
69 /// Returns an error if the client fails to stop.
70 fn stop(&mut self) -> anyhow::Result<()>;
71
72 /// Submits a single order command to the execution venue.
73 ///
74 /// # Errors
75 ///
76 /// Returns an error if submission fails.
77 fn submit_order(&self, cmd: &SubmitOrder) -> anyhow::Result<()> {
78 log_not_implemented(cmd);
79 Ok(())
80 }
81
82 /// Submits a list of orders to the execution venue.
83 ///
84 /// # Errors
85 ///
86 /// Returns an error if submission fails.
87 fn submit_order_list(&self, cmd: &SubmitOrderList) -> anyhow::Result<()> {
88 log_not_implemented(cmd);
89 Ok(())
90 }
91
92 /// Modifies an existing order.
93 ///
94 /// # Errors
95 ///
96 /// Returns an error if modification fails.
97 fn modify_order(&self, cmd: &ModifyOrder) -> anyhow::Result<()> {
98 log_not_implemented(cmd);
99 Ok(())
100 }
101
102 /// Cancels a specific order.
103 ///
104 /// # Errors
105 ///
106 /// Returns an error if cancellation fails.
107 fn cancel_order(&self, cmd: &CancelOrder) -> anyhow::Result<()> {
108 log_not_implemented(cmd);
109 Ok(())
110 }
111
112 /// Cancels all orders.
113 ///
114 /// # Errors
115 ///
116 /// Returns an error if cancellation fails.
117 fn cancel_all_orders(&self, cmd: &CancelAllOrders) -> anyhow::Result<()> {
118 log_not_implemented(cmd);
119 Ok(())
120 }
121
122 /// Cancels a batch of orders.
123 ///
124 /// # Errors
125 ///
126 /// Returns an error if batch cancellation fails.
127 fn batch_cancel_orders(&self, cmd: &BatchCancelOrders) -> anyhow::Result<()> {
128 log_not_implemented(cmd);
129 Ok(())
130 }
131
132 /// Queries the status of an account.
133 ///
134 /// # Errors
135 ///
136 /// Returns an error if the query fails.
137 fn query_account(&self, cmd: &QueryAccount) -> anyhow::Result<()> {
138 log_not_implemented(cmd);
139 Ok(())
140 }
141
142 /// Queries the status of an order.
143 ///
144 /// # Errors
145 ///
146 /// Returns an error if the query fails.
147 fn query_order(&self, cmd: &QueryOrder) -> anyhow::Result<()> {
148 log_not_implemented(cmd);
149 Ok(())
150 }
151}
152
153#[async_trait(?Send)]
154pub trait LiveExecutionClient: ExecutionClient {
155 /// Establishes a connection for live execution.
156 ///
157 /// # Errors
158 ///
159 /// Returns an error if connection fails.
160 async fn connect(&mut self) -> anyhow::Result<()>;
161
162 /// Disconnects the live execution client.
163 ///
164 /// # Errors
165 ///
166 /// Returns an error if disconnection fails.
167 async fn disconnect(&mut self) -> anyhow::Result<()>;
168
169 /// Generates a single order status report.
170 ///
171 /// # Errors
172 ///
173 /// Returns an error if report generation fails.
174 async fn generate_order_status_report(
175 &self,
176 cmd: &GenerateOrderStatusReport,
177 ) -> anyhow::Result<Option<OrderStatusReport>> {
178 log_not_implemented(cmd);
179 Ok(None)
180 }
181
182 /// Generates multiple order status reports.
183 ///
184 /// # Errors
185 ///
186 /// Returns an error if report generation fails.
187 async fn generate_order_status_reports(
188 &self,
189 cmd: &GenerateOrderStatusReport,
190 ) -> anyhow::Result<Vec<OrderStatusReport>> {
191 log_not_implemented(cmd);
192 Ok(Vec::new())
193 }
194
195 /// Generates fill reports based on execution results.
196 ///
197 /// # Errors
198 ///
199 /// Returns an error if fill report generation fails.
200 async fn generate_fill_reports(
201 &self,
202 cmd: GenerateFillReports,
203 ) -> anyhow::Result<Vec<FillReport>> {
204 log_not_implemented(&cmd);
205 Ok(Vec::new())
206 }
207
208 /// Generates position status reports.
209 ///
210 /// # Errors
211 ///
212 /// Returns an error if generation fails.
213 async fn generate_position_status_reports(
214 &self,
215 cmd: &GeneratePositionReports,
216 ) -> anyhow::Result<Vec<PositionStatusReport>> {
217 log_not_implemented(cmd);
218 Ok(Vec::new())
219 }
220
221 /// Generates mass status for executions.
222 ///
223 /// # Errors
224 ///
225 /// Returns an error if status generation fails.
226 async fn generate_mass_status(
227 &self,
228 lookback_mins: Option<u64>,
229 ) -> anyhow::Result<Option<ExecutionMassStatus>> {
230 log_not_implemented(&lookback_mins);
231 Ok(None)
232 }
233}
234
235#[inline(always)]
236fn log_not_implemented<T: Debug>(cmd: &T) {
237 log::warn!("{cmd:?} – handler not implemented");
238}