Skip to main content

nautilus_common/messages/data/
request.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
16use std::num::NonZeroUsize;
17
18use chrono::{DateTime, Utc};
19use nautilus_core::{Params, UUID4, UnixNanos};
20use nautilus_model::{
21    data::{BarType, DataType},
22    identifiers::{ClientId, InstrumentId, Venue},
23};
24use serde::{Deserialize, Serialize};
25use ustr::Ustr;
26
27use super::check_client_id_or_venue;
28
29#[derive(Clone, Debug, Serialize, Deserialize)]
30pub struct RequestCustomData {
31    pub client_id: ClientId,
32    pub data_type: DataType,
33    pub start: Option<DateTime<Utc>>,
34    pub end: Option<DateTime<Utc>>,
35    pub limit: Option<NonZeroUsize>,
36    pub request_id: UUID4,
37    pub ts_init: UnixNanos,
38    pub params: Option<Params>,
39}
40
41impl RequestCustomData {
42    /// Creates a new [`RequestCustomData`] instance.
43    #[expect(clippy::too_many_arguments)]
44    pub fn new(
45        client_id: ClientId,
46        data_type: DataType,
47        start: Option<DateTime<Utc>>,
48        end: Option<DateTime<Utc>>,
49        limit: Option<NonZeroUsize>,
50        request_id: UUID4,
51        ts_init: UnixNanos,
52        params: Option<Params>,
53    ) -> Self {
54        Self {
55            client_id,
56            data_type,
57            start,
58            end,
59            limit,
60            request_id,
61            ts_init,
62            params,
63        }
64    }
65}
66
67#[derive(Clone, Debug, Serialize, Deserialize)]
68pub struct RequestInstrument {
69    pub instrument_id: InstrumentId,
70    pub start: Option<DateTime<Utc>>,
71    pub end: Option<DateTime<Utc>>,
72    pub client_id: Option<ClientId>,
73    pub request_id: UUID4,
74    pub ts_init: UnixNanos,
75    pub params: Option<Params>,
76}
77
78impl RequestInstrument {
79    /// Creates a new [`RequestInstrument`] instance.
80    pub fn new(
81        instrument_id: InstrumentId,
82        start: Option<DateTime<Utc>>,
83        end: Option<DateTime<Utc>>,
84        client_id: Option<ClientId>,
85        request_id: UUID4,
86        ts_init: UnixNanos,
87        params: Option<Params>,
88    ) -> Self {
89        Self {
90            instrument_id,
91            start,
92            end,
93            client_id,
94            request_id,
95            ts_init,
96            params,
97        }
98    }
99}
100
101#[derive(Clone, Debug, Serialize, Deserialize)]
102pub struct RequestInstruments {
103    pub start: Option<DateTime<Utc>>,
104    pub end: Option<DateTime<Utc>>,
105    pub client_id: Option<ClientId>,
106    pub venue: Option<Venue>,
107    pub request_id: UUID4,
108    pub ts_init: UnixNanos,
109    pub params: Option<Params>,
110}
111
112impl RequestInstruments {
113    /// Creates a new [`RequestInstruments`] instance.
114    pub fn new(
115        start: Option<DateTime<Utc>>,
116        end: Option<DateTime<Utc>>,
117        client_id: Option<ClientId>,
118        venue: Option<Venue>,
119        request_id: UUID4,
120        ts_init: UnixNanos,
121        params: Option<Params>,
122    ) -> Self {
123        check_client_id_or_venue(&client_id, &venue);
124        Self {
125            start,
126            end,
127            client_id,
128            venue,
129            request_id,
130            ts_init,
131            params,
132        }
133    }
134}
135
136#[derive(Clone, Debug, Serialize, Deserialize)]
137pub struct RequestBookSnapshot {
138    pub instrument_id: InstrumentId,
139    pub depth: Option<NonZeroUsize>,
140    pub client_id: Option<ClientId>,
141    pub request_id: UUID4,
142    pub ts_init: UnixNanos,
143    pub params: Option<Params>,
144}
145
146impl RequestBookSnapshot {
147    /// Creates a new [`RequestBookSnapshot`] instance.
148    pub fn new(
149        instrument_id: InstrumentId,
150        depth: Option<NonZeroUsize>,
151        client_id: Option<ClientId>,
152        request_id: UUID4,
153        ts_init: UnixNanos,
154        params: Option<Params>,
155    ) -> Self {
156        Self {
157            instrument_id,
158            depth,
159            client_id,
160            request_id,
161            ts_init,
162            params,
163        }
164    }
165}
166
167#[derive(Clone, Debug, Serialize, Deserialize)]
168pub struct RequestQuotes {
169    pub instrument_id: InstrumentId,
170    pub start: Option<DateTime<Utc>>,
171    pub end: Option<DateTime<Utc>>,
172    pub limit: Option<NonZeroUsize>,
173    pub client_id: Option<ClientId>,
174    pub request_id: UUID4,
175    pub ts_init: UnixNanos,
176    pub params: Option<Params>,
177}
178
179impl RequestQuotes {
180    /// Creates a new [`RequestQuotes`] instance.
181    #[expect(clippy::too_many_arguments)]
182    pub fn new(
183        instrument_id: InstrumentId,
184        start: Option<DateTime<Utc>>,
185        end: Option<DateTime<Utc>>,
186        limit: Option<NonZeroUsize>,
187        client_id: Option<ClientId>,
188        request_id: UUID4,
189        ts_init: UnixNanos,
190        params: Option<Params>,
191    ) -> Self {
192        Self {
193            instrument_id,
194            start,
195            end,
196            limit,
197            client_id,
198            request_id,
199            ts_init,
200            params,
201        }
202    }
203}
204
205#[derive(Clone, Debug, Serialize, Deserialize)]
206pub struct RequestTrades {
207    pub instrument_id: InstrumentId,
208    pub start: Option<DateTime<Utc>>,
209    pub end: Option<DateTime<Utc>>,
210    pub limit: Option<NonZeroUsize>,
211    pub client_id: Option<ClientId>,
212    pub request_id: UUID4,
213    pub ts_init: UnixNanos,
214    pub params: Option<Params>,
215}
216
217impl RequestTrades {
218    /// Creates a new [`RequestTrades`] instance.
219    #[expect(clippy::too_many_arguments)]
220    pub fn new(
221        instrument_id: InstrumentId,
222        start: Option<DateTime<Utc>>,
223        end: Option<DateTime<Utc>>,
224        limit: Option<NonZeroUsize>,
225        client_id: Option<ClientId>,
226        request_id: UUID4,
227        ts_init: UnixNanos,
228        params: Option<Params>,
229    ) -> Self {
230        Self {
231            instrument_id,
232            start,
233            end,
234            limit,
235            client_id,
236            request_id,
237            ts_init,
238            params,
239        }
240    }
241}
242
243#[derive(Clone, Debug, Serialize, Deserialize)]
244pub struct RequestFundingRates {
245    pub instrument_id: InstrumentId,
246    pub start: Option<DateTime<Utc>>,
247    pub end: Option<DateTime<Utc>>,
248    pub limit: Option<NonZeroUsize>,
249    pub client_id: Option<ClientId>,
250    pub request_id: UUID4,
251    pub ts_init: UnixNanos,
252    pub params: Option<Params>,
253}
254
255impl RequestFundingRates {
256    /// Creates a new [`RequestFundingRates`] instance.
257    #[expect(clippy::too_many_arguments)]
258    pub fn new(
259        instrument_id: InstrumentId,
260        start: Option<DateTime<Utc>>,
261        end: Option<DateTime<Utc>>,
262        limit: Option<NonZeroUsize>,
263        client_id: Option<ClientId>,
264        request_id: UUID4,
265        ts_init: UnixNanos,
266        params: Option<Params>,
267    ) -> Self {
268        Self {
269            instrument_id,
270            start,
271            end,
272            limit,
273            client_id,
274            request_id,
275            ts_init,
276            params,
277        }
278    }
279}
280
281#[derive(Clone, Debug, Serialize, Deserialize)]
282pub struct RequestForwardPrices {
283    pub venue: Venue,
284    pub underlying: Ustr,
285    pub instrument_id: Option<InstrumentId>,
286    pub client_id: Option<ClientId>,
287    pub request_id: UUID4,
288    pub ts_init: UnixNanos,
289    pub params: Option<Params>,
290}
291
292impl RequestForwardPrices {
293    /// Creates a new [`RequestForwardPrices`] instance.
294    pub fn new(
295        venue: Venue,
296        underlying: Ustr,
297        instrument_id: Option<InstrumentId>,
298        client_id: Option<ClientId>,
299        request_id: UUID4,
300        ts_init: UnixNanos,
301        params: Option<Params>,
302    ) -> Self {
303        Self {
304            venue,
305            underlying,
306            instrument_id,
307            client_id,
308            request_id,
309            ts_init,
310            params,
311        }
312    }
313}
314
315#[derive(Clone, Debug, Serialize, Deserialize)]
316pub struct RequestBookDepth {
317    pub instrument_id: InstrumentId,
318    pub start: Option<DateTime<Utc>>,
319    pub end: Option<DateTime<Utc>>,
320    pub limit: Option<NonZeroUsize>,
321    pub depth: Option<NonZeroUsize>,
322    pub client_id: Option<ClientId>,
323    pub request_id: UUID4,
324    pub ts_init: UnixNanos,
325    pub params: Option<Params>,
326}
327
328impl RequestBookDepth {
329    /// Creates a new [`RequestBookDepth`] instance.
330    #[expect(clippy::too_many_arguments)]
331    pub fn new(
332        instrument_id: InstrumentId,
333        start: Option<DateTime<Utc>>,
334        end: Option<DateTime<Utc>>,
335        limit: Option<NonZeroUsize>,
336        depth: Option<NonZeroUsize>,
337        client_id: Option<ClientId>,
338        request_id: UUID4,
339        ts_init: UnixNanos,
340        params: Option<Params>,
341    ) -> Self {
342        Self {
343            instrument_id,
344            start,
345            end,
346            limit,
347            depth,
348            client_id,
349            request_id,
350            ts_init,
351            params,
352        }
353    }
354}
355
356#[derive(Clone, Debug, Serialize, Deserialize)]
357pub struct RequestBookDeltas {
358    pub instrument_id: InstrumentId,
359    pub start: Option<DateTime<Utc>>,
360    pub end: Option<DateTime<Utc>>,
361    pub limit: Option<NonZeroUsize>,
362    pub client_id: Option<ClientId>,
363    pub request_id: UUID4,
364    pub ts_init: UnixNanos,
365    pub params: Option<Params>,
366}
367
368impl RequestBookDeltas {
369    /// Creates a new [`RequestBookDeltas`] instance.
370    #[expect(clippy::too_many_arguments)]
371    pub fn new(
372        instrument_id: InstrumentId,
373        start: Option<DateTime<Utc>>,
374        end: Option<DateTime<Utc>>,
375        limit: Option<NonZeroUsize>,
376        client_id: Option<ClientId>,
377        request_id: UUID4,
378        ts_init: UnixNanos,
379        params: Option<Params>,
380    ) -> Self {
381        Self {
382            instrument_id,
383            start,
384            end,
385            limit,
386            client_id,
387            request_id,
388            ts_init,
389            params,
390        }
391    }
392}
393
394#[derive(Clone, Debug, Serialize, Deserialize)]
395pub struct RequestBars {
396    pub bar_type: BarType,
397    pub start: Option<DateTime<Utc>>,
398    pub end: Option<DateTime<Utc>>,
399    pub limit: Option<NonZeroUsize>,
400    pub client_id: Option<ClientId>,
401    pub request_id: UUID4,
402    pub ts_init: UnixNanos,
403    pub params: Option<Params>,
404}
405
406impl RequestBars {
407    /// Creates a new [`RequestBars`] instance.
408    #[expect(clippy::too_many_arguments)]
409    pub fn new(
410        bar_type: BarType,
411        start: Option<DateTime<Utc>>,
412        end: Option<DateTime<Utc>>,
413        limit: Option<NonZeroUsize>,
414        client_id: Option<ClientId>,
415        request_id: UUID4,
416        ts_init: UnixNanos,
417        params: Option<Params>,
418    ) -> Self {
419        Self {
420            bar_type,
421            start,
422            end,
423            limit,
424            client_id,
425            request_id,
426            ts_init,
427            params,
428        }
429    }
430}
431
432/// A request to join multiple in-flight data requests under a single parent response.
433///
434/// The engine first issues a combined date-range request to bound the join window,
435/// then fans out the leg responses through the request-pipeline machinery so the
436/// caller receives one consolidated `DataResponse` keyed by the join `request_id`.
437#[derive(Clone, Debug, Serialize, Deserialize)]
438pub struct RequestJoin {
439    pub request_ids: Vec<UUID4>,
440    pub start: Option<DateTime<Utc>>,
441    pub end: Option<DateTime<Utc>>,
442    pub request_id: UUID4,
443    pub ts_init: UnixNanos,
444    pub params: Option<Params>,
445    pub correlation_id: Option<UUID4>,
446}
447
448impl RequestJoin {
449    /// Creates a new [`RequestJoin`] instance.
450    ///
451    /// # Panics
452    ///
453    /// Panics if `request_ids` is empty.
454    pub fn new(
455        request_ids: Vec<UUID4>,
456        start: Option<DateTime<Utc>>,
457        end: Option<DateTime<Utc>>,
458        request_id: UUID4,
459        ts_init: UnixNanos,
460        params: Option<Params>,
461        correlation_id: Option<UUID4>,
462    ) -> Self {
463        assert!(!request_ids.is_empty(), "request_ids must not be empty");
464        Self {
465            request_ids,
466            start,
467            end,
468            request_id,
469            ts_init,
470            params,
471            correlation_id,
472        }
473    }
474
475    /// Returns a fresh [`RequestJoin`] for the combined date-range bootstrap leg.
476    ///
477    /// The returned request inherits `request_ids` and `params`, carries the
478    /// supplied dates, and sets `correlation_id` to the original request id so
479    /// the response can be matched back to the parent join.
480    #[must_use]
481    pub fn with_dates(
482        &self,
483        start: Option<DateTime<Utc>>,
484        end: Option<DateTime<Utc>>,
485        ts_init: UnixNanos,
486    ) -> Self {
487        Self {
488            request_ids: self.request_ids.clone(),
489            start,
490            end,
491            request_id: UUID4::new(),
492            ts_init,
493            params: self.params.clone(),
494            correlation_id: Some(self.request_id),
495        }
496    }
497}