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}