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}