nautilus_common/messages/
data.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
16use std::{any::Any, collections::HashMap, num::NonZeroUsize, sync::Arc};
17
18use chrono::{DateTime, Utc};
19use nautilus_core::{UUID4, UnixNanos};
20use nautilus_model::{
21    data::{BarType, DataType},
22    enums::BookType,
23    identifiers::{ClientId, InstrumentId, Venue},
24};
25
26#[derive(Clone, Debug)]
27pub enum DataCommand {
28    Request(DataRequest),
29    Subscribe(SubscribeCommand),
30    Unsubscribe(UnsubscribeCommand),
31}
32
33impl DataCommand {
34    /// Converts the command to a dyn Any trait object for messaging.
35    pub fn as_any(&self) -> &dyn Any {
36        self
37    }
38}
39
40#[derive(Clone, Debug)]
41pub enum SubscribeCommand {
42    Data(SubscribeData),
43    Instruments(SubscribeInstruments),
44    Instrument(SubscribeInstrument),
45    BookDeltas(SubscribeBookDeltas),
46    BookDepth10(SubscribeBookDepth10),
47    BookSnapshots(SubscribeBookSnapshots),
48    Quotes(SubscribeQuotes),
49    Trades(SubscribeTrades),
50    Bars(SubscribeBars),
51    MarkPrices(SubscribeMarkPrices),
52    IndexPrices(SubscribeIndexPrices),
53    InstrumentStatus(SubscribeInstrumentStatus),
54    InstrumentClose(SubscribeInstrumentClose),
55}
56
57impl SubscribeCommand {
58    pub fn client_id(&self) -> Option<&ClientId> {
59        match self {
60            Self::Data(cmd) => cmd.client_id.as_ref(),
61            Self::Instruments(cmd) => cmd.client_id.as_ref(),
62            Self::Instrument(cmd) => cmd.client_id.as_ref(),
63            Self::BookDeltas(cmd) => cmd.client_id.as_ref(),
64            Self::BookDepth10(cmd) => cmd.client_id.as_ref(),
65            Self::BookSnapshots(cmd) => cmd.client_id.as_ref(),
66            Self::Quotes(cmd) => cmd.client_id.as_ref(),
67            Self::Trades(cmd) => cmd.client_id.as_ref(),
68            Self::MarkPrices(cmd) => cmd.client_id.as_ref(),
69            Self::IndexPrices(cmd) => cmd.client_id.as_ref(),
70            Self::Bars(cmd) => cmd.client_id.as_ref(),
71            Self::InstrumentStatus(cmd) => cmd.client_id.as_ref(),
72            Self::InstrumentClose(cmd) => cmd.client_id.as_ref(),
73        }
74    }
75
76    pub fn venue(&self) -> Option<&Venue> {
77        match self {
78            Self::Data(cmd) => cmd.venue.as_ref(),
79            Self::Instruments(cmd) => Some(&cmd.venue),
80            Self::Instrument(cmd) => cmd.venue.as_ref(),
81            Self::BookDeltas(cmd) => cmd.venue.as_ref(),
82            Self::BookDepth10(cmd) => cmd.venue.as_ref(),
83            Self::BookSnapshots(cmd) => cmd.venue.as_ref(),
84            Self::Quotes(cmd) => cmd.venue.as_ref(),
85            Self::Trades(cmd) => cmd.venue.as_ref(),
86            Self::MarkPrices(cmd) => cmd.venue.as_ref(),
87            Self::IndexPrices(cmd) => cmd.venue.as_ref(),
88            Self::Bars(cmd) => cmd.venue.as_ref(),
89            Self::InstrumentStatus(cmd) => cmd.venue.as_ref(),
90            Self::InstrumentClose(cmd) => cmd.venue.as_ref(),
91        }
92    }
93}
94
95#[derive(Clone, Debug)]
96pub enum UnsubscribeCommand {
97    Data(UnsubscribeData),
98    Instruments(UnsubscribeInstruments),
99    Instrument(UnsubscribeInstrument),
100    BookDeltas(UnsubscribeBookDeltas),
101    BookDepth10(UnsubscribeBookDepth10),
102    BookSnapshots(UnsubscribeBookSnapshots),
103    Quotes(UnsubscribeQuotes),
104    Trades(UnsubscribeTrades),
105    Bars(UnsubscribeBars),
106    MarkPrices(UnsubscribeMarkPrices),
107    IndexPrices(UnsubscribeIndexPrices),
108    InstrumentStatus(UnsubscribeInstrumentStatus),
109    InstrumentClose(UnsubscribeInstrumentClose),
110}
111
112impl UnsubscribeCommand {
113    pub fn client_id(&self) -> Option<&ClientId> {
114        match self {
115            Self::Data(cmd) => cmd.client_id.as_ref(),
116            Self::Instruments(cmd) => cmd.client_id.as_ref(),
117            Self::Instrument(cmd) => cmd.client_id.as_ref(),
118            Self::BookDeltas(cmd) => cmd.client_id.as_ref(),
119            Self::BookDepth10(cmd) => cmd.client_id.as_ref(),
120            Self::BookSnapshots(cmd) => cmd.client_id.as_ref(),
121            Self::Quotes(cmd) => cmd.client_id.as_ref(),
122            Self::Trades(cmd) => cmd.client_id.as_ref(),
123            Self::Bars(cmd) => cmd.client_id.as_ref(),
124            Self::MarkPrices(cmd) => cmd.client_id.as_ref(),
125            Self::IndexPrices(cmd) => cmd.client_id.as_ref(),
126            Self::InstrumentStatus(cmd) => cmd.client_id.as_ref(),
127            Self::InstrumentClose(cmd) => cmd.client_id.as_ref(),
128        }
129    }
130
131    pub fn venue(&self) -> Option<&Venue> {
132        match self {
133            Self::Data(cmd) => cmd.venue.as_ref(),
134            Self::Instruments(cmd) => Some(&cmd.venue),
135            Self::Instrument(cmd) => cmd.venue.as_ref(),
136            Self::BookDeltas(cmd) => cmd.venue.as_ref(),
137            Self::BookDepth10(cmd) => cmd.venue.as_ref(),
138            Self::BookSnapshots(cmd) => cmd.venue.as_ref(),
139            Self::Quotes(cmd) => cmd.venue.as_ref(),
140            Self::Trades(cmd) => cmd.venue.as_ref(),
141            Self::Bars(cmd) => cmd.venue.as_ref(),
142            Self::MarkPrices(cmd) => cmd.venue.as_ref(),
143            Self::IndexPrices(cmd) => cmd.venue.as_ref(),
144            Self::InstrumentStatus(cmd) => cmd.venue.as_ref(),
145            Self::InstrumentClose(cmd) => cmd.venue.as_ref(),
146        }
147    }
148}
149
150fn check_client_id_or_venue(client_id: &Option<ClientId>, venue: &Option<Venue>) {
151    assert!(
152        client_id.is_some() || venue.is_some(),
153        "Both `client_id` and `venue` were None"
154    );
155}
156
157#[derive(Clone, Debug)]
158pub struct SubscribeData {
159    pub client_id: Option<ClientId>,
160    pub venue: Option<Venue>,
161    pub data_type: DataType,
162    pub command_id: UUID4,
163    pub ts_init: UnixNanos,
164    pub params: Option<HashMap<String, String>>,
165}
166
167impl SubscribeData {
168    pub fn new(
169        client_id: Option<ClientId>,
170        venue: Option<Venue>,
171        data_type: DataType,
172        command_id: UUID4,
173        ts_init: UnixNanos,
174        params: Option<HashMap<String, String>>,
175    ) -> Self {
176        check_client_id_or_venue(&client_id, &venue);
177        Self {
178            client_id,
179            venue,
180            data_type,
181            command_id,
182            ts_init,
183            params,
184        }
185    }
186}
187
188#[derive(Clone, Debug)]
189pub struct SubscribeInstruments {
190    pub client_id: Option<ClientId>,
191    pub venue: Venue,
192    pub command_id: UUID4,
193    pub ts_init: UnixNanos,
194    pub params: Option<HashMap<String, String>>,
195}
196
197impl SubscribeInstruments {
198    pub fn new(
199        client_id: Option<ClientId>,
200        venue: Venue,
201        command_id: UUID4,
202        ts_init: UnixNanos,
203        params: Option<HashMap<String, String>>,
204    ) -> Self {
205        Self {
206            client_id,
207            venue,
208            command_id,
209            ts_init,
210            params,
211        }
212    }
213}
214
215#[derive(Clone, Debug)]
216pub struct SubscribeInstrument {
217    pub instrument_id: InstrumentId,
218    pub client_id: Option<ClientId>,
219    pub venue: Option<Venue>,
220    pub command_id: UUID4,
221    pub ts_init: UnixNanos,
222    pub params: Option<HashMap<String, String>>,
223}
224
225impl SubscribeInstrument {
226    pub fn new(
227        instrument_id: InstrumentId,
228        client_id: Option<ClientId>,
229        venue: Option<Venue>,
230        command_id: UUID4,
231        ts_init: UnixNanos,
232        params: Option<HashMap<String, String>>,
233    ) -> Self {
234        check_client_id_or_venue(&client_id, &venue);
235        Self {
236            instrument_id,
237            client_id,
238            venue,
239            command_id,
240            ts_init,
241            params,
242        }
243    }
244}
245
246#[derive(Clone, Debug)]
247pub struct SubscribeBookDeltas {
248    pub instrument_id: InstrumentId,
249    pub book_type: BookType,
250    pub client_id: Option<ClientId>,
251    pub venue: Option<Venue>,
252    pub command_id: UUID4,
253    pub ts_init: UnixNanos,
254    pub depth: Option<NonZeroUsize>,
255    pub managed: bool,
256    pub params: Option<HashMap<String, String>>,
257}
258
259impl SubscribeBookDeltas {
260    #[allow(clippy::too_many_arguments)]
261    pub fn new(
262        instrument_id: InstrumentId,
263        book_type: BookType,
264        client_id: Option<ClientId>,
265        venue: Option<Venue>,
266        command_id: UUID4,
267        ts_init: UnixNanos,
268        depth: Option<NonZeroUsize>,
269        managed: bool,
270        params: Option<HashMap<String, String>>,
271    ) -> Self {
272        check_client_id_or_venue(&client_id, &venue);
273        Self {
274            instrument_id,
275            book_type,
276            client_id,
277            venue,
278            command_id,
279            ts_init,
280            depth,
281            managed,
282            params,
283        }
284    }
285}
286
287#[derive(Clone, Debug)]
288pub struct SubscribeBookDepth10 {
289    pub instrument_id: InstrumentId,
290    pub book_type: BookType,
291    pub client_id: Option<ClientId>,
292    pub venue: Option<Venue>,
293    pub command_id: UUID4,
294    pub ts_init: UnixNanos,
295    pub depth: Option<NonZeroUsize>,
296    pub managed: bool,
297    pub params: Option<HashMap<String, String>>,
298}
299
300impl SubscribeBookDepth10 {
301    #[allow(clippy::too_many_arguments)]
302    pub fn new(
303        instrument_id: InstrumentId,
304        book_type: BookType,
305        client_id: Option<ClientId>,
306        venue: Option<Venue>,
307        command_id: UUID4,
308        ts_init: UnixNanos,
309        depth: Option<NonZeroUsize>,
310        managed: bool,
311        params: Option<HashMap<String, String>>,
312    ) -> Self {
313        check_client_id_or_venue(&client_id, &venue);
314        Self {
315            instrument_id,
316            book_type,
317            client_id,
318            venue,
319            command_id,
320            ts_init,
321            depth,
322            managed,
323            params,
324        }
325    }
326}
327
328#[derive(Clone, Debug)]
329pub struct SubscribeBookSnapshots {
330    pub instrument_id: InstrumentId,
331    pub book_type: BookType,
332    pub client_id: Option<ClientId>,
333    pub venue: Option<Venue>,
334    pub command_id: UUID4,
335    pub ts_init: UnixNanos,
336    pub depth: Option<NonZeroUsize>,
337    pub interval_ms: NonZeroUsize,
338    pub params: Option<HashMap<String, String>>,
339}
340
341impl SubscribeBookSnapshots {
342    #[allow(clippy::too_many_arguments)]
343    pub fn new(
344        instrument_id: InstrumentId,
345        book_type: BookType,
346        client_id: Option<ClientId>,
347        venue: Option<Venue>,
348        command_id: UUID4,
349        ts_init: UnixNanos,
350        depth: Option<NonZeroUsize>,
351        interval_ms: NonZeroUsize,
352        params: Option<HashMap<String, String>>,
353    ) -> Self {
354        check_client_id_or_venue(&client_id, &venue);
355        Self {
356            instrument_id,
357            book_type,
358            client_id,
359            venue,
360            command_id,
361            ts_init,
362            depth,
363            interval_ms,
364            params,
365        }
366    }
367}
368
369#[derive(Clone, Debug)]
370pub struct SubscribeQuotes {
371    pub instrument_id: InstrumentId,
372    pub client_id: Option<ClientId>,
373    pub venue: Option<Venue>,
374    pub command_id: UUID4,
375    pub ts_init: UnixNanos,
376    pub params: Option<HashMap<String, String>>,
377}
378
379impl SubscribeQuotes {
380    pub fn new(
381        instrument_id: InstrumentId,
382        client_id: Option<ClientId>,
383        venue: Option<Venue>,
384        command_id: UUID4,
385        ts_init: UnixNanos,
386        params: Option<HashMap<String, String>>,
387    ) -> Self {
388        check_client_id_or_venue(&client_id, &venue);
389        Self {
390            instrument_id,
391            client_id,
392            venue,
393            command_id,
394            ts_init,
395            params,
396        }
397    }
398}
399
400#[derive(Clone, Debug)]
401pub struct SubscribeTrades {
402    pub instrument_id: InstrumentId,
403    pub client_id: Option<ClientId>,
404    pub venue: Option<Venue>,
405    pub command_id: UUID4,
406    pub ts_init: UnixNanos,
407    pub params: Option<HashMap<String, String>>,
408}
409
410impl SubscribeTrades {
411    pub fn new(
412        instrument_id: InstrumentId,
413        client_id: Option<ClientId>,
414        venue: Option<Venue>,
415        command_id: UUID4,
416        ts_init: UnixNanos,
417        params: Option<HashMap<String, String>>,
418    ) -> Self {
419        check_client_id_or_venue(&client_id, &venue);
420        Self {
421            instrument_id,
422            client_id,
423            venue,
424            command_id,
425            ts_init,
426            params,
427        }
428    }
429}
430
431#[derive(Clone, Debug)]
432pub struct SubscribeBars {
433    pub bar_type: BarType,
434    pub client_id: Option<ClientId>,
435    pub venue: Option<Venue>,
436    pub command_id: UUID4,
437    pub ts_init: UnixNanos,
438    pub await_partial: bool,
439    pub params: Option<HashMap<String, String>>,
440}
441
442impl SubscribeBars {
443    pub fn new(
444        bar_type: BarType,
445        client_id: Option<ClientId>,
446        venue: Option<Venue>,
447        command_id: UUID4,
448        ts_init: UnixNanos,
449        await_partial: bool,
450        params: Option<HashMap<String, String>>,
451    ) -> Self {
452        check_client_id_or_venue(&client_id, &venue);
453        Self {
454            bar_type,
455            client_id,
456            venue,
457            command_id,
458            ts_init,
459            await_partial,
460            params,
461        }
462    }
463}
464
465#[derive(Clone, Debug)]
466pub struct SubscribeMarkPrices {
467    pub instrument_id: InstrumentId,
468    pub client_id: Option<ClientId>,
469    pub venue: Option<Venue>,
470    pub command_id: UUID4,
471    pub ts_init: UnixNanos,
472    pub params: Option<HashMap<String, String>>,
473}
474
475impl SubscribeMarkPrices {
476    pub fn new(
477        instrument_id: InstrumentId,
478        client_id: Option<ClientId>,
479        venue: Option<Venue>,
480        command_id: UUID4,
481        ts_init: UnixNanos,
482        params: Option<HashMap<String, String>>,
483    ) -> Self {
484        check_client_id_or_venue(&client_id, &venue);
485        Self {
486            instrument_id,
487            client_id,
488            venue,
489            command_id,
490            ts_init,
491            params,
492        }
493    }
494}
495
496#[derive(Clone, Debug)]
497pub struct SubscribeIndexPrices {
498    pub instrument_id: InstrumentId,
499    pub client_id: Option<ClientId>,
500    pub venue: Option<Venue>,
501    pub command_id: UUID4,
502    pub ts_init: UnixNanos,
503    pub params: Option<HashMap<String, String>>,
504}
505
506impl SubscribeIndexPrices {
507    pub fn new(
508        instrument_id: InstrumentId,
509        client_id: Option<ClientId>,
510        venue: Option<Venue>,
511        command_id: UUID4,
512        ts_init: UnixNanos,
513        params: Option<HashMap<String, String>>,
514    ) -> Self {
515        check_client_id_or_venue(&client_id, &venue);
516        Self {
517            instrument_id,
518            client_id,
519            venue,
520            command_id,
521            ts_init,
522            params,
523        }
524    }
525}
526
527#[derive(Clone, Debug)]
528pub struct SubscribeInstrumentStatus {
529    pub instrument_id: InstrumentId,
530    pub client_id: Option<ClientId>,
531    pub venue: Option<Venue>,
532    pub command_id: UUID4,
533    pub ts_init: UnixNanos,
534    pub params: Option<HashMap<String, String>>,
535}
536
537impl SubscribeInstrumentStatus {
538    pub fn new(
539        instrument_id: InstrumentId,
540        client_id: Option<ClientId>,
541        venue: Option<Venue>,
542        command_id: UUID4,
543        ts_init: UnixNanos,
544        params: Option<HashMap<String, String>>,
545    ) -> Self {
546        check_client_id_or_venue(&client_id, &venue);
547        Self {
548            instrument_id,
549            client_id,
550            venue,
551            command_id,
552            ts_init,
553            params,
554        }
555    }
556}
557
558#[derive(Clone, Debug)]
559pub struct SubscribeInstrumentClose {
560    pub instrument_id: InstrumentId,
561    pub client_id: Option<ClientId>,
562    pub venue: Option<Venue>,
563    pub command_id: UUID4,
564    pub ts_init: UnixNanos,
565    pub params: Option<HashMap<String, String>>,
566}
567
568impl SubscribeInstrumentClose {
569    pub fn new(
570        instrument_id: InstrumentId,
571        client_id: Option<ClientId>,
572        venue: Option<Venue>,
573        command_id: UUID4,
574        ts_init: UnixNanos,
575        params: Option<HashMap<String, String>>,
576    ) -> Self {
577        check_client_id_or_venue(&client_id, &venue);
578        Self {
579            instrument_id,
580            client_id,
581            venue,
582            command_id,
583            ts_init,
584            params,
585        }
586    }
587}
588
589#[derive(Clone, Debug)]
590pub struct UnsubscribeData {
591    pub client_id: Option<ClientId>,
592    pub venue: Option<Venue>,
593    pub data_type: DataType,
594    pub command_id: UUID4,
595    pub ts_init: UnixNanos,
596    pub params: Option<HashMap<String, String>>,
597}
598
599impl UnsubscribeData {
600    pub fn new(
601        client_id: Option<ClientId>,
602        venue: Option<Venue>,
603        data_type: DataType,
604        command_id: UUID4,
605        ts_init: UnixNanos,
606        params: Option<HashMap<String, String>>,
607    ) -> Self {
608        check_client_id_or_venue(&client_id, &venue);
609        Self {
610            client_id,
611            venue,
612            data_type,
613            command_id,
614            ts_init,
615            params,
616        }
617    }
618}
619
620// Unsubscribe commands
621#[derive(Clone, Debug)]
622pub struct UnsubscribeInstruments {
623    pub client_id: Option<ClientId>,
624    pub venue: Venue,
625    pub command_id: UUID4,
626    pub ts_init: UnixNanos,
627    pub params: Option<HashMap<String, String>>,
628}
629
630impl UnsubscribeInstruments {
631    pub fn new(
632        client_id: Option<ClientId>,
633        venue: Venue,
634        command_id: UUID4,
635        ts_init: UnixNanos,
636        params: Option<HashMap<String, String>>,
637    ) -> Self {
638        Self {
639            client_id,
640            venue,
641            command_id,
642            ts_init,
643            params,
644        }
645    }
646}
647
648#[derive(Clone, Debug)]
649pub struct UnsubscribeInstrument {
650    pub instrument_id: InstrumentId,
651    pub client_id: Option<ClientId>,
652    pub venue: Option<Venue>,
653    pub command_id: UUID4,
654    pub ts_init: UnixNanos,
655    pub params: Option<HashMap<String, String>>,
656}
657
658impl UnsubscribeInstrument {
659    pub fn new(
660        instrument_id: InstrumentId,
661        client_id: Option<ClientId>,
662        venue: Option<Venue>,
663        command_id: UUID4,
664        ts_init: UnixNanos,
665        params: Option<HashMap<String, String>>,
666    ) -> Self {
667        check_client_id_or_venue(&client_id, &venue);
668        Self {
669            instrument_id,
670            client_id,
671            venue,
672            command_id,
673            ts_init,
674            params,
675        }
676    }
677}
678
679#[derive(Clone, Debug)]
680pub struct UnsubscribeBookDeltas {
681    pub instrument_id: InstrumentId,
682    pub client_id: Option<ClientId>,
683    pub venue: Option<Venue>,
684    pub command_id: UUID4,
685    pub ts_init: UnixNanos,
686    pub params: Option<HashMap<String, String>>,
687}
688
689impl UnsubscribeBookDeltas {
690    #[allow(clippy::too_many_arguments)]
691    pub fn new(
692        instrument_id: InstrumentId,
693        client_id: Option<ClientId>,
694        venue: Option<Venue>,
695        command_id: UUID4,
696        ts_init: UnixNanos,
697        params: Option<HashMap<String, String>>,
698    ) -> Self {
699        check_client_id_or_venue(&client_id, &venue);
700        Self {
701            instrument_id,
702            client_id,
703            venue,
704            command_id,
705            ts_init,
706            params,
707        }
708    }
709}
710
711#[derive(Clone, Debug)]
712pub struct UnsubscribeBookDepth10 {
713    pub instrument_id: InstrumentId,
714    pub client_id: Option<ClientId>,
715    pub venue: Option<Venue>,
716    pub command_id: UUID4,
717    pub ts_init: UnixNanos,
718    pub params: Option<HashMap<String, String>>,
719}
720
721impl UnsubscribeBookDepth10 {
722    #[allow(clippy::too_many_arguments)]
723    pub fn new(
724        instrument_id: InstrumentId,
725        client_id: Option<ClientId>,
726        venue: Option<Venue>,
727        command_id: UUID4,
728        ts_init: UnixNanos,
729        params: Option<HashMap<String, String>>,
730    ) -> Self {
731        check_client_id_or_venue(&client_id, &venue);
732        Self {
733            instrument_id,
734            client_id,
735            venue,
736            command_id,
737            ts_init,
738            params,
739        }
740    }
741}
742
743#[derive(Clone, Debug)]
744pub struct UnsubscribeBookSnapshots {
745    pub instrument_id: InstrumentId,
746    pub client_id: Option<ClientId>,
747    pub venue: Option<Venue>,
748    pub command_id: UUID4,
749    pub ts_init: UnixNanos,
750    pub params: Option<HashMap<String, String>>,
751}
752
753impl UnsubscribeBookSnapshots {
754    #[allow(clippy::too_many_arguments)]
755    pub fn new(
756        instrument_id: InstrumentId,
757        client_id: Option<ClientId>,
758        venue: Option<Venue>,
759        command_id: UUID4,
760        ts_init: UnixNanos,
761        params: Option<HashMap<String, String>>,
762    ) -> Self {
763        check_client_id_or_venue(&client_id, &venue);
764        Self {
765            instrument_id,
766            client_id,
767            venue,
768            command_id,
769            ts_init,
770            params,
771        }
772    }
773}
774
775#[derive(Clone, Debug)]
776pub struct UnsubscribeQuotes {
777    pub instrument_id: InstrumentId,
778    pub client_id: Option<ClientId>,
779    pub venue: Option<Venue>,
780    pub command_id: UUID4,
781    pub ts_init: UnixNanos,
782    pub params: Option<HashMap<String, String>>,
783}
784
785impl UnsubscribeQuotes {
786    #[allow(clippy::too_many_arguments)]
787    pub fn new(
788        instrument_id: InstrumentId,
789        client_id: Option<ClientId>,
790        venue: Option<Venue>,
791        command_id: UUID4,
792        ts_init: UnixNanos,
793        params: Option<HashMap<String, String>>,
794    ) -> Self {
795        check_client_id_or_venue(&client_id, &venue);
796        Self {
797            instrument_id,
798            client_id,
799            venue,
800            command_id,
801            ts_init,
802            params,
803        }
804    }
805}
806
807#[derive(Clone, Debug)]
808pub struct UnsubscribeTrades {
809    pub instrument_id: InstrumentId,
810    pub client_id: Option<ClientId>,
811    pub venue: Option<Venue>,
812    pub command_id: UUID4,
813    pub ts_init: UnixNanos,
814    pub params: Option<HashMap<String, String>>,
815}
816
817impl UnsubscribeTrades {
818    #[allow(clippy::too_many_arguments)]
819    pub fn new(
820        instrument_id: InstrumentId,
821        client_id: Option<ClientId>,
822        venue: Option<Venue>,
823        command_id: UUID4,
824        ts_init: UnixNanos,
825        params: Option<HashMap<String, String>>,
826    ) -> Self {
827        check_client_id_or_venue(&client_id, &venue);
828        Self {
829            instrument_id,
830            client_id,
831            venue,
832            command_id,
833            ts_init,
834            params,
835        }
836    }
837}
838
839#[derive(Clone, Debug)]
840pub struct UnsubscribeBars {
841    pub bar_type: BarType,
842    pub client_id: Option<ClientId>,
843    pub venue: Option<Venue>,
844    pub command_id: UUID4,
845    pub ts_init: UnixNanos,
846    pub params: Option<HashMap<String, String>>,
847}
848
849impl UnsubscribeBars {
850    #[allow(clippy::too_many_arguments)]
851    pub fn new(
852        bar_type: BarType,
853        client_id: Option<ClientId>,
854        venue: Option<Venue>,
855        command_id: UUID4,
856        ts_init: UnixNanos,
857        params: Option<HashMap<String, String>>,
858    ) -> Self {
859        check_client_id_or_venue(&client_id, &venue);
860        Self {
861            bar_type,
862            client_id,
863            venue,
864            command_id,
865            ts_init,
866            params,
867        }
868    }
869}
870
871#[derive(Clone, Debug)]
872pub struct UnsubscribeMarkPrices {
873    pub instrument_id: InstrumentId,
874    pub client_id: Option<ClientId>,
875    pub venue: Option<Venue>,
876    pub command_id: UUID4,
877    pub ts_init: UnixNanos,
878    pub params: Option<HashMap<String, String>>,
879}
880
881impl UnsubscribeMarkPrices {
882    #[allow(clippy::too_many_arguments)]
883    pub fn new(
884        instrument_id: InstrumentId,
885        client_id: Option<ClientId>,
886        venue: Option<Venue>,
887        command_id: UUID4,
888        ts_init: UnixNanos,
889        params: Option<HashMap<String, String>>,
890    ) -> Self {
891        check_client_id_or_venue(&client_id, &venue);
892        Self {
893            instrument_id,
894            client_id,
895            venue,
896            command_id,
897            ts_init,
898            params,
899        }
900    }
901}
902
903#[derive(Clone, Debug)]
904pub struct UnsubscribeIndexPrices {
905    pub instrument_id: InstrumentId,
906    pub client_id: Option<ClientId>,
907    pub venue: Option<Venue>,
908    pub command_id: UUID4,
909    pub ts_init: UnixNanos,
910    pub params: Option<HashMap<String, String>>,
911}
912
913impl UnsubscribeIndexPrices {
914    #[allow(clippy::too_many_arguments)]
915    pub fn new(
916        instrument_id: InstrumentId,
917        client_id: Option<ClientId>,
918        venue: Option<Venue>,
919        command_id: UUID4,
920        ts_init: UnixNanos,
921        params: Option<HashMap<String, String>>,
922    ) -> Self {
923        check_client_id_or_venue(&client_id, &venue);
924        Self {
925            instrument_id,
926            client_id,
927            venue,
928            command_id,
929            ts_init,
930            params,
931        }
932    }
933}
934
935#[derive(Clone, Debug)]
936pub struct UnsubscribeInstrumentStatus {
937    pub instrument_id: InstrumentId,
938    pub client_id: Option<ClientId>,
939    pub venue: Option<Venue>,
940    pub command_id: UUID4,
941    pub ts_init: UnixNanos,
942    pub params: Option<HashMap<String, String>>,
943}
944
945impl UnsubscribeInstrumentStatus {
946    #[allow(clippy::too_many_arguments)]
947    pub fn new(
948        instrument_id: InstrumentId,
949        client_id: Option<ClientId>,
950        venue: Option<Venue>,
951        command_id: UUID4,
952        ts_init: UnixNanos,
953        params: Option<HashMap<String, String>>,
954    ) -> Self {
955        check_client_id_or_venue(&client_id, &venue);
956        Self {
957            instrument_id,
958            client_id,
959            venue,
960            command_id,
961            ts_init,
962            params,
963        }
964    }
965}
966
967#[derive(Clone, Debug)]
968pub struct UnsubscribeInstrumentClose {
969    pub instrument_id: InstrumentId,
970    pub client_id: Option<ClientId>,
971    pub venue: Option<Venue>,
972    pub command_id: UUID4,
973    pub ts_init: UnixNanos,
974    pub params: Option<HashMap<String, String>>,
975}
976
977impl UnsubscribeInstrumentClose {
978    #[allow(clippy::too_many_arguments)]
979    pub fn new(
980        instrument_id: InstrumentId,
981        client_id: Option<ClientId>,
982        venue: Option<Venue>,
983        command_id: UUID4,
984        ts_init: UnixNanos,
985        params: Option<HashMap<String, String>>,
986    ) -> Self {
987        check_client_id_or_venue(&client_id, &venue);
988        Self {
989            instrument_id,
990            client_id,
991            venue,
992            command_id,
993            ts_init,
994            params,
995        }
996    }
997}
998
999// Request data structures
1000#[derive(Clone, Debug)]
1001pub struct RequestInstrument {
1002    pub instrument_id: InstrumentId,
1003    pub start: Option<DateTime<Utc>>,
1004    pub end: Option<DateTime<Utc>>,
1005    pub client_id: Option<ClientId>,
1006    pub venue: Option<Venue>,
1007    pub request_id: UUID4,
1008    pub ts_init: UnixNanos,
1009    pub params: Option<HashMap<String, String>>,
1010}
1011
1012impl RequestInstrument {
1013    #[allow(clippy::too_many_arguments)]
1014    pub fn new(
1015        instrument_id: InstrumentId,
1016        start: Option<DateTime<Utc>>,
1017        end: Option<DateTime<Utc>>,
1018        client_id: Option<ClientId>,
1019        venue: Option<Venue>,
1020        request_id: UUID4,
1021        ts_init: UnixNanos,
1022        params: Option<HashMap<String, String>>,
1023    ) -> Self {
1024        check_client_id_or_venue(&client_id, &venue);
1025        Self {
1026            instrument_id,
1027            start,
1028            end,
1029            client_id,
1030            venue,
1031            request_id,
1032            ts_init,
1033            params,
1034        }
1035    }
1036}
1037
1038#[derive(Clone, Debug)]
1039pub struct RequestInstruments {
1040    pub start: Option<DateTime<Utc>>,
1041    pub end: Option<DateTime<Utc>>,
1042    pub client_id: Option<ClientId>,
1043    pub venue: Option<Venue>,
1044    pub request_id: UUID4,
1045    pub ts_init: UnixNanos,
1046    pub params: Option<HashMap<String, String>>,
1047}
1048
1049impl RequestInstruments {
1050    #[allow(clippy::too_many_arguments)]
1051    pub fn new(
1052        start: Option<DateTime<Utc>>,
1053        end: Option<DateTime<Utc>>,
1054        client_id: Option<ClientId>,
1055        venue: Option<Venue>,
1056        request_id: UUID4,
1057        ts_init: UnixNanos,
1058        params: Option<HashMap<String, String>>,
1059    ) -> Self {
1060        check_client_id_or_venue(&client_id, &venue);
1061        Self {
1062            start,
1063            end,
1064            client_id,
1065            venue,
1066            request_id,
1067            ts_init,
1068            params,
1069        }
1070    }
1071}
1072
1073#[derive(Clone, Debug)]
1074pub struct RequestOrderBookSnapshot {
1075    pub instrument_id: InstrumentId,
1076    pub limit: usize,
1077    pub client_id: Option<ClientId>,
1078    pub venue: Option<Venue>,
1079    pub request_id: UUID4,
1080    pub ts_init: UnixNanos,
1081    pub params: Option<HashMap<String, String>>,
1082}
1083
1084impl RequestOrderBookSnapshot {
1085    #[allow(clippy::too_many_arguments)]
1086    pub fn new(
1087        instrument_id: InstrumentId,
1088        limit: usize,
1089        client_id: Option<ClientId>,
1090        venue: Option<Venue>,
1091        request_id: UUID4,
1092        ts_init: UnixNanos,
1093        params: Option<HashMap<String, String>>,
1094    ) -> Self {
1095        check_client_id_or_venue(&client_id, &venue);
1096        Self {
1097            instrument_id,
1098            limit,
1099            client_id,
1100            venue,
1101            request_id,
1102            ts_init,
1103            params,
1104        }
1105    }
1106}
1107
1108#[derive(Clone, Debug)]
1109pub struct RequestQuoteTicks {
1110    pub instrument_id: InstrumentId,
1111    pub start: Option<DateTime<Utc>>,
1112    pub end: Option<DateTime<Utc>>,
1113    pub limit: usize,
1114    pub client_id: Option<ClientId>,
1115    pub venue: Option<Venue>,
1116    pub request_id: UUID4,
1117    pub ts_init: UnixNanos,
1118    pub params: Option<HashMap<String, String>>,
1119}
1120
1121impl RequestQuoteTicks {
1122    #[allow(clippy::too_many_arguments)]
1123    pub fn new(
1124        instrument_id: InstrumentId,
1125        start: Option<DateTime<Utc>>,
1126        end: Option<DateTime<Utc>>,
1127        limit: usize,
1128        client_id: Option<ClientId>,
1129        venue: Option<Venue>,
1130        request_id: UUID4,
1131        ts_init: UnixNanos,
1132        params: Option<HashMap<String, String>>,
1133    ) -> Self {
1134        check_client_id_or_venue(&client_id, &venue);
1135        Self {
1136            instrument_id,
1137            start,
1138            end,
1139            limit,
1140            client_id,
1141            venue,
1142            request_id,
1143            ts_init,
1144            params,
1145        }
1146    }
1147}
1148
1149#[derive(Clone, Debug)]
1150pub struct RequestTradeTicks {
1151    pub instrument_id: InstrumentId,
1152    pub start: Option<DateTime<Utc>>,
1153    pub end: Option<DateTime<Utc>>,
1154    pub limit: usize,
1155    pub client_id: Option<ClientId>,
1156    pub venue: Option<Venue>,
1157    pub request_id: UUID4,
1158    pub ts_init: UnixNanos,
1159    pub params: Option<HashMap<String, String>>,
1160}
1161
1162impl RequestTradeTicks {
1163    #[allow(clippy::too_many_arguments)]
1164    pub fn new(
1165        instrument_id: InstrumentId,
1166        start: Option<DateTime<Utc>>,
1167        end: Option<DateTime<Utc>>,
1168        limit: usize,
1169        client_id: Option<ClientId>,
1170        venue: Option<Venue>,
1171        request_id: UUID4,
1172        ts_init: UnixNanos,
1173        params: Option<HashMap<String, String>>,
1174    ) -> Self {
1175        check_client_id_or_venue(&client_id, &venue);
1176        Self {
1177            instrument_id,
1178            start,
1179            end,
1180            limit,
1181            client_id,
1182            venue,
1183            request_id,
1184            ts_init,
1185            params,
1186        }
1187    }
1188}
1189
1190#[derive(Clone, Debug)]
1191pub struct RequestBars {
1192    pub bar_type: BarType,
1193    pub start: Option<DateTime<Utc>>,
1194    pub end: Option<DateTime<Utc>>,
1195    pub limit: usize,
1196    pub client_id: Option<ClientId>,
1197    pub venue: Option<Venue>,
1198    pub request_id: UUID4,
1199    pub ts_init: UnixNanos,
1200    pub params: Option<HashMap<String, String>>,
1201}
1202
1203impl RequestBars {
1204    #[allow(clippy::too_many_arguments)]
1205    pub fn new(
1206        bar_type: BarType,
1207        start: Option<DateTime<Utc>>,
1208        end: Option<DateTime<Utc>>,
1209        limit: usize,
1210        client_id: Option<ClientId>,
1211        venue: Option<Venue>,
1212        request_id: UUID4,
1213        ts_init: UnixNanos,
1214        params: Option<HashMap<String, String>>,
1215    ) -> Self {
1216        check_client_id_or_venue(&client_id, &venue);
1217        Self {
1218            bar_type,
1219            start,
1220            end,
1221            limit,
1222            client_id,
1223            venue,
1224            request_id,
1225            ts_init,
1226            params,
1227        }
1228    }
1229}
1230
1231#[derive(Clone, Debug)]
1232pub struct DataRequest {
1233    pub correlation_id: UUID4,
1234    pub client_id: ClientId,
1235    pub venue: Venue,
1236    pub data_type: DataType,
1237    pub ts_init: UnixNanos,
1238    pub params: Option<HashMap<String, String>>,
1239}
1240
1241pub type Payload = Arc<dyn Any + Send + Sync>;
1242
1243#[derive(Clone, Debug)]
1244pub struct DataResponse {
1245    pub correlation_id: UUID4,
1246    pub client_id: ClientId,
1247    pub venue: Venue,
1248    pub data_type: DataType,
1249    pub data: Payload,
1250    pub ts_init: UnixNanos,
1251    pub params: Option<HashMap<String, String>>,
1252}
1253
1254impl DataResponse {
1255    pub fn new<T: Any + Send + Sync>(
1256        correlation_id: UUID4,
1257        client_id: ClientId,
1258        venue: Venue,
1259        data_type: DataType,
1260        data: T,
1261        ts_init: UnixNanos,
1262        params: Option<HashMap<String, String>>,
1263    ) -> Self {
1264        Self {
1265            correlation_id,
1266            client_id,
1267            venue,
1268            data_type,
1269            data: Arc::new(data),
1270            ts_init,
1271            params,
1272        }
1273    }
1274}