dbn/
record.rs

1//! Market data types for encoding different Databento [`Schema`](crate::enums::Schema)s
2//! in the most recent DBN version, as well as conversion functions.
3
4pub(crate) mod conv;
5mod impl_default;
6mod layout_tests;
7mod methods;
8mod record_methods_tests;
9mod traits;
10mod with_ts_out_methods;
11
12use std::{ffi::CStr, mem, os::raw::c_char, ptr::NonNull, slice};
13
14// Dummy derive macro to get around `cfg_attr` incompatibility of several
15// of pyo3's attribute macros. See https://github.com/PyO3/pyo3/issues/780
16#[cfg(not(feature = "python"))]
17use dbn_macros::MockPyo3;
18
19use crate::{
20    enums::rtype,
21    macros::{dbn_record, CsvSerialize, JsonSerialize, RecordDebug},
22    Action, Error, FlagSet, InstrumentClass, MatchAlgorithm, Publisher, RType, Result,
23    SecurityUpdateAction, Side, StatUpdateAction, UserDefinedInstrument, ASSET_CSTR_LEN,
24    SYMBOL_CSTR_LEN,
25};
26pub(crate) use conv::as_u8_slice;
27#[cfg(feature = "serde")]
28pub(crate) use conv::cstr_serde;
29pub use conv::{
30    c_chars_to_str, str_to_c_chars, transmute_header_bytes, transmute_record,
31    transmute_record_bytes, transmute_record_mut, ts_to_dt,
32};
33pub use traits::{HasRType, Record, RecordMut};
34
35/// Common data for all Databento records. Always found at the beginning of a record
36/// struct.
37#[repr(C)]
38#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
39#[cfg_attr(feature = "trivial_copy", derive(Copy))]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41#[cfg_attr(feature = "python", derive(crate::macros::PyFieldDesc))]
42#[cfg_attr(test, derive(type_layout::TypeLayout))]
43pub struct RecordHeader {
44    /// The length of the record in 32-bit words.
45    #[dbn(skip)]
46    pub(crate) length: u8,
47    /// The record type; with `0x00..0x0F` specifying MBP levels size. Record types
48    /// implement the trait [`HasRType`], and the [`has_rtype`][HasRType::has_rtype]
49    /// function can be used to check if that type can be used to decode a message with
50    /// a given rtype. The set of possible values is defined in [`rtype`].
51    pub rtype: u8,
52    /// The publisher ID assigned by Databento, which denotes the dataset and venue.
53    ///
54    /// See [Publishers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#publishers-datasets-and-venues).
55    pub publisher_id: u16,
56    /// The numeric instrument ID. See [Instrument identifiers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#instrument-identifiers).
57    pub instrument_id: u32,
58    /// The matching-engine-received timestamp expressed as the number of nanoseconds
59    /// since the UNIX epoch.
60    ///
61    /// See [ts_event](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-event).
62    #[dbn(encode_order(0), unix_nanos)]
63    pub ts_event: u64,
64}
65
66/// A market-by-order (MBO) tick message. The record of the [`Mbo`](crate::Schema::Mbo)
67/// schema.
68#[repr(C)]
69#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
70#[cfg_attr(feature = "trivial_copy", derive(Copy))]
71#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
72#[cfg_attr(
73    feature = "python",
74    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "MBOMsg"),
75    derive(crate::macros::PyFieldDesc)
76)]
77#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
78#[cfg_attr(test, derive(type_layout::TypeLayout))]
79#[dbn_record(rtype::MBO)]
80pub struct MboMsg {
81    /// The common header.
82    pub hd: RecordHeader,
83    /// The order ID assigned at the venue.
84    #[pyo3(get, set)]
85    pub order_id: u64,
86    /// The order price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
87    /// 0.000000001.
88    ///
89    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
90    #[dbn(encode_order(4), fixed_price)]
91    #[pyo3(get, set)]
92    pub price: i64,
93    /// The order quantity.
94    #[dbn(encode_order(5))]
95    #[pyo3(get, set)]
96    pub size: u32,
97    /// A bit field indicating event end, message characteristics, and data quality.
98    /// See [`flags`](crate::flags) for possible values.
99    #[pyo3(get, set)]
100    pub flags: FlagSet,
101    /// The channel ID assigned by Databento as an incrementing integer starting at zero.
102    #[dbn(encode_order(6))]
103    #[pyo3(get, set)]
104    pub channel_id: u8,
105    /// The event action. Can be **A**dd, **C**ancel, **M**odify, clea**R** book, **T**rade, **F**ill, or **N**one.
106    ///
107    /// See [Action](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#action).
108    #[dbn(c_char, encode_order(2))]
109    pub action: c_char,
110    /// The side that initiates the event. Can be **A**sk for a sell order (or sell aggressor in
111    /// a trade), **B**id for a buy order (or buy aggressor in a trade), or **N**one where no side is specified.
112    ///
113    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
114    #[dbn(c_char, encode_order(3))]
115    pub side: c_char,
116    /// The capture-server-received timestamp expressed as the number of nanoseconds
117    /// since the UNIX epoch.
118    ///
119    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
120    #[dbn(encode_order(0), index_ts, unix_nanos)]
121    #[pyo3(get, set)]
122    pub ts_recv: u64,
123    /// The matching-engine-sending timestamp expressed as the number of nanoseconds before
124    /// `ts_recv`.
125    ///
126    /// See [ts_in_delta](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-in-delta).
127    #[pyo3(get, set)]
128    pub ts_in_delta: i32,
129    /// The message sequence number assigned at the venue.
130    #[pyo3(get, set)]
131    pub sequence: u32,
132}
133
134/// A price level.
135#[repr(C)]
136#[derive(Clone, JsonSerialize, RecordDebug, PartialEq, Eq, Hash)]
137#[cfg_attr(feature = "trivial_copy", derive(Copy))]
138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
139#[cfg_attr(
140    feature = "python",
141    pyo3::pyclass(dict, eq, module = "databento_dbn"),
142    derive(crate::macros::PyFieldDesc)
143)]
144#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
145#[cfg_attr(test, derive(type_layout::TypeLayout))]
146pub struct BidAskPair {
147    /// The bid price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
148    /// 0.000000001.
149    ///
150    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
151    #[dbn(fixed_price)]
152    #[pyo3(get, set)]
153    pub bid_px: i64,
154    /// The ask price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
155    /// 0.000000001.
156    ///
157    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
158    #[dbn(fixed_price)]
159    #[pyo3(get, set)]
160    pub ask_px: i64,
161    /// The bid size.
162    #[pyo3(get, set)]
163    pub bid_sz: u32,
164    /// The ask size.
165    #[pyo3(get, set)]
166    pub ask_sz: u32,
167    /// The bid order count.
168    #[pyo3(get, set)]
169    pub bid_ct: u32,
170    /// The ask order count.
171    #[pyo3(get, set)]
172    pub ask_ct: u32,
173}
174
175/// A price level consolidated from multiple venues.
176#[repr(C)]
177#[derive(Clone, JsonSerialize, RecordDebug, PartialEq, Eq, Hash)]
178#[cfg_attr(feature = "trivial_copy", derive(Copy))]
179#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
180#[cfg_attr(
181    feature = "python",
182    pyo3::pyclass(dict, eq, module = "databento_dbn"),
183    derive(crate::macros::PyFieldDesc)
184)]
185#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
186#[cfg_attr(test, derive(type_layout::TypeLayout))]
187pub struct ConsolidatedBidAskPair {
188    /// The bid price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
189    /// 0.000000001.
190    ///
191    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
192    #[dbn(fixed_price)]
193    #[pyo3(get, set)]
194    pub bid_px: i64,
195    /// The ask price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
196    /// 0.000000001.
197    ///
198    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
199    #[dbn(fixed_price)]
200    #[pyo3(get, set)]
201    pub ask_px: i64,
202    /// The bid size.
203    #[pyo3(get, set)]
204    pub bid_sz: u32,
205    /// The ask size.
206    #[pyo3(get, set)]
207    pub ask_sz: u32,
208    /// The publisher ID indicating the venue containing the best bid.
209    ///
210    /// See [Publishers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#publishers-datasets-and-venues).
211    #[dbn(fmt_method)]
212    #[pyo3(get, set)]
213    pub bid_pb: u16,
214    #[doc(hidden)]
215    #[cfg_attr(feature = "serde", serde(skip))]
216    pub _reserved1: [u8; 2],
217    /// The publisher ID indicating the venue containing the best ask.
218    ///
219    /// See [Publishers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#publishers-datasets-and-venues).
220    #[dbn(fmt_method)]
221    #[pyo3(get, set)]
222    pub ask_pb: u16,
223    #[doc(hidden)]
224    #[cfg_attr(feature = "serde", serde(skip))]
225    pub _reserved2: [u8; 2],
226}
227
228/// Market-by-price implementation with a book depth of 0. Equivalent to MBP-0. The record of the [`Trades`](crate::Schema::Trades) schema.
229#[repr(C)]
230#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
231#[cfg_attr(feature = "trivial_copy", derive(Copy))]
232#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
233#[cfg_attr(
234    feature = "python",
235    pyo3::pyclass(dict, eq, module = "databento_dbn"),
236    derive(crate::macros::PyFieldDesc)
237)]
238#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
239#[cfg_attr(test, derive(type_layout::TypeLayout))]
240#[dbn_record(rtype::MBP_0)]
241pub struct TradeMsg {
242    /// The common header.
243    pub hd: RecordHeader,
244    /// The trade price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
245    ///
246    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
247    #[dbn(fixed_price)]
248    #[pyo3(get, set)]
249    pub price: i64,
250    /// The order quantity.
251    #[pyo3(get, set)]
252    pub size: u32,
253    /// The event action. Always **T**rade in the trades schema.
254    ///
255    /// See [Action](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#action).
256    #[dbn(c_char, encode_order(2))]
257    pub action: c_char,
258    /// The side that initiates the trade. Can be **A**sk for a sell aggressor in a trade, **B**id for a buy aggressor in a trade, or **N**one where no side is specified.
259    ///
260    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
261    #[dbn(c_char, encode_order(3))]
262    pub side: c_char,
263    /// A bit field indicating event end, message characteristics, and data quality.
264    /// See [`flags`](crate::flags) for possible values.
265    #[pyo3(get, set)]
266    pub flags: FlagSet,
267    /// The book level where the update event occurred.
268    #[dbn(encode_order(4))]
269    #[pyo3(get, set)]
270    pub depth: u8,
271    /// The capture-server-received timestamp expressed as the number of nanoseconds
272    /// since the UNIX epoch.
273    ///
274    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
275    #[dbn(encode_order(0), index_ts, unix_nanos)]
276    #[pyo3(get, set)]
277    pub ts_recv: u64,
278    /// The matching-engine-sending timestamp expressed as the number of nanoseconds before
279    /// `ts_recv`.
280    ///
281    /// See [ts_in_delta](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-in-delta).
282    #[pyo3(get, set)]
283    pub ts_in_delta: i32,
284    /// The message sequence number assigned at the venue.
285    #[pyo3(get, set)]
286    pub sequence: u32,
287}
288
289/// Market-by-price implementation with a known book depth of 1. The record of the
290/// [`Mbp1`](crate::Schema::Mbp1) schema.
291#[repr(C)]
292#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
293#[cfg_attr(feature = "trivial_copy", derive(Copy))]
294#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
295#[cfg_attr(
296    feature = "python",
297    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "MBP1Msg"),
298    derive(crate::macros::PyFieldDesc)
299)]
300#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
301#[cfg_attr(test, derive(type_layout::TypeLayout))]
302#[dbn_record(rtype::MBP_1)]
303pub struct Mbp1Msg {
304    /// The common header.
305    pub hd: RecordHeader,
306    /// The order price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
307    /// 0.000000001.
308    ///
309    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
310    #[dbn(fixed_price)]
311    #[pyo3(get, set)]
312    pub price: i64,
313    /// The order quantity.
314    #[pyo3(get, set)]
315    pub size: u32,
316    /// The event action. Can be **A**dd, **C**ancel, **M**odify, clea**R** book, or **T**rade.
317    ///
318    /// See [Action](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#action).
319    #[dbn(c_char, encode_order(2))]
320    pub action: c_char,
321    /// The side that initiates the event. Can be **A**sk for a sell order (or sell aggressor in
322    /// a trade), **B**id for a buy order (or buy aggressor in a trade), or **N**one where no side is specified.
323    ///
324    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
325    #[dbn(c_char, encode_order(3))]
326    pub side: c_char,
327    /// A bit field indicating event end, message characteristics, and data quality.
328    /// See [`flags`](crate::flags) for possible values.
329    #[pyo3(get, set)]
330    pub flags: FlagSet,
331    /// The book level where the update event occurred.
332    #[dbn(encode_order(4))]
333    #[pyo3(get, set)]
334    pub depth: u8,
335    /// The capture-server-received timestamp expressed as the number of nanoseconds
336    /// since the UNIX epoch.
337    ///
338    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
339    #[dbn(encode_order(0), index_ts, unix_nanos)]
340    #[pyo3(get, set)]
341    pub ts_recv: u64,
342    /// The matching-engine-sending timestamp expressed as the number of nanoseconds before
343    /// `ts_recv`.
344    ///
345    /// See [ts_in_delta](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-in-delta).
346    #[pyo3(get, set)]
347    pub ts_in_delta: i32,
348    /// The message sequence number assigned at the venue.
349    #[pyo3(get, set)]
350    pub sequence: u32,
351    /// The top of the order book.
352    #[pyo3(get, set)]
353    pub levels: [BidAskPair; 1],
354}
355
356/// Market-by-price implementation with a known book depth of 10. The record of the
357/// [`Mbp10`](crate::Schema::Mbp10) schema.
358#[repr(C)]
359#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
360#[cfg_attr(feature = "trivial_copy", derive(Copy))]
361#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
362#[cfg_attr(
363    feature = "python",
364    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "MBP10Msg"),
365    derive(crate::macros::PyFieldDesc)
366)]
367#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
368#[cfg_attr(test, derive(type_layout::TypeLayout))]
369#[dbn_record(rtype::MBP_10)]
370pub struct Mbp10Msg {
371    /// The common header.
372    pub hd: RecordHeader,
373    /// The order price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
374    /// 0.000000001.
375    ///
376    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
377    #[dbn(fixed_price)]
378    #[pyo3(get, set)]
379    pub price: i64,
380    /// The order quantity.
381    #[pyo3(get, set)]
382    pub size: u32,
383    /// The event action. Can be **A**dd, **C**ancel, **M**odify, clea**R** book, or **T**rade.
384    ///
385    /// See [Action](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#action).
386    #[dbn(c_char, encode_order(2))]
387    pub action: c_char,
388    /// The side that initiates the event. Can be **A**sk for a sell order (or sell aggressor in
389    /// a trade), **B**id for a buy order (or buy aggressor in a trade), or **N**one where no side is specified.
390    ///
391    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
392    #[dbn(c_char, encode_order(3))]
393    pub side: c_char,
394    /// A bit field indicating event end, message characteristics, and data quality.
395    /// See [`flags`](crate::flags) for possible values.
396    #[pyo3(get, set)]
397    pub flags: FlagSet,
398    /// The book level where the update event occurred.
399    #[dbn(encode_order(4))]
400    #[pyo3(get, set)]
401    pub depth: u8,
402    /// The capture-server-received timestamp expressed as the number of nanoseconds
403    /// since the UNIX epoch.
404    ///
405    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
406    #[dbn(encode_order(0), index_ts, unix_nanos)]
407    #[pyo3(get, set)]
408    pub ts_recv: u64,
409    /// The matching-engine-sending timestamp expressed as the number of nanoseconds before
410    /// `ts_recv`.
411    ///
412    /// See [ts_in_delta](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-in-delta).
413    #[pyo3(get, set)]
414    pub ts_in_delta: i32,
415    /// The message sequence number assigned at the venue.
416    #[pyo3(get, set)]
417    pub sequence: u32,
418    /// The top 10 levels of the order book.
419    #[pyo3(get, set)]
420    pub levels: [BidAskPair; 10],
421}
422
423/// Subsampled market by price with a known book depth of 1. The record of the
424/// [`Bbo1S`](crate::Schema::Bbo1S) and [`Bbo1M`](crate::Schema::Bbo1M) schemas.
425#[repr(C)]
426#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
427#[cfg_attr(feature = "trivial_copy", derive(Copy))]
428#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
429#[cfg_attr(
430    feature = "python",
431    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "BBOMsg"),
432    derive(crate::macros::PyFieldDesc)
433)]
434#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
435#[cfg_attr(test, derive(type_layout::TypeLayout))]
436#[dbn_record(rtype::BBO_1S, rtype::BBO_1M)]
437pub struct BboMsg {
438    /// The common header.
439    pub hd: RecordHeader,
440    /// The last trade price price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000
441    /// or 0.000000001. Will be [`UNDEF_PRICE`](crate::UNDEF_PRICE) if there was no last trade
442    /// in the session.
443    ///
444    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
445    #[dbn(fixed_price)]
446    #[pyo3(get, set)]
447    pub price: i64,
448    /// The quantity of the last trade.
449    #[pyo3(get, set)]
450    pub size: u32,
451    #[doc(hidden)]
452    #[cfg_attr(feature = "serde", serde(skip))]
453    pub _reserved1: u8,
454    /// The side that initiated the last trade. Can be **A**sk for a sell order (or sell
455    /// aggressor in a trade), **B**id for a buy order (or buy aggressor in a trade), or
456    /// **N**one where no side is specified.
457    ///
458    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
459    #[dbn(c_char, encode_order(2))]
460    pub side: c_char,
461    /// A bit field indicating event end, message characteristics, and data quality.
462    /// See [`flags`](crate::flags) for possible values.
463    #[pyo3(get, set)]
464    pub flags: FlagSet,
465    #[doc(hidden)]
466    #[cfg_attr(feature = "serde", serde(skip))]
467    pub _reserved2: u8,
468    /// The end timestamp of the interval capture-server-received timestamp expressed as the
469    /// number of nanoseconds since the UNIX epoch.
470    ///
471    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
472    #[dbn(encode_order(0), index_ts, unix_nanos)]
473    #[pyo3(get, set)]
474    pub ts_recv: u64,
475    #[doc(hidden)]
476    #[cfg_attr(feature = "serde", serde(skip))]
477    pub _reserved3: [u8; 4],
478    /// The message sequence number assigned at the venue of the last update.
479    #[pyo3(get, set)]
480    pub sequence: u32,
481    /// The top of the order book.
482    #[pyo3(get, set)]
483    pub levels: [BidAskPair; 1],
484}
485
486/// Consolidated market-by-price implementation with a known book depth of 1. The record of
487/// the [`Cmbp1`](crate::Schema::Cmbp1) schema.
488#[repr(C)]
489#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
490#[cfg_attr(feature = "trivial_copy", derive(Copy))]
491#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
492#[cfg_attr(
493    feature = "python",
494    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "CMBP1Msg"),
495    derive(crate::macros::PyFieldDesc)
496)]
497#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
498#[cfg_attr(test, derive(type_layout::TypeLayout))]
499#[dbn_record(rtype::CMBP_1, rtype::TCBBO)]
500pub struct Cmbp1Msg {
501    /// The common header.
502    pub hd: RecordHeader,
503    /// The order price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or
504    /// 0.000000001.
505    ///
506    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
507    #[dbn(fixed_price)]
508    #[pyo3(get, set)]
509    pub price: i64,
510    /// The order quantity.
511    #[pyo3(get, set)]
512    pub size: u32,
513    /// The event action. Can be **A**dd, **C**ancel, **M**odify, clea**R** book, or **T**rade.
514    ///
515    /// See [Action](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#action).
516    #[dbn(c_char, encode_order(2))]
517    pub action: c_char,
518    /// The side that initiates the event. Can be **A**sk for a sell order (or sell aggressor in
519    /// a trade), **B**id for a buy order (or buy aggressor in a trade), or **N**one where no side is specified.
520    ///
521    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
522    #[dbn(c_char, encode_order(3))]
523    pub side: c_char,
524    /// A bit field indicating event end, message characteristics, and data quality.
525    /// See [`flags`](crate::flags) for possible values.
526    #[pyo3(get, set)]
527    pub flags: FlagSet,
528    #[doc(hidden)]
529    #[cfg_attr(feature = "serde", serde(skip))]
530    pub _reserved1: [u8; 1],
531    /// The capture-server-received timestamp expressed as the number of nanoseconds
532    /// since the UNIX epoch.
533    ///
534    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
535    #[dbn(encode_order(0), index_ts, unix_nanos)]
536    #[pyo3(get, set)]
537    pub ts_recv: u64,
538    /// The matching-engine-sending timestamp expressed as the number of nanoseconds before
539    /// `ts_recv`.
540    ///
541    /// See [ts_in_delta](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-in-delta).
542    #[pyo3(get, set)]
543    pub ts_in_delta: i32,
544    #[doc(hidden)]
545    #[cfg_attr(feature = "serde", serde(skip))]
546    pub _reserved2: [u8; 4],
547    /// The top of the order book.
548    #[pyo3(get, set)]
549    pub levels: [ConsolidatedBidAskPair; 1],
550}
551
552/// Subsampled consolidated market by price with a known book depth of 1. The record of the [`Cbbo1S`](crate::Schema::Cbbo1S) and [`Cbbo1M`](crate::Schema::Cbbo1M) schemas.
553#[repr(C)]
554#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
555#[cfg_attr(feature = "trivial_copy", derive(Copy))]
556#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
557#[cfg_attr(
558    feature = "python",
559    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "CBBOMsg"),
560    derive(crate::macros::PyFieldDesc)
561)]
562#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
563#[cfg_attr(test, derive(type_layout::TypeLayout))]
564#[dbn_record(rtype::CBBO_1S, rtype::CBBO_1M)]
565pub struct CbboMsg {
566    /// The common header.
567    pub hd: RecordHeader,
568    /// The last trade price price where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000
569    /// or 0.000000001. Will be [`UNDEF_PRICE`](crate::UNDEF_PRICE) if there was no last trade
570    /// in the session.
571    ///
572    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
573    #[dbn(fixed_price)]
574    #[pyo3(get, set)]
575    pub price: i64,
576    /// The quantity of the last trade.
577    #[pyo3(get, set)]
578    pub size: u32,
579    #[doc(hidden)]
580    #[cfg_attr(feature = "serde", serde(skip))]
581    pub _reserved1: u8,
582    /// The side that initiated the last trade. Can be **A**sk for a sell order (or sell
583    /// aggressor in a trade), **B**id for a buy order (or buy aggressor in a trade), or
584    /// **N**one where no side is specified.
585    ///
586    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
587    #[dbn(c_char, encode_order(2))]
588    pub side: c_char,
589    /// A bit field indicating event end, message characteristics, and data quality.
590    /// See [`flags`](crate::flags) for possible values.
591    #[pyo3(get, set)]
592    pub flags: FlagSet,
593    #[doc(hidden)]
594    #[cfg_attr(feature = "serde", serde(skip))]
595    pub _reserved2: u8,
596    /// The end timestamp of the interval capture-server-received timestamp expressed as the
597    /// number of nanoseconds since the UNIX epoch.
598    ///
599    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
600    #[dbn(encode_order(0), index_ts, unix_nanos)]
601    #[pyo3(get, set)]
602    pub ts_recv: u64,
603    #[doc(hidden)]
604    #[cfg_attr(feature = "serde", serde(skip))]
605    pub _reserved3: [u8; 8],
606    /// The top of the order book.
607    #[pyo3(get, set)]
608    pub levels: [ConsolidatedBidAskPair; 1],
609}
610
611/// The record of the [`Tbbo`](crate::Schema::Tbbo) schema.
612pub type TbboMsg = Mbp1Msg;
613
614/// The record of the [`Bbo1S`](crate::Schema::Bbo1S) schema.
615pub type Bbo1SMsg = BboMsg;
616
617/// The record of the [`Bbo1M`](crate::Schema::Bbo1M) schema.
618pub type Bbo1MMsg = BboMsg;
619
620/// The record of the [`Tcbbo`](crate::Schema::Tcbbo) schema.
621pub type TcbboMsg = Cmbp1Msg;
622
623/// The record of the [`Cbbo1S`](crate::Schema::Cbbo1S) schema.
624pub type Cbbo1SMsg = CbboMsg;
625
626/// The record of the [`Cbbo1M`](crate::Schema::Cbbo1M) schema.
627pub type Cbbo1MMsg = CbboMsg;
628
629/// Open, high, low, close, and volume. The record of the following schemas:
630/// - [`Ohlcv1S`](crate::enums::Schema::Ohlcv1S)
631/// - [`Ohlcv1M`](crate::enums::Schema::Ohlcv1M)
632/// - [`Ohlcv1H`](crate::enums::Schema::Ohlcv1H)
633/// - [`Ohlcv1D`](crate::enums::Schema::Ohlcv1D)
634/// - [`OhlcvEod`](crate::enums::Schema::OhlcvEod)
635#[repr(C)]
636#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
637#[cfg_attr(feature = "trivial_copy", derive(Copy))]
638#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
639#[cfg_attr(
640    feature = "python",
641    pyo3::pyclass(dict, eq, module = "databento_dbn", name = "OHLCVMsg"),
642    derive(crate::macros::PyFieldDesc)
643)]
644#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
645#[cfg_attr(test, derive(type_layout::TypeLayout))]
646#[dbn_record(
647    rtype::OHLCV_1S,
648    rtype::OHLCV_1M,
649    rtype::OHLCV_1H,
650    rtype::OHLCV_1D,
651    rtype::OHLCV_EOD,
652    rtype::OHLCV_DEPRECATED
653)]
654pub struct OhlcvMsg {
655    /// The common header.
656    pub hd: RecordHeader,
657    /// The open price for the bar where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000
658    /// or 0.000000001.
659    ///
660    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
661    #[dbn(fixed_price)]
662    #[pyo3(get, set)]
663    pub open: i64,
664    /// The high price for the bar where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000
665    /// or 0.000000001.
666    ///
667    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
668    #[dbn(fixed_price)]
669    #[pyo3(get, set)]
670    pub high: i64,
671    /// The low price for the bar where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000
672    /// or 0.000000001.
673    ///
674    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
675    #[dbn(fixed_price)]
676    #[pyo3(get, set)]
677    pub low: i64,
678    /// The close price for the bar where every 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000
679    /// or 0.000000001.
680    ///
681    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
682    #[dbn(fixed_price)]
683    #[pyo3(get, set)]
684    pub close: i64,
685    /// The total volume traded during the aggregation period.
686    #[pyo3(get, set)]
687    pub volume: u64,
688}
689
690/// A trading status update message. The record of the [`Status`](crate::Schema::Status) schema.
691#[repr(C)]
692#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
693#[cfg_attr(feature = "trivial_copy", derive(Copy))]
694#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
695#[cfg_attr(
696    feature = "python",
697    pyo3::pyclass(dict, eq, module = "databento_dbn"),
698    derive(crate::macros::PyFieldDesc)
699)]
700#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
701#[cfg_attr(test, derive(type_layout::TypeLayout))]
702#[dbn_record(rtype::STATUS)]
703pub struct StatusMsg {
704    /// The common header.
705    pub hd: RecordHeader,
706    /// The capture-server-received timestamp expressed as the number of nanoseconds
707    /// since the UNIX epoch.
708    ///
709    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
710    #[dbn(encode_order(0), index_ts, unix_nanos)]
711    #[pyo3(get, set)]
712    pub ts_recv: u64,
713    /// The type of status change.
714    #[dbn(fmt_method)]
715    #[pyo3(get, set)]
716    pub action: u16,
717    /// Additional details about the cause of the status change.
718    #[dbn(fmt_method)]
719    #[pyo3(get, set)]
720    pub reason: u16,
721    /// Further information about the status change and its effect on trading.
722    #[dbn(fmt_method)]
723    #[pyo3(get, set)]
724    pub trading_event: u16,
725    /// The best-efforts state of trading in the instrument, either `Y`, `N` or `~`.
726    #[dbn(c_char)]
727    pub is_trading: c_char,
728    /// The best-efforts state of quoting in the instrument, either `Y`, `N` or `~`.
729    #[dbn(c_char)]
730    pub is_quoting: c_char,
731    /// The best-efforts state of short sell restrictions for the instrument (if applicable), either `Y`, `N` or `~`.
732    #[dbn(c_char)]
733    pub is_short_sell_restricted: c_char,
734    #[doc(hidden)]
735    #[cfg_attr(feature = "serde", serde(skip))]
736    pub _reserved: [u8; 7],
737}
738
739/// A definition of an instrument. The record of the
740/// [`Definition`](crate::Schema::Definition) schema.
741#[repr(C)]
742#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
743#[cfg_attr(feature = "trivial_copy", derive(Copy))]
744#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
745#[cfg_attr(
746    feature = "python",
747    pyo3::pyclass(dict, eq, module = "databento_dbn"),
748    derive(crate::macros::PyFieldDesc)
749)]
750#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
751#[cfg_attr(test, derive(type_layout::TypeLayout))]
752#[dbn_record(rtype::INSTRUMENT_DEF)]
753pub struct InstrumentDefMsg {
754    /// The common header.
755    pub hd: RecordHeader,
756    /// The capture-server-received timestamp expressed as the number of nanoseconds
757    /// since the UNIX epoch.
758    ///
759    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
760    #[dbn(encode_order(0), index_ts, unix_nanos)]
761    #[pyo3(get, set)]
762    pub ts_recv: u64,
763    /// The minimum constant tick for the instrument where every 1 unit corresponds to 1e-9, i.e.
764    /// 1/1,000,000,000 or 0.000000001.
765    ///
766    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
767    #[dbn(fixed_price)]
768    #[pyo3(get, set)]
769    pub min_price_increment: i64,
770    /// The multiplier to convert the venue's display price to the conventional price where every
771    /// 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
772    #[dbn(fixed_price)]
773    #[pyo3(get, set)]
774    pub display_factor: i64,
775    /// The last eligible trade time expressed as the number of nanoseconds since the
776    /// UNIX epoch.
777    ///
778    /// Will be [`crate::UNDEF_TIMESTAMP`] when null, such as for equities. Some publishers
779    /// only provide date-level granularity.
780    #[dbn(unix_nanos)]
781    #[pyo3(get, set)]
782    pub expiration: u64,
783    /// The time of instrument activation expressed as the number of nanoseconds since the
784    /// UNIX epoch.
785    ///
786    /// Will be [`crate::UNDEF_TIMESTAMP`] when null, such as for equities. Some publishers
787    /// only provide date-level granularity.
788    #[dbn(unix_nanos)]
789    #[pyo3(get, set)]
790    pub activation: u64,
791    /// The allowable high limit price for the trading day where every 1 unit corresponds to
792    /// 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
793    ///
794    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
795    #[dbn(fixed_price)]
796    #[pyo3(get, set)]
797    pub high_limit_price: i64,
798    /// The allowable low limit price for the trading day where every 1 unit corresponds to
799    /// 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
800    ///
801    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
802    #[dbn(fixed_price)]
803    #[pyo3(get, set)]
804    pub low_limit_price: i64,
805    /// The differential value for price banding where every 1 unit corresponds to 1e-9,
806    /// i.e. 1/1,000,000,000 or 0.000000001.
807    ///
808    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
809    #[dbn(fixed_price)]
810    #[pyo3(get, set)]
811    pub max_price_variation: i64,
812    /// The contract size for each instrument, in combination with `unit_of_measure`, where every
813    /// 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
814    #[dbn(fixed_price)]
815    #[pyo3(get, set)]
816    pub unit_of_measure_qty: i64,
817    /// The value currently under development by the venue where every 1 unit corresponds to 1e-9,
818    /// i.e. 1/1,000,000,000 or 0.000000001.
819    ///
820    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
821    #[dbn(fixed_price)]
822    #[pyo3(get, set)]
823    pub min_price_increment_amount: i64,
824    /// The value used for price calculation in spread and leg pricing where every 1 unit
825    /// corresponds to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
826    #[dbn(fixed_price)]
827    #[pyo3(get, set)]
828    pub price_ratio: i64,
829    /// The strike price of the option where every 1 unit corresponds to 1e-9, i.e.
830    /// 1/1,000,000,000 or 0.000000001.
831    ///
832    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
833    #[dbn(encode_order(54), fixed_price)]
834    #[pyo3(get, set)]
835    pub strike_price: i64,
836    /// The instrument ID assigned by the publisher. May be the same as `instrument_id`.
837    ///
838    /// See [Instrument identifiers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#instrument-identifiers)
839    #[dbn(encode_order(20))]
840    #[pyo3(get, set)]
841    pub raw_instrument_id: u64,
842    /// The tied price (if any) of the leg.
843    #[dbn(encode_order(165), fixed_price)]
844    #[pyo3(get, set)]
845    pub leg_price: i64,
846    /// The associated delta (if any) of the leg.
847    #[dbn(encode_order(166), fixed_price)]
848    #[pyo3(get, set)]
849    pub leg_delta: i64,
850    /// A bitmap of instrument eligibility attributes.
851    #[dbn(fmt_binary)]
852    #[pyo3(get, set)]
853    pub inst_attrib_value: i32,
854    /// The `instrument_id` of the first underlying instrument.
855    ///
856    /// See [Instrument identifiers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#instrument-identifiers).
857    #[pyo3(get, set)]
858    pub underlying_id: u32,
859    /// The implied book depth on the price level data feed.
860    #[pyo3(get, set)]
861    pub market_depth_implied: i32,
862    /// The (outright) book depth on the price level data feed.
863    #[pyo3(get, set)]
864    pub market_depth: i32,
865    /// The market segment of the instrument.
866    #[pyo3(get, set)]
867    pub market_segment_id: u32,
868    /// The maximum trading volume for the instrument.
869    #[pyo3(get, set)]
870    pub max_trade_vol: u32,
871    /// The minimum order entry quantity for the instrument.
872    #[pyo3(get, set)]
873    pub min_lot_size: i32,
874    /// The minimum quantity required for a block trade of the instrument.
875    #[pyo3(get, set)]
876    pub min_lot_size_block: i32,
877    /// The minimum quantity required for a round lot of the instrument. Multiples of this
878    /// quantity are also round lots.
879    #[pyo3(get, set)]
880    pub min_lot_size_round_lot: i32,
881    /// The minimum trading volume for the instrument.
882    #[pyo3(get, set)]
883    pub min_trade_vol: u32,
884    /// The number of deliverables per instrument, i.e. peak days.
885    #[pyo3(get, set)]
886    pub contract_multiplier: i32,
887    /// The quantity that a contract will decay daily, after `decay_start_date` has been reached.
888    #[pyo3(get, set)]
889    pub decay_quantity: i32,
890    /// The fixed contract value assigned to each instrument.
891    #[pyo3(get, set)]
892    pub original_contract_size: i32,
893    /// The numeric ID assigned to the leg instrument.
894    ///
895    /// See [Instrument identifiers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#instrument-identifiers).
896    #[dbn(encode_order(160))]
897    #[pyo3(get, set)]
898    pub leg_instrument_id: u32,
899    /// The numerator of the price ratio of the leg within the spread.
900    #[dbn(encode_order(167))]
901    #[pyo3(get, set)]
902    pub leg_ratio_price_numerator: i32,
903    /// The denominator of the price ratio of the leg within the spread.
904    #[dbn(encode_order(168))]
905    #[pyo3(get, set)]
906    pub leg_ratio_price_denominator: i32,
907    /// The numerator of the quantity ratio of the leg within the spread.
908    #[dbn(encode_order(169))]
909    #[pyo3(get, set)]
910    pub leg_ratio_qty_numerator: i32,
911    /// The denominator of the quantity ratio of the leg within the spread.
912    #[dbn(encode_order(170))]
913    #[pyo3(get, set)]
914    pub leg_ratio_qty_denominator: i32,
915    /// The numeric ID of the leg instrument's underlying instrument.
916    ///
917    /// See [Instrument identifiers](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#instrument-identifiers).
918    #[dbn(encode_order(171))]
919    #[pyo3(get, set)]
920    pub leg_underlying_id: u32,
921    /// The channel ID assigned at the venue.
922    #[pyo3(get, set)]
923    pub appl_id: i16,
924    /// The calendar year reflected in the instrument symbol.
925    #[pyo3(get, set)]
926    pub maturity_year: u16,
927    /// The date at which a contract will begin to decay.
928    #[pyo3(get, set)]
929    pub decay_start_date: u16,
930    /// The channel ID assigned by Databento as an incrementing integer starting at zero.
931    #[pyo3(get, set)]
932    pub channel_id: u16,
933    /// The number of legs in the strategy or spread. Will be 0 for outrights.
934    #[dbn(encode_order(158))]
935    #[pyo3(get, set)]
936    pub leg_count: u16,
937    /// The 0-based index of the leg.
938    #[dbn(encode_order(159))]
939    #[pyo3(get, set)]
940    pub leg_index: u16,
941    /// The currency used for price fields.
942    #[dbn(fmt_method)]
943    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
944    pub currency: [c_char; 4],
945    /// The currency used for settlement, if different from `currency`.
946    #[dbn(fmt_method)]
947    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
948    pub settl_currency: [c_char; 4],
949    /// The strategy type of the spread.
950    #[dbn(fmt_method)]
951    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
952    pub secsubtype: [c_char; 6],
953    /// The instrument raw symbol assigned by the publisher.
954    #[dbn(encode_order(2), fmt_method)]
955    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
956    pub raw_symbol: [c_char; SYMBOL_CSTR_LEN],
957    /// The security group code of the instrument.
958    #[dbn(fmt_method)]
959    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
960    pub group: [c_char; 21],
961    /// The exchange used to identify the instrument.
962    #[dbn(fmt_method)]
963    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
964    pub exchange: [c_char; 5],
965    /// The underlying asset code (product code) of the instrument.
966    #[dbn(fmt_method)]
967    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
968    pub asset: [c_char; ASSET_CSTR_LEN],
969    /// The ISO standard instrument categorization code.
970    #[dbn(fmt_method)]
971    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
972    pub cfi: [c_char; 7],
973    /// The security type of the instrument, e.g. FUT for future or future spread.
974    ///
975    /// See [Security type](https://databento.com/docs/schemas-and-data-formats/instrument-definitions#security-type).
976    #[dbn(fmt_method)]
977    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
978    pub security_type: [c_char; 7],
979    /// The unit of measure for the instrument’s original contract size, e.g. USD or LBS.
980    #[dbn(fmt_method)]
981    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
982    pub unit_of_measure: [c_char; 31],
983    /// The symbol of the first underlying instrument.
984    #[dbn(fmt_method)]
985    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
986    pub underlying: [c_char; 21],
987    /// The currency of [`strike_price`](Self::strike_price).
988    #[dbn(fmt_method)]
989    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
990    pub strike_price_currency: [c_char; 4],
991    /// The leg instrument's raw symbol assigned by the publisher.
992    #[dbn(encode_order(161), fmt_method)]
993    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
994    pub leg_raw_symbol: [c_char; SYMBOL_CSTR_LEN],
995    /// The classification of the instrument.
996    ///
997    /// See [Instrument class](https://databento.com/docs/schemas-and-data-formats/instrument-definitions#instrument-class).
998    #[dbn(c_char, encode_order(4))]
999    pub instrument_class: c_char,
1000    /// The matching algorithm used for the instrument, typically **F**IFO.
1001    ///
1002    /// See [Matching algorithm](https://databento.com/docs/schemas-and-data-formats/instrument-definitions#matching-algorithm).
1003    #[dbn(c_char)]
1004    pub match_algorithm: c_char,
1005    /// The price denominator of the main fraction.
1006    #[pyo3(get, set)]
1007    pub main_fraction: u8,
1008    /// The number of digits to the right of the tick mark, to display fractional prices.
1009    #[pyo3(get, set)]
1010    pub price_display_format: u8,
1011    /// The price denominator of the sub fraction.
1012    #[pyo3(get, set)]
1013    pub sub_fraction: u8,
1014    /// The product complex of the instrument.
1015    #[pyo3(get, set)]
1016    pub underlying_product: u8,
1017    /// Indicates if the instrument definition has been added, modified, or deleted.
1018    #[dbn(c_char, encode_order(3))]
1019    pub security_update_action: c_char,
1020    /// The calendar month reflected in the instrument symbol.
1021    #[pyo3(get, set)]
1022    pub maturity_month: u8,
1023    /// The calendar day reflected in the instrument symbol, or 0.
1024    #[pyo3(get, set)]
1025    pub maturity_day: u8,
1026    /// The calendar week reflected in the instrument symbol, or 0.
1027    #[pyo3(get, set)]
1028    pub maturity_week: u8,
1029    /// Indicates if the instrument is user defined: **Y**es or **N**o.
1030    #[dbn(c_char)]
1031    pub user_defined_instrument: c_char,
1032    /// The type of `contract_multiplier`. Either `1` for hours, or `2` for days.
1033    #[pyo3(get, set)]
1034    pub contract_multiplier_unit: i8,
1035    /// The schedule for delivering electricity.
1036    #[pyo3(get, set)]
1037    pub flow_schedule_type: i8,
1038    /// The tick rule of the spread.
1039    #[pyo3(get, set)]
1040    pub tick_rule: u8,
1041    /// The classification of the leg instrument.
1042    #[dbn(c_char, encode_order(163))]
1043    pub leg_instrument_class: c_char,
1044    /// The side taken for the leg when purchasing the spread.
1045    #[dbn(c_char, encode_order(164))]
1046    pub leg_side: c_char,
1047    #[doc(hidden)]
1048    #[cfg_attr(feature = "serde", serde(skip))]
1049    pub _reserved: [u8; 17],
1050}
1051
1052/// An auction imbalance message.
1053#[repr(C)]
1054#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
1055#[cfg_attr(feature = "trivial_copy", derive(Copy))]
1056#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1057#[cfg_attr(
1058    feature = "python",
1059    pyo3::pyclass(dict, eq, module = "databento_dbn"),
1060    derive(crate::macros::PyFieldDesc)
1061)]
1062#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
1063#[cfg_attr(test, derive(type_layout::TypeLayout))]
1064#[dbn_record(rtype::IMBALANCE)]
1065pub struct ImbalanceMsg {
1066    /// The common header.
1067    pub hd: RecordHeader,
1068    /// The capture-server-received timestamp expressed as the number of nanoseconds
1069    /// since the UNIX epoch.
1070    ///
1071    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
1072    #[dbn(encode_order(0), index_ts, unix_nanos)]
1073    #[pyo3(get, set)]
1074    pub ts_recv: u64,
1075    /// The price at which the imbalance shares are calculated, where every 1 unit corresponds
1076    /// to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
1077    ///
1078    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
1079    #[dbn(fixed_price)]
1080    #[pyo3(get, set)]
1081    pub ref_price: i64,
1082    /// Reserved for future use.
1083    #[dbn(unix_nanos)]
1084    #[pyo3(get, set)]
1085    pub auction_time: u64,
1086    /// The hypothetical auction-clearing price for both cross and continuous orders where every
1087    /// 1 unit corresponds to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
1088    ///
1089    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
1090    #[dbn(fixed_price)]
1091    #[pyo3(get, set)]
1092    pub cont_book_clr_price: i64,
1093    /// The hypothetical auction-clearing price for cross orders only where every 1 unit corresponds
1094    /// to 1e-9, i.e. 1/1,000,000,000 or 0.000000001.
1095    ///
1096    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
1097    #[dbn(fixed_price)]
1098    #[pyo3(get, set)]
1099    pub auct_interest_clr_price: i64,
1100    /// Reserved for future use.
1101    #[dbn(fixed_price)]
1102    #[pyo3(get, set)]
1103    pub ssr_filling_price: i64,
1104    /// Reserved for future use.
1105    #[dbn(fixed_price)]
1106    #[pyo3(get, set)]
1107    pub ind_match_price: i64,
1108    /// Reserved for future use.
1109    #[dbn(fixed_price)]
1110    #[pyo3(get, set)]
1111    pub upper_collar: i64,
1112    /// Reserved for future use.
1113    #[dbn(fixed_price)]
1114    #[pyo3(get, set)]
1115    pub lower_collar: i64,
1116    /// The quantity of shares that are eligible to be matched at `ref_price`.
1117    #[pyo3(get, set)]
1118    pub paired_qty: u32,
1119    /// The quantity of shares that are not paired at `ref_price`.
1120    #[pyo3(get, set)]
1121    pub total_imbalance_qty: u32,
1122    /// Reserved for future use.
1123    #[pyo3(get, set)]
1124    pub market_imbalance_qty: u32,
1125    /// Reserved for future use.
1126    #[pyo3(get, set)]
1127    pub unpaired_qty: u32,
1128    /// Venue-specific character code indicating the auction type.
1129    #[dbn(c_char)]
1130    pub auction_type: c_char,
1131    /// The market side of the `total_imbalance_qty`. Can be **A**sk, **B**id, or **N**one.
1132    ///
1133    /// See [Side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#side).
1134    #[dbn(c_char)]
1135    pub side: c_char,
1136    /// Reserved for future use.
1137    #[pyo3(get, set)]
1138    pub auction_status: u8,
1139    /// Reserved for future use.
1140    #[pyo3(get, set)]
1141    pub freeze_status: u8,
1142    /// Reserved for future use.
1143    #[pyo3(get, set)]
1144    pub num_extensions: u8,
1145    /// Reserved for future use.
1146    #[dbn(c_char)]
1147    pub unpaired_side: c_char,
1148    /// Venue-specific character code. For Nasdaq, contains the raw Price Variation Indicator.
1149    #[dbn(c_char)]
1150    pub significant_imbalance: c_char,
1151    #[doc(hidden)]
1152    #[cfg_attr(feature = "serde", serde(skip))]
1153    pub _reserved: [u8; 1],
1154}
1155
1156/// A statistics message. A catchall for various data disseminated by publishers. The
1157/// [`stat_type`](Self::stat_type) indicates the statistic contained in the message.
1158#[repr(C)]
1159#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
1160#[cfg_attr(feature = "trivial_copy", derive(Copy))]
1161#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1162#[cfg_attr(
1163    feature = "python",
1164    pyo3::pyclass(dict, eq, module = "databento_dbn"),
1165    derive(crate::macros::PyFieldDesc)
1166)]
1167#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
1168#[cfg_attr(test, derive(type_layout::TypeLayout))]
1169#[dbn_record(rtype::STATISTICS)]
1170pub struct StatMsg {
1171    /// The common header.
1172    pub hd: RecordHeader,
1173    /// The capture-server-received timestamp expressed as the number of nanoseconds
1174    /// since the UNIX epoch.
1175    ///
1176    /// See [ts_recv](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-recv).
1177    #[dbn(encode_order(0), index_ts, unix_nanos)]
1178    #[pyo3(get, set)]
1179    pub ts_recv: u64,
1180    /// The reference timestamp of the statistic value expressed as the number of
1181    /// nanoseconds since the UNIX epoch. Will be [`crate::UNDEF_TIMESTAMP`] when
1182    /// unused.
1183    #[dbn(unix_nanos)]
1184    #[pyo3(get, set)]
1185    pub ts_ref: u64,
1186    /// The value for price statistics where every 1 unit corresponds to 1e-9, i.e.
1187    /// 1/1,000,000,000 or 0.000000001. Will be [`UNDEF_PRICE`](crate::UNDEF_PRICE)
1188    /// when unused.
1189    ///
1190    /// See [Prices](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#prices).
1191    #[dbn(fixed_price)]
1192    #[pyo3(get, set)]
1193    pub price: i64,
1194    /// The value for non-price statistics. Will be [`crate::UNDEF_STAT_QUANTITY`] when
1195    /// unused.
1196    #[pyo3(get, set)]
1197    pub quantity: i64,
1198    /// The message sequence number assigned at the venue.
1199    #[pyo3(get, set)]
1200    pub sequence: u32,
1201    /// The matching-engine-sending timestamp expressed as the number of nanoseconds before
1202    /// `ts_recv`.
1203    ///
1204    /// See [ts_in_delta](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-in-delta).
1205    #[pyo3(get, set)]
1206    pub ts_in_delta: i32,
1207    /// The type of statistic value contained in the message. Refer to the
1208    /// [`StatType`](crate::enums::StatType) enum for possible variants.
1209    #[dbn(fmt_method)]
1210    #[pyo3(get, set)]
1211    pub stat_type: u16,
1212    /// The channel ID assigned by Databento as an incrementing integer starting at zero.
1213    #[pyo3(get, set)]
1214    pub channel_id: u16,
1215    /// Indicates if the statistic is newly added (1) or deleted (2). (Deleted is only
1216    /// used with some stat types).
1217    #[dbn(fmt_method)]
1218    #[pyo3(get, set)]
1219    pub update_action: u8,
1220    /// Additional flags associate with certain stat types.
1221    #[dbn(fmt_binary)]
1222    #[pyo3(get, set)]
1223    pub stat_flags: u8,
1224    #[doc(hidden)]
1225    #[cfg_attr(feature = "serde", serde(skip))]
1226    pub _reserved: [u8; 18],
1227}
1228
1229/// An error message from the Databento Live Subscription Gateway (LSG).
1230#[repr(C)]
1231#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
1232#[cfg_attr(feature = "trivial_copy", derive(Copy))]
1233#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1234#[cfg_attr(
1235    feature = "python",
1236    pyo3::pyclass(dict, eq, module = "databento_dbn"),
1237    derive(crate::macros::PyFieldDesc)
1238)]
1239#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
1240#[cfg_attr(test, derive(type_layout::TypeLayout))]
1241#[dbn_record(rtype::ERROR)]
1242pub struct ErrorMsg {
1243    /// The common header.
1244    pub hd: RecordHeader,
1245    /// The error message.
1246    #[dbn(fmt_method)]
1247    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
1248    pub err: [c_char; 302],
1249    /// The error code. See the [`ErrorCode`](crate::enums::ErrorCode) enum
1250    /// for possible values.
1251    #[dbn(fmt_method)]
1252    #[pyo3(get, set)]
1253    pub code: u8,
1254    /// Sometimes multiple errors are sent together. This field will be non-zero for the
1255    /// last error.
1256    #[pyo3(get, set)]
1257    pub is_last: u8,
1258}
1259
1260/// A symbol mapping message from the live API which maps a symbol from one
1261/// [`SType`](crate::enums::SType) to another.
1262#[repr(C)]
1263#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
1264#[cfg_attr(feature = "trivial_copy", derive(Copy))]
1265#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1266#[cfg_attr(
1267    feature = "python",
1268    pyo3::pyclass(dict, eq, module = "databento_dbn"),
1269    derive(crate::macros::PyFieldDesc)
1270)]
1271#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
1272#[cfg_attr(test, derive(type_layout::TypeLayout))]
1273#[dbn_record(rtype::SYMBOL_MAPPING)]
1274pub struct SymbolMappingMsg {
1275    /// The common header.
1276    pub hd: RecordHeader,
1277    /// The input symbology type of `stype_in_symbol`.
1278    #[dbn(fmt_method)]
1279    #[pyo3(get, set)]
1280    pub stype_in: u8,
1281    /// The input symbol.
1282    #[dbn(fmt_method)]
1283    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
1284    pub stype_in_symbol: [c_char; SYMBOL_CSTR_LEN],
1285    /// The output symbology type of `stype_out_symbol`.
1286    #[dbn(fmt_method)]
1287    #[pyo3(get, set)]
1288    pub stype_out: u8,
1289    /// The output symbol.
1290    #[dbn(fmt_method)]
1291    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
1292    pub stype_out_symbol: [c_char; SYMBOL_CSTR_LEN],
1293    /// The start of the mapping interval expressed as the number of nanoseconds since
1294    /// the UNIX epoch.
1295    #[dbn(unix_nanos)]
1296    #[pyo3(get, set)]
1297    pub start_ts: u64,
1298    /// The end of the mapping interval expressed as the number of nanoseconds since
1299    /// the UNIX epoch.
1300    #[dbn(unix_nanos)]
1301    #[pyo3(get, set)]
1302    pub end_ts: u64,
1303}
1304
1305/// A non-error message from the Databento Live Subscription Gateway (LSG). Also used
1306/// for heartbeating.
1307#[repr(C)]
1308#[derive(Clone, CsvSerialize, JsonSerialize, PartialEq, Eq, Hash)]
1309#[cfg_attr(feature = "trivial_copy", derive(Copy))]
1310#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1311#[cfg_attr(
1312    feature = "python",
1313    pyo3::pyclass(dict, eq, module = "databento_dbn"),
1314    derive(crate::macros::PyFieldDesc)
1315)]
1316#[cfg_attr(not(feature = "python"), derive(MockPyo3))] // bring `pyo3` attribute into scope
1317#[cfg_attr(test, derive(type_layout::TypeLayout))]
1318#[dbn_record(rtype::SYSTEM)]
1319pub struct SystemMsg {
1320    /// The common header.
1321    pub hd: RecordHeader,
1322    /// The message from the Databento gateway.
1323    #[dbn(fmt_method)]
1324    #[cfg_attr(feature = "serde", serde(with = "crate::record::cstr_serde"))]
1325    pub msg: [c_char; 303],
1326    /// Type of system message. See the [`SystemCode`](crate::enums::SystemCode) enum
1327    /// for possible values.
1328    #[dbn(fmt_method)]
1329    #[pyo3(get, set)]
1330    pub code: u8,
1331}
1332
1333/// Wrapper object for records that include the live gateway send timestamp (`ts_out`).
1334#[repr(C)]
1335#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1336#[cfg_attr(feature = "trivial_copy", derive(Copy))]
1337#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1338pub struct WithTsOut<T: HasRType> {
1339    /// The inner record.
1340    pub rec: T,
1341    /// The live gateway send timestamp expressed as the number of nanoseconds since the
1342    /// UNIX epoch.
1343    ///
1344    /// See [ts_out](https://databento.com/docs/standards-and-conventions/common-fields-enums-types#ts-out).
1345    pub ts_out: u64,
1346}