Skip to main content

nautilus_common/clients/
data.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//! Data client trait definition.
17
18use async_trait::async_trait;
19use nautilus_model::identifiers::{ClientId, Venue};
20
21use super::{SocketReconnectRegistry, log_not_implemented};
22use crate::messages::data::{
23    RequestBars, RequestBookDeltas, RequestBookDepth, RequestBookSnapshot, RequestCustomData,
24    RequestForwardPrices, RequestFundingRates, RequestInstrument, RequestInstruments,
25    RequestQuotes, RequestTrades, SubscribeBars, SubscribeBookDeltas, SubscribeBookDepth10,
26    SubscribeCustomData, SubscribeFundingRates, SubscribeIndexPrices, SubscribeInstrument,
27    SubscribeInstrumentClose, SubscribeInstrumentStatus, SubscribeInstruments, SubscribeMarkPrices,
28    SubscribeOptionGreeks, SubscribeQuotes, SubscribeTrades, UnsubscribeBars,
29    UnsubscribeBookDeltas, UnsubscribeBookDepth10, UnsubscribeCustomData, UnsubscribeFundingRates,
30    UnsubscribeIndexPrices, UnsubscribeInstrument, UnsubscribeInstrumentClose,
31    UnsubscribeInstrumentStatus, UnsubscribeInstruments, UnsubscribeMarkPrices,
32    UnsubscribeOptionGreeks, UnsubscribeQuotes, UnsubscribeTrades,
33};
34#[cfg(feature = "defi")]
35use crate::messages::defi::{
36    RequestPoolSnapshot, SubscribeBlocks, SubscribePool, SubscribePoolFeeCollects,
37    SubscribePoolFlashEvents, SubscribePoolLiquidityUpdates, SubscribePoolSwaps, UnsubscribeBlocks,
38    UnsubscribePool, UnsubscribePoolFeeCollects, UnsubscribePoolFlashEvents,
39    UnsubscribePoolLiquidityUpdates, UnsubscribePoolSwaps,
40};
41
42/// Defines the interface for a data client, managing connections, subscriptions, and requests.
43///
44/// # Thread Safety
45///
46/// Client instances are not intended to be sent across threads. The `?Send` bound
47/// allows implementations to hold non-Send state for any Python interop.
48#[async_trait(?Send)]
49pub trait DataClient {
50    /// Returns the unique identifier for this data client.
51    fn client_id(&self) -> ClientId;
52
53    /// Returns the optional venue this client is associated with.
54    fn venue(&self) -> Option<Venue>;
55
56    /// Returns endpoint-level socket reconnect controls exposed by this client.
57    fn socket_reconnect_registry(&self) -> Option<&SocketReconnectRegistry> {
58        None
59    }
60
61    /// Starts the data client.
62    ///
63    /// # Errors
64    ///
65    /// Returns an error if the operation fails.
66    fn start(&mut self) -> anyhow::Result<()>;
67
68    /// Stops the data client.
69    ///
70    /// # Errors
71    ///
72    /// Returns an error if the operation fails.
73    fn stop(&mut self) -> anyhow::Result<()>;
74
75    /// Resets the data client to its initial state.
76    ///
77    /// # Errors
78    ///
79    /// Returns an error if the operation fails.
80    fn reset(&mut self) -> anyhow::Result<()>;
81
82    /// Disposes of client resources and cleans up.
83    ///
84    /// # Errors
85    ///
86    /// Returns an error if the operation fails.
87    fn dispose(&mut self) -> anyhow::Result<()>;
88
89    /// Returns `true` if the client is currently connected.
90    fn is_connected(&self) -> bool;
91
92    /// Returns `true` if the client is currently disconnected.
93    fn is_disconnected(&self) -> bool;
94
95    /// Connects the client to the data provider.
96    ///
97    /// For live clients, this triggers the actual connection to external APIs.
98    /// For backtest clients, this is a no-op.
99    ///
100    /// # Errors
101    ///
102    /// Returns an error if the connection fails.
103    async fn connect(&mut self) -> anyhow::Result<()> {
104        Ok(())
105    }
106
107    /// Disconnects the client from the data provider.
108    ///
109    /// For live clients, this closes connections to external APIs.
110    /// For backtest clients, this is a no-op.
111    ///
112    /// # Errors
113    ///
114    /// Returns an error if the disconnection fails.
115    async fn disconnect(&mut self) -> anyhow::Result<()> {
116        Ok(())
117    }
118
119    /// Subscribes to custom data types according to the command.
120    ///
121    /// # Errors
122    ///
123    /// Returns an error if the subscribe operation fails.
124    fn subscribe(&mut self, cmd: SubscribeCustomData) -> anyhow::Result<()> {
125        log_not_implemented(&cmd);
126        Ok(())
127    }
128
129    /// Subscribes to instruments list for the specified venue.
130    ///
131    /// # Errors
132    ///
133    /// Returns an error if the subscribe operation fails.
134    fn subscribe_instruments(&mut self, cmd: SubscribeInstruments) -> anyhow::Result<()> {
135        log_not_implemented(&cmd);
136        Ok(())
137    }
138
139    /// Subscribes to data for a single instrument.
140    ///
141    /// # Errors
142    ///
143    /// Returns an error if the subscribe operation fails.
144    fn subscribe_instrument(&mut self, cmd: SubscribeInstrument) -> anyhow::Result<()> {
145        log_not_implemented(&cmd);
146        Ok(())
147    }
148
149    /// Subscribes to order book delta updates for the specified instrument.
150    ///
151    /// # Errors
152    ///
153    /// Returns an error if the subscribe operation fails.
154    fn subscribe_book_deltas(&mut self, cmd: SubscribeBookDeltas) -> anyhow::Result<()> {
155        log_not_implemented(&cmd);
156        Ok(())
157    }
158
159    /// Subscribes to top 10 order book depth updates for the specified instrument.
160    ///
161    /// # Errors
162    ///
163    /// Returns an error if the subscribe operation fails.
164    fn subscribe_book_depth10(&mut self, cmd: SubscribeBookDepth10) -> anyhow::Result<()> {
165        log_not_implemented(&cmd);
166        Ok(())
167    }
168
169    /// Subscribes to quote updates for the specified instrument.
170    ///
171    /// # Errors
172    ///
173    /// Returns an error if the subscribe operation fails.
174    fn subscribe_quotes(&mut self, cmd: SubscribeQuotes) -> anyhow::Result<()> {
175        log_not_implemented(&cmd);
176        Ok(())
177    }
178
179    /// Subscribes to trade updates for the specified instrument.
180    ///
181    /// # Errors
182    ///
183    /// Returns an error if the subscribe operation fails.
184    fn subscribe_trades(&mut self, cmd: SubscribeTrades) -> anyhow::Result<()> {
185        log_not_implemented(&cmd);
186        Ok(())
187    }
188
189    /// Subscribes to mark price updates for the specified instrument.
190    ///
191    /// # Errors
192    ///
193    /// Returns an error if the subscribe operation fails.
194    fn subscribe_mark_prices(&mut self, cmd: SubscribeMarkPrices) -> anyhow::Result<()> {
195        log_not_implemented(&cmd);
196        Ok(())
197    }
198
199    /// Subscribes to index price updates for the specified instrument.
200    ///
201    /// # Errors
202    ///
203    /// Returns an error if the subscribe operation fails.
204    fn subscribe_index_prices(&mut self, cmd: SubscribeIndexPrices) -> anyhow::Result<()> {
205        log_not_implemented(&cmd);
206        Ok(())
207    }
208
209    /// Subscribes to funding rate updates for the specified instrument.
210    ///
211    /// # Errors
212    ///
213    /// Returns an error if the subscribe operation fails.
214    fn subscribe_funding_rates(&mut self, cmd: SubscribeFundingRates) -> anyhow::Result<()> {
215        log_not_implemented(&cmd);
216        Ok(())
217    }
218
219    /// Subscribes to bar updates of the specified bar type.
220    ///
221    /// # Errors
222    ///
223    /// Returns an error if the subscribe operation fails.
224    fn subscribe_bars(&mut self, cmd: SubscribeBars) -> anyhow::Result<()> {
225        log_not_implemented(&cmd);
226        Ok(())
227    }
228
229    /// Subscribes to status updates for the specified instrument.
230    ///
231    /// # Errors
232    ///
233    /// Returns an error if the subscribe operation fails.
234    fn subscribe_instrument_status(
235        &mut self,
236        cmd: SubscribeInstrumentStatus,
237    ) -> anyhow::Result<()> {
238        log_not_implemented(&cmd);
239        Ok(())
240    }
241
242    /// Subscribes to instrument close events for the specified instrument.
243    ///
244    /// # Errors
245    ///
246    /// Returns an error if the subscription operation fails.
247    fn subscribe_instrument_close(&mut self, cmd: SubscribeInstrumentClose) -> anyhow::Result<()> {
248        log_not_implemented(&cmd);
249        Ok(())
250    }
251
252    /// Subscribes to exchange-provided option greeks for the specified instrument.
253    ///
254    /// # Errors
255    ///
256    /// Returns an error if the subscription operation fails.
257    fn subscribe_option_greeks(&mut self, cmd: SubscribeOptionGreeks) -> anyhow::Result<()> {
258        log_not_implemented(&cmd);
259        Ok(())
260    }
261
262    #[cfg(feature = "defi")]
263    /// Subscribes to blocks for a specified blockchain.
264    ///
265    /// # Errors
266    ///
267    /// Returns an error if the subscription operation fails.
268    fn subscribe_blocks(&mut self, cmd: SubscribeBlocks) -> anyhow::Result<()> {
269        log_not_implemented(&cmd);
270        Ok(())
271    }
272
273    #[cfg(feature = "defi")]
274    /// Subscribes to pool definition updates for a specified AMM pool.
275    ///
276    /// # Errors
277    ///
278    /// Returns an error if the subscription operation fails.
279    fn subscribe_pool(&mut self, cmd: SubscribePool) -> anyhow::Result<()> {
280        log_not_implemented(&cmd);
281        Ok(())
282    }
283
284    #[cfg(feature = "defi")]
285    /// Subscribes to pool swaps for a specified AMM pool.
286    ///
287    /// # Errors
288    ///
289    /// Returns an error if the subscription operation fails.
290    fn subscribe_pool_swaps(&mut self, cmd: SubscribePoolSwaps) -> anyhow::Result<()> {
291        log_not_implemented(&cmd);
292        Ok(())
293    }
294
295    #[cfg(feature = "defi")]
296    /// Subscribes to pool liquidity updates for a specified AMM pool.
297    ///
298    /// # Errors
299    ///
300    /// Returns an error if the subscription operation fails.
301    fn subscribe_pool_liquidity_updates(
302        &mut self,
303        cmd: SubscribePoolLiquidityUpdates,
304    ) -> anyhow::Result<()> {
305        log_not_implemented(&cmd);
306        Ok(())
307    }
308
309    #[cfg(feature = "defi")]
310    /// Subscribes to pool fee collects for a specified AMM pool.
311    ///
312    /// # Errors
313    ///
314    /// Returns an error if the subscription operation fails.
315    fn subscribe_pool_fee_collects(&mut self, cmd: SubscribePoolFeeCollects) -> anyhow::Result<()> {
316        log_not_implemented(&cmd);
317        Ok(())
318    }
319
320    #[cfg(feature = "defi")]
321    /// Subscribes to pool flash loan events for a specified AMM pool.
322    ///
323    /// # Errors
324    ///
325    /// Returns an error if the subscription operation fails.
326    fn subscribe_pool_flash_events(&mut self, cmd: SubscribePoolFlashEvents) -> anyhow::Result<()> {
327        log_not_implemented(&cmd);
328        Ok(())
329    }
330
331    /// Unsubscribes from custom data types according to the command.
332    ///
333    /// # Errors
334    ///
335    /// Returns an error if the unsubscribe operation fails.
336    fn unsubscribe(&mut self, cmd: &UnsubscribeCustomData) -> anyhow::Result<()> {
337        log_not_implemented(&cmd);
338        Ok(())
339    }
340
341    /// Unsubscribes from instruments list for the specified venue.
342    ///
343    /// # Errors
344    ///
345    /// Returns an error if the unsubscribe operation fails.
346    fn unsubscribe_instruments(&mut self, cmd: &UnsubscribeInstruments) -> anyhow::Result<()> {
347        log_not_implemented(&cmd);
348        Ok(())
349    }
350
351    /// Unsubscribes from data for the specified instrument.
352    ///
353    /// # Errors
354    ///
355    /// Returns an error if the unsubscribe operation fails.
356    fn unsubscribe_instrument(&mut self, cmd: &UnsubscribeInstrument) -> anyhow::Result<()> {
357        log_not_implemented(&cmd);
358        Ok(())
359    }
360
361    /// Unsubscribes from order book delta updates for the specified instrument.
362    ///
363    /// # Errors
364    ///
365    /// Returns an error if the unsubscribe operation fails.
366    fn unsubscribe_book_deltas(&mut self, cmd: &UnsubscribeBookDeltas) -> anyhow::Result<()> {
367        log_not_implemented(&cmd);
368        Ok(())
369    }
370
371    /// Unsubscribes from top 10 order book depth updates for the specified instrument.
372    ///
373    /// # Errors
374    ///
375    /// Returns an error if the unsubscribe operation fails.
376    fn unsubscribe_book_depth10(&mut self, cmd: &UnsubscribeBookDepth10) -> anyhow::Result<()> {
377        log_not_implemented(&cmd);
378        Ok(())
379    }
380
381    /// Unsubscribes from quote updates for the specified instrument.
382    ///
383    /// # Errors
384    ///
385    /// Returns an error if the unsubscribe operation fails.
386    fn unsubscribe_quotes(&mut self, cmd: &UnsubscribeQuotes) -> anyhow::Result<()> {
387        log_not_implemented(&cmd);
388        Ok(())
389    }
390
391    /// Unsubscribes from trade updates for the specified instrument.
392    ///
393    /// # Errors
394    ///
395    /// Returns an error if the unsubscribe operation fails.
396    fn unsubscribe_trades(&mut self, cmd: &UnsubscribeTrades) -> anyhow::Result<()> {
397        log_not_implemented(&cmd);
398        Ok(())
399    }
400
401    /// Unsubscribes from mark price updates for the specified instrument.
402    ///
403    /// # Errors
404    ///
405    /// Returns an error if the unsubscribe operation fails.
406    fn unsubscribe_mark_prices(&mut self, cmd: &UnsubscribeMarkPrices) -> anyhow::Result<()> {
407        log_not_implemented(&cmd);
408        Ok(())
409    }
410
411    /// Unsubscribes from index price updates for the specified instrument.
412    ///
413    /// # Errors
414    ///
415    /// Returns an error if the unsubscribe operation fails.
416    fn unsubscribe_index_prices(&mut self, cmd: &UnsubscribeIndexPrices) -> anyhow::Result<()> {
417        log_not_implemented(&cmd);
418        Ok(())
419    }
420
421    /// Unsubscribes from funding rate updates for the specified instrument.
422    ///
423    /// # Errors
424    ///
425    /// Returns an error if the unsubscribe operation fails.
426    fn unsubscribe_funding_rates(&mut self, cmd: &UnsubscribeFundingRates) -> anyhow::Result<()> {
427        log_not_implemented(&cmd);
428        Ok(())
429    }
430
431    /// Unsubscribes from bar updates of the specified bar type.
432    ///
433    /// # Errors
434    ///
435    /// Returns an error if the unsubscribe operation fails.
436    fn unsubscribe_bars(&mut self, cmd: &UnsubscribeBars) -> anyhow::Result<()> {
437        log_not_implemented(&cmd);
438        Ok(())
439    }
440
441    /// Unsubscribes from instrument status updates for the specified instrument.
442    ///
443    /// # Errors
444    ///
445    /// Returns an error if the unsubscribe operation fails.
446    fn unsubscribe_instrument_status(
447        &mut self,
448        cmd: &UnsubscribeInstrumentStatus,
449    ) -> anyhow::Result<()> {
450        log_not_implemented(&cmd);
451        Ok(())
452    }
453
454    /// Unsubscribes from instrument close events for the specified instrument.
455    ///
456    /// # Errors
457    ///
458    /// Returns an error if the unsubscribe operation fails.
459    fn unsubscribe_instrument_close(
460        &mut self,
461        cmd: &UnsubscribeInstrumentClose,
462    ) -> anyhow::Result<()> {
463        log_not_implemented(&cmd);
464        Ok(())
465    }
466
467    /// Unsubscribes from exchange-provided option greeks for the specified instrument.
468    ///
469    /// # Errors
470    ///
471    /// Returns an error if the unsubscribe operation fails.
472    fn unsubscribe_option_greeks(&mut self, cmd: &UnsubscribeOptionGreeks) -> anyhow::Result<()> {
473        log_not_implemented(&cmd);
474        Ok(())
475    }
476
477    #[cfg(feature = "defi")]
478    /// Unsubscribes from blocks for a specified blockchain.
479    ///
480    /// # Errors
481    ///
482    /// Returns an error if the subscription operation fails.
483    fn unsubscribe_blocks(&mut self, cmd: &UnsubscribeBlocks) -> anyhow::Result<()> {
484        log_not_implemented(&cmd);
485        Ok(())
486    }
487
488    #[cfg(feature = "defi")]
489    /// Unsubscribes from pool definition updates for a specified AMM pool.
490    ///
491    /// # Errors
492    ///
493    /// Returns an error if the subscription operation fails.
494    fn unsubscribe_pool(&mut self, cmd: &UnsubscribePool) -> anyhow::Result<()> {
495        log_not_implemented(&cmd);
496        Ok(())
497    }
498
499    #[cfg(feature = "defi")]
500    /// Unsubscribes from swaps for a specified AMM pool.
501    ///
502    /// # Errors
503    ///
504    /// Returns an error if the subscription operation fails.
505    fn unsubscribe_pool_swaps(&mut self, cmd: &UnsubscribePoolSwaps) -> anyhow::Result<()> {
506        log_not_implemented(&cmd);
507        Ok(())
508    }
509
510    #[cfg(feature = "defi")]
511    /// Unsubscribes from pool liquidity updates for a specified AMM pool.
512    ///
513    /// # Errors
514    ///
515    /// Returns an error if the subscription operation fails.
516    fn unsubscribe_pool_liquidity_updates(
517        &mut self,
518        cmd: &UnsubscribePoolLiquidityUpdates,
519    ) -> anyhow::Result<()> {
520        log_not_implemented(&cmd);
521        Ok(())
522    }
523
524    #[cfg(feature = "defi")]
525    /// Unsubscribes from pool fee collects for a specified AMM pool.
526    ///
527    /// # Errors
528    ///
529    /// Returns an error if the subscription operation fails.
530    fn unsubscribe_pool_fee_collects(
531        &mut self,
532        cmd: &UnsubscribePoolFeeCollects,
533    ) -> anyhow::Result<()> {
534        log_not_implemented(&cmd);
535        Ok(())
536    }
537
538    #[cfg(feature = "defi")]
539    /// Unsubscribes from pool flash loan events for a specified AMM pool.
540    ///
541    /// # Errors
542    ///
543    /// Returns an error if the subscription operation fails.
544    fn unsubscribe_pool_flash_events(
545        &mut self,
546        cmd: &UnsubscribePoolFlashEvents,
547    ) -> anyhow::Result<()> {
548        log_not_implemented(&cmd);
549        Ok(())
550    }
551
552    /// Sends a custom data request to the provider.
553    ///
554    /// # Errors
555    ///
556    /// Returns an error if the data request fails.
557    fn request_data(&self, request: RequestCustomData) -> anyhow::Result<()> {
558        log_not_implemented(&request);
559        Ok(())
560    }
561
562    /// Requests a list of instruments from the provider for a given venue.
563    ///
564    /// # Errors
565    ///
566    /// Returns an error if the instruments request fails.
567    fn request_instruments(&self, request: RequestInstruments) -> anyhow::Result<()> {
568        log_not_implemented(&request);
569        Ok(())
570    }
571
572    /// Requests detailed data for a single instrument.
573    ///
574    /// # Errors
575    ///
576    /// Returns an error if the instrument request fails.
577    fn request_instrument(&self, request: RequestInstrument) -> anyhow::Result<()> {
578        log_not_implemented(&request);
579        Ok(())
580    }
581
582    /// Requests a snapshot of the order book for a specified instrument.
583    ///
584    /// # Errors
585    ///
586    /// Returns an error if the book snapshot request fails.
587    fn request_book_snapshot(&self, request: RequestBookSnapshot) -> anyhow::Result<()> {
588        log_not_implemented(&request);
589        Ok(())
590    }
591
592    /// Requests historical or streaming quote data for a specified instrument.
593    ///
594    /// # Errors
595    ///
596    /// Returns an error if the quotes request fails.
597    fn request_quotes(&self, request: RequestQuotes) -> anyhow::Result<()> {
598        log_not_implemented(&request);
599        Ok(())
600    }
601
602    /// Requests historical or streaming trade data for a specified instrument.
603    ///
604    /// # Errors
605    ///
606    /// Returns an error if the trades request fails.
607    fn request_trades(&self, request: RequestTrades) -> anyhow::Result<()> {
608        log_not_implemented(&request);
609        Ok(())
610    }
611
612    /// Requests historical or streaming funding rate data for a specified instrument.
613    ///
614    /// # Errors
615    ///
616    /// Returns an error if the trades request fails.
617    fn request_funding_rates(&self, request: RequestFundingRates) -> anyhow::Result<()> {
618        log_not_implemented(&request);
619        Ok(())
620    }
621
622    /// Requests forward/underlying prices for derivatives instruments.
623    ///
624    /// # Errors
625    ///
626    /// Returns an error if the forward prices request fails.
627    fn request_forward_prices(&self, request: RequestForwardPrices) -> anyhow::Result<()> {
628        log_not_implemented(&request);
629        Ok(())
630    }
631
632    /// Requests historical or streaming bar data for a specified instrument and bar type.
633    ///
634    /// # Errors
635    ///
636    /// Returns an error if the bars request fails.
637    fn request_bars(&self, request: RequestBars) -> anyhow::Result<()> {
638        log_not_implemented(&request);
639        Ok(())
640    }
641
642    /// Requests historical order book depth data for a specified instrument.
643    ///
644    /// # Errors
645    ///
646    /// Returns an error if the order book depths request fails.
647    fn request_book_depth(&self, request: RequestBookDepth) -> anyhow::Result<()> {
648        log_not_implemented(&request);
649        Ok(())
650    }
651
652    /// Requests historical order book delta data for a specified instrument.
653    ///
654    /// # Errors
655    ///
656    /// Returns an error if the order book deltas request fails.
657    fn request_book_deltas(&self, request: RequestBookDeltas) -> anyhow::Result<()> {
658        log_not_implemented(&request);
659        Ok(())
660    }
661
662    #[cfg(feature = "defi")]
663    /// Requests a snapshot of a specific AMM pool.
664    ///
665    /// # Errors
666    ///
667    /// Returns an error if the pool snapshot request fails.
668    fn request_pool_snapshot(&self, request: RequestPoolSnapshot) -> anyhow::Result<()> {
669        log_not_implemented(&request);
670        Ok(())
671    }
672}