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