nautilus_serialization/sbe/market/
book.rs1use nautilus_model::{
17 data::{BookOrder, OrderBookDelta, OrderBookDeltas, OrderBookDepth10},
18 enums::OrderSide,
19};
20
21use super::{
22 super::{SbeCursor, SbeDecodeError, SbeEncodeError, SbeWriter},
23 FromSbeReuse, MarketSbeMessage,
24 common::{
25 BOOK_ORDER_BLOCK_LENGTH, DEPTH10_COUNTS_BLOCK_LENGTH, DEPTH10_LEVEL_BLOCK_LENGTH,
26 DEPTH10_LEVEL_COUNT, GROUP_HEADER_16_LENGTH, ORDER_BOOK_DELTA_GROUP_BLOCK_LENGTH,
27 decode_book_action, decode_header, decode_instrument_id, decode_order_side, decode_price,
28 decode_quantity, decode_unix_nanos, encode_group_header_16, encode_instrument_id,
29 encode_price, encode_quantity, encode_unix_nanos, encoded_instrument_id_size,
30 validate_header,
31 },
32 template_id,
33};
34
35impl MarketSbeMessage for BookOrder {
36 const TEMPLATE_ID: u16 = template_id::BOOK_ORDER;
37 const BLOCK_LENGTH: u16 = BOOK_ORDER_BLOCK_LENGTH;
38
39 fn encode_body(&self, writer: &mut SbeWriter<'_>) -> Result<(), SbeEncodeError> {
40 encode_book_order(writer, self);
41 Ok(())
42 }
43
44 fn decode_body(cursor: &mut SbeCursor<'_>) -> Result<Self, SbeDecodeError> {
45 decode_book_order(cursor)
46 }
47}
48
49impl MarketSbeMessage for OrderBookDelta {
50 const TEMPLATE_ID: u16 = template_id::ORDER_BOOK_DELTA;
51 const BLOCK_LENGTH: u16 = ORDER_BOOK_DELTA_GROUP_BLOCK_LENGTH;
52
53 fn encode_body(&self, writer: &mut SbeWriter<'_>) -> Result<(), SbeEncodeError> {
54 encode_order_book_delta_fields(writer, self);
55 encode_instrument_id(writer, &self.instrument_id)
56 }
57
58 fn decode_body(cursor: &mut SbeCursor<'_>) -> Result<Self, SbeDecodeError> {
59 let action = decode_book_action(cursor)?;
60 let order = decode_book_order(cursor)?;
61 let flags = cursor.read_u8()?;
62 let sequence = cursor.read_u64_le()?;
63 let ts_event = decode_unix_nanos(cursor)?;
64 let ts_init = decode_unix_nanos(cursor)?;
65 let instrument_id = decode_instrument_id(cursor)?;
66
67 Ok(Self {
68 instrument_id,
69 action,
70 order,
71 flags,
72 sequence,
73 ts_event,
74 ts_init,
75 })
76 }
77
78 fn encoded_body_size(&self) -> usize {
79 usize::from(Self::BLOCK_LENGTH) + encoded_instrument_id_size(&self.instrument_id)
80 }
81}
82
83impl MarketSbeMessage for OrderBookDeltas {
84 const TEMPLATE_ID: u16 = template_id::ORDER_BOOK_DELTAS;
85 const BLOCK_LENGTH: u16 = 25;
86
87 fn encode_body(&self, writer: &mut SbeWriter<'_>) -> Result<(), SbeEncodeError> {
88 writer.write_u8(self.flags);
89 writer.write_u64_le(self.sequence);
90 encode_unix_nanos(writer, self.ts_event);
91 encode_unix_nanos(writer, self.ts_init);
92 encode_instrument_id(writer, &self.instrument_id)?;
93 encode_group_header_16(
94 writer,
95 "OrderBookDeltas.deltas",
96 self.deltas.len(),
97 ORDER_BOOK_DELTA_GROUP_BLOCK_LENGTH,
98 )?;
99
100 for delta in &self.deltas {
101 encode_order_book_delta_fields(writer, delta);
102 encode_instrument_id(writer, &delta.instrument_id)?;
103 }
104 Ok(())
105 }
106
107 fn decode_body(cursor: &mut SbeCursor<'_>) -> Result<Self, SbeDecodeError> {
108 let mut scratch = Vec::new();
109 decode_order_book_deltas_body(cursor, &mut scratch)
110 }
111
112 fn encoded_body_size(&self) -> usize {
113 usize::from(Self::BLOCK_LENGTH)
114 + encoded_instrument_id_size(&self.instrument_id)
115 + GROUP_HEADER_16_LENGTH
116 + self
117 .deltas
118 .iter()
119 .map(encoded_order_book_delta_size)
120 .sum::<usize>()
121 }
122}
123
124impl FromSbeReuse for OrderBookDeltas {
125 type Scratch = Vec<OrderBookDelta>;
126
127 fn from_sbe_reuse(
128 bytes: &[u8],
129 scratch: &mut Vec<OrderBookDelta>,
130 ) -> Result<Self, SbeDecodeError> {
131 let mut cursor = SbeCursor::new(bytes);
132 let header = decode_header(&mut cursor)?;
133 validate_header(
134 header,
135 <Self as MarketSbeMessage>::TEMPLATE_ID,
136 <Self as MarketSbeMessage>::BLOCK_LENGTH,
137 )?;
138 decode_order_book_deltas_body(&mut cursor, scratch)
139 }
140}
141
142fn decode_order_book_deltas_body(
143 cursor: &mut SbeCursor<'_>,
144 scratch: &mut Vec<OrderBookDelta>,
145) -> Result<OrderBookDeltas, SbeDecodeError> {
146 let flags = cursor.read_u8()?;
147 let sequence = cursor.read_u64_le()?;
148 let ts_event = decode_unix_nanos(cursor)?;
149 let ts_init = decode_unix_nanos(cursor)?;
150 let instrument_id = decode_instrument_id(cursor)?;
151 let (block_length, count) = cursor.read_group_header_16()?;
152
153 if block_length != ORDER_BOOK_DELTA_GROUP_BLOCK_LENGTH {
154 return Err(SbeDecodeError::InvalidBlockLength {
155 expected: ORDER_BOOK_DELTA_GROUP_BLOCK_LENGTH,
156 actual: block_length,
157 });
158 }
159
160 let count = usize::from(count);
161 scratch.clear();
162 scratch.reserve(count);
163
164 for _ in 0..count {
165 let action = decode_book_action(cursor)?;
166 let order = decode_book_order(cursor)?;
167 let delta_flags = cursor.read_u8()?;
168 let delta_sequence = cursor.read_u64_le()?;
169 let delta_ts_event = decode_unix_nanos(cursor)?;
170 let delta_ts_init = decode_unix_nanos(cursor)?;
171 let delta_instrument_id = decode_instrument_id(cursor)?;
172
173 scratch.push(OrderBookDelta {
174 instrument_id: delta_instrument_id,
175 action,
176 order,
177 flags: delta_flags,
178 sequence: delta_sequence,
179 ts_event: delta_ts_event,
180 ts_init: delta_ts_init,
181 });
182 }
183
184 Ok(OrderBookDeltas {
185 instrument_id,
186 deltas: std::mem::take(scratch),
187 flags,
188 sequence,
189 ts_event,
190 ts_init,
191 })
192}
193
194impl MarketSbeMessage for OrderBookDepth10 {
195 const TEMPLATE_ID: u16 = template_id::ORDER_BOOK_DEPTH10;
196 const BLOCK_LENGTH: u16 =
197 (DEPTH10_LEVEL_BLOCK_LENGTH * 20) + (DEPTH10_COUNTS_BLOCK_LENGTH as u16 * 2) + 25;
198
199 fn encode_body(&self, writer: &mut SbeWriter<'_>) -> Result<(), SbeEncodeError> {
200 for bid in &self.bids {
201 encode_price(writer, &bid.price);
202 encode_quantity(writer, &bid.size);
203 }
204
205 for ask in &self.asks {
206 encode_price(writer, &ask.price);
207 encode_quantity(writer, &ask.size);
208 }
209
210 for count in &self.bid_counts {
211 writer.write_u32_le(*count);
212 }
213
214 for count in &self.ask_counts {
215 writer.write_u32_le(*count);
216 }
217 writer.write_u8(self.flags);
218 writer.write_u64_le(self.sequence);
219 encode_unix_nanos(writer, self.ts_event);
220 encode_unix_nanos(writer, self.ts_init);
221 encode_instrument_id(writer, &self.instrument_id)
222 }
223
224 fn decode_body(cursor: &mut SbeCursor<'_>) -> Result<Self, SbeDecodeError> {
225 let mut bids = [BookOrder::default(); DEPTH10_LEVEL_COUNT];
226 let mut asks = [BookOrder::default(); DEPTH10_LEVEL_COUNT];
227
228 for bid in &mut bids {
229 *bid = BookOrder::new(
230 OrderSide::Buy,
231 decode_price(cursor)?,
232 decode_quantity(cursor)?,
233 0,
234 );
235 }
236
237 for ask in &mut asks {
238 *ask = BookOrder::new(
239 OrderSide::Sell,
240 decode_price(cursor)?,
241 decode_quantity(cursor)?,
242 0,
243 );
244 }
245
246 let mut bid_counts = [0u32; DEPTH10_LEVEL_COUNT];
247 let mut ask_counts = [0u32; DEPTH10_LEVEL_COUNT];
248
249 for count in &mut bid_counts {
250 *count = cursor.read_u32_le()?;
251 }
252
253 for count in &mut ask_counts {
254 *count = cursor.read_u32_le()?;
255 }
256
257 let flags = cursor.read_u8()?;
258 let sequence = cursor.read_u64_le()?;
259 let ts_event = decode_unix_nanos(cursor)?;
260 let ts_init = decode_unix_nanos(cursor)?;
261 let instrument_id = decode_instrument_id(cursor)?;
262
263 Ok(Self {
264 instrument_id,
265 bids,
266 asks,
267 bid_counts,
268 ask_counts,
269 flags,
270 sequence,
271 ts_event,
272 ts_init,
273 })
274 }
275
276 fn encoded_body_size(&self) -> usize {
277 usize::from(Self::BLOCK_LENGTH) + encoded_instrument_id_size(&self.instrument_id)
278 }
279}
280
281fn encode_book_order(writer: &mut SbeWriter<'_>, order: &BookOrder) {
282 encode_price(writer, &order.price);
283 encode_quantity(writer, &order.size);
284 writer.write_u8(order.side as u8);
285 writer.write_u64_le(order.order_id);
286}
287
288fn decode_book_order(cursor: &mut SbeCursor<'_>) -> Result<BookOrder, SbeDecodeError> {
289 let price = decode_price(cursor)?;
290 let size = decode_quantity(cursor)?;
291 let side = decode_order_side(cursor)?;
292 let order_id = cursor.read_u64_le()?;
293 Ok(BookOrder {
294 side,
295 price,
296 size,
297 order_id,
298 })
299}
300
301fn encode_order_book_delta_fields(writer: &mut SbeWriter<'_>, delta: &OrderBookDelta) {
302 writer.write_u8(delta.action as u8);
303 encode_book_order(writer, &delta.order);
304 writer.write_u8(delta.flags);
305 writer.write_u64_le(delta.sequence);
306 encode_unix_nanos(writer, delta.ts_event);
307 encode_unix_nanos(writer, delta.ts_init);
308}
309
310fn encoded_order_book_delta_size(delta: &OrderBookDelta) -> usize {
311 usize::from(ORDER_BOOK_DELTA_GROUP_BLOCK_LENGTH)
312 + encoded_instrument_id_size(&delta.instrument_id)
313}