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(&mut self, cmd: SubscribePoolFeeCollects) -> anyhow::Result<()> {
311 log_not_implemented(&cmd);
312 Ok(())
313 }
314
315 #[cfg(feature = "defi")]
316 /// Subscribes to pool flash loan events for a specified AMM pool.
317 ///
318 /// # Errors
319 ///
320 /// Returns an error if the subscription operation fails.
321 fn subscribe_pool_flash_events(&mut self, cmd: SubscribePoolFlashEvents) -> anyhow::Result<()> {
322 log_not_implemented(&cmd);
323 Ok(())
324 }
325
326 /// Unsubscribes from custom data types according to the command.
327 ///
328 /// # Errors
329 ///
330 /// Returns an error if the unsubscribe operation fails.
331 fn unsubscribe(&mut self, cmd: &UnsubscribeCustomData) -> anyhow::Result<()> {
332 log_not_implemented(&cmd);
333 Ok(())
334 }
335
336 /// Unsubscribes from instruments list for the specified venue.
337 ///
338 /// # Errors
339 ///
340 /// Returns an error if the unsubscribe operation fails.
341 fn unsubscribe_instruments(&mut self, cmd: &UnsubscribeInstruments) -> anyhow::Result<()> {
342 log_not_implemented(&cmd);
343 Ok(())
344 }
345
346 /// Unsubscribes from data for the specified instrument.
347 ///
348 /// # Errors
349 ///
350 /// Returns an error if the unsubscribe operation fails.
351 fn unsubscribe_instrument(&mut self, cmd: &UnsubscribeInstrument) -> anyhow::Result<()> {
352 log_not_implemented(&cmd);
353 Ok(())
354 }
355
356 /// Unsubscribes from order book delta updates for the specified instrument.
357 ///
358 /// # Errors
359 ///
360 /// Returns an error if the unsubscribe operation fails.
361 fn unsubscribe_book_deltas(&mut self, cmd: &UnsubscribeBookDeltas) -> anyhow::Result<()> {
362 log_not_implemented(&cmd);
363 Ok(())
364 }
365
366 /// Unsubscribes from top 10 order book depth updates for the specified instrument.
367 ///
368 /// # Errors
369 ///
370 /// Returns an error if the unsubscribe operation fails.
371 fn unsubscribe_book_depth10(&mut self, cmd: &UnsubscribeBookDepth10) -> anyhow::Result<()> {
372 log_not_implemented(&cmd);
373 Ok(())
374 }
375
376 /// Unsubscribes from quote updates for the specified instrument.
377 ///
378 /// # Errors
379 ///
380 /// Returns an error if the unsubscribe operation fails.
381 fn unsubscribe_quotes(&mut self, cmd: &UnsubscribeQuotes) -> anyhow::Result<()> {
382 log_not_implemented(&cmd);
383 Ok(())
384 }
385
386 /// Unsubscribes from trade updates for the specified instrument.
387 ///
388 /// # Errors
389 ///
390 /// Returns an error if the unsubscribe operation fails.
391 fn unsubscribe_trades(&mut self, cmd: &UnsubscribeTrades) -> anyhow::Result<()> {
392 log_not_implemented(&cmd);
393 Ok(())
394 }
395
396 /// Unsubscribes from mark price updates for the specified instrument.
397 ///
398 /// # Errors
399 ///
400 /// Returns an error if the unsubscribe operation fails.
401 fn unsubscribe_mark_prices(&mut self, cmd: &UnsubscribeMarkPrices) -> anyhow::Result<()> {
402 log_not_implemented(&cmd);
403 Ok(())
404 }
405
406 /// Unsubscribes from index price updates for the specified instrument.
407 ///
408 /// # Errors
409 ///
410 /// Returns an error if the unsubscribe operation fails.
411 fn unsubscribe_index_prices(&mut self, cmd: &UnsubscribeIndexPrices) -> anyhow::Result<()> {
412 log_not_implemented(&cmd);
413 Ok(())
414 }
415
416 /// Unsubscribes from funding rate updates for the specified instrument.
417 ///
418 /// # Errors
419 ///
420 /// Returns an error if the unsubscribe operation fails.
421 fn unsubscribe_funding_rates(&mut self, cmd: &UnsubscribeFundingRates) -> anyhow::Result<()> {
422 log_not_implemented(&cmd);
423 Ok(())
424 }
425
426 /// Unsubscribes from bar updates of the specified bar type.
427 ///
428 /// # Errors
429 ///
430 /// Returns an error if the unsubscribe operation fails.
431 fn unsubscribe_bars(&mut self, cmd: &UnsubscribeBars) -> anyhow::Result<()> {
432 log_not_implemented(&cmd);
433 Ok(())
434 }
435
436 /// Unsubscribes from instrument status updates for the specified instrument.
437 ///
438 /// # Errors
439 ///
440 /// Returns an error if the unsubscribe operation fails.
441 fn unsubscribe_instrument_status(
442 &mut self,
443 cmd: &UnsubscribeInstrumentStatus,
444 ) -> anyhow::Result<()> {
445 log_not_implemented(&cmd);
446 Ok(())
447 }
448
449 /// Unsubscribes from instrument close events for the specified instrument.
450 ///
451 /// # Errors
452 ///
453 /// Returns an error if the unsubscribe operation fails.
454 fn unsubscribe_instrument_close(
455 &mut self,
456 cmd: &UnsubscribeInstrumentClose,
457 ) -> anyhow::Result<()> {
458 log_not_implemented(&cmd);
459 Ok(())
460 }
461
462 /// Unsubscribes from exchange-provided option greeks for the specified instrument.
463 ///
464 /// # Errors
465 ///
466 /// Returns an error if the unsubscribe operation fails.
467 fn unsubscribe_option_greeks(&mut self, cmd: &UnsubscribeOptionGreeks) -> anyhow::Result<()> {
468 log_not_implemented(&cmd);
469 Ok(())
470 }
471
472 #[cfg(feature = "defi")]
473 /// Unsubscribes from blocks for a specified blockchain.
474 ///
475 /// # Errors
476 ///
477 /// Returns an error if the subscription operation fails.
478 fn unsubscribe_blocks(&mut self, cmd: &UnsubscribeBlocks) -> anyhow::Result<()> {
479 log_not_implemented(&cmd);
480 Ok(())
481 }
482
483 #[cfg(feature = "defi")]
484 /// Unsubscribes from pool definition updates for a specified AMM pool.
485 ///
486 /// # Errors
487 ///
488 /// Returns an error if the subscription operation fails.
489 fn unsubscribe_pool(&mut self, cmd: &UnsubscribePool) -> anyhow::Result<()> {
490 log_not_implemented(&cmd);
491 Ok(())
492 }
493
494 #[cfg(feature = "defi")]
495 /// Unsubscribes from swaps for a specified AMM pool.
496 ///
497 /// # Errors
498 ///
499 /// Returns an error if the subscription operation fails.
500 fn unsubscribe_pool_swaps(&mut self, cmd: &UnsubscribePoolSwaps) -> anyhow::Result<()> {
501 log_not_implemented(&cmd);
502 Ok(())
503 }
504
505 #[cfg(feature = "defi")]
506 /// Unsubscribes from pool liquidity updates for a specified AMM pool.
507 ///
508 /// # Errors
509 ///
510 /// Returns an error if the subscription operation fails.
511 fn unsubscribe_pool_liquidity_updates(
512 &mut self,
513 cmd: &UnsubscribePoolLiquidityUpdates,
514 ) -> anyhow::Result<()> {
515 log_not_implemented(&cmd);
516 Ok(())
517 }
518
519 #[cfg(feature = "defi")]
520 /// Unsubscribes from pool fee collects for a specified AMM pool.
521 ///
522 /// # Errors
523 ///
524 /// Returns an error if the subscription operation fails.
525 fn unsubscribe_pool_fee_collects(
526 &mut self,
527 cmd: &UnsubscribePoolFeeCollects,
528 ) -> anyhow::Result<()> {
529 log_not_implemented(&cmd);
530 Ok(())
531 }
532
533 #[cfg(feature = "defi")]
534 /// Unsubscribes from pool flash loan events for a specified AMM pool.
535 ///
536 /// # Errors
537 ///
538 /// Returns an error if the subscription operation fails.
539 fn unsubscribe_pool_flash_events(
540 &mut self,
541 cmd: &UnsubscribePoolFlashEvents,
542 ) -> anyhow::Result<()> {
543 log_not_implemented(&cmd);
544 Ok(())
545 }
546
547 /// Sends a custom data request to the provider.
548 ///
549 /// # Errors
550 ///
551 /// Returns an error if the data request fails.
552 fn request_data(&self, request: RequestCustomData) -> anyhow::Result<()> {
553 log_not_implemented(&request);
554 Ok(())
555 }
556
557 /// Requests a list of instruments from the provider for a given venue.
558 ///
559 /// # Errors
560 ///
561 /// Returns an error if the instruments request fails.
562 fn request_instruments(&self, request: RequestInstruments) -> anyhow::Result<()> {
563 log_not_implemented(&request);
564 Ok(())
565 }
566
567 /// Requests detailed data for a single instrument.
568 ///
569 /// # Errors
570 ///
571 /// Returns an error if the instrument request fails.
572 fn request_instrument(&self, request: RequestInstrument) -> anyhow::Result<()> {
573 log_not_implemented(&request);
574 Ok(())
575 }
576
577 /// Requests a snapshot of the order book for a specified instrument.
578 ///
579 /// # Errors
580 ///
581 /// Returns an error if the book snapshot request fails.
582 fn request_book_snapshot(&self, request: RequestBookSnapshot) -> anyhow::Result<()> {
583 log_not_implemented(&request);
584 Ok(())
585 }
586
587 /// Requests historical or streaming quote data for a specified instrument.
588 ///
589 /// # Errors
590 ///
591 /// Returns an error if the quotes request fails.
592 fn request_quotes(&self, request: RequestQuotes) -> anyhow::Result<()> {
593 log_not_implemented(&request);
594 Ok(())
595 }
596
597 /// Requests historical or streaming trade data for a specified instrument.
598 ///
599 /// # Errors
600 ///
601 /// Returns an error if the trades request fails.
602 fn request_trades(&self, request: RequestTrades) -> anyhow::Result<()> {
603 log_not_implemented(&request);
604 Ok(())
605 }
606
607 /// Requests historical or streaming funding rate data for a specified instrument.
608 ///
609 /// # Errors
610 ///
611 /// Returns an error if the trades request fails.
612 fn request_funding_rates(&self, request: RequestFundingRates) -> anyhow::Result<()> {
613 log_not_implemented(&request);
614 Ok(())
615 }
616
617 /// Requests forward/underlying prices for derivatives instruments.
618 ///
619 /// # Errors
620 ///
621 /// Returns an error if the forward prices request fails.
622 fn request_forward_prices(&self, request: RequestForwardPrices) -> anyhow::Result<()> {
623 log_not_implemented(&request);
624 Ok(())
625 }
626
627 /// Requests historical or streaming bar data for a specified instrument and bar type.
628 ///
629 /// # Errors
630 ///
631 /// Returns an error if the bars request fails.
632 fn request_bars(&self, request: RequestBars) -> anyhow::Result<()> {
633 log_not_implemented(&request);
634 Ok(())
635 }
636
637 /// Requests historical order book depth data for a specified instrument.
638 ///
639 /// # Errors
640 ///
641 /// Returns an error if the order book depths request fails.
642 fn request_book_depth(&self, request: RequestBookDepth) -> anyhow::Result<()> {
643 log_not_implemented(&request);
644 Ok(())
645 }
646
647 #[cfg(feature = "defi")]
648 /// Requests a snapshot of a specific AMM pool.
649 ///
650 /// # Errors
651 ///
652 /// Returns an error if the pool snapshot request fails.
653 fn request_pool_snapshot(&self, request: RequestPoolSnapshot) -> anyhow::Result<()> {
654 log_not_implemented(&request);
655 Ok(())
656 }
657}