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