1use std::error::Error;
19
20use indexmap::IndexMap;
21use nautilus_core::DurationNanos;
22use nautilus_model::{
23 data::{
24 FundingRateUpdate, IndexPriceUpdate, InstrumentClose, InstrumentStatus, MarkPriceUpdate,
25 OptionGreekValues, OptionGreeks, QuoteTick, TradeTick,
26 bar::{Bar, BarSpecification, BarType},
27 delta::OrderBookDelta,
28 deltas::OrderBookDeltas,
29 depth::OrderBookDepth,
30 order::BookOrder,
31 },
32 enums::{
33 AccountType, AggregationSource, AggressorSide, AssetClass, BarAggregation, BookAction,
34 BookType, ContingencyType, CurrencyType, GreeksConvention, InstrumentClass,
35 InstrumentCloseType, LiquiditySide, MarketStatusAction, OmsType, OptionKind, OrderSide,
36 OrderStatus, OrderType, PositionAdjustmentType, PositionSide, PriceType, RecordFlag,
37 TimeInForce, TrailingOffsetType, TriggerType,
38 },
39 events::{
40 OrderAccepted, OrderCancelRejected, OrderCanceled, OrderDenied, OrderEmulated,
41 OrderExpired, OrderFillVoided, OrderFilled, OrderInitialized, OrderModifyRejected,
42 OrderPendingCancel, OrderPendingUpdate, OrderRejected, OrderReleased, OrderSubmitted,
43 OrderTriggered, OrderUpdated, PositionAdjusted, PositionChanged, PositionClosed,
44 PositionOpened,
45 },
46 identifiers::{
47 AccountId, ActorId, ClientId, ClientOrderId, ComponentId, ExecAlgorithmId, InstrumentId,
48 OrderListId, PositionId, StrategyId, Symbol, TradeId, TraderId, Venue, VenueOrderId,
49 },
50 types::{
51 AccountBalance, Currency, MarginBalance, Money, Price, Quantity, money::MoneyRaw,
52 price::PriceRaw, quantity::QuantityRaw,
53 },
54};
55use rust_decimal::Decimal;
56use ustr::Ustr;
57use uuid::Uuid;
58
59use super::{FromCapnp, ToCapnp};
60use crate::{
61 base_capnp, enums_capnp, identifiers_capnp, market_capnp,
62 numeric::{raw_to_wire, wire_to_raw},
63 order_capnp, position_capnp, types_capnp,
64};
65
66const DECIMAL_FLAGS_RESERVED_MASK: u32 = 0x7F00_FFFF;
67const DECIMAL_SCALE_MASK: u32 = 0x00FF_0000;
68const DECIMAL_SCALE_SHIFT: u32 = 16;
69
70pub(crate) trait CapnpWriteExt<'a, T>
71where
72 T: ToCapnp<'a>,
73{
74 fn write_capnp<F>(&self, init: F)
75 where
76 F: FnOnce() -> T::Builder;
77}
78
79impl<'a, T> CapnpWriteExt<'a, T> for T
80where
81 T: ToCapnp<'a>,
82{
83 fn write_capnp<F>(&self, init: F)
84 where
85 F: FnOnce() -> T::Builder,
86 {
87 self.to_capnp(init());
88 }
89}
90
91impl<'a, T> CapnpWriteExt<'a, T> for Option<T>
92where
93 T: ToCapnp<'a>,
94{
95 fn write_capnp<F>(&self, init: F)
96 where
97 F: FnOnce() -> T::Builder,
98 {
99 if let Some(value) = self {
100 value.to_capnp(init());
101 }
102 }
103}
104
105pub(crate) fn read_optional_from_capnp<'a, T, FHas, FGet>(
106 has: FHas,
107 get: FGet,
108) -> Result<Option<T>, Box<dyn Error>>
109where
110 T: FromCapnp<'a>,
111 FHas: FnOnce() -> bool,
112 FGet: FnOnce() -> capnp::Result<<T as FromCapnp<'a>>::Reader>,
113{
114 if has() {
115 let reader = get()?;
116 Ok(Some(T::from_capnp(reader)?))
117 } else {
118 Ok(None)
119 }
120}
121
122fn write_string_map(map: &IndexMap<Ustr, Ustr>, mut builder: base_capnp::string_map::Builder<'_>) {
123 let mut entries = builder.reborrow().init_entries(map.len() as u32);
124 for (index, (key, value)) in map.iter().enumerate() {
125 let mut entry = entries.reborrow().get(index as u32);
126 entry.set_key(key.as_str());
127 entry.set_value(value.as_str());
128 }
129}
130
131fn read_string_map(
132 reader: base_capnp::string_map::Reader<'_>,
133) -> Result<IndexMap<Ustr, Ustr>, Box<dyn Error>> {
134 let entries = reader.get_entries()?;
135 let mut map = IndexMap::with_capacity(entries.len() as usize);
136 for entry in entries {
137 map.insert(
138 Ustr::from(entry.get_key()?.to_str()?),
139 Ustr::from(entry.get_value()?.to_str()?),
140 );
141 }
142 Ok(map)
143}
144
145impl<'a> ToCapnp<'a> for nautilus_core::UUID4 {
146 type Builder = base_capnp::u_u_i_d4::Builder<'a>;
147
148 fn to_capnp(&self, mut builder: Self::Builder) {
149 builder.set_value(&self.as_bytes());
150 }
151}
152
153impl<'a> FromCapnp<'a> for nautilus_core::UUID4 {
154 type Reader = base_capnp::u_u_i_d4::Reader<'a>;
155
156 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
157 let bytes = reader.get_value()?;
158 let bytes_array: [u8; 16] = bytes.try_into().map_err(|_| {
159 std::io::Error::new(
160 std::io::ErrorKind::InvalidData,
161 "Invalid UUID4 bytes length",
162 )
163 })?;
164 let uuid = Uuid::from_bytes(bytes_array);
165 Ok(Self::from(uuid))
166 }
167}
168
169fn decimal_to_parts(value: &Decimal) -> (u64, u64, u64, u32) {
176 let bytes = value.serialize();
177 let flags = u32::from_le_bytes(bytes[0..4].try_into().expect("flags slice"));
178 let lo = u32::from_le_bytes(bytes[4..8].try_into().expect("lo slice"));
179 let mid = u32::from_le_bytes(bytes[8..12].try_into().expect("mid slice"));
180 let hi = u32::from_le_bytes(bytes[12..16].try_into().expect("hi slice"));
181 (lo as u64, mid as u64, hi as u64, flags)
182}
183
184fn decimal_from_parts(lo: u64, mid: u64, hi: u64, flags: u32) -> Result<Decimal, Box<dyn Error>> {
185 if flags & DECIMAL_FLAGS_RESERVED_MASK != 0 {
186 return Err("Decimal flags contain unsupported bits".into());
187 }
188
189 let scale = (flags & DECIMAL_SCALE_MASK) >> DECIMAL_SCALE_SHIFT;
190 if scale > Decimal::MAX_SCALE {
191 return Err(format!(
192 "Decimal scale exceeds maximum {}, was {scale}",
193 Decimal::MAX_SCALE
194 )
195 .into());
196 }
197
198 let lo = u32::try_from(lo).map_err(|_| "Decimal lo limb exceeds u32")?;
199 let mid = u32::try_from(mid).map_err(|_| "Decimal mid limb exceeds u32")?;
200 let hi = u32::try_from(hi).map_err(|_| "Decimal hi limb exceeds u32")?;
201
202 let mut bytes = [0u8; 16];
203 bytes[0..4].copy_from_slice(&flags.to_le_bytes());
204 bytes[4..8].copy_from_slice(&lo.to_le_bytes());
205 bytes[8..12].copy_from_slice(&mid.to_le_bytes());
206 bytes[12..16].copy_from_slice(&hi.to_le_bytes());
207 Ok(Decimal::deserialize(bytes))
208}
209
210impl<'a> ToCapnp<'a> for Decimal {
211 type Builder = types_capnp::decimal::Builder<'a>;
212
213 fn to_capnp(&self, mut builder: Self::Builder) {
214 let (lo, mid, hi, flags) = decimal_to_parts(self);
215 builder.set_flags(flags);
216 builder.set_lo(lo);
217 builder.set_mid(mid);
218 builder.set_hi(hi);
219 }
220}
221
222impl<'a> FromCapnp<'a> for Decimal {
223 type Reader = types_capnp::decimal::Reader<'a>;
224
225 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
226 let flags = reader.get_flags();
227 let lo = reader.get_lo();
228 let mid = reader.get_mid();
229 let hi = reader.get_hi();
230 decimal_from_parts(lo, mid, hi, flags)
231 }
232}
233
234impl<'a> ToCapnp<'a> for TraderId {
235 type Builder = identifiers_capnp::trader_id::Builder<'a>;
236
237 fn to_capnp(&self, mut builder: Self::Builder) {
238 builder.set_value(self.as_str());
239 }
240}
241
242impl<'a> FromCapnp<'a> for TraderId {
243 type Reader = identifiers_capnp::trader_id::Reader<'a>;
244
245 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
246 let value = reader.get_value()?.to_str()?;
247 Ok(Self::new_checked(value)?)
248 }
249}
250
251impl<'a> ToCapnp<'a> for StrategyId {
252 type Builder = identifiers_capnp::strategy_id::Builder<'a>;
253
254 fn to_capnp(&self, mut builder: Self::Builder) {
255 builder.set_value(self.as_str());
256 }
257}
258
259impl<'a> FromCapnp<'a> for StrategyId {
260 type Reader = identifiers_capnp::strategy_id::Reader<'a>;
261
262 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
263 let value = reader.get_value()?.to_str()?;
264 Ok(Self::new_checked(value)?)
265 }
266}
267
268impl<'a> ToCapnp<'a> for ActorId {
269 type Builder = identifiers_capnp::actor_id::Builder<'a>;
270
271 fn to_capnp(&self, mut builder: Self::Builder) {
272 builder.set_value(self.as_str());
273 }
274}
275
276impl<'a> FromCapnp<'a> for ActorId {
277 type Reader = identifiers_capnp::actor_id::Reader<'a>;
278
279 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
280 let value = reader.get_value()?.to_str()?;
281 Ok(Self::new_checked(value)?)
282 }
283}
284
285impl<'a> ToCapnp<'a> for AccountId {
286 type Builder = identifiers_capnp::account_id::Builder<'a>;
287
288 fn to_capnp(&self, mut builder: Self::Builder) {
289 builder.set_value(self.as_str());
290 }
291}
292
293impl<'a> FromCapnp<'a> for AccountId {
294 type Reader = identifiers_capnp::account_id::Reader<'a>;
295
296 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
297 let value = reader.get_value()?.to_str()?;
298 Ok(Self::new_checked(value)?)
299 }
300}
301
302impl<'a> ToCapnp<'a> for ClientId {
303 type Builder = identifiers_capnp::client_id::Builder<'a>;
304
305 fn to_capnp(&self, mut builder: Self::Builder) {
306 builder.set_value(self.as_str());
307 }
308}
309
310impl<'a> FromCapnp<'a> for ClientId {
311 type Reader = identifiers_capnp::client_id::Reader<'a>;
312
313 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
314 let value = reader.get_value()?.to_str()?;
315 Ok(Self::new_checked(value)?)
316 }
317}
318
319impl<'a> ToCapnp<'a> for ClientOrderId {
320 type Builder = identifiers_capnp::client_order_id::Builder<'a>;
321
322 fn to_capnp(&self, mut builder: Self::Builder) {
323 builder.set_value(self.as_str());
324 }
325}
326
327impl<'a> FromCapnp<'a> for ClientOrderId {
328 type Reader = identifiers_capnp::client_order_id::Reader<'a>;
329
330 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
331 let value = reader.get_value()?.to_str()?;
332 Ok(Self::new_checked(value)?)
333 }
334}
335
336impl<'a> ToCapnp<'a> for VenueOrderId {
337 type Builder = identifiers_capnp::venue_order_id::Builder<'a>;
338
339 fn to_capnp(&self, mut builder: Self::Builder) {
340 builder.set_value(self.as_str());
341 }
342}
343
344impl<'a> FromCapnp<'a> for VenueOrderId {
345 type Reader = identifiers_capnp::venue_order_id::Reader<'a>;
346
347 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
348 let value = reader.get_value()?.to_str()?;
349 Ok(Self::new_checked(value)?)
350 }
351}
352
353impl<'a> ToCapnp<'a> for TradeId {
354 type Builder = identifiers_capnp::trade_id::Builder<'a>;
355
356 fn to_capnp(&self, mut builder: Self::Builder) {
357 builder.set_value(self.as_cstr().to_str().expect("Valid UTF-8"));
358 }
359}
360
361impl<'a> FromCapnp<'a> for TradeId {
362 type Reader = identifiers_capnp::trade_id::Reader<'a>;
363
364 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
365 let value = reader.get_value()?.to_str()?;
366 Ok(Self::new_checked(value)?)
367 }
368}
369
370impl<'a> ToCapnp<'a> for PositionId {
371 type Builder = identifiers_capnp::position_id::Builder<'a>;
372
373 fn to_capnp(&self, mut builder: Self::Builder) {
374 builder.set_value(self.as_str());
375 }
376}
377
378impl<'a> FromCapnp<'a> for PositionId {
379 type Reader = identifiers_capnp::position_id::Reader<'a>;
380
381 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
382 let value = reader.get_value()?.to_str()?;
383 Ok(Self::new_checked(value)?)
384 }
385}
386
387impl<'a> ToCapnp<'a> for ExecAlgorithmId {
388 type Builder = identifiers_capnp::exec_algorithm_id::Builder<'a>;
389
390 fn to_capnp(&self, mut builder: Self::Builder) {
391 builder.set_value(self.as_str());
392 }
393}
394
395impl<'a> FromCapnp<'a> for ExecAlgorithmId {
396 type Reader = identifiers_capnp::exec_algorithm_id::Reader<'a>;
397
398 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
399 let value = reader.get_value()?.to_str()?;
400 Ok(Self::new_checked(value)?)
401 }
402}
403
404impl<'a> ToCapnp<'a> for ComponentId {
405 type Builder = identifiers_capnp::component_id::Builder<'a>;
406
407 fn to_capnp(&self, mut builder: Self::Builder) {
408 builder.set_value(self.as_str());
409 }
410}
411
412impl<'a> FromCapnp<'a> for ComponentId {
413 type Reader = identifiers_capnp::component_id::Reader<'a>;
414
415 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
416 let value = reader.get_value()?.to_str()?;
417 Ok(Self::new_checked(value)?)
418 }
419}
420
421impl<'a> ToCapnp<'a> for OrderListId {
422 type Builder = identifiers_capnp::order_list_id::Builder<'a>;
423
424 fn to_capnp(&self, mut builder: Self::Builder) {
425 builder.set_value(self.as_str());
426 }
427}
428
429impl<'a> FromCapnp<'a> for OrderListId {
430 type Reader = identifiers_capnp::order_list_id::Reader<'a>;
431
432 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
433 let value = reader.get_value()?.to_str()?;
434 Ok(Self::new_checked(value)?)
435 }
436}
437
438impl<'a> ToCapnp<'a> for Symbol {
439 type Builder = identifiers_capnp::symbol::Builder<'a>;
440
441 fn to_capnp(&self, mut builder: Self::Builder) {
442 builder.set_value(self.as_str());
443 }
444}
445
446impl<'a> FromCapnp<'a> for Symbol {
447 type Reader = identifiers_capnp::symbol::Reader<'a>;
448
449 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
450 let value = reader.get_value()?.to_str()?;
451 Ok(Self::new_checked(value)?)
452 }
453}
454
455impl<'a> ToCapnp<'a> for Venue {
456 type Builder = identifiers_capnp::venue::Builder<'a>;
457
458 fn to_capnp(&self, mut builder: Self::Builder) {
459 builder.set_value(self.as_str());
460 }
461}
462
463impl<'a> FromCapnp<'a> for Venue {
464 type Reader = identifiers_capnp::venue::Reader<'a>;
465
466 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
467 let value = reader.get_value()?.to_str()?;
468 Ok(Self::new_checked(value)?)
469 }
470}
471
472impl<'a> ToCapnp<'a> for InstrumentId {
473 type Builder = identifiers_capnp::instrument_id::Builder<'a>;
474
475 fn to_capnp(&self, mut builder: Self::Builder) {
476 self.symbol.to_capnp(builder.reborrow().init_symbol());
477 self.venue.to_capnp(builder.init_venue());
478 }
479}
480
481impl<'a> FromCapnp<'a> for InstrumentId {
482 type Reader = identifiers_capnp::instrument_id::Reader<'a>;
483
484 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
485 let symbol = Symbol::from_capnp(reader.get_symbol()?)?;
486 let venue = Venue::from_capnp(reader.get_venue()?)?;
487 Ok(Self::new(symbol, venue))
488 }
489}
490
491impl<'a> ToCapnp<'a> for Price {
492 type Builder = types_capnp::price::Builder<'a>;
493
494 fn to_capnp(&self, mut builder: Self::Builder) {
495 let raw_i128: i128 = raw_to_wire(self.raw());
496 let lo = raw_i128 as u64;
497 let hi = (raw_i128 >> 64) as u64;
498
499 let mut raw_builder = builder.reborrow().init_raw();
500 raw_builder.set_lo(lo);
501 raw_builder.set_hi(hi);
502
503 builder.set_precision(self.precision);
504 }
505}
506
507impl<'a> FromCapnp<'a> for Price {
508 type Reader = types_capnp::price::Reader<'a>;
509
510 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
511 let raw_reader = reader.get_raw()?;
512 let lo = raw_reader.get_lo();
513 let hi = raw_reader.get_hi();
514 let precision = reader.get_precision();
515
516 let raw_i128 = ((hi as i64 as i128) << 64) | (lo as i128);
520
521 let raw: PriceRaw = wire_to_raw(raw_i128).ok_or_else(|| -> Box<dyn Error> {
522 "Price value overflows i64 in standard precision mode".into()
523 })?;
524
525 Ok(Self::from_raw_checked(raw, precision)?)
526 }
527}
528
529impl<'a> ToCapnp<'a> for Quantity {
530 type Builder = types_capnp::quantity::Builder<'a>;
531
532 fn to_capnp(&self, mut builder: Self::Builder) {
533 let raw_u128: u128 = raw_to_wire(self.raw());
534 let lo = raw_u128 as u64;
535 let hi = (raw_u128 >> 64) as u64;
536
537 let mut raw_builder = builder.reborrow().init_raw();
538 raw_builder.set_lo(lo);
539 raw_builder.set_hi(hi);
540
541 builder.set_precision(self.precision);
542 }
543}
544
545impl<'a> FromCapnp<'a> for Quantity {
546 type Reader = types_capnp::quantity::Reader<'a>;
547
548 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
549 let raw_reader = reader.get_raw()?;
550 let lo = raw_reader.get_lo();
551 let hi = raw_reader.get_hi();
552 let precision = reader.get_precision();
553
554 let raw_u128 = ((hi as u128) << 64) | (lo as u128);
556
557 let raw: QuantityRaw = wire_to_raw(raw_u128).ok_or_else(|| -> Box<dyn Error> {
558 "Quantity value overflows u64 in standard precision mode".into()
559 })?;
560
561 Ok(Self::from_raw_checked(raw, precision)?)
562 }
563}
564
565#[must_use]
566pub fn currency_type_to_capnp(value: CurrencyType) -> enums_capnp::CurrencyType {
567 match value {
568 CurrencyType::Crypto => enums_capnp::CurrencyType::Crypto,
569 CurrencyType::Fiat => enums_capnp::CurrencyType::Fiat,
570 CurrencyType::CommodityBacked => enums_capnp::CurrencyType::CommodityBacked,
571 }
572}
573
574#[must_use]
575pub fn currency_type_from_capnp(value: enums_capnp::CurrencyType) -> CurrencyType {
576 match value {
577 enums_capnp::CurrencyType::Crypto => CurrencyType::Crypto,
578 enums_capnp::CurrencyType::Fiat => CurrencyType::Fiat,
579 enums_capnp::CurrencyType::CommodityBacked => CurrencyType::CommodityBacked,
580 }
581}
582
583#[must_use]
584pub fn account_type_to_capnp(value: AccountType) -> enums_capnp::AccountType {
585 match value {
586 AccountType::Cash => enums_capnp::AccountType::Cash,
587 AccountType::Margin => enums_capnp::AccountType::Margin,
588 AccountType::Betting => enums_capnp::AccountType::Betting,
589 AccountType::Wallet => enums_capnp::AccountType::Wallet,
590 }
591}
592
593#[must_use]
594pub fn account_type_from_capnp(value: enums_capnp::AccountType) -> AccountType {
595 match value {
596 enums_capnp::AccountType::Cash => AccountType::Cash,
597 enums_capnp::AccountType::Margin => AccountType::Margin,
598 enums_capnp::AccountType::Betting => AccountType::Betting,
599 enums_capnp::AccountType::Wallet => AccountType::Wallet,
600 }
601}
602
603#[must_use]
604pub fn aggressor_side_to_capnp(value: AggressorSide) -> enums_capnp::AggressorSide {
605 match value {
606 AggressorSide::NoAggressor => enums_capnp::AggressorSide::NoAggressor,
607 AggressorSide::Buy => enums_capnp::AggressorSide::Buy,
608 AggressorSide::Sell => enums_capnp::AggressorSide::Sell,
609 }
610}
611
612#[must_use]
613pub fn aggressor_side_from_capnp(value: enums_capnp::AggressorSide) -> AggressorSide {
614 match value {
615 enums_capnp::AggressorSide::NoAggressor => AggressorSide::NoAggressor,
616 enums_capnp::AggressorSide::Buy => AggressorSide::Buy,
617 enums_capnp::AggressorSide::Sell => AggressorSide::Sell,
618 }
619}
620
621#[must_use]
622pub fn asset_class_to_capnp(value: AssetClass) -> enums_capnp::AssetClass {
623 match value {
624 AssetClass::FX => enums_capnp::AssetClass::Fx,
625 AssetClass::Equity => enums_capnp::AssetClass::Equity,
626 AssetClass::Commodity => enums_capnp::AssetClass::Commodity,
627 AssetClass::Debt => enums_capnp::AssetClass::Debt,
628 AssetClass::Index => enums_capnp::AssetClass::Index,
629 AssetClass::Cryptocurrency => enums_capnp::AssetClass::Cryptocurrency,
630 AssetClass::Alternative => enums_capnp::AssetClass::Alternative,
631 }
632}
633
634#[must_use]
635pub fn asset_class_from_capnp(value: enums_capnp::AssetClass) -> AssetClass {
636 match value {
637 enums_capnp::AssetClass::Fx => AssetClass::FX,
638 enums_capnp::AssetClass::Equity => AssetClass::Equity,
639 enums_capnp::AssetClass::Commodity => AssetClass::Commodity,
640 enums_capnp::AssetClass::Debt => AssetClass::Debt,
641 enums_capnp::AssetClass::Index => AssetClass::Index,
642 enums_capnp::AssetClass::Cryptocurrency => AssetClass::Cryptocurrency,
643 enums_capnp::AssetClass::Alternative => AssetClass::Alternative,
644 }
645}
646
647#[must_use]
648pub fn instrument_class_to_capnp(value: InstrumentClass) -> enums_capnp::InstrumentClass {
649 match value {
650 InstrumentClass::Spot => enums_capnp::InstrumentClass::Spot,
651 InstrumentClass::Swap => enums_capnp::InstrumentClass::Swap,
652 InstrumentClass::Future => enums_capnp::InstrumentClass::Future,
653 InstrumentClass::FuturesSpread => enums_capnp::InstrumentClass::FuturesSpread,
654 InstrumentClass::Forward => enums_capnp::InstrumentClass::Forward,
655 InstrumentClass::Cfd => enums_capnp::InstrumentClass::Cfd,
656 InstrumentClass::Bond => enums_capnp::InstrumentClass::Bond,
657 InstrumentClass::Option => enums_capnp::InstrumentClass::Option,
658 InstrumentClass::OptionSpread => enums_capnp::InstrumentClass::OptionSpread,
659 InstrumentClass::Warrant => enums_capnp::InstrumentClass::Warrant,
660 InstrumentClass::SportsBetting => enums_capnp::InstrumentClass::SportsBetting,
661 InstrumentClass::BinaryOption => enums_capnp::InstrumentClass::BinaryOption,
662 }
663}
664
665#[must_use]
666pub fn instrument_class_from_capnp(value: enums_capnp::InstrumentClass) -> InstrumentClass {
667 match value {
668 enums_capnp::InstrumentClass::Spot => InstrumentClass::Spot,
669 enums_capnp::InstrumentClass::Swap => InstrumentClass::Swap,
670 enums_capnp::InstrumentClass::Future => InstrumentClass::Future,
671 enums_capnp::InstrumentClass::FuturesSpread => InstrumentClass::FuturesSpread,
672 enums_capnp::InstrumentClass::Forward => InstrumentClass::Forward,
673 enums_capnp::InstrumentClass::Cfd => InstrumentClass::Cfd,
674 enums_capnp::InstrumentClass::Bond => InstrumentClass::Bond,
675 enums_capnp::InstrumentClass::Option => InstrumentClass::Option,
676 enums_capnp::InstrumentClass::OptionSpread => InstrumentClass::OptionSpread,
677 enums_capnp::InstrumentClass::Warrant => InstrumentClass::Warrant,
678 enums_capnp::InstrumentClass::SportsBetting => InstrumentClass::SportsBetting,
679 enums_capnp::InstrumentClass::BinaryOption => InstrumentClass::BinaryOption,
680 }
681}
682
683#[must_use]
684pub fn option_kind_to_capnp(value: OptionKind) -> enums_capnp::OptionKind {
685 match value {
686 OptionKind::Call => enums_capnp::OptionKind::Call,
687 OptionKind::Put => enums_capnp::OptionKind::Put,
688 }
689}
690
691#[must_use]
692pub fn option_kind_from_capnp(value: enums_capnp::OptionKind) -> OptionKind {
693 match value {
694 enums_capnp::OptionKind::Call => OptionKind::Call,
695 enums_capnp::OptionKind::Put => OptionKind::Put,
696 }
697}
698
699#[must_use]
700pub fn greeks_convention_to_capnp(value: GreeksConvention) -> enums_capnp::GreeksConvention {
701 match value {
702 GreeksConvention::BlackScholes => enums_capnp::GreeksConvention::BlackScholes,
703 GreeksConvention::PriceAdjusted => enums_capnp::GreeksConvention::PriceAdjusted,
704 }
705}
706
707#[must_use]
708pub fn greeks_convention_from_capnp(value: enums_capnp::GreeksConvention) -> GreeksConvention {
709 match value {
710 enums_capnp::GreeksConvention::BlackScholes => GreeksConvention::BlackScholes,
711 enums_capnp::GreeksConvention::PriceAdjusted => GreeksConvention::PriceAdjusted,
712 }
713}
714
715#[must_use]
716pub fn order_side_to_capnp(value: Option<OrderSide>) -> enums_capnp::OrderSide {
717 match value {
718 None => enums_capnp::OrderSide::NoOrderSide,
719 Some(OrderSide::Buy) => enums_capnp::OrderSide::Buy,
720 Some(OrderSide::Sell) => enums_capnp::OrderSide::Sell,
721 }
722}
723
724#[must_use]
725pub fn order_side_from_capnp(value: enums_capnp::OrderSide) -> Option<OrderSide> {
726 match value {
727 enums_capnp::OrderSide::NoOrderSide => None,
728 enums_capnp::OrderSide::Buy => Some(OrderSide::Buy),
729 enums_capnp::OrderSide::Sell => Some(OrderSide::Sell),
730 }
731}
732
733fn order_side_required_from_capnp(
734 value: enums_capnp::OrderSide,
735) -> Result<OrderSide, Box<dyn Error>> {
736 order_side_from_capnp(value)
737 .ok_or_else(|| "Cap'n Proto required order side was NO_ORDER_SIDE".into())
738}
739
740#[must_use]
741pub fn order_type_to_capnp(value: OrderType) -> enums_capnp::OrderType {
742 match value {
743 OrderType::Market => enums_capnp::OrderType::Market,
744 OrderType::Limit => enums_capnp::OrderType::Limit,
745 OrderType::StopMarket => enums_capnp::OrderType::StopMarket,
746 OrderType::StopLimit => enums_capnp::OrderType::StopLimit,
747 OrderType::MarketToLimit => enums_capnp::OrderType::MarketToLimit,
748 OrderType::MarketIfTouched => enums_capnp::OrderType::MarketIfTouched,
749 OrderType::LimitIfTouched => enums_capnp::OrderType::LimitIfTouched,
750 OrderType::TrailingStopMarket => enums_capnp::OrderType::TrailingStopMarket,
751 OrderType::TrailingStopLimit => enums_capnp::OrderType::TrailingStopLimit,
752 }
753}
754
755#[must_use]
756pub fn order_type_from_capnp(value: enums_capnp::OrderType) -> OrderType {
757 match value {
758 enums_capnp::OrderType::Market => OrderType::Market,
759 enums_capnp::OrderType::Limit => OrderType::Limit,
760 enums_capnp::OrderType::StopMarket => OrderType::StopMarket,
761 enums_capnp::OrderType::StopLimit => OrderType::StopLimit,
762 enums_capnp::OrderType::MarketToLimit => OrderType::MarketToLimit,
763 enums_capnp::OrderType::MarketIfTouched => OrderType::MarketIfTouched,
764 enums_capnp::OrderType::LimitIfTouched => OrderType::LimitIfTouched,
765 enums_capnp::OrderType::TrailingStopMarket => OrderType::TrailingStopMarket,
766 enums_capnp::OrderType::TrailingStopLimit => OrderType::TrailingStopLimit,
767 }
768}
769
770#[must_use]
771pub fn order_status_to_capnp(value: OrderStatus) -> enums_capnp::OrderStatus {
772 match value {
773 OrderStatus::Initialized => enums_capnp::OrderStatus::Initialized,
774 OrderStatus::Denied => enums_capnp::OrderStatus::Denied,
775 OrderStatus::Emulated => enums_capnp::OrderStatus::Emulated,
776 OrderStatus::Released => enums_capnp::OrderStatus::Released,
777 OrderStatus::Submitted => enums_capnp::OrderStatus::Submitted,
778 OrderStatus::Accepted => enums_capnp::OrderStatus::Accepted,
779 OrderStatus::Rejected => enums_capnp::OrderStatus::Rejected,
780 OrderStatus::Canceled => enums_capnp::OrderStatus::Canceled,
781 OrderStatus::Expired => enums_capnp::OrderStatus::Expired,
782 OrderStatus::Triggered => enums_capnp::OrderStatus::Triggered,
783 OrderStatus::PendingUpdate => enums_capnp::OrderStatus::PendingUpdate,
784 OrderStatus::PendingCancel => enums_capnp::OrderStatus::PendingCancel,
785 OrderStatus::PartiallyFilled => enums_capnp::OrderStatus::PartiallyFilled,
786 OrderStatus::Filled => enums_capnp::OrderStatus::Filled,
787 OrderStatus::Voided => enums_capnp::OrderStatus::Voided,
788 }
789}
790
791#[must_use]
792pub fn order_status_from_capnp(value: enums_capnp::OrderStatus) -> OrderStatus {
793 match value {
794 enums_capnp::OrderStatus::Initialized => OrderStatus::Initialized,
795 enums_capnp::OrderStatus::Denied => OrderStatus::Denied,
796 enums_capnp::OrderStatus::Emulated => OrderStatus::Emulated,
797 enums_capnp::OrderStatus::Released => OrderStatus::Released,
798 enums_capnp::OrderStatus::Submitted => OrderStatus::Submitted,
799 enums_capnp::OrderStatus::Accepted => OrderStatus::Accepted,
800 enums_capnp::OrderStatus::Rejected => OrderStatus::Rejected,
801 enums_capnp::OrderStatus::Canceled => OrderStatus::Canceled,
802 enums_capnp::OrderStatus::Expired => OrderStatus::Expired,
803 enums_capnp::OrderStatus::Triggered => OrderStatus::Triggered,
804 enums_capnp::OrderStatus::PendingUpdate => OrderStatus::PendingUpdate,
805 enums_capnp::OrderStatus::PendingCancel => OrderStatus::PendingCancel,
806 enums_capnp::OrderStatus::PartiallyFilled => OrderStatus::PartiallyFilled,
807 enums_capnp::OrderStatus::Filled => OrderStatus::Filled,
808 enums_capnp::OrderStatus::Voided => OrderStatus::Voided,
809 }
810}
811
812#[must_use]
813pub fn time_in_force_to_capnp(value: TimeInForce) -> enums_capnp::TimeInForce {
814 match value {
815 TimeInForce::Gtc => enums_capnp::TimeInForce::Gtc,
816 TimeInForce::Ioc => enums_capnp::TimeInForce::Ioc,
817 TimeInForce::Fok => enums_capnp::TimeInForce::Fok,
818 TimeInForce::Gtd => enums_capnp::TimeInForce::Gtd,
819 TimeInForce::Day => enums_capnp::TimeInForce::Day,
820 TimeInForce::AtTheOpen => enums_capnp::TimeInForce::AtTheOpen,
821 TimeInForce::AtTheClose => enums_capnp::TimeInForce::AtTheClose,
822 }
823}
824
825#[must_use]
826pub fn time_in_force_from_capnp(value: enums_capnp::TimeInForce) -> TimeInForce {
827 match value {
828 enums_capnp::TimeInForce::Gtc => TimeInForce::Gtc,
829 enums_capnp::TimeInForce::Ioc => TimeInForce::Ioc,
830 enums_capnp::TimeInForce::Fok => TimeInForce::Fok,
831 enums_capnp::TimeInForce::Gtd => TimeInForce::Gtd,
832 enums_capnp::TimeInForce::Day => TimeInForce::Day,
833 enums_capnp::TimeInForce::AtTheOpen => TimeInForce::AtTheOpen,
834 enums_capnp::TimeInForce::AtTheClose => TimeInForce::AtTheClose,
835 }
836}
837
838#[must_use]
839pub fn trigger_type_to_capnp(value: Option<TriggerType>) -> enums_capnp::TriggerType {
840 match value {
841 None => enums_capnp::TriggerType::NoTrigger,
842 Some(TriggerType::Default) => enums_capnp::TriggerType::Default,
843 Some(TriggerType::LastPrice) => enums_capnp::TriggerType::LastPrice,
844 Some(TriggerType::MarkPrice) => enums_capnp::TriggerType::MarkPrice,
845 Some(TriggerType::IndexPrice) => enums_capnp::TriggerType::IndexPrice,
846 Some(TriggerType::BidAsk) => enums_capnp::TriggerType::BidAsk,
847 Some(TriggerType::DoubleLast) => enums_capnp::TriggerType::DoubleLast,
848 Some(TriggerType::DoubleBidAsk) => enums_capnp::TriggerType::DoubleBidAsk,
849 Some(TriggerType::LastOrBidAsk) => enums_capnp::TriggerType::LastOrBidAsk,
850 Some(TriggerType::MidPoint) => enums_capnp::TriggerType::MidPoint,
851 }
852}
853
854#[must_use]
855pub fn trigger_type_from_capnp(value: enums_capnp::TriggerType) -> Option<TriggerType> {
856 match value {
857 enums_capnp::TriggerType::NoTrigger => None,
858 enums_capnp::TriggerType::Default => Some(TriggerType::Default),
859 enums_capnp::TriggerType::LastPrice => Some(TriggerType::LastPrice),
860 enums_capnp::TriggerType::MarkPrice => Some(TriggerType::MarkPrice),
861 enums_capnp::TriggerType::IndexPrice => Some(TriggerType::IndexPrice),
862 enums_capnp::TriggerType::BidAsk => Some(TriggerType::BidAsk),
863 enums_capnp::TriggerType::DoubleLast => Some(TriggerType::DoubleLast),
864 enums_capnp::TriggerType::DoubleBidAsk => Some(TriggerType::DoubleBidAsk),
865 enums_capnp::TriggerType::LastOrBidAsk => Some(TriggerType::LastOrBidAsk),
866 enums_capnp::TriggerType::MidPoint => Some(TriggerType::MidPoint),
867 }
868}
869
870#[must_use]
871pub fn contingency_type_to_capnp(value: Option<ContingencyType>) -> enums_capnp::ContingencyType {
872 match value {
873 None => enums_capnp::ContingencyType::NoContingency,
874 Some(ContingencyType::Oco) => enums_capnp::ContingencyType::Oco,
875 Some(ContingencyType::Oto) => enums_capnp::ContingencyType::Oto,
876 Some(ContingencyType::Ouo) => enums_capnp::ContingencyType::Ouo,
877 }
878}
879
880#[must_use]
881pub fn contingency_type_from_capnp(value: enums_capnp::ContingencyType) -> Option<ContingencyType> {
882 match value {
883 enums_capnp::ContingencyType::NoContingency => None,
884 enums_capnp::ContingencyType::Oco => Some(ContingencyType::Oco),
885 enums_capnp::ContingencyType::Oto => Some(ContingencyType::Oto),
886 enums_capnp::ContingencyType::Ouo => Some(ContingencyType::Ouo),
887 }
888}
889
890#[must_use]
891pub fn position_side_to_capnp(value: Option<PositionSide>) -> enums_capnp::PositionSide {
892 match value {
893 None => enums_capnp::PositionSide::NoPositionSide,
894 Some(PositionSide::Flat) => enums_capnp::PositionSide::Flat,
895 Some(PositionSide::Long) => enums_capnp::PositionSide::Long,
896 Some(PositionSide::Short) => enums_capnp::PositionSide::Short,
897 }
898}
899
900#[must_use]
901pub fn position_side_from_capnp(value: enums_capnp::PositionSide) -> Option<PositionSide> {
902 match value {
903 enums_capnp::PositionSide::NoPositionSide => None,
904 enums_capnp::PositionSide::Flat => Some(PositionSide::Flat),
905 enums_capnp::PositionSide::Long => Some(PositionSide::Long),
906 enums_capnp::PositionSide::Short => Some(PositionSide::Short),
907 }
908}
909
910fn position_side_required_from_capnp(
911 value: enums_capnp::PositionSide,
912) -> Result<PositionSide, Box<dyn Error>> {
913 position_side_from_capnp(value)
914 .ok_or_else(|| "Cap'n Proto required position side was NO_POSITION_SIDE".into())
915}
916
917#[must_use]
918pub fn position_adjustment_type_to_capnp(
919 value: PositionAdjustmentType,
920) -> enums_capnp::PositionAdjustmentType {
921 match value {
922 PositionAdjustmentType::Commission => enums_capnp::PositionAdjustmentType::Commission,
923 PositionAdjustmentType::Funding => enums_capnp::PositionAdjustmentType::Funding,
924 }
925}
926
927#[must_use]
928pub fn position_adjustment_type_from_capnp(
929 value: enums_capnp::PositionAdjustmentType,
930) -> PositionAdjustmentType {
931 match value {
932 enums_capnp::PositionAdjustmentType::Commission => PositionAdjustmentType::Commission,
933 enums_capnp::PositionAdjustmentType::Funding => PositionAdjustmentType::Funding,
934 }
935}
936
937#[must_use]
938pub fn liquidity_side_to_capnp(value: LiquiditySide) -> enums_capnp::LiquiditySide {
939 match value {
940 LiquiditySide::NoLiquiditySide => enums_capnp::LiquiditySide::NoLiquiditySide,
941 LiquiditySide::Maker => enums_capnp::LiquiditySide::Maker,
942 LiquiditySide::Taker => enums_capnp::LiquiditySide::Taker,
943 }
944}
945
946#[must_use]
947pub fn liquidity_side_from_capnp(value: enums_capnp::LiquiditySide) -> LiquiditySide {
948 match value {
949 enums_capnp::LiquiditySide::NoLiquiditySide => LiquiditySide::NoLiquiditySide,
950 enums_capnp::LiquiditySide::Maker => LiquiditySide::Maker,
951 enums_capnp::LiquiditySide::Taker => LiquiditySide::Taker,
952 }
953}
954
955#[must_use]
956pub fn book_action_to_capnp(value: BookAction) -> enums_capnp::BookAction {
957 match value {
958 BookAction::Add => enums_capnp::BookAction::Add,
959 BookAction::Update => enums_capnp::BookAction::Update,
960 BookAction::Delete => enums_capnp::BookAction::Delete,
961 BookAction::Clear => enums_capnp::BookAction::Clear,
962 }
963}
964
965#[must_use]
966pub fn book_action_from_capnp(value: enums_capnp::BookAction) -> BookAction {
967 match value {
968 enums_capnp::BookAction::Add => BookAction::Add,
969 enums_capnp::BookAction::Update => BookAction::Update,
970 enums_capnp::BookAction::Delete => BookAction::Delete,
971 enums_capnp::BookAction::Clear => BookAction::Clear,
972 }
973}
974
975#[must_use]
976pub fn book_type_to_capnp(value: BookType) -> enums_capnp::BookType {
977 match value {
978 BookType::L1_MBP => enums_capnp::BookType::TopOfBookBidOffer,
979 BookType::L2_MBP => enums_capnp::BookType::MarketByPrice,
980 BookType::L3_MBO => enums_capnp::BookType::MarketByOrder,
981 }
982}
983
984#[must_use]
985pub fn book_type_from_capnp(value: enums_capnp::BookType) -> BookType {
986 match value {
987 enums_capnp::BookType::TopOfBookBidOffer => BookType::L1_MBP,
988 enums_capnp::BookType::MarketByPrice => BookType::L2_MBP,
989 enums_capnp::BookType::MarketByOrder => BookType::L3_MBO,
990 }
991}
992
993#[must_use]
994pub fn record_flag_to_capnp(value: RecordFlag) -> enums_capnp::RecordFlag {
995 match value {
996 RecordFlag::F_LAST => enums_capnp::RecordFlag::FLast,
997 RecordFlag::F_TOB => enums_capnp::RecordFlag::FTob,
998 RecordFlag::F_SNAPSHOT => enums_capnp::RecordFlag::FSnapshot,
999 RecordFlag::F_MBP => enums_capnp::RecordFlag::FMbp,
1000 RecordFlag::RESERVED_2 => enums_capnp::RecordFlag::Reserved2,
1001 RecordFlag::RESERVED_1 => enums_capnp::RecordFlag::Reserved1,
1002 }
1003}
1004
1005#[must_use]
1006pub fn record_flag_from_capnp(value: enums_capnp::RecordFlag) -> RecordFlag {
1007 match value {
1008 enums_capnp::RecordFlag::FLast => RecordFlag::F_LAST,
1009 enums_capnp::RecordFlag::FTob => RecordFlag::F_TOB,
1010 enums_capnp::RecordFlag::FSnapshot => RecordFlag::F_SNAPSHOT,
1011 enums_capnp::RecordFlag::FMbp => RecordFlag::F_MBP,
1012 enums_capnp::RecordFlag::Reserved2 => RecordFlag::RESERVED_2,
1013 enums_capnp::RecordFlag::Reserved1 => RecordFlag::RESERVED_1,
1014 }
1015}
1016
1017#[must_use]
1018pub fn aggregation_source_to_capnp(value: AggregationSource) -> enums_capnp::AggregationSource {
1019 match value {
1020 AggregationSource::External => enums_capnp::AggregationSource::External,
1021 AggregationSource::Internal => enums_capnp::AggregationSource::Internal,
1022 }
1023}
1024
1025#[must_use]
1026pub fn aggregation_source_from_capnp(value: enums_capnp::AggregationSource) -> AggregationSource {
1027 match value {
1028 enums_capnp::AggregationSource::External => AggregationSource::External,
1029 enums_capnp::AggregationSource::Internal => AggregationSource::Internal,
1030 }
1031}
1032
1033#[must_use]
1034pub fn price_type_to_capnp(value: PriceType) -> enums_capnp::PriceType {
1035 match value {
1036 PriceType::Bid => enums_capnp::PriceType::Bid,
1037 PriceType::Ask => enums_capnp::PriceType::Ask,
1038 PriceType::Mid => enums_capnp::PriceType::Mid,
1039 PriceType::Last => enums_capnp::PriceType::Last,
1040 PriceType::Mark => enums_capnp::PriceType::Mark,
1041 }
1042}
1043
1044#[must_use]
1045pub fn price_type_from_capnp(value: enums_capnp::PriceType) -> PriceType {
1046 match value {
1047 enums_capnp::PriceType::Bid => PriceType::Bid,
1048 enums_capnp::PriceType::Ask => PriceType::Ask,
1049 enums_capnp::PriceType::Mid => PriceType::Mid,
1050 enums_capnp::PriceType::Last => PriceType::Last,
1051 enums_capnp::PriceType::Mark => PriceType::Mark,
1052 }
1053}
1054
1055#[must_use]
1056pub fn bar_aggregation_to_capnp(value: BarAggregation) -> enums_capnp::BarAggregation {
1057 match value {
1058 BarAggregation::Tick => enums_capnp::BarAggregation::Tick,
1059 BarAggregation::TickImbalance => enums_capnp::BarAggregation::TickImbalance,
1060 BarAggregation::TickRuns => enums_capnp::BarAggregation::TickRuns,
1061 BarAggregation::Volume => enums_capnp::BarAggregation::Volume,
1062 BarAggregation::VolumeImbalance => enums_capnp::BarAggregation::VolumeImbalance,
1063 BarAggregation::VolumeRuns => enums_capnp::BarAggregation::VolumeRuns,
1064 BarAggregation::Value => enums_capnp::BarAggregation::Value,
1065 BarAggregation::ValueImbalance => enums_capnp::BarAggregation::ValueImbalance,
1066 BarAggregation::ValueRuns => enums_capnp::BarAggregation::ValueRuns,
1067 BarAggregation::Millisecond => enums_capnp::BarAggregation::Millisecond,
1068 BarAggregation::Second => enums_capnp::BarAggregation::Second,
1069 BarAggregation::Minute => enums_capnp::BarAggregation::Minute,
1070 BarAggregation::Hour => enums_capnp::BarAggregation::Hour,
1071 BarAggregation::Day => enums_capnp::BarAggregation::Day,
1072 BarAggregation::Week => enums_capnp::BarAggregation::Week,
1073 BarAggregation::Month => enums_capnp::BarAggregation::Month,
1074 BarAggregation::Year => enums_capnp::BarAggregation::Year,
1075 BarAggregation::Renko => enums_capnp::BarAggregation::Renko,
1076 }
1077}
1078
1079#[must_use]
1080pub fn bar_aggregation_from_capnp(value: enums_capnp::BarAggregation) -> BarAggregation {
1081 match value {
1082 enums_capnp::BarAggregation::Tick => BarAggregation::Tick,
1083 enums_capnp::BarAggregation::TickImbalance => BarAggregation::TickImbalance,
1084 enums_capnp::BarAggregation::TickRuns => BarAggregation::TickRuns,
1085 enums_capnp::BarAggregation::Volume => BarAggregation::Volume,
1086 enums_capnp::BarAggregation::VolumeImbalance => BarAggregation::VolumeImbalance,
1087 enums_capnp::BarAggregation::VolumeRuns => BarAggregation::VolumeRuns,
1088 enums_capnp::BarAggregation::Value => BarAggregation::Value,
1089 enums_capnp::BarAggregation::ValueImbalance => BarAggregation::ValueImbalance,
1090 enums_capnp::BarAggregation::ValueRuns => BarAggregation::ValueRuns,
1091 enums_capnp::BarAggregation::Millisecond => BarAggregation::Millisecond,
1092 enums_capnp::BarAggregation::Second => BarAggregation::Second,
1093 enums_capnp::BarAggregation::Minute => BarAggregation::Minute,
1094 enums_capnp::BarAggregation::Hour => BarAggregation::Hour,
1095 enums_capnp::BarAggregation::Day => BarAggregation::Day,
1096 enums_capnp::BarAggregation::Week => BarAggregation::Week,
1097 enums_capnp::BarAggregation::Month => BarAggregation::Month,
1098 enums_capnp::BarAggregation::Year => BarAggregation::Year,
1099 enums_capnp::BarAggregation::Renko => BarAggregation::Renko,
1100 }
1101}
1102
1103#[must_use]
1104pub fn trailing_offset_type_to_capnp(
1105 value: Option<TrailingOffsetType>,
1106) -> enums_capnp::TrailingOffsetType {
1107 match value {
1108 None => enums_capnp::TrailingOffsetType::NoTrailingOffset,
1109 Some(TrailingOffsetType::Price) => enums_capnp::TrailingOffsetType::Price,
1110 Some(TrailingOffsetType::BasisPoints) => enums_capnp::TrailingOffsetType::BasisPoints,
1111 Some(TrailingOffsetType::Ticks) => enums_capnp::TrailingOffsetType::Ticks,
1112 Some(TrailingOffsetType::PriceTier) => enums_capnp::TrailingOffsetType::PriceTier,
1113 }
1114}
1115
1116#[must_use]
1117pub fn trailing_offset_type_from_capnp(
1118 value: enums_capnp::TrailingOffsetType,
1119) -> Option<TrailingOffsetType> {
1120 match value {
1121 enums_capnp::TrailingOffsetType::NoTrailingOffset => None,
1122 enums_capnp::TrailingOffsetType::Price => Some(TrailingOffsetType::Price),
1123 enums_capnp::TrailingOffsetType::BasisPoints => Some(TrailingOffsetType::BasisPoints),
1124 enums_capnp::TrailingOffsetType::Ticks => Some(TrailingOffsetType::Ticks),
1125 enums_capnp::TrailingOffsetType::PriceTier => Some(TrailingOffsetType::PriceTier),
1126 }
1127}
1128
1129#[must_use]
1130pub fn oms_type_to_capnp(value: OmsType) -> enums_capnp::OmsType {
1131 match value {
1132 OmsType::Unspecified => enums_capnp::OmsType::Unspecified,
1133 OmsType::Netting => enums_capnp::OmsType::Netting,
1134 OmsType::Hedging => enums_capnp::OmsType::Hedging,
1135 }
1136}
1137
1138#[must_use]
1139pub fn oms_type_from_capnp(value: enums_capnp::OmsType) -> OmsType {
1140 match value {
1141 enums_capnp::OmsType::Unspecified => OmsType::Unspecified,
1142 enums_capnp::OmsType::Netting => OmsType::Netting,
1143 enums_capnp::OmsType::Hedging => OmsType::Hedging,
1144 }
1145}
1146
1147#[must_use]
1148pub fn instrument_close_type_to_capnp(
1149 value: InstrumentCloseType,
1150) -> enums_capnp::InstrumentCloseType {
1151 match value {
1152 InstrumentCloseType::EndOfSession => enums_capnp::InstrumentCloseType::EndOfSession,
1153 InstrumentCloseType::ContractExpired => enums_capnp::InstrumentCloseType::ContractExpired,
1154 }
1155}
1156
1157#[must_use]
1158pub fn instrument_close_type_from_capnp(
1159 value: enums_capnp::InstrumentCloseType,
1160) -> InstrumentCloseType {
1161 match value {
1162 enums_capnp::InstrumentCloseType::EndOfSession => InstrumentCloseType::EndOfSession,
1163 enums_capnp::InstrumentCloseType::ContractExpired => InstrumentCloseType::ContractExpired,
1164 }
1165}
1166
1167#[must_use]
1168#[rustfmt::skip]
1169pub fn market_status_action_to_capnp(value: MarketStatusAction) -> enums_capnp::MarketStatusAction {
1170 match value {
1171 MarketStatusAction::None => enums_capnp::MarketStatusAction::None,
1172 MarketStatusAction::PreOpen => enums_capnp::MarketStatusAction::PreOpen,
1173 MarketStatusAction::PreCross => enums_capnp::MarketStatusAction::PreCross,
1174 MarketStatusAction::Quoting => enums_capnp::MarketStatusAction::Quoting,
1175 MarketStatusAction::Cross => enums_capnp::MarketStatusAction::Cross,
1176 MarketStatusAction::Rotation => enums_capnp::MarketStatusAction::Rotation,
1177 MarketStatusAction::NewPriceIndication => enums_capnp::MarketStatusAction::NewPriceIndication,
1178 MarketStatusAction::Trading => enums_capnp::MarketStatusAction::Trading,
1179 MarketStatusAction::Halt => enums_capnp::MarketStatusAction::Halt,
1180 MarketStatusAction::Pause => enums_capnp::MarketStatusAction::Pause,
1181 MarketStatusAction::Suspend => enums_capnp::MarketStatusAction::Suspend,
1182 MarketStatusAction::PreClose => enums_capnp::MarketStatusAction::PreClose,
1183 MarketStatusAction::Close => enums_capnp::MarketStatusAction::Close,
1184 MarketStatusAction::PostClose => enums_capnp::MarketStatusAction::PostClose,
1185 MarketStatusAction::ShortSellRestrictionChange => enums_capnp::MarketStatusAction::ShortSellRestrictionChange,
1186 MarketStatusAction::NotAvailableForTrading => enums_capnp::MarketStatusAction::NotAvailableForTrading,
1187 }
1188}
1189
1190#[must_use]
1191#[rustfmt::skip]
1192pub fn market_status_action_from_capnp(
1193 value: enums_capnp::MarketStatusAction,
1194) -> MarketStatusAction {
1195 match value {
1196 enums_capnp::MarketStatusAction::None => MarketStatusAction::None,
1197 enums_capnp::MarketStatusAction::PreOpen => MarketStatusAction::PreOpen,
1198 enums_capnp::MarketStatusAction::PreCross => MarketStatusAction::PreCross,
1199 enums_capnp::MarketStatusAction::Quoting => MarketStatusAction::Quoting,
1200 enums_capnp::MarketStatusAction::Cross => MarketStatusAction::Cross,
1201 enums_capnp::MarketStatusAction::Rotation => MarketStatusAction::Rotation,
1202 enums_capnp::MarketStatusAction::NewPriceIndication => MarketStatusAction::NewPriceIndication,
1203 enums_capnp::MarketStatusAction::Trading => MarketStatusAction::Trading,
1204 enums_capnp::MarketStatusAction::Halt => MarketStatusAction::Halt,
1205 enums_capnp::MarketStatusAction::Pause => MarketStatusAction::Pause,
1206 enums_capnp::MarketStatusAction::Suspend => MarketStatusAction::Suspend,
1207 enums_capnp::MarketStatusAction::PreClose => MarketStatusAction::PreClose,
1208 enums_capnp::MarketStatusAction::Close => MarketStatusAction::Close,
1209 enums_capnp::MarketStatusAction::PostClose => MarketStatusAction::PostClose,
1210 enums_capnp::MarketStatusAction::ShortSellRestrictionChange => MarketStatusAction::ShortSellRestrictionChange,
1211 enums_capnp::MarketStatusAction::NotAvailableForTrading => MarketStatusAction::NotAvailableForTrading,
1212 }
1213}
1214
1215#[must_use]
1216pub fn optional_bool_to_capnp(value: Option<bool>) -> enums_capnp::OptionalBool {
1217 match value {
1218 None => enums_capnp::OptionalBool::Unknown,
1219 Some(true) => enums_capnp::OptionalBool::True,
1220 Some(false) => enums_capnp::OptionalBool::False,
1221 }
1222}
1223
1224#[must_use]
1225pub fn optional_bool_from_capnp(value: enums_capnp::OptionalBool) -> Option<bool> {
1226 match value {
1227 enums_capnp::OptionalBool::Unknown => None,
1228 enums_capnp::OptionalBool::True => Some(true),
1229 enums_capnp::OptionalBool::False => Some(false),
1230 }
1231}
1232
1233impl<'a> ToCapnp<'a> for Currency {
1234 type Builder = types_capnp::currency::Builder<'a>;
1235
1236 fn to_capnp(&self, mut builder: Self::Builder) {
1237 builder.set_code(self.code);
1238 builder.set_precision(self.precision);
1239 builder.set_iso4217(self.iso4217);
1240 builder.set_name(self.name);
1241 builder.set_currency_type(currency_type_to_capnp(self.currency_type));
1242 }
1243}
1244
1245impl<'a> FromCapnp<'a> for Currency {
1246 type Reader = types_capnp::currency::Reader<'a>;
1247
1248 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1249 let code = reader.get_code()?.to_str()?;
1250 let precision = reader.get_precision();
1251 let iso4217 = reader.get_iso4217();
1252 let name = reader.get_name()?.to_str()?;
1253 let currency_type = currency_type_from_capnp(reader.get_currency_type()?);
1254
1255 Ok(Self::new_checked(
1256 code,
1257 precision,
1258 iso4217,
1259 name,
1260 currency_type,
1261 )?)
1262 }
1263}
1264
1265impl<'a> ToCapnp<'a> for Money {
1266 type Builder = types_capnp::money::Builder<'a>;
1267
1268 fn to_capnp(&self, mut builder: Self::Builder) {
1269 let mut raw_builder = builder.reborrow().init_raw();
1270
1271 let raw_i128: i128 = raw_to_wire(self.raw());
1272 raw_builder.set_lo(raw_i128 as u64);
1273 raw_builder.set_hi((raw_i128 >> 64) as u64);
1274
1275 let currency_builder = builder.init_currency();
1276 self.currency.to_capnp(currency_builder);
1277 }
1278}
1279
1280impl<'a> FromCapnp<'a> for Money {
1281 type Reader = types_capnp::money::Reader<'a>;
1282
1283 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1284 let raw_reader = reader.get_raw()?;
1285 let lo = raw_reader.get_lo();
1286 let hi = raw_reader.get_hi();
1287
1288 let raw_i128 = ((hi as i64 as i128) << 64) | (lo as i128);
1290
1291 let currency_reader = reader.get_currency()?;
1292 let currency = Currency::from_capnp(currency_reader)?;
1293
1294 let raw: MoneyRaw = wire_to_raw(raw_i128).ok_or_else(|| -> Box<dyn Error> {
1295 "Money value overflows i64 in standard precision mode".into()
1296 })?;
1297
1298 Ok(Self::from_raw(raw, currency))
1299 }
1300}
1301
1302impl<'a> ToCapnp<'a> for AccountBalance {
1303 type Builder = types_capnp::account_balance::Builder<'a>;
1304
1305 fn to_capnp(&self, mut builder: Self::Builder) {
1306 let total_builder = builder.reborrow().init_total();
1307 self.total.to_capnp(total_builder);
1308
1309 let locked_builder = builder.reborrow().init_locked();
1310 self.locked.to_capnp(locked_builder);
1311
1312 let free_builder = builder.init_free();
1313 self.free.to_capnp(free_builder);
1314 }
1315}
1316
1317impl<'a> FromCapnp<'a> for AccountBalance {
1318 type Reader = types_capnp::account_balance::Reader<'a>;
1319
1320 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1321 let total_reader = reader.get_total()?;
1322 let total = Money::from_capnp(total_reader)?;
1323
1324 let locked_reader = reader.get_locked()?;
1325 let locked = Money::from_capnp(locked_reader)?;
1326
1327 let free_reader = reader.get_free()?;
1328 let free = Money::from_capnp(free_reader)?;
1329
1330 Ok(Self::new_checked(total, locked, free)?)
1331 }
1332}
1333
1334impl<'a> ToCapnp<'a> for MarginBalance {
1335 type Builder = types_capnp::margin_balance::Builder<'a>;
1336
1337 fn to_capnp(&self, mut builder: Self::Builder) {
1338 let initial_builder = builder.reborrow().init_initial();
1339 self.initial.to_capnp(initial_builder);
1340
1341 let maintenance_builder = builder.reborrow().init_maintenance();
1342 self.maintenance.to_capnp(maintenance_builder);
1343
1344 self.instrument_id.write_capnp(|| builder.init_instrument());
1346 }
1347}
1348
1349impl<'a> FromCapnp<'a> for MarginBalance {
1350 type Reader = types_capnp::margin_balance::Reader<'a>;
1351
1352 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1353 let initial_reader = reader.get_initial()?;
1354 let initial = Money::from_capnp(initial_reader)?;
1355
1356 let maintenance_reader = reader.get_maintenance()?;
1357 let maintenance = Money::from_capnp(maintenance_reader)?;
1358
1359 let instrument_id =
1360 read_optional_from_capnp(|| reader.has_instrument(), || reader.get_instrument())?;
1361
1362 Ok(Self::new_checked(initial, maintenance, instrument_id)?)
1363 }
1364}
1365
1366pub fn serialize_instrument_id(id: &InstrumentId) -> Result<Vec<u8>, Box<dyn Error>> {
1372 let mut message = capnp::message::Builder::new_default();
1373 let builder = message.init_root::<identifiers_capnp::instrument_id::Builder>();
1374 id.to_capnp(builder);
1375
1376 let mut bytes = Vec::new();
1377 capnp::serialize::write_message(&mut bytes, &message)?;
1378 Ok(bytes)
1379}
1380
1381pub fn deserialize_instrument_id(bytes: &[u8]) -> Result<InstrumentId, Box<dyn Error>> {
1387 let reader =
1388 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1389 let root = reader.get_root::<identifiers_capnp::instrument_id::Reader>()?;
1390 InstrumentId::from_capnp(root)
1391}
1392
1393pub fn serialize_price(price: &Price) -> Result<Vec<u8>, Box<dyn Error>> {
1399 let mut message = capnp::message::Builder::new_default();
1400 let builder = message.init_root::<types_capnp::price::Builder>();
1401 price.to_capnp(builder);
1402
1403 let mut bytes = Vec::new();
1404 capnp::serialize::write_message(&mut bytes, &message)?;
1405 Ok(bytes)
1406}
1407
1408pub fn deserialize_price(bytes: &[u8]) -> Result<Price, Box<dyn Error>> {
1414 let reader =
1415 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1416 let root = reader.get_root::<types_capnp::price::Reader>()?;
1417 Price::from_capnp(root)
1418}
1419
1420pub fn serialize_quantity(qty: &Quantity) -> Result<Vec<u8>, Box<dyn Error>> {
1426 let mut message = capnp::message::Builder::new_default();
1427 let builder = message.init_root::<types_capnp::quantity::Builder>();
1428 qty.to_capnp(builder);
1429
1430 let mut bytes = Vec::new();
1431 capnp::serialize::write_message(&mut bytes, &message)?;
1432 Ok(bytes)
1433}
1434
1435pub fn deserialize_quantity(bytes: &[u8]) -> Result<Quantity, Box<dyn Error>> {
1441 let reader =
1442 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1443 let root = reader.get_root::<types_capnp::quantity::Reader>()?;
1444 Quantity::from_capnp(root)
1445}
1446
1447pub fn serialize_currency(currency: &Currency) -> Result<Vec<u8>, Box<dyn Error>> {
1453 let mut message = capnp::message::Builder::new_default();
1454 let builder = message.init_root::<types_capnp::currency::Builder>();
1455 currency.to_capnp(builder);
1456
1457 let mut bytes = Vec::new();
1458 capnp::serialize::write_message(&mut bytes, &message)?;
1459 Ok(bytes)
1460}
1461
1462pub fn deserialize_currency(bytes: &[u8]) -> Result<Currency, Box<dyn Error>> {
1468 let reader =
1469 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1470 let root = reader.get_root::<types_capnp::currency::Reader>()?;
1471 Currency::from_capnp(root)
1472}
1473
1474pub fn serialize_money(money: &Money) -> Result<Vec<u8>, Box<dyn Error>> {
1480 let mut message = capnp::message::Builder::new_default();
1481 let builder = message.init_root::<types_capnp::money::Builder>();
1482 money.to_capnp(builder);
1483
1484 let mut bytes = Vec::new();
1485 capnp::serialize::write_message(&mut bytes, &message)?;
1486 Ok(bytes)
1487}
1488
1489pub fn deserialize_money(bytes: &[u8]) -> Result<Money, Box<dyn Error>> {
1495 let reader =
1496 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1497 let root = reader.get_root::<types_capnp::money::Reader>()?;
1498 Money::from_capnp(root)
1499}
1500
1501pub fn serialize_account_balance(balance: &AccountBalance) -> Result<Vec<u8>, Box<dyn Error>> {
1507 let mut message = capnp::message::Builder::new_default();
1508 let builder = message.init_root::<types_capnp::account_balance::Builder>();
1509 balance.to_capnp(builder);
1510
1511 let mut bytes = Vec::new();
1512 capnp::serialize::write_message(&mut bytes, &message)?;
1513 Ok(bytes)
1514}
1515
1516pub fn deserialize_account_balance(bytes: &[u8]) -> Result<AccountBalance, Box<dyn Error>> {
1522 let reader =
1523 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1524 let root = reader.get_root::<types_capnp::account_balance::Reader>()?;
1525 AccountBalance::from_capnp(root)
1526}
1527
1528pub fn serialize_margin_balance(balance: &MarginBalance) -> Result<Vec<u8>, Box<dyn Error>> {
1534 let mut message = capnp::message::Builder::new_default();
1535 let builder = message.init_root::<types_capnp::margin_balance::Builder>();
1536 balance.to_capnp(builder);
1537
1538 let mut bytes = Vec::new();
1539 capnp::serialize::write_message(&mut bytes, &message)?;
1540 Ok(bytes)
1541}
1542
1543pub fn deserialize_margin_balance(bytes: &[u8]) -> Result<MarginBalance, Box<dyn Error>> {
1549 let reader =
1550 capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1551 let root = reader.get_root::<types_capnp::margin_balance::Reader>()?;
1552 MarginBalance::from_capnp(root)
1553}
1554
1555impl<'a> ToCapnp<'a> for QuoteTick {
1556 type Builder = market_capnp::quote_tick::Builder<'a>;
1557
1558 fn to_capnp(&self, mut builder: Self::Builder) {
1559 let instrument_id_builder = builder.reborrow().init_instrument_id();
1560 self.instrument_id.to_capnp(instrument_id_builder);
1561
1562 let bid_price_builder = builder.reborrow().init_bid_price();
1563 self.bid_price.to_capnp(bid_price_builder);
1564
1565 let ask_price_builder = builder.reborrow().init_ask_price();
1566 self.ask_price.to_capnp(ask_price_builder);
1567
1568 let bid_size_builder = builder.reborrow().init_bid_size();
1569 self.bid_size.to_capnp(bid_size_builder);
1570
1571 let ask_size_builder = builder.reborrow().init_ask_size();
1572 self.ask_size.to_capnp(ask_size_builder);
1573
1574 let mut ts_event_builder = builder.reborrow().init_ts_event();
1575 ts_event_builder.set_value(*self.ts_event);
1576
1577 let mut ts_init_builder = builder.reborrow().init_ts_init();
1578 ts_init_builder.set_value(*self.ts_init);
1579 }
1580}
1581
1582impl<'a> FromCapnp<'a> for QuoteTick {
1583 type Reader = market_capnp::quote_tick::Reader<'a>;
1584
1585 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1586 let instrument_id_reader = reader.get_instrument_id()?;
1587 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1588
1589 let bid_price_reader = reader.get_bid_price()?;
1590 let bid_price = Price::from_capnp(bid_price_reader)?;
1591
1592 let ask_price_reader = reader.get_ask_price()?;
1593 let ask_price = Price::from_capnp(ask_price_reader)?;
1594
1595 let bid_size_reader = reader.get_bid_size()?;
1596 let bid_size = Quantity::from_capnp(bid_size_reader)?;
1597
1598 let ask_size_reader = reader.get_ask_size()?;
1599 let ask_size = Quantity::from_capnp(ask_size_reader)?;
1600
1601 let ts_event_reader = reader.get_ts_event()?;
1602 let ts_event = ts_event_reader.get_value();
1603
1604 let ts_init_reader = reader.get_ts_init()?;
1605 let ts_init = ts_init_reader.get_value();
1606
1607 Ok(Self {
1608 instrument_id,
1609 bid_price,
1610 ask_price,
1611 bid_size,
1612 ask_size,
1613 ts_event: ts_event.into(),
1614 ts_init: ts_init.into(),
1615 })
1616 }
1617}
1618
1619impl<'a> ToCapnp<'a> for TradeTick {
1620 type Builder = market_capnp::trade_tick::Builder<'a>;
1621
1622 fn to_capnp(&self, mut builder: Self::Builder) {
1623 let instrument_id_builder = builder.reborrow().init_instrument_id();
1624 self.instrument_id.to_capnp(instrument_id_builder);
1625
1626 let price_builder = builder.reborrow().init_price();
1627 self.price.to_capnp(price_builder);
1628
1629 let size_builder = builder.reborrow().init_size();
1630 self.size.to_capnp(size_builder);
1631
1632 builder.set_aggressor_side(aggressor_side_to_capnp(self.aggressor_side));
1633
1634 let trade_id_builder = builder.reborrow().init_trade_id();
1635 self.trade_id.to_capnp(trade_id_builder);
1636
1637 let mut ts_event_builder = builder.reborrow().init_ts_event();
1638 ts_event_builder.set_value(*self.ts_event);
1639
1640 let mut ts_init_builder = builder.reborrow().init_ts_init();
1641 ts_init_builder.set_value(*self.ts_init);
1642 }
1643}
1644
1645impl<'a> FromCapnp<'a> for TradeTick {
1646 type Reader = market_capnp::trade_tick::Reader<'a>;
1647
1648 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1649 let instrument_id_reader = reader.get_instrument_id()?;
1650 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1651
1652 let price_reader = reader.get_price()?;
1653 let price = Price::from_capnp(price_reader)?;
1654
1655 let size_reader = reader.get_size()?;
1656 let size = Quantity::from_capnp(size_reader)?;
1657
1658 let aggressor_side = aggressor_side_from_capnp(reader.get_aggressor_side()?);
1659
1660 let trade_id_reader = reader.get_trade_id()?;
1661 let trade_id = TradeId::from_capnp(trade_id_reader)?;
1662
1663 let ts_event_reader = reader.get_ts_event()?;
1664 let ts_event = ts_event_reader.get_value();
1665
1666 let ts_init_reader = reader.get_ts_init()?;
1667 let ts_init = ts_init_reader.get_value();
1668
1669 Ok(Self {
1670 instrument_id,
1671 price,
1672 size,
1673 aggressor_side,
1674 trade_id,
1675 ts_event: ts_event.into(),
1676 ts_init: ts_init.into(),
1677 })
1678 }
1679}
1680
1681impl<'a> ToCapnp<'a> for MarkPriceUpdate {
1682 type Builder = market_capnp::mark_price_update::Builder<'a>;
1683
1684 fn to_capnp(&self, mut builder: Self::Builder) {
1685 let instrument_id_builder = builder.reborrow().init_instrument_id();
1686 self.instrument_id.to_capnp(instrument_id_builder);
1687
1688 let mark_price_builder = builder.reborrow().init_mark_price();
1689 self.value.to_capnp(mark_price_builder);
1690
1691 let mut ts_event_builder = builder.reborrow().init_ts_event();
1692 ts_event_builder.set_value(*self.ts_event);
1693
1694 let mut ts_init_builder = builder.reborrow().init_ts_init();
1695 ts_init_builder.set_value(*self.ts_init);
1696 }
1697}
1698
1699impl<'a> FromCapnp<'a> for MarkPriceUpdate {
1700 type Reader = market_capnp::mark_price_update::Reader<'a>;
1701
1702 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1703 let instrument_id_reader = reader.get_instrument_id()?;
1704 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1705
1706 let mark_price_reader = reader.get_mark_price()?;
1707 let value = Price::from_capnp(mark_price_reader)?;
1708
1709 let ts_event_reader = reader.get_ts_event()?;
1710 let ts_event = ts_event_reader.get_value();
1711
1712 let ts_init_reader = reader.get_ts_init()?;
1713 let ts_init = ts_init_reader.get_value();
1714
1715 Ok(Self {
1716 instrument_id,
1717 value,
1718 ts_event: ts_event.into(),
1719 ts_init: ts_init.into(),
1720 })
1721 }
1722}
1723
1724impl<'a> ToCapnp<'a> for IndexPriceUpdate {
1725 type Builder = market_capnp::index_price_update::Builder<'a>;
1726
1727 fn to_capnp(&self, mut builder: Self::Builder) {
1728 let instrument_id_builder = builder.reborrow().init_instrument_id();
1729 self.instrument_id.to_capnp(instrument_id_builder);
1730
1731 let index_price_builder = builder.reborrow().init_index_price();
1732 self.value.to_capnp(index_price_builder);
1733
1734 let mut ts_event_builder = builder.reborrow().init_ts_event();
1735 ts_event_builder.set_value(*self.ts_event);
1736
1737 let mut ts_init_builder = builder.reborrow().init_ts_init();
1738 ts_init_builder.set_value(*self.ts_init);
1739 }
1740}
1741
1742impl<'a> FromCapnp<'a> for IndexPriceUpdate {
1743 type Reader = market_capnp::index_price_update::Reader<'a>;
1744
1745 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1746 let instrument_id_reader = reader.get_instrument_id()?;
1747 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1748
1749 let index_price_reader = reader.get_index_price()?;
1750 let value = Price::from_capnp(index_price_reader)?;
1751
1752 let ts_event_reader = reader.get_ts_event()?;
1753 let ts_event = ts_event_reader.get_value();
1754
1755 let ts_init_reader = reader.get_ts_init()?;
1756 let ts_init = ts_init_reader.get_value();
1757
1758 Ok(Self {
1759 instrument_id,
1760 value,
1761 ts_event: ts_event.into(),
1762 ts_init: ts_init.into(),
1763 })
1764 }
1765}
1766
1767impl<'a> ToCapnp<'a> for FundingRateUpdate {
1768 type Builder = market_capnp::funding_rate_update::Builder<'a>;
1769
1770 fn to_capnp(&self, mut builder: Self::Builder) {
1771 let instrument_id_builder = builder.reborrow().init_instrument_id();
1772 self.instrument_id.to_capnp(instrument_id_builder);
1773
1774 let rate_builder = builder.reborrow().init_rate();
1775 self.rate.to_capnp(rate_builder);
1776
1777 if let Some(interval) = self.interval {
1778 builder.reborrow().set_interval(interval);
1779 builder.reborrow().set_has_interval(true);
1780 }
1781
1782 if let Some(next_funding_ns) = self.next_funding_ns {
1783 let mut next_funding_time_builder = builder.reborrow().init_next_funding_time();
1784 next_funding_time_builder.set_value(*next_funding_ns);
1785 }
1786
1787 let mut ts_event_builder = builder.reborrow().init_ts_event();
1788 ts_event_builder.set_value(*self.ts_event);
1789
1790 let mut ts_init_builder = builder.reborrow().init_ts_init();
1791 ts_init_builder.set_value(*self.ts_init);
1792 }
1793}
1794
1795impl<'a> FromCapnp<'a> for FundingRateUpdate {
1796 type Reader = market_capnp::funding_rate_update::Reader<'a>;
1797
1798 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1799 let instrument_id_reader = reader.get_instrument_id()?;
1800 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1801
1802 let rate_reader = reader.get_rate()?;
1803 let rate = Decimal::from_capnp(rate_reader)?;
1804
1805 let interval = if reader.get_has_interval() {
1806 Some(reader.get_interval())
1807 } else {
1808 None
1809 };
1810
1811 let next_funding_ns = if reader.has_next_funding_time() {
1812 let next_funding_time_reader = reader.get_next_funding_time()?;
1813 Some(next_funding_time_reader.get_value().into())
1814 } else {
1815 None
1816 };
1817
1818 let ts_event_reader = reader.get_ts_event()?;
1819 let ts_event = ts_event_reader.get_value();
1820
1821 let ts_init_reader = reader.get_ts_init()?;
1822 let ts_init = ts_init_reader.get_value();
1823
1824 Ok(Self {
1825 instrument_id,
1826 rate,
1827 interval,
1828 next_funding_ns,
1829 ts_event: ts_event.into(),
1830 ts_init: ts_init.into(),
1831 })
1832 }
1833}
1834
1835impl<'a> ToCapnp<'a> for OptionGreeks {
1836 type Builder = market_capnp::option_greeks::Builder<'a>;
1837
1838 fn to_capnp(&self, mut builder: Self::Builder) {
1839 let instrument_id_builder = builder.reborrow().init_instrument_id();
1840 self.instrument_id.to_capnp(instrument_id_builder);
1841
1842 builder.set_convention(greeks_convention_to_capnp(self.convention));
1843 builder.set_delta(self.greeks.delta);
1844 builder.set_gamma(self.greeks.gamma);
1845 builder.set_vega(self.greeks.vega);
1846 builder.set_theta(self.greeks.theta);
1847 builder.set_rho(self.greeks.rho);
1848
1849 if let Some(mark_iv) = self.mark_iv {
1850 builder.reborrow().set_mark_iv(mark_iv);
1851 builder.reborrow().set_has_mark_iv(true);
1852 }
1853
1854 if let Some(bid_iv) = self.bid_iv {
1855 builder.reborrow().set_bid_iv(bid_iv);
1856 builder.reborrow().set_has_bid_iv(true);
1857 }
1858
1859 if let Some(ask_iv) = self.ask_iv {
1860 builder.reborrow().set_ask_iv(ask_iv);
1861 builder.reborrow().set_has_ask_iv(true);
1862 }
1863
1864 if let Some(underlying_price) = self.underlying_price {
1865 builder.reborrow().set_underlying_price(underlying_price);
1866 builder.reborrow().set_has_underlying_price(true);
1867 }
1868
1869 if let Some(open_interest) = self.open_interest {
1870 builder.reborrow().set_open_interest(open_interest);
1871 builder.reborrow().set_has_open_interest(true);
1872 }
1873
1874 let mut ts_event_builder = builder.reborrow().init_ts_event();
1875 ts_event_builder.set_value(*self.ts_event);
1876
1877 let mut ts_init_builder = builder.reborrow().init_ts_init();
1878 ts_init_builder.set_value(*self.ts_init);
1879 }
1880}
1881
1882impl<'a> FromCapnp<'a> for OptionGreeks {
1883 type Reader = market_capnp::option_greeks::Reader<'a>;
1884
1885 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1886 let instrument_id_reader = reader.get_instrument_id()?;
1887 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1888 let convention = greeks_convention_from_capnp(reader.get_convention()?);
1889 let greeks = OptionGreekValues {
1890 delta: reader.get_delta(),
1891 gamma: reader.get_gamma(),
1892 vega: reader.get_vega(),
1893 theta: reader.get_theta(),
1894 rho: reader.get_rho(),
1895 };
1896 let mark_iv = reader.get_has_mark_iv().then_some(reader.get_mark_iv());
1897 let bid_iv = reader.get_has_bid_iv().then_some(reader.get_bid_iv());
1898 let ask_iv = reader.get_has_ask_iv().then_some(reader.get_ask_iv());
1899 let underlying_price = reader
1900 .get_has_underlying_price()
1901 .then_some(reader.get_underlying_price());
1902 let open_interest = reader
1903 .get_has_open_interest()
1904 .then_some(reader.get_open_interest());
1905
1906 let ts_event_reader = reader.get_ts_event()?;
1907 let ts_event = ts_event_reader.get_value();
1908
1909 let ts_init_reader = reader.get_ts_init()?;
1910 let ts_init = ts_init_reader.get_value();
1911
1912 Ok(Self {
1913 instrument_id,
1914 convention,
1915 greeks,
1916 mark_iv,
1917 bid_iv,
1918 ask_iv,
1919 underlying_price,
1920 open_interest,
1921 ts_event: ts_event.into(),
1922 ts_init: ts_init.into(),
1923 })
1924 }
1925}
1926
1927impl<'a> ToCapnp<'a> for InstrumentClose {
1928 type Builder = market_capnp::instrument_close::Builder<'a>;
1929
1930 fn to_capnp(&self, mut builder: Self::Builder) {
1931 let instrument_id_builder = builder.reborrow().init_instrument_id();
1932 self.instrument_id.to_capnp(instrument_id_builder);
1933
1934 let close_price_builder = builder.reborrow().init_close_price();
1935 self.close_price.to_capnp(close_price_builder);
1936
1937 builder.set_close_type(instrument_close_type_to_capnp(self.close_type));
1938
1939 let mut ts_event_builder = builder.reborrow().init_ts_event();
1940 ts_event_builder.set_value(*self.ts_event);
1941
1942 let mut ts_init_builder = builder.reborrow().init_ts_init();
1943 ts_init_builder.set_value(*self.ts_init);
1944 }
1945}
1946
1947impl<'a> FromCapnp<'a> for InstrumentClose {
1948 type Reader = market_capnp::instrument_close::Reader<'a>;
1949
1950 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1951 let instrument_id_reader = reader.get_instrument_id()?;
1952 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1953
1954 let close_price_reader = reader.get_close_price()?;
1955 let close_price = Price::from_capnp(close_price_reader)?;
1956
1957 let close_type = instrument_close_type_from_capnp(reader.get_close_type()?);
1958
1959 let ts_event_reader = reader.get_ts_event()?;
1960 let ts_event = ts_event_reader.get_value();
1961
1962 let ts_init_reader = reader.get_ts_init()?;
1963 let ts_init = ts_init_reader.get_value();
1964
1965 Ok(Self {
1966 instrument_id,
1967 close_price,
1968 close_type,
1969 ts_event: ts_event.into(),
1970 ts_init: ts_init.into(),
1971 })
1972 }
1973}
1974
1975impl<'a> ToCapnp<'a> for InstrumentStatus {
1976 type Builder = market_capnp::instrument_status::Builder<'a>;
1977
1978 fn to_capnp(&self, mut builder: Self::Builder) {
1979 let instrument_id_builder = builder.reborrow().init_instrument_id();
1980 self.instrument_id.to_capnp(instrument_id_builder);
1981
1982 builder.set_action(market_status_action_to_capnp(self.action));
1983
1984 if let Some(reason) = self.reason {
1985 builder.reborrow().set_reason(reason.as_str());
1986 }
1987
1988 if let Some(trading_event) = self.trading_event {
1989 builder.reborrow().set_trading_event(trading_event.as_str());
1990 }
1991
1992 builder.set_is_trading(optional_bool_to_capnp(self.is_trading));
1993 builder.set_is_quoting(optional_bool_to_capnp(self.is_quoting));
1994 builder.set_is_short_sell_restricted(optional_bool_to_capnp(self.is_short_sell_restricted));
1995
1996 let mut ts_event_builder = builder.reborrow().init_ts_event();
1997 ts_event_builder.set_value(*self.ts_event);
1998
1999 let mut ts_init_builder = builder.reborrow().init_ts_init();
2000 ts_init_builder.set_value(*self.ts_init);
2001 }
2002}
2003
2004impl<'a> FromCapnp<'a> for InstrumentStatus {
2005 type Reader = market_capnp::instrument_status::Reader<'a>;
2006
2007 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2008 let instrument_id_reader = reader.get_instrument_id()?;
2009 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2010
2011 let action = market_status_action_from_capnp(reader.get_action()?);
2012
2013 let reason = if reader.has_reason() {
2014 Some(Ustr::from(reader.get_reason()?.to_str()?))
2015 } else {
2016 None
2017 };
2018
2019 let trading_event = if reader.has_trading_event() {
2020 Some(Ustr::from(reader.get_trading_event()?.to_str()?))
2021 } else {
2022 None
2023 };
2024
2025 let is_trading = optional_bool_from_capnp(reader.get_is_trading()?);
2026 let is_quoting = optional_bool_from_capnp(reader.get_is_quoting()?);
2027 let is_short_sell_restricted =
2028 optional_bool_from_capnp(reader.get_is_short_sell_restricted()?);
2029
2030 let ts_event_reader = reader.get_ts_event()?;
2031 let ts_event = ts_event_reader.get_value();
2032
2033 let ts_init_reader = reader.get_ts_init()?;
2034 let ts_init = ts_init_reader.get_value();
2035
2036 Ok(Self {
2037 instrument_id,
2038 action,
2039 ts_event: ts_event.into(),
2040 ts_init: ts_init.into(),
2041 reason,
2042 trading_event,
2043 is_trading,
2044 is_quoting,
2045 is_short_sell_restricted,
2046 })
2047 }
2048}
2049
2050impl<'a> ToCapnp<'a> for BarSpecification {
2051 type Builder = market_capnp::bar_spec::Builder<'a>;
2052
2053 fn to_capnp(&self, mut builder: Self::Builder) {
2054 builder.set_step(self.step.get() as u64);
2055 builder.set_aggregation(bar_aggregation_to_capnp(self.aggregation));
2056 builder.set_price_type(price_type_to_capnp(self.price_type));
2057 }
2058}
2059
2060impl<'a> FromCapnp<'a> for BarSpecification {
2061 type Reader = market_capnp::bar_spec::Reader<'a>;
2062
2063 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2064 use std::num::NonZero;
2065
2066 let step = usize::try_from(reader.get_step())
2067 .map_err(|_| "BarSpecification step exceeds usize range")?;
2068 let step = NonZero::new(step).ok_or("BarSpecification step must be non-zero")?;
2069
2070 let aggregation = bar_aggregation_from_capnp(reader.get_aggregation()?);
2071 let price_type = price_type_from_capnp(reader.get_price_type()?);
2072
2073 Ok(Self {
2074 step,
2075 aggregation,
2076 price_type,
2077 })
2078 }
2079}
2080
2081impl<'a> ToCapnp<'a> for BarType {
2082 type Builder = market_capnp::bar_type::Builder<'a>;
2083
2084 fn to_capnp(&self, mut builder: Self::Builder) {
2087 let standard = self.standard();
2088 let instrument_id_builder = builder.reborrow().init_instrument_id();
2089 standard.instrument_id().to_capnp(instrument_id_builder);
2090
2091 let spec_builder = builder.reborrow().init_spec();
2092 standard.spec().to_capnp(spec_builder);
2093
2094 builder.set_aggregation_source(aggregation_source_to_capnp(standard.aggregation_source()));
2095 }
2096}
2097
2098impl<'a> FromCapnp<'a> for BarType {
2099 type Reader = market_capnp::bar_type::Reader<'a>;
2100
2101 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2102 let instrument_id_reader = reader.get_instrument_id()?;
2103 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2104
2105 let spec_reader = reader.get_spec()?;
2106 let spec = BarSpecification::from_capnp(spec_reader)?;
2107
2108 let aggregation_source = aggregation_source_from_capnp(reader.get_aggregation_source()?);
2109
2110 Ok(Self::new(instrument_id, spec, aggregation_source))
2111 }
2112}
2113
2114impl<'a> ToCapnp<'a> for Bar {
2115 type Builder = market_capnp::bar::Builder<'a>;
2116
2117 fn to_capnp(&self, mut builder: Self::Builder) {
2118 let bar_type_builder = builder.reborrow().init_bar_type();
2119 self.bar_type.to_capnp(bar_type_builder);
2120
2121 let open_builder = builder.reborrow().init_open();
2122 self.open.to_capnp(open_builder);
2123
2124 let high_builder = builder.reborrow().init_high();
2125 self.high.to_capnp(high_builder);
2126
2127 let low_builder = builder.reborrow().init_low();
2128 self.low.to_capnp(low_builder);
2129
2130 let close_builder = builder.reborrow().init_close();
2131 self.close.to_capnp(close_builder);
2132
2133 let volume_builder = builder.reborrow().init_volume();
2134 self.volume.to_capnp(volume_builder);
2135
2136 let mut ts_event_builder = builder.reborrow().init_ts_event();
2137 ts_event_builder.set_value(*self.ts_event);
2138
2139 let mut ts_init_builder = builder.reborrow().init_ts_init();
2140 ts_init_builder.set_value(*self.ts_init);
2141 }
2142}
2143
2144impl<'a> FromCapnp<'a> for Bar {
2145 type Reader = market_capnp::bar::Reader<'a>;
2146
2147 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2148 let bar_type_reader = reader.get_bar_type()?;
2149 let bar_type = BarType::from_capnp(bar_type_reader)?;
2150
2151 let open_reader = reader.get_open()?;
2152 let open = Price::from_capnp(open_reader)?;
2153
2154 let high_reader = reader.get_high()?;
2155 let high = Price::from_capnp(high_reader)?;
2156
2157 let low_reader = reader.get_low()?;
2158 let low = Price::from_capnp(low_reader)?;
2159
2160 let close_reader = reader.get_close()?;
2161 let close = Price::from_capnp(close_reader)?;
2162
2163 let volume_reader = reader.get_volume()?;
2164 let volume = Quantity::from_capnp(volume_reader)?;
2165
2166 let ts_event_reader = reader.get_ts_event()?;
2167 let ts_event = ts_event_reader.get_value();
2168
2169 let ts_init_reader = reader.get_ts_init()?;
2170 let ts_init = ts_init_reader.get_value();
2171
2172 Ok(Self {
2173 bar_type,
2174 open,
2175 high,
2176 low,
2177 close,
2178 volume,
2179 ts_event: ts_event.into(),
2180 ts_init: ts_init.into(),
2181 })
2182 }
2183}
2184
2185impl<'a> ToCapnp<'a> for BookOrder {
2186 type Builder = market_capnp::book_order::Builder<'a>;
2187
2188 fn to_capnp(&self, mut builder: Self::Builder) {
2189 let price_builder = builder.reborrow().init_price();
2190 self.price.to_capnp(price_builder);
2191
2192 let size_builder = builder.reborrow().init_size();
2193 self.size.to_capnp(size_builder);
2194
2195 builder.set_side(order_side_to_capnp(self.side));
2196 builder.set_order_id(self.order_id);
2197 }
2198}
2199
2200impl<'a> FromCapnp<'a> for BookOrder {
2201 type Reader = market_capnp::book_order::Reader<'a>;
2202
2203 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2204 let price_reader = reader.get_price()?;
2205 let price = Price::from_capnp(price_reader)?;
2206
2207 let size_reader = reader.get_size()?;
2208 let size = Quantity::from_capnp(size_reader)?;
2209
2210 let side = order_side_from_capnp(reader.get_side()?);
2211 let order_id = reader.get_order_id();
2212
2213 Ok(Self {
2214 side,
2215 price,
2216 size,
2217 order_id,
2218 })
2219 }
2220}
2221
2222impl<'a> ToCapnp<'a> for OrderBookDelta {
2223 type Builder = market_capnp::order_book_delta::Builder<'a>;
2224
2225 fn to_capnp(&self, mut builder: Self::Builder) {
2226 let instrument_id_builder = builder.reborrow().init_instrument_id();
2227 self.instrument_id.to_capnp(instrument_id_builder);
2228
2229 builder.set_action(book_action_to_capnp(self.action));
2230
2231 let order_builder = builder.reborrow().init_order();
2232 self.order.to_capnp(order_builder);
2233
2234 builder.set_flags(self.flags);
2235 builder.set_sequence(self.sequence);
2236
2237 let mut ts_event_builder = builder.reborrow().init_ts_event();
2238 ts_event_builder.set_value(*self.ts_event);
2239
2240 let mut ts_init_builder = builder.reborrow().init_ts_init();
2241 ts_init_builder.set_value(*self.ts_init);
2242 }
2243}
2244
2245impl<'a> FromCapnp<'a> for OrderBookDelta {
2246 type Reader = market_capnp::order_book_delta::Reader<'a>;
2247
2248 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2249 let instrument_id_reader = reader.get_instrument_id()?;
2250 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2251
2252 let action = book_action_from_capnp(reader.get_action()?);
2253
2254 let order_reader = reader.get_order()?;
2255 let order = BookOrder::from_capnp(order_reader)?;
2256
2257 let flags = reader.get_flags();
2258 let sequence = reader.get_sequence();
2259
2260 let ts_event_reader = reader.get_ts_event()?;
2261 let ts_event = ts_event_reader.get_value();
2262
2263 let ts_init_reader = reader.get_ts_init()?;
2264 let ts_init = ts_init_reader.get_value();
2265
2266 Ok(Self {
2267 instrument_id,
2268 action,
2269 order,
2270 flags,
2271 sequence,
2272 ts_event: ts_event.into(),
2273 ts_init: ts_init.into(),
2274 })
2275 }
2276}
2277
2278impl<'a> ToCapnp<'a> for OrderBookDeltas {
2279 type Builder = market_capnp::order_book_deltas::Builder<'a>;
2280
2281 fn to_capnp(&self, mut builder: Self::Builder) {
2282 let instrument_id_builder = builder.reborrow().init_instrument_id();
2283 self.instrument_id.to_capnp(instrument_id_builder);
2284
2285 let mut deltas_builder = builder.reborrow().init_deltas(self.deltas.len() as u32);
2286 for (i, delta) in self.deltas.iter().enumerate() {
2287 let entry_builder = deltas_builder.reborrow().get(i as u32);
2288 delta.to_capnp(entry_builder);
2289 }
2290
2291 builder.set_flags(self.flags);
2292 builder.set_sequence(self.sequence);
2293
2294 let mut ts_event_builder = builder.reborrow().init_ts_event();
2295 ts_event_builder.set_value(*self.ts_event);
2296
2297 let mut ts_init_builder = builder.reborrow().init_ts_init();
2298 ts_init_builder.set_value(*self.ts_init);
2299 }
2300}
2301
2302impl<'a> FromCapnp<'a> for OrderBookDeltas {
2303 type Reader = market_capnp::order_book_deltas::Reader<'a>;
2304
2305 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2306 let instrument_id_reader = reader.get_instrument_id()?;
2307 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2308
2309 let deltas_reader = reader.get_deltas()?;
2310 let mut deltas = Vec::with_capacity(deltas_reader.len() as usize);
2311 for delta_reader in deltas_reader {
2312 let delta = OrderBookDelta::from_capnp(delta_reader)?;
2313 deltas.push(delta);
2314 }
2315
2316 let flags = reader.get_flags();
2317 let sequence = reader.get_sequence();
2318
2319 let ts_event_reader = reader.get_ts_event()?;
2320 let ts_event = ts_event_reader.get_value();
2321
2322 let ts_init_reader = reader.get_ts_init()?;
2323 let ts_init = ts_init_reader.get_value();
2324
2325 Ok(Self {
2326 instrument_id,
2327 deltas,
2328 flags,
2329 sequence,
2330 ts_event: ts_event.into(),
2331 ts_init: ts_init.into(),
2332 })
2333 }
2334}
2335
2336impl<'a> ToCapnp<'a> for OrderBookDepth {
2337 type Builder = market_capnp::order_book_depth::Builder<'a>;
2338
2339 fn to_capnp(&self, mut builder: Self::Builder) {
2340 let instrument_id_builder = builder.reborrow().init_instrument_id();
2341 self.instrument_id.to_capnp(instrument_id_builder);
2342
2343 let mut bids_builder = builder.reborrow().init_bids(self.bids.len() as u32);
2345 for (i, bid) in self.bids.iter().enumerate() {
2346 let mut level_builder = bids_builder.reborrow().get(i as u32);
2347 let price_builder = level_builder.reborrow().init_price();
2348 bid.price.to_capnp(price_builder);
2349 let size_builder = level_builder.init_size();
2350 bid.size.to_capnp(size_builder);
2351 }
2352
2353 let mut asks_builder = builder.reborrow().init_asks(self.asks.len() as u32);
2355 for (i, ask) in self.asks.iter().enumerate() {
2356 let mut level_builder = asks_builder.reborrow().get(i as u32);
2357 let price_builder = level_builder.reborrow().init_price();
2358 ask.price.to_capnp(price_builder);
2359 let size_builder = level_builder.init_size();
2360 ask.size.to_capnp(size_builder);
2361 }
2362
2363 let mut bid_counts_builder = builder
2365 .reborrow()
2366 .init_bid_counts(self.bid_counts.len() as u32);
2367 for (i, &count) in self.bid_counts.iter().enumerate() {
2368 bid_counts_builder.set(i as u32, count);
2369 }
2370
2371 let mut ask_counts_builder = builder
2372 .reborrow()
2373 .init_ask_counts(self.ask_counts.len() as u32);
2374 for (i, &count) in self.ask_counts.iter().enumerate() {
2375 ask_counts_builder.set(i as u32, count);
2376 }
2377
2378 builder.set_flags(self.flags);
2379 builder.set_sequence(self.sequence);
2380
2381 let mut ts_event_builder = builder.reborrow().init_ts_event();
2382 ts_event_builder.set_value(*self.ts_event);
2383
2384 let mut ts_init_builder = builder.reborrow().init_ts_init();
2385 ts_init_builder.set_value(*self.ts_init);
2386 }
2387}
2388
2389impl<'a> FromCapnp<'a> for OrderBookDepth {
2390 type Reader = market_capnp::order_book_depth::Reader<'a>;
2391
2392 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2393 let instrument_id_reader = reader.get_instrument_id()?;
2394 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2395
2396 let bids_reader = reader.get_bids()?;
2398 let mut bids = Vec::with_capacity(bids_reader.len() as usize);
2399
2400 for level_reader in bids_reader {
2401 let price_reader = level_reader.get_price()?;
2402 let price = Price::from_capnp(price_reader)?;
2403
2404 let size_reader = level_reader.get_size()?;
2405 let size = Quantity::from_capnp(size_reader)?;
2406
2407 bids.push(BookOrder::new(OrderSide::Buy, price, size, 0));
2408 }
2409
2410 let asks_reader = reader.get_asks()?;
2411 let mut asks = Vec::with_capacity(asks_reader.len() as usize);
2412
2413 for level_reader in asks_reader {
2414 let price_reader = level_reader.get_price()?;
2415 let price = Price::from_capnp(price_reader)?;
2416
2417 let size_reader = level_reader.get_size()?;
2418 let size = Quantity::from_capnp(size_reader)?;
2419
2420 asks.push(BookOrder::new(OrderSide::Sell, price, size, 0));
2421 }
2422
2423 let bid_counts = reader.get_bid_counts()?.iter().collect::<Vec<_>>();
2424 let ask_counts = reader.get_ask_counts()?.iter().collect::<Vec<_>>();
2425
2426 let flags = reader.get_flags();
2427 let sequence = reader.get_sequence();
2428
2429 let ts_event_reader = reader.get_ts_event()?;
2430 let ts_event = ts_event_reader.get_value();
2431
2432 let ts_init_reader = reader.get_ts_init()?;
2433 let ts_init = ts_init_reader.get_value();
2434
2435 Ok(Self::new_checked(
2436 instrument_id,
2437 bids,
2438 asks,
2439 bid_counts,
2440 ask_counts,
2441 flags,
2442 sequence,
2443 ts_event.into(),
2444 ts_init.into(),
2445 )?)
2446 }
2447}
2448
2449impl<'a> ToCapnp<'a> for OrderDenied {
2450 type Builder = order_capnp::order_denied::Builder<'a>;
2451
2452 fn to_capnp(&self, mut builder: Self::Builder) {
2453 let trader_id_builder = builder.reborrow().init_trader_id();
2454 self.trader_id.to_capnp(trader_id_builder);
2455
2456 let strategy_id_builder = builder.reborrow().init_strategy_id();
2457 self.strategy_id.to_capnp(strategy_id_builder);
2458
2459 let instrument_id_builder = builder.reborrow().init_instrument_id();
2460 self.instrument_id.to_capnp(instrument_id_builder);
2461
2462 let client_order_id_builder = builder.reborrow().init_client_order_id();
2463 self.client_order_id.to_capnp(client_order_id_builder);
2464
2465 builder.set_reason(self.reason.as_str());
2466
2467 let event_id_builder = builder.reborrow().init_event_id();
2468 self.event_id.to_capnp(event_id_builder);
2469
2470 let mut ts_init_builder = builder.reborrow().init_ts_init();
2471 ts_init_builder.set_value(*self.ts_init);
2472 }
2473}
2474
2475impl<'a> FromCapnp<'a> for OrderDenied {
2476 type Reader = order_capnp::order_denied::Reader<'a>;
2477
2478 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2479 let trader_id_reader = reader.get_trader_id()?;
2480 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2481
2482 let strategy_id_reader = reader.get_strategy_id()?;
2483 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2484
2485 let instrument_id_reader = reader.get_instrument_id()?;
2486 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2487
2488 let client_order_id_reader = reader.get_client_order_id()?;
2489 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2490
2491 let reason = Ustr::from(reader.get_reason()?.to_str()?);
2492
2493 let event_id_reader = reader.get_event_id()?;
2494 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2495
2496 let ts_init_reader = reader.get_ts_init()?;
2497 let ts_init = ts_init_reader.get_value();
2498
2499 Ok(Self {
2500 trader_id,
2501 strategy_id,
2502 instrument_id,
2503 client_order_id,
2504 reason,
2505 event_id,
2506 ts_event: ts_init.into(), ts_init: ts_init.into(),
2508 causation_id: None,
2509 })
2510 }
2511}
2512
2513impl<'a> ToCapnp<'a> for OrderEmulated {
2514 type Builder = order_capnp::order_emulated::Builder<'a>;
2515
2516 fn to_capnp(&self, mut builder: Self::Builder) {
2517 let trader_id_builder = builder.reborrow().init_trader_id();
2518 self.trader_id.to_capnp(trader_id_builder);
2519
2520 let strategy_id_builder = builder.reborrow().init_strategy_id();
2521 self.strategy_id.to_capnp(strategy_id_builder);
2522
2523 let instrument_id_builder = builder.reborrow().init_instrument_id();
2524 self.instrument_id.to_capnp(instrument_id_builder);
2525
2526 let client_order_id_builder = builder.reborrow().init_client_order_id();
2527 self.client_order_id.to_capnp(client_order_id_builder);
2528
2529 let event_id_builder = builder.reborrow().init_event_id();
2530 self.event_id.to_capnp(event_id_builder);
2531
2532 let mut ts_init_builder = builder.reborrow().init_ts_init();
2533 ts_init_builder.set_value(*self.ts_init);
2534 }
2535}
2536
2537impl<'a> FromCapnp<'a> for OrderEmulated {
2538 type Reader = order_capnp::order_emulated::Reader<'a>;
2539
2540 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2541 let trader_id_reader = reader.get_trader_id()?;
2542 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2543
2544 let strategy_id_reader = reader.get_strategy_id()?;
2545 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2546
2547 let instrument_id_reader = reader.get_instrument_id()?;
2548 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2549
2550 let client_order_id_reader = reader.get_client_order_id()?;
2551 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2552
2553 let event_id_reader = reader.get_event_id()?;
2554 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2555
2556 let ts_init_reader = reader.get_ts_init()?;
2557 let ts_init = ts_init_reader.get_value();
2558
2559 Ok(Self {
2560 trader_id,
2561 strategy_id,
2562 instrument_id,
2563 client_order_id,
2564 event_id,
2565 ts_event: ts_init.into(), ts_init: ts_init.into(),
2567 causation_id: None,
2568 })
2569 }
2570}
2571
2572impl<'a> ToCapnp<'a> for OrderReleased {
2573 type Builder = order_capnp::order_released::Builder<'a>;
2574
2575 fn to_capnp(&self, mut builder: Self::Builder) {
2576 let trader_id_builder = builder.reborrow().init_trader_id();
2577 self.trader_id.to_capnp(trader_id_builder);
2578
2579 let strategy_id_builder = builder.reborrow().init_strategy_id();
2580 self.strategy_id.to_capnp(strategy_id_builder);
2581
2582 let instrument_id_builder = builder.reborrow().init_instrument_id();
2583 self.instrument_id.to_capnp(instrument_id_builder);
2584
2585 let client_order_id_builder = builder.reborrow().init_client_order_id();
2586 self.client_order_id.to_capnp(client_order_id_builder);
2587
2588 let released_price_builder = builder.reborrow().init_released_price();
2589 self.released_price.to_capnp(released_price_builder);
2590
2591 let event_id_builder = builder.reborrow().init_event_id();
2592 self.event_id.to_capnp(event_id_builder);
2593
2594 let mut ts_init_builder = builder.reborrow().init_ts_init();
2595 ts_init_builder.set_value(*self.ts_init);
2596 }
2597}
2598
2599impl<'a> FromCapnp<'a> for OrderReleased {
2600 type Reader = order_capnp::order_released::Reader<'a>;
2601
2602 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2603 let trader_id_reader = reader.get_trader_id()?;
2604 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2605
2606 let strategy_id_reader = reader.get_strategy_id()?;
2607 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2608
2609 let instrument_id_reader = reader.get_instrument_id()?;
2610 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2611
2612 let client_order_id_reader = reader.get_client_order_id()?;
2613 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2614
2615 let released_price_reader = reader.get_released_price()?;
2616 let released_price = Price::from_capnp(released_price_reader)?;
2617
2618 let event_id_reader = reader.get_event_id()?;
2619 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2620
2621 let ts_init_reader = reader.get_ts_init()?;
2622 let ts_init = ts_init_reader.get_value();
2623
2624 Ok(Self {
2625 trader_id,
2626 strategy_id,
2627 instrument_id,
2628 client_order_id,
2629 released_price,
2630 event_id,
2631 ts_event: ts_init.into(), ts_init: ts_init.into(),
2633 causation_id: None,
2634 })
2635 }
2636}
2637
2638impl<'a> ToCapnp<'a> for OrderSubmitted {
2640 type Builder = order_capnp::order_submitted::Builder<'a>;
2641
2642 fn to_capnp(&self, mut builder: Self::Builder) {
2643 let trader_id_builder = builder.reborrow().init_trader_id();
2644 self.trader_id.to_capnp(trader_id_builder);
2645
2646 let strategy_id_builder = builder.reborrow().init_strategy_id();
2647 self.strategy_id.to_capnp(strategy_id_builder);
2648
2649 let instrument_id_builder = builder.reborrow().init_instrument_id();
2650 self.instrument_id.to_capnp(instrument_id_builder);
2651
2652 let client_order_id_builder = builder.reborrow().init_client_order_id();
2653 self.client_order_id.to_capnp(client_order_id_builder);
2654
2655 self.account_id
2656 .write_capnp(|| builder.reborrow().init_account_id());
2657
2658 let event_id_builder = builder.reborrow().init_event_id();
2659 self.event_id.to_capnp(event_id_builder);
2660
2661 let mut ts_event_builder = builder.reborrow().init_ts_event();
2662 ts_event_builder.set_value(*self.ts_event);
2663
2664 let mut ts_init_builder = builder.reborrow().init_ts_init();
2665 ts_init_builder.set_value(*self.ts_init);
2666 }
2667}
2668
2669impl<'a> FromCapnp<'a> for OrderSubmitted {
2670 type Reader = order_capnp::order_submitted::Reader<'a>;
2671
2672 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2673 let trader_id_reader = reader.get_trader_id()?;
2674 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2675
2676 let strategy_id_reader = reader.get_strategy_id()?;
2677 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2678
2679 let instrument_id_reader = reader.get_instrument_id()?;
2680 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2681
2682 let client_order_id_reader = reader.get_client_order_id()?;
2683 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2684
2685 let account_id_reader = reader.get_account_id()?;
2686 let account_id = AccountId::from_capnp(account_id_reader)?;
2687
2688 let event_id_reader = reader.get_event_id()?;
2689 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2690
2691 let ts_event_reader = reader.get_ts_event()?;
2692 let ts_event = ts_event_reader.get_value();
2693
2694 let ts_init_reader = reader.get_ts_init()?;
2695 let ts_init = ts_init_reader.get_value();
2696
2697 Ok(Self {
2698 trader_id,
2699 strategy_id,
2700 instrument_id,
2701 client_order_id,
2702 account_id,
2703 event_id,
2704 ts_event: ts_event.into(),
2705 ts_init: ts_init.into(),
2706 causation_id: None,
2707 })
2708 }
2709}
2710
2711impl<'a> ToCapnp<'a> for OrderAccepted {
2713 type Builder = order_capnp::order_accepted::Builder<'a>;
2714
2715 fn to_capnp(&self, mut builder: Self::Builder) {
2716 let trader_id_builder = builder.reborrow().init_trader_id();
2717 self.trader_id.to_capnp(trader_id_builder);
2718
2719 let strategy_id_builder = builder.reborrow().init_strategy_id();
2720 self.strategy_id.to_capnp(strategy_id_builder);
2721
2722 let instrument_id_builder = builder.reborrow().init_instrument_id();
2723 self.instrument_id.to_capnp(instrument_id_builder);
2724
2725 let client_order_id_builder = builder.reborrow().init_client_order_id();
2726 self.client_order_id.to_capnp(client_order_id_builder);
2727
2728 self.venue_order_id
2729 .write_capnp(|| builder.reborrow().init_venue_order_id());
2730 self.account_id
2731 .write_capnp(|| builder.reborrow().init_account_id());
2732
2733 let event_id_builder = builder.reborrow().init_event_id();
2734 self.event_id.to_capnp(event_id_builder);
2735
2736 let mut ts_event_builder = builder.reborrow().init_ts_event();
2737 ts_event_builder.set_value(*self.ts_event);
2738
2739 let mut ts_init_builder = builder.reborrow().init_ts_init();
2740 ts_init_builder.set_value(*self.ts_init);
2741
2742 builder.set_reconciliation(self.reconciliation);
2743 }
2744}
2745
2746impl<'a> FromCapnp<'a> for OrderAccepted {
2747 type Reader = order_capnp::order_accepted::Reader<'a>;
2748
2749 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2750 let trader_id_reader = reader.get_trader_id()?;
2751 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2752
2753 let strategy_id_reader = reader.get_strategy_id()?;
2754 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2755
2756 let instrument_id_reader = reader.get_instrument_id()?;
2757 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2758
2759 let client_order_id_reader = reader.get_client_order_id()?;
2760 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2761
2762 let venue_order_id_reader = reader.get_venue_order_id()?;
2763 let venue_order_id = VenueOrderId::from_capnp(venue_order_id_reader)?;
2764
2765 let account_id_reader = reader.get_account_id()?;
2766 let account_id = AccountId::from_capnp(account_id_reader)?;
2767
2768 let event_id_reader = reader.get_event_id()?;
2769 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2770
2771 let ts_event_reader = reader.get_ts_event()?;
2772 let ts_event = ts_event_reader.get_value();
2773
2774 let ts_init_reader = reader.get_ts_init()?;
2775 let ts_init = ts_init_reader.get_value();
2776
2777 let reconciliation = reader.get_reconciliation();
2778
2779 Ok(Self {
2780 trader_id,
2781 strategy_id,
2782 instrument_id,
2783 client_order_id,
2784 venue_order_id,
2785 account_id,
2786 event_id,
2787 ts_event: ts_event.into(),
2788 ts_init: ts_init.into(),
2789 reconciliation,
2790 causation_id: None,
2791 })
2792 }
2793}
2794
2795impl<'a> ToCapnp<'a> for OrderRejected {
2797 type Builder = order_capnp::order_rejected::Builder<'a>;
2798
2799 fn to_capnp(&self, mut builder: Self::Builder) {
2800 let trader_id_builder = builder.reborrow().init_trader_id();
2801 self.trader_id.to_capnp(trader_id_builder);
2802
2803 let strategy_id_builder = builder.reborrow().init_strategy_id();
2804 self.strategy_id.to_capnp(strategy_id_builder);
2805
2806 let instrument_id_builder = builder.reborrow().init_instrument_id();
2807 self.instrument_id.to_capnp(instrument_id_builder);
2808
2809 let client_order_id_builder = builder.reborrow().init_client_order_id();
2810 self.client_order_id.to_capnp(client_order_id_builder);
2811
2812 self.account_id
2813 .write_capnp(|| builder.reborrow().init_account_id());
2814
2815 builder.set_reason(self.reason.as_str());
2816
2817 let event_id_builder = builder.reborrow().init_event_id();
2818 self.event_id.to_capnp(event_id_builder);
2819
2820 let mut ts_event_builder = builder.reborrow().init_ts_event();
2821 ts_event_builder.set_value(*self.ts_event);
2822
2823 let mut ts_init_builder = builder.reborrow().init_ts_init();
2824 ts_init_builder.set_value(*self.ts_init);
2825
2826 builder.set_reconciliation(self.reconciliation);
2827 builder.set_due_post_only(self.due_post_only);
2828 }
2829}
2830
2831impl<'a> FromCapnp<'a> for OrderRejected {
2832 type Reader = order_capnp::order_rejected::Reader<'a>;
2833
2834 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2835 let trader_id_reader = reader.get_trader_id()?;
2836 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2837
2838 let strategy_id_reader = reader.get_strategy_id()?;
2839 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2840
2841 let instrument_id_reader = reader.get_instrument_id()?;
2842 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2843
2844 let client_order_id_reader = reader.get_client_order_id()?;
2845 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2846
2847 let account_id_reader = reader.get_account_id()?;
2848 let account_id = AccountId::from_capnp(account_id_reader)?;
2849
2850 let reason = Ustr::from(reader.get_reason()?.to_str()?);
2851
2852 let event_id_reader = reader.get_event_id()?;
2853 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2854
2855 let ts_event_reader = reader.get_ts_event()?;
2856 let ts_event = ts_event_reader.get_value();
2857
2858 let ts_init_reader = reader.get_ts_init()?;
2859 let ts_init = ts_init_reader.get_value();
2860
2861 let reconciliation = reader.get_reconciliation();
2862 let due_post_only = reader.get_due_post_only();
2863
2864 Ok(Self {
2865 trader_id,
2866 strategy_id,
2867 instrument_id,
2868 client_order_id,
2869 account_id,
2870 reason,
2871 event_id,
2872 ts_event: ts_event.into(),
2873 ts_init: ts_init.into(),
2874 reconciliation,
2875 due_post_only,
2876 causation_id: None,
2877 })
2878 }
2879}
2880
2881impl<'a> ToCapnp<'a> for OrderCanceled {
2883 type Builder = order_capnp::order_canceled::Builder<'a>;
2884
2885 fn to_capnp(&self, mut builder: Self::Builder) {
2886 let trader_id_builder = builder.reborrow().init_trader_id();
2887 self.trader_id.to_capnp(trader_id_builder);
2888
2889 let strategy_id_builder = builder.reborrow().init_strategy_id();
2890 self.strategy_id.to_capnp(strategy_id_builder);
2891
2892 let instrument_id_builder = builder.reborrow().init_instrument_id();
2893 self.instrument_id.to_capnp(instrument_id_builder);
2894
2895 let client_order_id_builder = builder.reborrow().init_client_order_id();
2896 self.client_order_id.to_capnp(client_order_id_builder);
2897
2898 self.venue_order_id
2899 .write_capnp(|| builder.reborrow().init_venue_order_id());
2900
2901 self.account_id
2902 .write_capnp(|| builder.reborrow().init_account_id());
2903
2904 if let Some(reason) = self.reason {
2905 builder.reborrow().set_reason(reason.as_str());
2906 }
2907
2908 let event_id_builder = builder.reborrow().init_event_id();
2909 self.event_id.to_capnp(event_id_builder);
2910
2911 let mut ts_event_builder = builder.reborrow().init_ts_event();
2912 ts_event_builder.set_value(*self.ts_event);
2913
2914 let mut ts_init_builder = builder.reborrow().init_ts_init();
2915 ts_init_builder.set_value(*self.ts_init);
2916
2917 builder.set_reconciliation(self.reconciliation);
2918 }
2919}
2920
2921impl<'a> FromCapnp<'a> for OrderCanceled {
2922 type Reader = order_capnp::order_canceled::Reader<'a>;
2923
2924 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2925 let trader_id_reader = reader.get_trader_id()?;
2926 let trader_id = TraderId::from_capnp(trader_id_reader)?;
2927
2928 let strategy_id_reader = reader.get_strategy_id()?;
2929 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2930
2931 let instrument_id_reader = reader.get_instrument_id()?;
2932 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2933
2934 let client_order_id_reader = reader.get_client_order_id()?;
2935 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2936
2937 let venue_order_id = read_optional_from_capnp(
2938 || reader.has_venue_order_id(),
2939 || reader.get_venue_order_id(),
2940 )?;
2941
2942 let account_id =
2943 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
2944
2945 let reason = if reader.has_reason() {
2946 Some(Ustr::from(reader.get_reason()?.to_str()?))
2947 } else {
2948 None
2949 };
2950
2951 let event_id_reader = reader.get_event_id()?;
2952 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2953
2954 let ts_event_reader = reader.get_ts_event()?;
2955 let ts_event = ts_event_reader.get_value();
2956
2957 let ts_init_reader = reader.get_ts_init()?;
2958 let ts_init = ts_init_reader.get_value();
2959
2960 let reconciliation = reader.get_reconciliation();
2961
2962 Ok(Self {
2963 trader_id,
2964 strategy_id,
2965 instrument_id,
2966 client_order_id,
2967 venue_order_id,
2968 account_id,
2969 event_id,
2970 ts_event: ts_event.into(),
2971 ts_init: ts_init.into(),
2972 reconciliation,
2973 reason,
2974 causation_id: None,
2975 })
2976 }
2977}
2978
2979impl<'a> ToCapnp<'a> for OrderExpired {
2981 type Builder = order_capnp::order_expired::Builder<'a>;
2982
2983 fn to_capnp(&self, mut builder: Self::Builder) {
2984 let trader_id_builder = builder.reborrow().init_trader_id();
2985 self.trader_id.to_capnp(trader_id_builder);
2986
2987 let strategy_id_builder = builder.reborrow().init_strategy_id();
2988 self.strategy_id.to_capnp(strategy_id_builder);
2989
2990 let instrument_id_builder = builder.reborrow().init_instrument_id();
2991 self.instrument_id.to_capnp(instrument_id_builder);
2992
2993 let client_order_id_builder = builder.reborrow().init_client_order_id();
2994 self.client_order_id.to_capnp(client_order_id_builder);
2995
2996 self.venue_order_id
2997 .write_capnp(|| builder.reborrow().init_venue_order_id());
2998
2999 self.account_id
3000 .write_capnp(|| builder.reborrow().init_account_id());
3001
3002 let event_id_builder = builder.reborrow().init_event_id();
3003 self.event_id.to_capnp(event_id_builder);
3004
3005 let mut ts_event_builder = builder.reborrow().init_ts_event();
3006 ts_event_builder.set_value(*self.ts_event);
3007
3008 let mut ts_init_builder = builder.reborrow().init_ts_init();
3009 ts_init_builder.set_value(*self.ts_init);
3010
3011 builder.set_reconciliation(self.reconciliation);
3012 }
3013}
3014
3015impl<'a> FromCapnp<'a> for OrderExpired {
3016 type Reader = order_capnp::order_expired::Reader<'a>;
3017
3018 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3019 let trader_id_reader = reader.get_trader_id()?;
3020 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3021
3022 let strategy_id_reader = reader.get_strategy_id()?;
3023 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3024
3025 let instrument_id_reader = reader.get_instrument_id()?;
3026 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3027
3028 let client_order_id_reader = reader.get_client_order_id()?;
3029 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3030
3031 let venue_order_id = read_optional_from_capnp(
3032 || reader.has_venue_order_id(),
3033 || reader.get_venue_order_id(),
3034 )?;
3035
3036 let account_id =
3037 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3038
3039 let event_id_reader = reader.get_event_id()?;
3040 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3041
3042 let ts_event_reader = reader.get_ts_event()?;
3043 let ts_event = ts_event_reader.get_value();
3044
3045 let ts_init_reader = reader.get_ts_init()?;
3046 let ts_init = ts_init_reader.get_value();
3047
3048 let reconciliation = reader.get_reconciliation();
3049
3050 Ok(Self {
3051 trader_id,
3052 strategy_id,
3053 instrument_id,
3054 client_order_id,
3055 venue_order_id,
3056 account_id,
3057 event_id,
3058 ts_event: ts_event.into(),
3059 ts_init: ts_init.into(),
3060 reconciliation,
3061 causation_id: None,
3062 })
3063 }
3064}
3065
3066impl<'a> ToCapnp<'a> for OrderTriggered {
3068 type Builder = order_capnp::order_triggered::Builder<'a>;
3069
3070 fn to_capnp(&self, mut builder: Self::Builder) {
3071 let trader_id_builder = builder.reborrow().init_trader_id();
3072 self.trader_id.to_capnp(trader_id_builder);
3073
3074 let strategy_id_builder = builder.reborrow().init_strategy_id();
3075 self.strategy_id.to_capnp(strategy_id_builder);
3076
3077 let instrument_id_builder = builder.reborrow().init_instrument_id();
3078 self.instrument_id.to_capnp(instrument_id_builder);
3079
3080 let client_order_id_builder = builder.reborrow().init_client_order_id();
3081 self.client_order_id.to_capnp(client_order_id_builder);
3082
3083 self.venue_order_id
3084 .write_capnp(|| builder.reborrow().init_venue_order_id());
3085
3086 self.account_id
3087 .write_capnp(|| builder.reborrow().init_account_id());
3088
3089 let event_id_builder = builder.reborrow().init_event_id();
3090 self.event_id.to_capnp(event_id_builder);
3091
3092 let mut ts_event_builder = builder.reborrow().init_ts_event();
3093 ts_event_builder.set_value(*self.ts_event);
3094
3095 let mut ts_init_builder = builder.reborrow().init_ts_init();
3096 ts_init_builder.set_value(*self.ts_init);
3097
3098 builder.set_reconciliation(self.reconciliation);
3099 }
3100}
3101
3102impl<'a> FromCapnp<'a> for OrderTriggered {
3103 type Reader = order_capnp::order_triggered::Reader<'a>;
3104
3105 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3106 let trader_id_reader = reader.get_trader_id()?;
3107 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3108
3109 let strategy_id_reader = reader.get_strategy_id()?;
3110 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3111
3112 let instrument_id_reader = reader.get_instrument_id()?;
3113 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3114
3115 let client_order_id_reader = reader.get_client_order_id()?;
3116 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3117
3118 let venue_order_id = read_optional_from_capnp(
3119 || reader.has_venue_order_id(),
3120 || reader.get_venue_order_id(),
3121 )?;
3122
3123 let account_id =
3124 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3125
3126 let event_id_reader = reader.get_event_id()?;
3127 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3128
3129 let ts_event_reader = reader.get_ts_event()?;
3130 let ts_event = ts_event_reader.get_value();
3131
3132 let ts_init_reader = reader.get_ts_init()?;
3133 let ts_init = ts_init_reader.get_value();
3134
3135 let reconciliation = reader.get_reconciliation();
3136
3137 Ok(Self {
3138 trader_id,
3139 strategy_id,
3140 instrument_id,
3141 client_order_id,
3142 venue_order_id,
3143 account_id,
3144 event_id,
3145 ts_event: ts_event.into(),
3146 ts_init: ts_init.into(),
3147 reconciliation,
3148 causation_id: None,
3149 })
3150 }
3151}
3152
3153impl<'a> ToCapnp<'a> for OrderPendingUpdate {
3155 type Builder = order_capnp::order_pending_update::Builder<'a>;
3156
3157 fn to_capnp(&self, mut builder: Self::Builder) {
3158 let trader_id_builder = builder.reborrow().init_trader_id();
3159 self.trader_id.to_capnp(trader_id_builder);
3160
3161 let strategy_id_builder = builder.reborrow().init_strategy_id();
3162 self.strategy_id.to_capnp(strategy_id_builder);
3163
3164 let instrument_id_builder = builder.reborrow().init_instrument_id();
3165 self.instrument_id.to_capnp(instrument_id_builder);
3166
3167 let client_order_id_builder = builder.reborrow().init_client_order_id();
3168 self.client_order_id.to_capnp(client_order_id_builder);
3169
3170 self.venue_order_id
3171 .write_capnp(|| builder.reborrow().init_venue_order_id());
3172 self.account_id
3173 .write_capnp(|| builder.reborrow().init_account_id());
3174
3175 let event_id_builder = builder.reborrow().init_event_id();
3176 self.event_id.to_capnp(event_id_builder);
3177
3178 let mut ts_event_builder = builder.reborrow().init_ts_event();
3179 ts_event_builder.set_value(*self.ts_event);
3180
3181 let mut ts_init_builder = builder.reborrow().init_ts_init();
3182 ts_init_builder.set_value(*self.ts_init);
3183
3184 builder.set_reconciliation(self.reconciliation);
3185 }
3186}
3187
3188impl<'a> FromCapnp<'a> for OrderPendingUpdate {
3189 type Reader = order_capnp::order_pending_update::Reader<'a>;
3190
3191 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3192 let trader_id_reader = reader.get_trader_id()?;
3193 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3194
3195 let strategy_id_reader = reader.get_strategy_id()?;
3196 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3197
3198 let instrument_id_reader = reader.get_instrument_id()?;
3199 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3200
3201 let client_order_id_reader = reader.get_client_order_id()?;
3202 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3203
3204 let venue_order_id = read_optional_from_capnp(
3205 || reader.has_venue_order_id(),
3206 || reader.get_venue_order_id(),
3207 )?;
3208
3209 let account_id =
3210 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3211
3212 let event_id_reader = reader.get_event_id()?;
3213 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3214
3215 let ts_event_reader = reader.get_ts_event()?;
3216 let ts_event = ts_event_reader.get_value();
3217
3218 let ts_init_reader = reader.get_ts_init()?;
3219 let ts_init = ts_init_reader.get_value();
3220
3221 let reconciliation = reader.get_reconciliation();
3222
3223 Ok(Self {
3224 trader_id,
3225 strategy_id,
3226 instrument_id,
3227 client_order_id,
3228 venue_order_id,
3229 account_id,
3230 event_id,
3231 ts_event: ts_event.into(),
3232 ts_init: ts_init.into(),
3233 reconciliation,
3234 causation_id: None,
3235 })
3236 }
3237}
3238
3239impl<'a> ToCapnp<'a> for OrderPendingCancel {
3241 type Builder = order_capnp::order_pending_cancel::Builder<'a>;
3242
3243 fn to_capnp(&self, mut builder: Self::Builder) {
3244 let trader_id_builder = builder.reborrow().init_trader_id();
3245 self.trader_id.to_capnp(trader_id_builder);
3246
3247 let strategy_id_builder = builder.reborrow().init_strategy_id();
3248 self.strategy_id.to_capnp(strategy_id_builder);
3249
3250 let instrument_id_builder = builder.reborrow().init_instrument_id();
3251 self.instrument_id.to_capnp(instrument_id_builder);
3252
3253 let client_order_id_builder = builder.reborrow().init_client_order_id();
3254 self.client_order_id.to_capnp(client_order_id_builder);
3255
3256 self.venue_order_id
3257 .write_capnp(|| builder.reborrow().init_venue_order_id());
3258 self.account_id
3259 .write_capnp(|| builder.reborrow().init_account_id());
3260
3261 let event_id_builder = builder.reborrow().init_event_id();
3262 self.event_id.to_capnp(event_id_builder);
3263
3264 let mut ts_event_builder = builder.reborrow().init_ts_event();
3265 ts_event_builder.set_value(*self.ts_event);
3266
3267 let mut ts_init_builder = builder.reborrow().init_ts_init();
3268 ts_init_builder.set_value(*self.ts_init);
3269
3270 builder.set_reconciliation(self.reconciliation);
3271 }
3272}
3273
3274impl<'a> FromCapnp<'a> for OrderPendingCancel {
3275 type Reader = order_capnp::order_pending_cancel::Reader<'a>;
3276
3277 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3278 let trader_id_reader = reader.get_trader_id()?;
3279 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3280
3281 let strategy_id_reader = reader.get_strategy_id()?;
3282 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3283
3284 let instrument_id_reader = reader.get_instrument_id()?;
3285 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3286
3287 let client_order_id_reader = reader.get_client_order_id()?;
3288 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3289
3290 let venue_order_id = read_optional_from_capnp(
3291 || reader.has_venue_order_id(),
3292 || reader.get_venue_order_id(),
3293 )?;
3294
3295 let account_id =
3296 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3297
3298 let event_id_reader = reader.get_event_id()?;
3299 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3300
3301 let ts_event_reader = reader.get_ts_event()?;
3302 let ts_event = ts_event_reader.get_value();
3303
3304 let ts_init_reader = reader.get_ts_init()?;
3305 let ts_init = ts_init_reader.get_value();
3306
3307 let reconciliation = reader.get_reconciliation();
3308
3309 Ok(Self {
3310 trader_id,
3311 strategy_id,
3312 instrument_id,
3313 client_order_id,
3314 venue_order_id,
3315 account_id,
3316 event_id,
3317 ts_event: ts_event.into(),
3318 ts_init: ts_init.into(),
3319 reconciliation,
3320 causation_id: None,
3321 })
3322 }
3323}
3324
3325impl<'a> ToCapnp<'a> for OrderModifyRejected {
3327 type Builder = order_capnp::order_modify_rejected::Builder<'a>;
3328
3329 fn to_capnp(&self, mut builder: Self::Builder) {
3330 let trader_id_builder = builder.reborrow().init_trader_id();
3331 self.trader_id.to_capnp(trader_id_builder);
3332
3333 let strategy_id_builder = builder.reborrow().init_strategy_id();
3334 self.strategy_id.to_capnp(strategy_id_builder);
3335
3336 let instrument_id_builder = builder.reborrow().init_instrument_id();
3337 self.instrument_id.to_capnp(instrument_id_builder);
3338
3339 let client_order_id_builder = builder.reborrow().init_client_order_id();
3340 self.client_order_id.to_capnp(client_order_id_builder);
3341
3342 self.venue_order_id
3343 .write_capnp(|| builder.reborrow().init_venue_order_id());
3344 self.account_id
3345 .write_capnp(|| builder.reborrow().init_account_id());
3346
3347 builder.set_reason(self.reason.as_str());
3348
3349 let event_id_builder = builder.reborrow().init_event_id();
3350 self.event_id.to_capnp(event_id_builder);
3351
3352 let mut ts_event_builder = builder.reborrow().init_ts_event();
3353 ts_event_builder.set_value(*self.ts_event);
3354
3355 let mut ts_init_builder = builder.reborrow().init_ts_init();
3356 ts_init_builder.set_value(*self.ts_init);
3357
3358 builder.set_reconciliation(self.reconciliation);
3359 }
3360}
3361
3362impl<'a> FromCapnp<'a> for OrderModifyRejected {
3363 type Reader = order_capnp::order_modify_rejected::Reader<'a>;
3364
3365 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3366 let trader_id_reader = reader.get_trader_id()?;
3367 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3368
3369 let strategy_id_reader = reader.get_strategy_id()?;
3370 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3371
3372 let instrument_id_reader = reader.get_instrument_id()?;
3373 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3374
3375 let client_order_id_reader = reader.get_client_order_id()?;
3376 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3377
3378 let venue_order_id = read_optional_from_capnp(
3379 || reader.has_venue_order_id(),
3380 || reader.get_venue_order_id(),
3381 )?;
3382
3383 let account_id =
3384 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3385
3386 let reason = Ustr::from(reader.get_reason()?.to_str()?);
3387
3388 let event_id_reader = reader.get_event_id()?;
3389 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3390
3391 let ts_event_reader = reader.get_ts_event()?;
3392 let ts_event = ts_event_reader.get_value();
3393
3394 let ts_init_reader = reader.get_ts_init()?;
3395 let ts_init = ts_init_reader.get_value();
3396
3397 let reconciliation = reader.get_reconciliation();
3398
3399 Ok(Self {
3400 trader_id,
3401 strategy_id,
3402 instrument_id,
3403 client_order_id,
3404 venue_order_id,
3405 account_id,
3406 reason,
3407 event_id,
3408 ts_event: ts_event.into(),
3409 ts_init: ts_init.into(),
3410 reconciliation,
3411 causation_id: None,
3412 })
3413 }
3414}
3415
3416impl<'a> ToCapnp<'a> for OrderCancelRejected {
3418 type Builder = order_capnp::order_cancel_rejected::Builder<'a>;
3419
3420 fn to_capnp(&self, mut builder: Self::Builder) {
3421 let trader_id_builder = builder.reborrow().init_trader_id();
3422 self.trader_id.to_capnp(trader_id_builder);
3423
3424 let strategy_id_builder = builder.reborrow().init_strategy_id();
3425 self.strategy_id.to_capnp(strategy_id_builder);
3426
3427 let instrument_id_builder = builder.reborrow().init_instrument_id();
3428 self.instrument_id.to_capnp(instrument_id_builder);
3429
3430 let client_order_id_builder = builder.reborrow().init_client_order_id();
3431 self.client_order_id.to_capnp(client_order_id_builder);
3432
3433 self.venue_order_id
3434 .write_capnp(|| builder.reborrow().init_venue_order_id());
3435 self.account_id
3436 .write_capnp(|| builder.reborrow().init_account_id());
3437
3438 builder.set_reason(self.reason.as_str());
3439
3440 let event_id_builder = builder.reborrow().init_event_id();
3441 self.event_id.to_capnp(event_id_builder);
3442
3443 let mut ts_event_builder = builder.reborrow().init_ts_event();
3444 ts_event_builder.set_value(*self.ts_event);
3445
3446 let mut ts_init_builder = builder.reborrow().init_ts_init();
3447 ts_init_builder.set_value(*self.ts_init);
3448
3449 builder.set_reconciliation(self.reconciliation);
3450 }
3451}
3452
3453impl<'a> FromCapnp<'a> for OrderCancelRejected {
3454 type Reader = order_capnp::order_cancel_rejected::Reader<'a>;
3455
3456 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3457 let trader_id_reader = reader.get_trader_id()?;
3458 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3459
3460 let strategy_id_reader = reader.get_strategy_id()?;
3461 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3462
3463 let instrument_id_reader = reader.get_instrument_id()?;
3464 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3465
3466 let client_order_id_reader = reader.get_client_order_id()?;
3467 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3468
3469 let venue_order_id = read_optional_from_capnp(
3470 || reader.has_venue_order_id(),
3471 || reader.get_venue_order_id(),
3472 )?;
3473
3474 let account_id =
3475 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3476
3477 let reason = Ustr::from(reader.get_reason()?.to_str()?);
3478
3479 let event_id_reader = reader.get_event_id()?;
3480 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3481
3482 let ts_event_reader = reader.get_ts_event()?;
3483 let ts_event = ts_event_reader.get_value();
3484
3485 let ts_init_reader = reader.get_ts_init()?;
3486 let ts_init = ts_init_reader.get_value();
3487
3488 let reconciliation = reader.get_reconciliation();
3489
3490 Ok(Self {
3491 trader_id,
3492 strategy_id,
3493 instrument_id,
3494 client_order_id,
3495 venue_order_id,
3496 account_id,
3497 reason,
3498 event_id,
3499 ts_event: ts_event.into(),
3500 ts_init: ts_init.into(),
3501 reconciliation,
3502 causation_id: None,
3503 })
3504 }
3505}
3506
3507impl<'a> ToCapnp<'a> for OrderUpdated {
3509 type Builder = order_capnp::order_updated::Builder<'a>;
3510
3511 fn to_capnp(&self, mut builder: Self::Builder) {
3512 let trader_id_builder = builder.reborrow().init_trader_id();
3513 self.trader_id.to_capnp(trader_id_builder);
3514
3515 let strategy_id_builder = builder.reborrow().init_strategy_id();
3516 self.strategy_id.to_capnp(strategy_id_builder);
3517
3518 let instrument_id_builder = builder.reborrow().init_instrument_id();
3519 self.instrument_id.to_capnp(instrument_id_builder);
3520
3521 let client_order_id_builder = builder.reborrow().init_client_order_id();
3522 self.client_order_id.to_capnp(client_order_id_builder);
3523
3524 self.venue_order_id
3525 .write_capnp(|| builder.reborrow().init_venue_order_id());
3526 self.account_id
3527 .write_capnp(|| builder.reborrow().init_account_id());
3528
3529 let quantity_builder = builder.reborrow().init_quantity();
3530 self.quantity.to_capnp(quantity_builder);
3531
3532 self.price.write_capnp(|| builder.reborrow().init_price());
3533 self.trigger_price
3534 .write_capnp(|| builder.reborrow().init_trigger_price());
3535 self.protection_price
3536 .write_capnp(|| builder.reborrow().init_protection_price());
3537
3538 let event_id_builder = builder.reborrow().init_event_id();
3539 self.event_id.to_capnp(event_id_builder);
3540
3541 let mut ts_event_builder = builder.reborrow().init_ts_event();
3542 ts_event_builder.set_value(*self.ts_event);
3543
3544 let mut ts_init_builder = builder.reborrow().init_ts_init();
3545 ts_init_builder.set_value(*self.ts_init);
3546
3547 builder.set_reconciliation(self.reconciliation);
3548 builder.set_is_quote_quantity(self.is_quote_quantity);
3549 }
3550}
3551
3552impl<'a> FromCapnp<'a> for OrderUpdated {
3553 type Reader = order_capnp::order_updated::Reader<'a>;
3554
3555 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3556 let trader_id_reader = reader.get_trader_id()?;
3557 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3558
3559 let strategy_id_reader = reader.get_strategy_id()?;
3560 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3561
3562 let instrument_id_reader = reader.get_instrument_id()?;
3563 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3564
3565 let client_order_id_reader = reader.get_client_order_id()?;
3566 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3567
3568 let venue_order_id = read_optional_from_capnp(
3569 || reader.has_venue_order_id(),
3570 || reader.get_venue_order_id(),
3571 )?;
3572
3573 let account_id =
3574 read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3575
3576 let quantity_reader = reader.get_quantity()?;
3577 let quantity = Quantity::from_capnp(quantity_reader)?;
3578
3579 let price = read_optional_from_capnp(|| reader.has_price(), || reader.get_price())?;
3580
3581 let trigger_price =
3582 read_optional_from_capnp(|| reader.has_trigger_price(), || reader.get_trigger_price())?;
3583
3584 let protection_price = read_optional_from_capnp(
3585 || reader.has_protection_price(),
3586 || reader.get_protection_price(),
3587 )?;
3588
3589 let event_id_reader = reader.get_event_id()?;
3590 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3591
3592 let ts_event_reader = reader.get_ts_event()?;
3593 let ts_event = ts_event_reader.get_value();
3594
3595 let ts_init_reader = reader.get_ts_init()?;
3596 let ts_init = ts_init_reader.get_value();
3597
3598 let reconciliation = reader.get_reconciliation();
3599
3600 Ok(Self {
3601 trader_id,
3602 strategy_id,
3603 instrument_id,
3604 client_order_id,
3605 venue_order_id,
3606 account_id,
3607 quantity,
3608 price,
3609 trigger_price,
3610 protection_price,
3611 is_quote_quantity: reader.get_is_quote_quantity(),
3612 event_id,
3613 ts_event: ts_event.into(),
3614 ts_init: ts_init.into(),
3615 reconciliation,
3616 causation_id: None,
3617 })
3618 }
3619}
3620
3621impl<'a> ToCapnp<'a> for OrderFilled {
3623 type Builder = order_capnp::order_filled::Builder<'a>;
3624
3625 fn to_capnp(&self, mut builder: Self::Builder) {
3626 let trader_id_builder = builder.reborrow().init_trader_id();
3627 self.trader_id.to_capnp(trader_id_builder);
3628
3629 let strategy_id_builder = builder.reborrow().init_strategy_id();
3630 self.strategy_id.to_capnp(strategy_id_builder);
3631
3632 let instrument_id_builder = builder.reborrow().init_instrument_id();
3633 self.instrument_id.to_capnp(instrument_id_builder);
3634
3635 let client_order_id_builder = builder.reborrow().init_client_order_id();
3636 self.client_order_id.to_capnp(client_order_id_builder);
3637
3638 let venue_order_id_builder = builder.reborrow().init_venue_order_id();
3639 self.venue_order_id.to_capnp(venue_order_id_builder);
3640
3641 let account_id_builder = builder.reborrow().init_account_id();
3642 self.account_id.to_capnp(account_id_builder);
3643
3644 let trade_id_builder = builder.reborrow().init_trade_id();
3645 self.trade_id.to_capnp(trade_id_builder);
3646
3647 builder.set_order_side(order_side_to_capnp(self.order_side.into()));
3648 builder.set_order_type(order_type_to_capnp(self.order_type));
3649
3650 let last_qty_builder = builder.reborrow().init_last_qty();
3651 self.last_qty.to_capnp(last_qty_builder);
3652
3653 let last_px_builder = builder.reborrow().init_last_px();
3654 self.last_px.to_capnp(last_px_builder);
3655
3656 let currency_builder = builder.reborrow().init_currency();
3657 self.currency.to_capnp(currency_builder);
3658
3659 builder.set_liquidity_side(liquidity_side_to_capnp(self.liquidity_side));
3660
3661 let event_id_builder = builder.reborrow().init_event_id();
3662 self.event_id.to_capnp(event_id_builder);
3663
3664 let mut ts_event_builder = builder.reborrow().init_ts_event();
3665 ts_event_builder.set_value(*self.ts_event);
3666
3667 let mut ts_init_builder = builder.reborrow().init_ts_init();
3668 ts_init_builder.set_value(*self.ts_init);
3669
3670 builder.set_reconciliation(self.reconciliation);
3671
3672 self.position_id
3673 .write_capnp(|| builder.reborrow().init_position_id());
3674 self.commission
3675 .write_capnp(|| builder.reborrow().init_commission());
3676
3677 if let Some(info) = &self.info {
3678 write_string_map(info, builder.reborrow().init_info());
3679 }
3680 }
3681}
3682
3683impl<'a> FromCapnp<'a> for OrderFilled {
3684 type Reader = order_capnp::order_filled::Reader<'a>;
3685
3686 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3687 let trader_id_reader = reader.get_trader_id()?;
3688 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3689
3690 let strategy_id_reader = reader.get_strategy_id()?;
3691 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3692
3693 let instrument_id_reader = reader.get_instrument_id()?;
3694 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3695
3696 let client_order_id_reader = reader.get_client_order_id()?;
3697 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3698
3699 let venue_order_id_reader = reader.get_venue_order_id()?;
3700 let venue_order_id = VenueOrderId::from_capnp(venue_order_id_reader)?;
3701
3702 let account_id_reader = reader.get_account_id()?;
3703 let account_id = AccountId::from_capnp(account_id_reader)?;
3704
3705 let trade_id_reader = reader.get_trade_id()?;
3706 let trade_id = TradeId::from_capnp(trade_id_reader)?;
3707
3708 let order_side = order_side_required_from_capnp(reader.get_order_side()?)?;
3709 let order_type = order_type_from_capnp(reader.get_order_type()?);
3710
3711 let last_qty_reader = reader.get_last_qty()?;
3712 let last_qty = Quantity::from_capnp(last_qty_reader)?;
3713
3714 let last_px_reader = reader.get_last_px()?;
3715 let last_px = Price::from_capnp(last_px_reader)?;
3716
3717 let currency_reader = reader.get_currency()?;
3718 let currency = Currency::from_capnp(currency_reader)?;
3719
3720 let liquidity_side = liquidity_side_from_capnp(reader.get_liquidity_side()?);
3721
3722 let event_id_reader = reader.get_event_id()?;
3723 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3724
3725 let ts_event_reader = reader.get_ts_event()?;
3726 let ts_event = ts_event_reader.get_value();
3727
3728 let ts_init_reader = reader.get_ts_init()?;
3729 let ts_init = ts_init_reader.get_value();
3730
3731 let reconciliation = reader.get_reconciliation();
3732
3733 let position_id =
3734 read_optional_from_capnp(|| reader.has_position_id(), || reader.get_position_id())?;
3735
3736 let commission =
3737 read_optional_from_capnp(|| reader.has_commission(), || reader.get_commission())?;
3738
3739 let info = if reader.has_info() {
3740 Some(read_string_map(reader.get_info()?)?)
3741 } else {
3742 None
3743 };
3744
3745 Ok(Self {
3746 trader_id,
3747 strategy_id,
3748 instrument_id,
3749 client_order_id,
3750 venue_order_id,
3751 account_id,
3752 trade_id,
3753 order_side,
3754 order_type,
3755 last_qty,
3756 last_px,
3757 currency,
3758 liquidity_side,
3759 event_id,
3760 ts_event: ts_event.into(),
3761 ts_init: ts_init.into(),
3762 reconciliation,
3763 position_id,
3764 commission,
3765 info,
3766 causation_id: None,
3767 })
3768 }
3769}
3770
3771impl<'a> ToCapnp<'a> for OrderFillVoided {
3772 type Builder = order_capnp::order_fill_voided::Builder<'a>;
3773
3774 fn to_capnp(&self, mut builder: Self::Builder) {
3775 self.trader_id.to_capnp(builder.reborrow().init_trader_id());
3776 self.strategy_id
3777 .to_capnp(builder.reborrow().init_strategy_id());
3778 self.instrument_id
3779 .to_capnp(builder.reborrow().init_instrument_id());
3780 self.client_order_id
3781 .to_capnp(builder.reborrow().init_client_order_id());
3782 self.venue_order_id
3783 .to_capnp(builder.reborrow().init_venue_order_id());
3784 self.account_id
3785 .to_capnp(builder.reborrow().init_account_id());
3786 builder.set_correction_id(self.correction_id.as_str());
3787 self.trade_id.to_capnp(builder.reborrow().init_trade_id());
3788 self.voided_qty
3789 .to_capnp(builder.reborrow().init_voided_qty());
3790 self.commission_voided
3791 .write_capnp(|| builder.reborrow().init_commission_voided());
3792 builder.set_order_side(order_side_to_capnp(self.order_side.into()));
3793 builder.set_order_type(order_type_to_capnp(self.order_type));
3794 self.last_px.to_capnp(builder.reborrow().init_last_px());
3795 self.currency.to_capnp(builder.reborrow().init_currency());
3796 builder.set_liquidity_side(liquidity_side_to_capnp(self.liquidity_side));
3797
3798 self.position_id
3799 .write_capnp(|| builder.reborrow().init_position_id());
3800
3801 if let Some(reason) = self.reason {
3802 builder.set_reason(reason.as_str());
3803 }
3804
3805 if let Some(info) = &self.info {
3806 write_string_map(info, builder.reborrow().init_info());
3807 }
3808 self.event_id.to_capnp(builder.reborrow().init_event_id());
3809 builder.reborrow().init_ts_event().set_value(*self.ts_event);
3810 builder.reborrow().init_ts_init().set_value(*self.ts_init);
3811 builder.set_reconciliation(self.reconciliation);
3812 builder.set_is_reopened(self.is_reopened);
3813 self.causation_id
3814 .write_capnp(|| builder.reborrow().init_causation_id());
3815 }
3816}
3817
3818impl<'a> FromCapnp<'a> for OrderFillVoided {
3819 type Reader = order_capnp::order_fill_voided::Reader<'a>;
3820
3821 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3822 let trader_id = TraderId::from_capnp(reader.get_trader_id()?)?;
3823 let strategy_id = StrategyId::from_capnp(reader.get_strategy_id()?)?;
3824 let instrument_id = InstrumentId::from_capnp(reader.get_instrument_id()?)?;
3825 let client_order_id = ClientOrderId::from_capnp(reader.get_client_order_id()?)?;
3826 let venue_order_id = VenueOrderId::from_capnp(reader.get_venue_order_id()?)?;
3827 let account_id = AccountId::from_capnp(reader.get_account_id()?)?;
3828 let correction_id = Ustr::from(reader.get_correction_id()?.to_str()?);
3829 let trade_id = TradeId::from_capnp(reader.get_trade_id()?)?;
3830 let voided_qty = Quantity::from_capnp(reader.get_voided_qty()?)?;
3831 let commission_voided = read_optional_from_capnp(
3832 || reader.has_commission_voided(),
3833 || reader.get_commission_voided(),
3834 )?;
3835 let order_side = order_side_required_from_capnp(reader.get_order_side()?)?;
3836 let order_type = order_type_from_capnp(reader.get_order_type()?);
3837 let last_px = Price::from_capnp(reader.get_last_px()?)?;
3838 let currency = Currency::from_capnp(reader.get_currency()?)?;
3839 let liquidity_side = liquidity_side_from_capnp(reader.get_liquidity_side()?);
3840 let position_id =
3841 read_optional_from_capnp(|| reader.has_position_id(), || reader.get_position_id())?;
3842 let reason = if reader.has_reason() {
3843 Some(Ustr::from(reader.get_reason()?.to_str()?))
3844 } else {
3845 None
3846 };
3847 let info = if reader.has_info() {
3848 Some(read_string_map(reader.get_info()?)?)
3849 } else {
3850 None
3851 };
3852 let event_id = nautilus_core::UUID4::from_capnp(reader.get_event_id()?)?;
3853 let ts_event = reader.get_ts_event()?.get_value().into();
3854 let ts_init = reader.get_ts_init()?.get_value().into();
3855 let causation_id =
3856 read_optional_from_capnp(|| reader.has_causation_id(), || reader.get_causation_id())?;
3857
3858 Ok(Self {
3859 trader_id,
3860 strategy_id,
3861 instrument_id,
3862 client_order_id,
3863 venue_order_id,
3864 account_id,
3865 correction_id,
3866 trade_id,
3867 voided_qty,
3868 commission_voided,
3869 order_side,
3870 order_type,
3871 last_px,
3872 currency,
3873 liquidity_side,
3874 position_id,
3875 reason,
3876 info,
3877 event_id,
3878 ts_event,
3879 ts_init,
3880 reconciliation: reader.get_reconciliation(),
3881 is_reopened: reader.get_is_reopened(),
3882 causation_id,
3883 })
3884 }
3885}
3886
3887impl<'a> ToCapnp<'a> for OrderInitialized {
3889 type Builder = order_capnp::order_initialized::Builder<'a>;
3890
3891 fn to_capnp(&self, mut builder: Self::Builder) {
3892 let trader_id_builder = builder.reborrow().init_trader_id();
3893 self.trader_id.to_capnp(trader_id_builder);
3894
3895 let strategy_id_builder = builder.reborrow().init_strategy_id();
3896 self.strategy_id.to_capnp(strategy_id_builder);
3897
3898 let instrument_id_builder = builder.reborrow().init_instrument_id();
3899 self.instrument_id.to_capnp(instrument_id_builder);
3900
3901 let client_order_id_builder = builder.reborrow().init_client_order_id();
3902 self.client_order_id.to_capnp(client_order_id_builder);
3903
3904 builder.set_order_side(order_side_to_capnp(self.order_side.into()));
3905 builder.set_order_type(order_type_to_capnp(self.order_type));
3906
3907 let quantity_builder = builder.reborrow().init_quantity();
3908 self.quantity.to_capnp(quantity_builder);
3909
3910 builder.set_time_in_force(time_in_force_to_capnp(self.time_in_force));
3911 builder.set_post_only(self.post_only);
3912 builder.set_reduce_only(self.reduce_only);
3913 builder.set_quote_quantity(self.quote_quantity);
3914 builder.set_reconciliation(self.reconciliation);
3915
3916 let event_id_builder = builder.reborrow().init_event_id();
3917 self.event_id.to_capnp(event_id_builder);
3918
3919 let mut ts_event_builder = builder.reborrow().init_ts_event();
3920 ts_event_builder.set_value(*self.ts_event);
3921
3922 let mut ts_init_builder = builder.reborrow().init_ts_init();
3923 ts_init_builder.set_value(*self.ts_init);
3924
3925 self.price.write_capnp(|| builder.reborrow().init_price());
3926 self.activation_price
3927 .write_capnp(|| builder.reborrow().init_activation_price());
3928 self.trigger_price
3929 .write_capnp(|| builder.reborrow().init_trigger_price());
3930
3931 builder.set_trigger_type(trigger_type_to_capnp(self.trigger_type));
3932
3933 self.limit_offset
3934 .write_capnp(|| builder.reborrow().init_limit_offset());
3935 self.trailing_offset
3936 .write_capnp(|| builder.reborrow().init_trailing_offset());
3937
3938 builder.set_trailing_offset_type(trailing_offset_type_to_capnp(self.trailing_offset_type));
3939
3940 if let Some(expire_time) = self.expire_time {
3941 let mut expire_time_builder = builder.reborrow().init_expire_time();
3942 expire_time_builder.set_value(*expire_time);
3943 }
3944
3945 self.display_qty
3946 .write_capnp(|| builder.reborrow().init_display_qty());
3947
3948 builder.set_emulation_trigger(trigger_type_to_capnp(self.emulation_trigger));
3949
3950 self.trigger_instrument_id
3951 .write_capnp(|| builder.reborrow().init_trigger_instrument_id());
3952
3953 builder.set_contingency_type(contingency_type_to_capnp(self.contingency_type));
3954
3955 self.order_list_id
3956 .write_capnp(|| builder.reborrow().init_order_list_id());
3957
3958 if let Some(linked_order_ids) = &self.linked_order_ids {
3959 let mut linked_order_ids_builder = builder
3960 .reborrow()
3961 .init_linked_order_ids(linked_order_ids.len() as u32);
3962 for (i, order_id) in linked_order_ids.iter().enumerate() {
3963 let order_id_builder = linked_order_ids_builder.reborrow().get(i as u32);
3964 order_id.to_capnp(order_id_builder);
3965 }
3966 }
3967
3968 self.parent_order_id
3969 .write_capnp(|| builder.reborrow().init_parent_order_id());
3970
3971 self.exec_algorithm_id
3972 .write_capnp(|| builder.reborrow().init_exec_algorithm_id());
3973
3974 if let Some(exec_algorithm_params) = &self.exec_algorithm_params {
3975 write_string_map(
3976 exec_algorithm_params,
3977 builder.reborrow().init_exec_algorithm_params(),
3978 );
3979 }
3980
3981 self.exec_spawn_id
3982 .write_capnp(|| builder.reborrow().init_exec_spawn_id());
3983
3984 if let Some(tags) = &self.tags {
3985 let mut tags_builder = builder.reborrow().init_tags(tags.len() as u32);
3986 for (i, tag) in tags.iter().enumerate() {
3987 tags_builder.set(i as u32, tag.as_str());
3988 }
3989 }
3990 }
3991}
3992
3993impl<'a> FromCapnp<'a> for OrderInitialized {
3994 type Reader = order_capnp::order_initialized::Reader<'a>;
3995
3996 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3997 let trader_id_reader = reader.get_trader_id()?;
3998 let trader_id = TraderId::from_capnp(trader_id_reader)?;
3999
4000 let strategy_id_reader = reader.get_strategy_id()?;
4001 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4002
4003 let instrument_id_reader = reader.get_instrument_id()?;
4004 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4005
4006 let client_order_id_reader = reader.get_client_order_id()?;
4007 let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
4008
4009 let order_side = order_side_required_from_capnp(reader.get_order_side()?)?;
4010 let order_type = order_type_from_capnp(reader.get_order_type()?);
4011
4012 let quantity_reader = reader.get_quantity()?;
4013 let quantity = Quantity::from_capnp(quantity_reader)?;
4014
4015 let time_in_force = time_in_force_from_capnp(reader.get_time_in_force()?);
4016 let post_only = reader.get_post_only();
4017 let reduce_only = reader.get_reduce_only();
4018 let quote_quantity = reader.get_quote_quantity();
4019 let reconciliation = reader.get_reconciliation();
4020
4021 let event_id_reader = reader.get_event_id()?;
4022 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4023
4024 let ts_event_reader = reader.get_ts_event()?;
4025 let ts_event = ts_event_reader.get_value();
4026
4027 let ts_init_reader = reader.get_ts_init()?;
4028 let ts_init = ts_init_reader.get_value();
4029
4030 let price = read_optional_from_capnp(|| reader.has_price(), || reader.get_price())?;
4031
4032 let activation_price = read_optional_from_capnp(
4033 || reader.has_activation_price(),
4034 || reader.get_activation_price(),
4035 )?;
4036
4037 let trigger_price =
4038 read_optional_from_capnp(|| reader.has_trigger_price(), || reader.get_trigger_price())?;
4039
4040 let trigger_type = trigger_type_from_capnp(reader.get_trigger_type()?);
4041
4042 let limit_offset =
4043 read_optional_from_capnp(|| reader.has_limit_offset(), || reader.get_limit_offset())?;
4044
4045 let trailing_offset = read_optional_from_capnp(
4046 || reader.has_trailing_offset(),
4047 || reader.get_trailing_offset(),
4048 )?;
4049
4050 let trailing_offset_type =
4051 trailing_offset_type_from_capnp(reader.get_trailing_offset_type()?);
4052
4053 let expire_time = if reader.has_expire_time() {
4054 let expire_time_reader = reader.get_expire_time()?;
4055 let value = expire_time_reader.get_value();
4056 Some(value.into())
4057 } else {
4058 None
4059 };
4060
4061 let display_qty =
4062 read_optional_from_capnp(|| reader.has_display_qty(), || reader.get_display_qty())?;
4063
4064 let emulation_trigger = trigger_type_from_capnp(reader.get_emulation_trigger()?);
4065
4066 let trigger_instrument_id = read_optional_from_capnp(
4067 || reader.has_trigger_instrument_id(),
4068 || reader.get_trigger_instrument_id(),
4069 )?;
4070
4071 let contingency_type = contingency_type_from_capnp(reader.get_contingency_type()?);
4072
4073 let order_list_id =
4074 read_optional_from_capnp(|| reader.has_order_list_id(), || reader.get_order_list_id())?;
4075
4076 let linked_order_ids = if reader.has_linked_order_ids() {
4077 let linked_order_ids_reader = reader.get_linked_order_ids()?;
4078 let mut linked_order_ids = Vec::with_capacity(linked_order_ids_reader.len() as usize);
4079 for order_id_reader in linked_order_ids_reader {
4080 linked_order_ids.push(ClientOrderId::from_capnp(order_id_reader)?);
4081 }
4082 Some(linked_order_ids)
4083 } else {
4084 None
4085 };
4086
4087 let parent_order_id = read_optional_from_capnp(
4088 || reader.has_parent_order_id(),
4089 || reader.get_parent_order_id(),
4090 )?;
4091
4092 let exec_algorithm_id = read_optional_from_capnp(
4093 || reader.has_exec_algorithm_id(),
4094 || reader.get_exec_algorithm_id(),
4095 )?;
4096
4097 let exec_algorithm_params = if reader.has_exec_algorithm_params() {
4098 Some(read_string_map(reader.get_exec_algorithm_params()?)?)
4099 } else {
4100 None
4101 };
4102
4103 let exec_spawn_id =
4104 read_optional_from_capnp(|| reader.has_exec_spawn_id(), || reader.get_exec_spawn_id())?;
4105
4106 let tags = if reader.has_tags() {
4107 let tags_reader = reader.get_tags()?;
4108 let mut tags = Vec::with_capacity(tags_reader.len() as usize);
4109 for tag in tags_reader {
4110 tags.push(Ustr::from(tag?.to_str()?));
4111 }
4112 Some(tags)
4113 } else {
4114 None
4115 };
4116
4117 Ok(Self {
4118 trader_id,
4119 strategy_id,
4120 instrument_id,
4121 client_order_id,
4122 order_side,
4123 order_type,
4124 quantity,
4125 time_in_force,
4126 post_only,
4127 reduce_only,
4128 quote_quantity,
4129 reconciliation,
4130 event_id,
4131 ts_event: ts_event.into(),
4132 ts_init: ts_init.into(),
4133 price,
4134 activation_price,
4135 trigger_price,
4136 trigger_type,
4137 limit_offset,
4138 trailing_offset,
4139 trailing_offset_type,
4140 expire_time,
4141 display_qty,
4142 emulation_trigger,
4143 trigger_instrument_id,
4144 contingency_type,
4145 order_list_id,
4146 linked_order_ids,
4147 parent_order_id,
4148 exec_algorithm_id,
4149 exec_algorithm_params,
4150 exec_spawn_id,
4151 tags,
4152 causation_id: None,
4153 })
4154 }
4155}
4156
4157impl<'a> ToCapnp<'a> for PositionOpened {
4159 type Builder = position_capnp::position_opened::Builder<'a>;
4160
4161 fn to_capnp(&self, mut builder: Self::Builder) {
4162 let trader_id_builder = builder.reborrow().init_trader_id();
4163 self.trader_id.to_capnp(trader_id_builder);
4164
4165 let strategy_id_builder = builder.reborrow().init_strategy_id();
4166 self.strategy_id.to_capnp(strategy_id_builder);
4167
4168 let instrument_id_builder = builder.reborrow().init_instrument_id();
4169 self.instrument_id.to_capnp(instrument_id_builder);
4170
4171 let position_id_builder = builder.reborrow().init_position_id();
4172 self.position_id.to_capnp(position_id_builder);
4173
4174 let account_id_builder = builder.reborrow().init_account_id();
4175 self.account_id.to_capnp(account_id_builder);
4176
4177 let opening_order_id_builder = builder.reborrow().init_opening_order_id();
4178 self.opening_order_id.to_capnp(opening_order_id_builder);
4179
4180 builder.set_entry(order_side_to_capnp(self.entry.into()));
4181 builder.set_side(position_side_to_capnp(self.side.into()));
4182 builder.set_signed_qty(self.signed_qty);
4183
4184 let quantity_builder = builder.reborrow().init_quantity();
4185 self.quantity.to_capnp(quantity_builder);
4186
4187 let last_qty_builder = builder.reborrow().init_last_qty();
4188 self.last_qty.to_capnp(last_qty_builder);
4189
4190 let last_px_builder = builder.reborrow().init_last_px();
4191 self.last_px.to_capnp(last_px_builder);
4192
4193 let currency_builder = builder.reborrow().init_currency();
4194 self.currency.to_capnp(currency_builder);
4195
4196 builder.set_avg_px_open(self.avg_px_open);
4197
4198 self.realized_pnl
4199 .write_capnp(|| builder.reborrow().init_realized_pnl());
4200
4201 let event_id_builder = builder.reborrow().init_event_id();
4202 self.event_id.to_capnp(event_id_builder);
4203
4204 let mut ts_event_builder = builder.reborrow().init_ts_event();
4205 ts_event_builder.set_value(*self.ts_event);
4206
4207 let mut ts_init_builder = builder.reborrow().init_ts_init();
4208 ts_init_builder.set_value(*self.ts_init);
4209 }
4210}
4211
4212impl<'a> FromCapnp<'a> for PositionOpened {
4213 type Reader = position_capnp::position_opened::Reader<'a>;
4214
4215 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4216 let trader_id_reader = reader.get_trader_id()?;
4217 let trader_id = TraderId::from_capnp(trader_id_reader)?;
4218
4219 let strategy_id_reader = reader.get_strategy_id()?;
4220 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4221
4222 let instrument_id_reader = reader.get_instrument_id()?;
4223 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4224
4225 let position_id_reader = reader.get_position_id()?;
4226 let position_id = PositionId::from_capnp(position_id_reader)?;
4227
4228 let account_id_reader = reader.get_account_id()?;
4229 let account_id = AccountId::from_capnp(account_id_reader)?;
4230
4231 let opening_order_id_reader = reader.get_opening_order_id()?;
4232 let opening_order_id = ClientOrderId::from_capnp(opening_order_id_reader)?;
4233
4234 let entry = order_side_required_from_capnp(reader.get_entry()?)?;
4235 let side = position_side_required_from_capnp(reader.get_side()?)?;
4236 let signed_qty = reader.get_signed_qty();
4237
4238 let quantity_reader = reader.get_quantity()?;
4239 let quantity = Quantity::from_capnp(quantity_reader)?;
4240
4241 let last_qty_reader = reader.get_last_qty()?;
4242 let last_qty = Quantity::from_capnp(last_qty_reader)?;
4243
4244 let last_px_reader = reader.get_last_px()?;
4245 let last_px = Price::from_capnp(last_px_reader)?;
4246
4247 let currency_reader = reader.get_currency()?;
4248 let currency = Currency::from_capnp(currency_reader)?;
4249
4250 let avg_px_open = reader.get_avg_px_open();
4251
4252 let realized_pnl =
4253 read_optional_from_capnp(|| reader.has_realized_pnl(), || reader.get_realized_pnl())?;
4254
4255 let event_id_reader = reader.get_event_id()?;
4256 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4257
4258 let ts_event_reader = reader.get_ts_event()?;
4259 let ts_event = ts_event_reader.get_value();
4260
4261 let ts_init_reader = reader.get_ts_init()?;
4262 let ts_init = ts_init_reader.get_value();
4263
4264 Ok(Self {
4265 trader_id,
4266 strategy_id,
4267 instrument_id,
4268 position_id,
4269 account_id,
4270 opening_order_id,
4271 entry,
4272 side,
4273 signed_qty,
4274 quantity,
4275 last_qty,
4276 last_px,
4277 currency,
4278 avg_px_open,
4279 realized_pnl,
4280 event_id,
4281 ts_event: ts_event.into(),
4282 ts_init: ts_init.into(),
4283 })
4284 }
4285}
4286
4287impl<'a> ToCapnp<'a> for PositionChanged {
4289 type Builder = position_capnp::position_changed::Builder<'a>;
4290
4291 fn to_capnp(&self, mut builder: Self::Builder) {
4292 let trader_id_builder = builder.reborrow().init_trader_id();
4293 self.trader_id.to_capnp(trader_id_builder);
4294
4295 let strategy_id_builder = builder.reborrow().init_strategy_id();
4296 self.strategy_id.to_capnp(strategy_id_builder);
4297
4298 let instrument_id_builder = builder.reborrow().init_instrument_id();
4299 self.instrument_id.to_capnp(instrument_id_builder);
4300
4301 let position_id_builder = builder.reborrow().init_position_id();
4302 self.position_id.to_capnp(position_id_builder);
4303
4304 let account_id_builder = builder.reborrow().init_account_id();
4305 self.account_id.to_capnp(account_id_builder);
4306
4307 let opening_order_id_builder = builder.reborrow().init_opening_order_id();
4308 self.opening_order_id.to_capnp(opening_order_id_builder);
4309
4310 builder.set_entry(order_side_to_capnp(self.entry.into()));
4311 builder.set_side(position_side_to_capnp(self.side.into()));
4312 builder.set_signed_qty(self.signed_qty);
4313
4314 let quantity_builder = builder.reborrow().init_quantity();
4315 self.quantity.to_capnp(quantity_builder);
4316
4317 let peak_quantity_builder = builder.reborrow().init_peak_quantity();
4318 self.peak_quantity.to_capnp(peak_quantity_builder);
4319
4320 let last_qty_builder = builder.reborrow().init_last_qty();
4321 self.last_qty.to_capnp(last_qty_builder);
4322
4323 let last_px_builder = builder.reborrow().init_last_px();
4324 self.last_px.to_capnp(last_px_builder);
4325
4326 let currency_builder = builder.reborrow().init_currency();
4327 self.currency.to_capnp(currency_builder);
4328
4329 builder.set_avg_px_open(self.avg_px_open);
4330 builder.set_avg_px_close(self.avg_px_close.unwrap_or(f64::NAN));
4331 builder.set_realized_return(self.realized_return);
4332
4333 self.realized_pnl
4334 .write_capnp(|| builder.reborrow().init_realized_pnl());
4335
4336 let unrealized_pnl_builder = builder.reborrow().init_unrealized_pnl();
4337 self.unrealized_pnl.to_capnp(unrealized_pnl_builder);
4338
4339 let event_id_builder = builder.reborrow().init_event_id();
4340 self.event_id.to_capnp(event_id_builder);
4341
4342 let mut ts_opened_builder = builder.reborrow().init_ts_opened();
4343 ts_opened_builder.set_value(*self.ts_opened);
4344
4345 let mut ts_event_builder = builder.reborrow().init_ts_event();
4346 ts_event_builder.set_value(*self.ts_event);
4347
4348 let mut ts_init_builder = builder.reborrow().init_ts_init();
4349 ts_init_builder.set_value(*self.ts_init);
4350 }
4351}
4352
4353impl<'a> FromCapnp<'a> for PositionChanged {
4354 type Reader = position_capnp::position_changed::Reader<'a>;
4355
4356 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4357 let trader_id_reader = reader.get_trader_id()?;
4358 let trader_id = TraderId::from_capnp(trader_id_reader)?;
4359
4360 let strategy_id_reader = reader.get_strategy_id()?;
4361 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4362
4363 let instrument_id_reader = reader.get_instrument_id()?;
4364 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4365
4366 let position_id_reader = reader.get_position_id()?;
4367 let position_id = PositionId::from_capnp(position_id_reader)?;
4368
4369 let account_id_reader = reader.get_account_id()?;
4370 let account_id = AccountId::from_capnp(account_id_reader)?;
4371
4372 let opening_order_id_reader = reader.get_opening_order_id()?;
4373 let opening_order_id = ClientOrderId::from_capnp(opening_order_id_reader)?;
4374
4375 let entry = order_side_required_from_capnp(reader.get_entry()?)?;
4376 let side = position_side_required_from_capnp(reader.get_side()?)?;
4377 let signed_qty = reader.get_signed_qty();
4378
4379 let quantity_reader = reader.get_quantity()?;
4380 let quantity = Quantity::from_capnp(quantity_reader)?;
4381
4382 let peak_quantity_reader = reader.get_peak_quantity()?;
4383 let peak_quantity = Quantity::from_capnp(peak_quantity_reader)?;
4384
4385 let last_qty_reader = reader.get_last_qty()?;
4386 let last_qty = Quantity::from_capnp(last_qty_reader)?;
4387
4388 let last_px_reader = reader.get_last_px()?;
4389 let last_px = Price::from_capnp(last_px_reader)?;
4390
4391 let currency_reader = reader.get_currency()?;
4392 let currency = Currency::from_capnp(currency_reader)?;
4393
4394 let avg_px_open = reader.get_avg_px_open();
4395 let avg_px_close = {
4396 let value = reader.get_avg_px_close();
4397 if value.is_nan() { None } else { Some(value) }
4398 };
4399 let realized_return = reader.get_realized_return();
4400
4401 let realized_pnl =
4402 read_optional_from_capnp(|| reader.has_realized_pnl(), || reader.get_realized_pnl())?;
4403
4404 let unrealized_pnl_reader = reader.get_unrealized_pnl()?;
4405 let unrealized_pnl = Money::from_capnp(unrealized_pnl_reader)?;
4406
4407 let event_id_reader = reader.get_event_id()?;
4408 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4409
4410 let ts_opened_reader = reader.get_ts_opened()?;
4411 let ts_opened = ts_opened_reader.get_value();
4412
4413 let ts_event_reader = reader.get_ts_event()?;
4414 let ts_event = ts_event_reader.get_value();
4415
4416 let ts_init_reader = reader.get_ts_init()?;
4417 let ts_init = ts_init_reader.get_value();
4418
4419 Ok(Self {
4420 trader_id,
4421 strategy_id,
4422 instrument_id,
4423 position_id,
4424 account_id,
4425 opening_order_id,
4426 entry,
4427 side,
4428 signed_qty,
4429 quantity,
4430 peak_quantity,
4431 last_qty,
4432 last_px,
4433 currency,
4434 avg_px_open,
4435 avg_px_close,
4436 realized_return,
4437 realized_pnl,
4438 unrealized_pnl,
4439 event_id,
4440 ts_opened: ts_opened.into(),
4441 ts_event: ts_event.into(),
4442 ts_init: ts_init.into(),
4443 })
4444 }
4445}
4446
4447impl<'a> ToCapnp<'a> for PositionClosed {
4449 type Builder = position_capnp::position_closed::Builder<'a>;
4450
4451 fn to_capnp(&self, mut builder: Self::Builder) {
4452 let trader_id_builder = builder.reborrow().init_trader_id();
4453 self.trader_id.to_capnp(trader_id_builder);
4454
4455 let strategy_id_builder = builder.reborrow().init_strategy_id();
4456 self.strategy_id.to_capnp(strategy_id_builder);
4457
4458 let instrument_id_builder = builder.reborrow().init_instrument_id();
4459 self.instrument_id.to_capnp(instrument_id_builder);
4460
4461 let position_id_builder = builder.reborrow().init_position_id();
4462 self.position_id.to_capnp(position_id_builder);
4463
4464 let account_id_builder = builder.reborrow().init_account_id();
4465 self.account_id.to_capnp(account_id_builder);
4466
4467 let opening_order_id_builder = builder.reborrow().init_opening_order_id();
4468 self.opening_order_id.to_capnp(opening_order_id_builder);
4469
4470 self.closing_order_id
4471 .write_capnp(|| builder.reborrow().init_closing_order_id());
4472
4473 builder.set_entry(order_side_to_capnp(self.entry.into()));
4474 builder.set_side(position_side_to_capnp(self.side.into()));
4475 builder.set_signed_qty(self.signed_qty);
4476
4477 let quantity_builder = builder.reborrow().init_quantity();
4478 self.quantity.to_capnp(quantity_builder);
4479
4480 let peak_quantity_builder = builder.reborrow().init_peak_quantity();
4481 self.peak_quantity.to_capnp(peak_quantity_builder);
4482
4483 let last_qty_builder = builder.reborrow().init_last_qty();
4484 self.last_qty.to_capnp(last_qty_builder);
4485
4486 let last_px_builder = builder.reborrow().init_last_px();
4487 self.last_px.to_capnp(last_px_builder);
4488
4489 let currency_builder = builder.reborrow().init_currency();
4490 self.currency.to_capnp(currency_builder);
4491
4492 builder.set_avg_px_open(self.avg_px_open);
4493 builder.set_avg_px_close(self.avg_px_close.unwrap_or(f64::NAN));
4494 builder.set_realized_return(self.realized_return);
4495
4496 self.realized_pnl
4497 .write_capnp(|| builder.reborrow().init_realized_pnl());
4498
4499 let unrealized_pnl_builder = builder.reborrow().init_unrealized_pnl();
4500 self.unrealized_pnl.to_capnp(unrealized_pnl_builder);
4501
4502 builder.set_duration(self.duration.as_u64());
4503
4504 let event_id_builder = builder.reborrow().init_event_id();
4505 self.event_id.to_capnp(event_id_builder);
4506
4507 let mut ts_opened_builder = builder.reborrow().init_ts_opened();
4508 ts_opened_builder.set_value(*self.ts_opened);
4509
4510 if let Some(ts_closed) = self.ts_closed {
4511 let mut ts_closed_builder = builder.reborrow().init_ts_closed();
4512 ts_closed_builder.set_value(*ts_closed);
4513 }
4514
4515 let mut ts_event_builder = builder.reborrow().init_ts_event();
4516 ts_event_builder.set_value(*self.ts_event);
4517
4518 let mut ts_init_builder = builder.reborrow().init_ts_init();
4519 ts_init_builder.set_value(*self.ts_init);
4520 }
4521}
4522
4523impl<'a> FromCapnp<'a> for PositionClosed {
4524 type Reader = position_capnp::position_closed::Reader<'a>;
4525
4526 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4527 let trader_id_reader = reader.get_trader_id()?;
4528 let trader_id = TraderId::from_capnp(trader_id_reader)?;
4529
4530 let strategy_id_reader = reader.get_strategy_id()?;
4531 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4532
4533 let instrument_id_reader = reader.get_instrument_id()?;
4534 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4535
4536 let position_id_reader = reader.get_position_id()?;
4537 let position_id = PositionId::from_capnp(position_id_reader)?;
4538
4539 let account_id_reader = reader.get_account_id()?;
4540 let account_id = AccountId::from_capnp(account_id_reader)?;
4541
4542 let opening_order_id_reader = reader.get_opening_order_id()?;
4543 let opening_order_id = ClientOrderId::from_capnp(opening_order_id_reader)?;
4544
4545 let closing_order_id = read_optional_from_capnp(
4546 || reader.has_closing_order_id(),
4547 || reader.get_closing_order_id(),
4548 )?;
4549
4550 let entry = order_side_required_from_capnp(reader.get_entry()?)?;
4551 let side = position_side_required_from_capnp(reader.get_side()?)?;
4552 let signed_qty = reader.get_signed_qty();
4553
4554 let quantity_reader = reader.get_quantity()?;
4555 let quantity = Quantity::from_capnp(quantity_reader)?;
4556
4557 let peak_quantity_reader = reader.get_peak_quantity()?;
4558 let peak_quantity = Quantity::from_capnp(peak_quantity_reader)?;
4559
4560 let last_qty_reader = reader.get_last_qty()?;
4561 let last_qty = Quantity::from_capnp(last_qty_reader)?;
4562
4563 let last_px_reader = reader.get_last_px()?;
4564 let last_px = Price::from_capnp(last_px_reader)?;
4565
4566 let currency_reader = reader.get_currency()?;
4567 let currency = Currency::from_capnp(currency_reader)?;
4568
4569 let avg_px_open = reader.get_avg_px_open();
4570 let avg_px_close = {
4571 let value = reader.get_avg_px_close();
4572 if value.is_nan() { None } else { Some(value) }
4573 };
4574 let realized_return = reader.get_realized_return();
4575
4576 let realized_pnl =
4577 read_optional_from_capnp(|| reader.has_realized_pnl(), || reader.get_realized_pnl())?;
4578
4579 let unrealized_pnl_reader = reader.get_unrealized_pnl()?;
4580 let unrealized_pnl = Money::from_capnp(unrealized_pnl_reader)?;
4581
4582 let duration = DurationNanos::new(reader.get_duration());
4583
4584 let event_id_reader = reader.get_event_id()?;
4585 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4586
4587 let ts_opened_reader = reader.get_ts_opened()?;
4588 let ts_opened = ts_opened_reader.get_value();
4589
4590 let ts_closed = if reader.has_ts_closed() {
4591 let ts_closed_reader = reader.get_ts_closed()?;
4592 Some(ts_closed_reader.get_value().into())
4593 } else {
4594 None
4595 };
4596
4597 let ts_event_reader = reader.get_ts_event()?;
4598 let ts_event = ts_event_reader.get_value();
4599
4600 let ts_init_reader = reader.get_ts_init()?;
4601 let ts_init = ts_init_reader.get_value();
4602
4603 Ok(Self {
4604 trader_id,
4605 strategy_id,
4606 instrument_id,
4607 position_id,
4608 account_id,
4609 opening_order_id,
4610 closing_order_id,
4611 entry,
4612 side,
4613 signed_qty,
4614 quantity,
4615 peak_quantity,
4616 last_qty,
4617 last_px,
4618 currency,
4619 avg_px_open,
4620 avg_px_close,
4621 realized_return,
4622 realized_pnl,
4623 unrealized_pnl,
4624 duration,
4625 event_id,
4626 ts_opened: ts_opened.into(),
4627 ts_closed,
4628 ts_event: ts_event.into(),
4629 ts_init: ts_init.into(),
4630 })
4631 }
4632}
4633
4634impl<'a> ToCapnp<'a> for PositionAdjusted {
4636 type Builder = position_capnp::position_adjusted::Builder<'a>;
4637
4638 fn to_capnp(&self, mut builder: Self::Builder) {
4639 let trader_id_builder = builder.reborrow().init_trader_id();
4640 self.trader_id.to_capnp(trader_id_builder);
4641
4642 let strategy_id_builder = builder.reborrow().init_strategy_id();
4643 self.strategy_id.to_capnp(strategy_id_builder);
4644
4645 let instrument_id_builder = builder.reborrow().init_instrument_id();
4646 self.instrument_id.to_capnp(instrument_id_builder);
4647
4648 let position_id_builder = builder.reborrow().init_position_id();
4649 self.position_id.to_capnp(position_id_builder);
4650
4651 let account_id_builder = builder.reborrow().init_account_id();
4652 self.account_id.to_capnp(account_id_builder);
4653
4654 builder.set_adjustment_type(position_adjustment_type_to_capnp(self.adjustment_type));
4655
4656 self.quantity_change
4657 .write_capnp(|| builder.reborrow().init_quantity_change());
4658
4659 self.pnl_change
4660 .write_capnp(|| builder.reborrow().init_pnl_change());
4661
4662 if let Some(reason) = self.reason {
4663 builder.set_reason(reason.as_str());
4664 }
4665
4666 let event_id_builder = builder.reborrow().init_event_id();
4667 self.event_id.to_capnp(event_id_builder);
4668
4669 let mut ts_event_builder = builder.reborrow().init_ts_event();
4670 ts_event_builder.set_value(*self.ts_event);
4671
4672 let mut ts_init_builder = builder.reborrow().init_ts_init();
4673 ts_init_builder.set_value(*self.ts_init);
4674 }
4675}
4676
4677impl<'a> FromCapnp<'a> for PositionAdjusted {
4678 type Reader = position_capnp::position_adjusted::Reader<'a>;
4679
4680 fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4681 let trader_id_reader = reader.get_trader_id()?;
4682 let trader_id = TraderId::from_capnp(trader_id_reader)?;
4683
4684 let strategy_id_reader = reader.get_strategy_id()?;
4685 let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4686
4687 let instrument_id_reader = reader.get_instrument_id()?;
4688 let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4689
4690 let position_id_reader = reader.get_position_id()?;
4691 let position_id = PositionId::from_capnp(position_id_reader)?;
4692
4693 let account_id_reader = reader.get_account_id()?;
4694 let account_id = AccountId::from_capnp(account_id_reader)?;
4695
4696 let adjustment_type = position_adjustment_type_from_capnp(reader.get_adjustment_type()?);
4697
4698 let quantity_change = read_optional_from_capnp(
4699 || reader.has_quantity_change(),
4700 || reader.get_quantity_change(),
4701 )?;
4702
4703 let pnl_change =
4704 read_optional_from_capnp(|| reader.has_pnl_change(), || reader.get_pnl_change())?;
4705
4706 let reason = if reader.has_reason() {
4707 Some(Ustr::from(reader.get_reason()?.to_str()?))
4708 } else {
4709 None
4710 };
4711
4712 let event_id_reader = reader.get_event_id()?;
4713 let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4714
4715 let ts_event_reader = reader.get_ts_event()?;
4716 let ts_event = ts_event_reader.get_value();
4717
4718 let ts_init_reader = reader.get_ts_init()?;
4719 let ts_init = ts_init_reader.get_value();
4720
4721 Ok(Self {
4722 trader_id,
4723 strategy_id,
4724 instrument_id,
4725 position_id,
4726 account_id,
4727 adjustment_type,
4728 quantity_change,
4729 pnl_change,
4730 reason,
4731 event_id,
4732 ts_event: ts_event.into(),
4733 ts_init: ts_init.into(),
4734 })
4735 }
4736}
4737
4738#[cfg(test)]
4739mod tests {
4740 use capnp::message::Builder;
4741 use nautilus_core::{DurationNanos, UUID4, UnixNanos};
4742 use nautilus_model::{
4743 data::stubs::*,
4744 events::order::{
4745 spec::{OrderCanceledSpec, OrderFillVoidedSpec},
4746 stubs::*,
4747 },
4748 };
4749 use rstest::rstest;
4750 use rust_decimal::Decimal;
4751 use rust_decimal_macros::dec;
4752
4753 use super::*;
4754
4755 macro_rules! assert_capnp_roundtrip {
4756 ($value:expr, $builder:path, $reader:path, $ty:ty) => {{
4757 let expected: $ty = $value;
4758 let mut message = Builder::new_default();
4759 {
4760 let builder = message.init_root::<$builder>();
4761 expected.to_capnp(builder);
4762 }
4763 let reader = message
4764 .get_root_as_reader::<$reader>()
4765 .expect("capnp reader");
4766 let decoded = <$ty>::from_capnp(reader).expect("capnp decode");
4767 assert_eq!(expected, decoded);
4768 }};
4769 }
4770
4771 macro_rules! capnp_simple_roundtrip_test {
4772 ($name:ident, $value:expr, $builder:path, $reader:path, $ty:ty) => {
4773 #[rstest]
4774 fn $name() {
4775 assert_capnp_roundtrip!($value, $builder, $reader, $ty);
4776 }
4777 };
4778 }
4779
4780 macro_rules! order_fixture_roundtrip_test {
4781 ($name:ident, $fixture:ident, $ty:ty, $builder:path, $reader:path) => {
4782 #[rstest]
4783 fn $name($fixture: $ty) {
4784 assert_capnp_roundtrip!($fixture, $builder, $reader, $ty);
4785 }
4786 };
4787 }
4788
4789 #[rstest]
4790 fn test_instrument_id_roundtrip() {
4791 let instrument_id = InstrumentId::from("AAPL.NASDAQ");
4792 let bytes = serialize_instrument_id(&instrument_id).unwrap();
4793 let decoded = deserialize_instrument_id(&bytes).unwrap();
4794 assert_eq!(instrument_id, decoded);
4795 }
4796
4797 #[rstest]
4798 fn test_price_roundtrip() {
4799 let price = Price::from("123.45");
4800 let bytes = serialize_price(&price).unwrap();
4801 let decoded = deserialize_price(&bytes).unwrap();
4802 assert_eq!(price, decoded);
4803 }
4804
4805 #[rstest]
4806 fn test_quantity_roundtrip() {
4807 let qty = Quantity::from("100.5");
4808 let bytes = serialize_quantity(&qty).unwrap();
4809 let decoded = deserialize_quantity(&bytes).unwrap();
4810 assert_eq!(qty, decoded);
4811 }
4812
4813 #[rstest]
4814 fn test_currency_roundtrip() {
4815 let currency = Currency::USD();
4816 let bytes = serialize_currency(¤cy).unwrap();
4817 let decoded = deserialize_currency(&bytes).unwrap();
4818 assert_currency_fields(currency, decoded);
4819 }
4820
4821 #[rstest]
4822 fn test_currency_crypto_roundtrip() {
4823 let currency = Currency::BTC();
4824 let bytes = serialize_currency(¤cy).unwrap();
4825 let decoded = deserialize_currency(&bytes).unwrap();
4826 assert_currency_fields(currency, decoded);
4827 }
4828
4829 fn assert_currency_fields(expected: Currency, actual: Currency) {
4830 assert_eq!(actual.code, expected.code);
4831 assert_eq!(actual.precision, expected.precision);
4832 assert_eq!(actual.iso4217, expected.iso4217);
4833 assert_eq!(actual.name, expected.name);
4834 assert_eq!(actual.currency_type, expected.currency_type);
4835 }
4836
4837 #[rstest]
4838 fn test_money_roundtrip() {
4839 let money = Money::from_raw(100_000_000, Currency::USD());
4840 let bytes = serialize_money(&money).unwrap();
4841 let decoded = deserialize_money(&bytes).unwrap();
4842 assert_eq!(money, decoded);
4843 }
4844
4845 #[rstest]
4846 fn test_money_negative() {
4847 let money = Money::from_raw(-50_000_000, Currency::USD());
4848 let bytes = serialize_money(&money).unwrap();
4849 let decoded = deserialize_money(&bytes).unwrap();
4850 assert_eq!(money, decoded);
4851 }
4852
4853 #[rstest]
4854 fn test_money_zero() {
4855 let money = Money::from_raw(0, Currency::USD());
4856 let bytes = serialize_money(&money).unwrap();
4857 let decoded = deserialize_money(&bytes).unwrap();
4858 assert_eq!(money, decoded);
4859 }
4860
4861 #[rstest]
4862 fn test_decimal_serialization_layout() {
4863 let decimal = Decimal::from_parts(
4864 0x89ab_cdef,
4865 0x0123_4567,
4866 0x0fed_cba9,
4867 true, 6, );
4870 let mut message = capnp::message::Builder::new_default();
4871 {
4872 let builder = message.init_root::<types_capnp::decimal::Builder>();
4873 decimal.to_capnp(builder);
4874 }
4875
4876 let reader = message
4877 .get_root_as_reader::<types_capnp::decimal::Reader>()
4878 .expect("reader");
4879
4880 let serialized = decimal.serialize();
4881 let expected_flags = u32::from_le_bytes(serialized[0..4].try_into().expect("flags slice"));
4882
4883 assert_eq!(reader.get_flags(), expected_flags);
4884 assert_eq!(reader.get_lo(), 0x89ab_cdef);
4885 assert_eq!(reader.get_mid(), 0x0123_4567);
4886 assert_eq!(reader.get_hi(), 0x0fed_cba9);
4887 }
4888
4889 #[rstest]
4890 #[case::positive(false, 9)]
4891 #[case::negative(true, 9)]
4892 #[case::maximum_scale_positive(false, Decimal::MAX_SCALE)]
4893 #[case::maximum_scale_negative(true, Decimal::MAX_SCALE)]
4894 fn test_decimal_roundtrip_preserves_scale_and_sign(#[case] negative: bool, #[case] scale: u32) {
4895 let decimal = Decimal::from_parts(0xffff_ffff, 0x7fff_ffff, 0x0000_00ff, negative, scale);
4896
4897 let mut message = capnp::message::Builder::new_default();
4898 {
4899 let builder = message.init_root::<types_capnp::decimal::Builder>();
4900 decimal.to_capnp(builder);
4901 }
4902
4903 let reader = message
4904 .get_root_as_reader::<types_capnp::decimal::Reader>()
4905 .expect("reader");
4906 let decoded = Decimal::from_capnp(reader).expect("decoded decimal");
4907 assert_eq!(decimal, decoded);
4908 assert_eq!(decimal.serialize(), decoded.serialize());
4909 }
4910
4911 #[rstest]
4912 fn test_account_balance_roundtrip() {
4913 let total = Money::new(100.0, Currency::USD());
4914 let locked = Money::new(10.0, Currency::USD());
4915 let free = Money::new(90.0, Currency::USD());
4916 let balance = AccountBalance::new(total, locked, free);
4917 let bytes = serialize_account_balance(&balance).unwrap();
4918 let decoded = deserialize_account_balance(&bytes).unwrap();
4919 assert_eq!(balance, decoded);
4920 }
4921
4922 #[rstest]
4923 fn test_margin_balance_roundtrip() {
4924 let initial = Money::new(500.0, Currency::USD());
4925 let maintenance = Money::new(250.0, Currency::USD());
4926 let instrument_id = InstrumentId::from("BTC-USD-PERP.BINANCE");
4927 let balance = MarginBalance::new(initial, maintenance, Some(instrument_id));
4928 let bytes = serialize_margin_balance(&balance).unwrap();
4929 let decoded = deserialize_margin_balance(&bytes).unwrap();
4930 assert_eq!(balance, decoded);
4931 }
4932
4933 #[rstest]
4934 fn test_margin_balance_account_scope_roundtrip() {
4935 let initial = Money::new(500.0, Currency::USD());
4936 let maintenance = Money::new(250.0, Currency::USD());
4937 let balance = MarginBalance::new(initial, maintenance, None);
4938 let bytes = serialize_margin_balance(&balance).unwrap();
4939 let decoded = deserialize_margin_balance(&bytes).unwrap();
4940 assert_eq!(balance, decoded);
4941 assert!(decoded.instrument_id.is_none());
4942 }
4943
4944 capnp_simple_roundtrip_test!(
4946 trader_id_capnp_roundtrip,
4947 TraderId::from("TRADER-CAPNP"),
4948 identifiers_capnp::trader_id::Builder,
4949 identifiers_capnp::trader_id::Reader,
4950 TraderId
4951 );
4952 capnp_simple_roundtrip_test!(
4953 strategy_id_capnp_roundtrip,
4954 StrategyId::from("STRATEGY-CAPNP"),
4955 identifiers_capnp::strategy_id::Builder,
4956 identifiers_capnp::strategy_id::Reader,
4957 StrategyId
4958 );
4959 capnp_simple_roundtrip_test!(
4960 actor_id_capnp_roundtrip,
4961 ActorId::from("ACTOR-CAPNP"),
4962 identifiers_capnp::actor_id::Builder,
4963 identifiers_capnp::actor_id::Reader,
4964 ActorId
4965 );
4966 capnp_simple_roundtrip_test!(
4967 account_id_capnp_roundtrip,
4968 AccountId::from("ACCOUNT-CAPNP"),
4969 identifiers_capnp::account_id::Builder,
4970 identifiers_capnp::account_id::Reader,
4971 AccountId
4972 );
4973 capnp_simple_roundtrip_test!(
4974 client_id_capnp_roundtrip,
4975 ClientId::from("CLIENT-CAPNP"),
4976 identifiers_capnp::client_id::Builder,
4977 identifiers_capnp::client_id::Reader,
4978 ClientId
4979 );
4980 capnp_simple_roundtrip_test!(
4981 client_order_id_capnp_roundtrip,
4982 ClientOrderId::from("O-20240101-000000-001-001-1"),
4983 identifiers_capnp::client_order_id::Builder,
4984 identifiers_capnp::client_order_id::Reader,
4985 ClientOrderId
4986 );
4987 capnp_simple_roundtrip_test!(
4988 venue_order_id_capnp_roundtrip,
4989 VenueOrderId::from("V-ORDER-1"),
4990 identifiers_capnp::venue_order_id::Builder,
4991 identifiers_capnp::venue_order_id::Reader,
4992 VenueOrderId
4993 );
4994 capnp_simple_roundtrip_test!(
4995 trade_id_capnp_roundtrip,
4996 TradeId::from("TRADE-12345"),
4997 identifiers_capnp::trade_id::Builder,
4998 identifiers_capnp::trade_id::Reader,
4999 TradeId
5000 );
5001 capnp_simple_roundtrip_test!(
5002 position_id_capnp_roundtrip,
5003 PositionId::from("POSITION-1"),
5004 identifiers_capnp::position_id::Builder,
5005 identifiers_capnp::position_id::Reader,
5006 PositionId
5007 );
5008 capnp_simple_roundtrip_test!(
5009 exec_algorithm_id_capnp_roundtrip,
5010 ExecAlgorithmId::from("EXEC-1"),
5011 identifiers_capnp::exec_algorithm_id::Builder,
5012 identifiers_capnp::exec_algorithm_id::Reader,
5013 ExecAlgorithmId
5014 );
5015 capnp_simple_roundtrip_test!(
5016 component_id_capnp_roundtrip,
5017 ComponentId::from("COMPONENT-RISK"),
5018 identifiers_capnp::component_id::Builder,
5019 identifiers_capnp::component_id::Reader,
5020 ComponentId
5021 );
5022 capnp_simple_roundtrip_test!(
5023 order_list_id_capnp_roundtrip,
5024 OrderListId::from("LIST-1"),
5025 identifiers_capnp::order_list_id::Builder,
5026 identifiers_capnp::order_list_id::Reader,
5027 OrderListId
5028 );
5029 capnp_simple_roundtrip_test!(
5030 symbol_capnp_roundtrip,
5031 Symbol::from("ETH-PERP"),
5032 identifiers_capnp::symbol::Builder,
5033 identifiers_capnp::symbol::Reader,
5034 Symbol
5035 );
5036 capnp_simple_roundtrip_test!(
5037 venue_capnp_roundtrip,
5038 Venue::from("BINANCE"),
5039 identifiers_capnp::venue::Builder,
5040 identifiers_capnp::venue::Reader,
5041 Venue
5042 );
5043 capnp_simple_roundtrip_test!(
5044 uuid4_capnp_roundtrip,
5045 uuid4(),
5046 base_capnp::u_u_i_d4::Builder,
5047 base_capnp::u_u_i_d4::Reader,
5048 nautilus_core::UUID4
5049 );
5050
5051 capnp_simple_roundtrip_test!(
5053 quote_tick_capnp_roundtrip,
5054 quote_ethusdt_binance(),
5055 market_capnp::quote_tick::Builder,
5056 market_capnp::quote_tick::Reader,
5057 QuoteTick
5058 );
5059 capnp_simple_roundtrip_test!(
5060 trade_tick_capnp_roundtrip,
5061 stub_trade_ethusdt_buy(),
5062 market_capnp::trade_tick::Builder,
5063 market_capnp::trade_tick::Reader,
5064 TradeTick
5065 );
5066 capnp_simple_roundtrip_test!(
5067 bar_specification_capnp_roundtrip,
5068 sample_bar_specification(),
5069 market_capnp::bar_spec::Builder,
5070 market_capnp::bar_spec::Reader,
5071 BarSpecification
5072 );
5073 capnp_simple_roundtrip_test!(
5074 bar_type_standard_capnp_roundtrip,
5075 sample_bar_type_standard(),
5076 market_capnp::bar_type::Builder,
5077 market_capnp::bar_type::Reader,
5078 BarType
5079 );
5080 capnp_simple_roundtrip_test!(
5081 bar_capnp_roundtrip,
5082 stub_bar(),
5083 market_capnp::bar::Builder,
5084 market_capnp::bar::Reader,
5085 Bar
5086 );
5087 capnp_simple_roundtrip_test!(
5088 book_order_capnp_roundtrip,
5089 stub_book_order(),
5090 market_capnp::book_order::Builder,
5091 market_capnp::book_order::Reader,
5092 BookOrder
5093 );
5094 capnp_simple_roundtrip_test!(
5095 order_book_delta_capnp_roundtrip,
5096 stub_delta(),
5097 market_capnp::order_book_delta::Builder,
5098 market_capnp::order_book_delta::Reader,
5099 OrderBookDelta
5100 );
5101 capnp_simple_roundtrip_test!(
5102 order_book_deltas_capnp_roundtrip,
5103 stub_deltas(),
5104 market_capnp::order_book_deltas::Builder,
5105 market_capnp::order_book_deltas::Reader,
5106 OrderBookDeltas
5107 );
5108 capnp_simple_roundtrip_test!(
5109 order_book_depth_capnp_roundtrip,
5110 sample_order_book_depth(),
5111 market_capnp::order_book_depth::Builder,
5112 market_capnp::order_book_depth::Reader,
5113 OrderBookDepth
5114 );
5115 capnp_simple_roundtrip_test!(
5116 mark_price_update_capnp_roundtrip,
5117 sample_mark_price_update(),
5118 market_capnp::mark_price_update::Builder,
5119 market_capnp::mark_price_update::Reader,
5120 MarkPriceUpdate
5121 );
5122 capnp_simple_roundtrip_test!(
5123 index_price_update_capnp_roundtrip,
5124 sample_index_price_update(),
5125 market_capnp::index_price_update::Builder,
5126 market_capnp::index_price_update::Reader,
5127 IndexPriceUpdate
5128 );
5129 capnp_simple_roundtrip_test!(
5130 funding_rate_update_capnp_roundtrip,
5131 sample_funding_rate_update(),
5132 market_capnp::funding_rate_update::Builder,
5133 market_capnp::funding_rate_update::Reader,
5134 FundingRateUpdate
5135 );
5136 capnp_simple_roundtrip_test!(
5137 option_greeks_capnp_roundtrip,
5138 sample_option_greeks(),
5139 market_capnp::option_greeks::Builder,
5140 market_capnp::option_greeks::Reader,
5141 OptionGreeks
5142 );
5143 capnp_simple_roundtrip_test!(
5144 option_greeks_black_scholes_zero_optional_capnp_roundtrip,
5145 sample_option_greeks_black_scholes_zero_optional(),
5146 market_capnp::option_greeks::Builder,
5147 market_capnp::option_greeks::Reader,
5148 OptionGreeks
5149 );
5150 capnp_simple_roundtrip_test!(
5151 instrument_close_capnp_roundtrip,
5152 stub_instrument_close(),
5153 market_capnp::instrument_close::Builder,
5154 market_capnp::instrument_close::Reader,
5155 InstrumentClose
5156 );
5157 capnp_simple_roundtrip_test!(
5158 instrument_status_capnp_roundtrip,
5159 sample_instrument_status_event(),
5160 market_capnp::instrument_status::Builder,
5161 market_capnp::instrument_status::Reader,
5162 InstrumentStatus
5163 );
5164
5165 order_fixture_roundtrip_test!(
5167 order_filled_capnp_roundtrip,
5168 order_filled,
5169 OrderFilled,
5170 order_capnp::order_filled::Builder,
5171 order_capnp::order_filled::Reader
5172 );
5173 capnp_simple_roundtrip_test!(
5174 order_fill_voided_capnp_roundtrip,
5175 OrderFillVoidedSpec::builder().is_reopened(true).build(),
5176 order_capnp::order_fill_voided::Builder,
5177 order_capnp::order_fill_voided::Reader,
5178 OrderFillVoided
5179 );
5180 capnp_simple_roundtrip_test!(
5181 order_fill_voided_populated_optionals_capnp_roundtrip,
5182 {
5183 let mut event = OrderFillVoidedSpec::builder()
5184 .voided_qty(Quantity::from("0.561000"))
5185 .commission_voided(Money::from("12.20000000 USDT"))
5186 .position_id(PositionId::from("P-001"))
5187 .reason(Ustr::from("VENUE_VOID"))
5188 .info(IndexMap::from([(Ustr::from("source"), Ustr::from("test"))]))
5189 .is_reopened(true)
5190 .build();
5191 event.causation_id = Some(UUID4::new());
5192 event
5193 },
5194 order_capnp::order_fill_voided::Builder,
5195 order_capnp::order_fill_voided::Reader,
5196 OrderFillVoided
5197 );
5198 order_fixture_roundtrip_test!(
5199 order_denied_capnp_roundtrip,
5200 order_denied_max_submitted_rate,
5201 OrderDenied,
5202 order_capnp::order_denied::Builder,
5203 order_capnp::order_denied::Reader
5204 );
5205 order_fixture_roundtrip_test!(
5206 order_rejected_capnp_roundtrip,
5207 order_rejected_insufficient_margin,
5208 OrderRejected,
5209 order_capnp::order_rejected::Builder,
5210 order_capnp::order_rejected::Reader
5211 );
5212 order_fixture_roundtrip_test!(
5213 order_initialized_capnp_roundtrip,
5214 order_initialized_buy_limit,
5215 OrderInitialized,
5216 order_capnp::order_initialized::Builder,
5217 order_capnp::order_initialized::Reader
5218 );
5219 #[rstest]
5220 fn order_initialized_activation_price_capnp_roundtrip(
5221 order_initialized_buy_limit: OrderInitialized,
5222 ) {
5223 let initialized = OrderInitialized {
5224 activation_price: Some(Price::from("21000")),
5225 ..order_initialized_buy_limit
5226 };
5227 assert_capnp_roundtrip!(
5228 initialized,
5229 order_capnp::order_initialized::Builder,
5230 order_capnp::order_initialized::Reader,
5231 OrderInitialized
5232 );
5233 }
5234
5235 #[rstest]
5236 #[case::empty(false)]
5237 #[case::populated(true)]
5238 fn order_initialized_optional_collections_capnp_roundtrip(
5239 order_initialized_buy_limit: OrderInitialized,
5240 #[case] populated: bool,
5241 ) {
5242 let initialized = OrderInitialized {
5243 expire_time: Some(UnixNanos::from(123_456)),
5244 linked_order_ids: Some(if populated {
5245 vec![ClientOrderId::from("O-101"), ClientOrderId::from("O-202")]
5246 } else {
5247 vec![]
5248 }),
5249 exec_algorithm_params: Some(if populated {
5250 IndexMap::from([
5251 (Ustr::from("interval"), Ustr::from("17")),
5252 (Ustr::from("duration"), Ustr::from("53")),
5253 ])
5254 } else {
5255 IndexMap::new()
5256 }),
5257 tags: Some(if populated {
5258 vec![Ustr::from("first"), Ustr::from("second")]
5259 } else {
5260 vec![]
5261 }),
5262 ..order_initialized_buy_limit
5263 };
5264
5265 let mut message = Builder::new_default();
5266 initialized.to_capnp(message.init_root::<order_capnp::order_initialized::Builder>());
5267 let reader = message
5268 .get_root_as_reader::<order_capnp::order_initialized::Reader>()
5269 .unwrap();
5270 let decoded = OrderInitialized::from_capnp(reader).unwrap();
5271
5272 assert_eq!(
5273 serde_json::to_value(&decoded).unwrap(),
5274 serde_json::to_value(&initialized).unwrap()
5275 );
5276 assert_eq!(
5277 decoded
5278 .exec_algorithm_params
5279 .unwrap()
5280 .into_iter()
5281 .collect::<Vec<_>>(),
5282 initialized
5283 .exec_algorithm_params
5284 .unwrap()
5285 .into_iter()
5286 .collect::<Vec<_>>()
5287 );
5288 }
5289
5290 #[rstest]
5291 fn order_filled_info_capnp_roundtrip(order_filled: OrderFilled) {
5292 let mut info = IndexMap::new();
5293 info.insert(Ustr::from("liquidation"), Ustr::from("true"));
5294 info.insert(Ustr::from("maker_order_id"), Ustr::from("ABC-123"));
5295 let filled = OrderFilled {
5296 info: Some(info),
5297 ..order_filled
5298 };
5299 assert_capnp_roundtrip!(
5300 filled,
5301 order_capnp::order_filled::Builder,
5302 order_capnp::order_filled::Reader,
5303 OrderFilled
5304 );
5305 }
5306 order_fixture_roundtrip_test!(
5307 order_submitted_capnp_roundtrip,
5308 order_submitted,
5309 OrderSubmitted,
5310 order_capnp::order_submitted::Builder,
5311 order_capnp::order_submitted::Reader
5312 );
5313 order_fixture_roundtrip_test!(
5314 order_triggered_capnp_roundtrip,
5315 order_triggered,
5316 OrderTriggered,
5317 order_capnp::order_triggered::Builder,
5318 order_capnp::order_triggered::Reader
5319 );
5320 order_fixture_roundtrip_test!(
5321 order_emulated_capnp_roundtrip,
5322 order_emulated,
5323 OrderEmulated,
5324 order_capnp::order_emulated::Builder,
5325 order_capnp::order_emulated::Reader
5326 );
5327 order_fixture_roundtrip_test!(
5328 order_released_capnp_roundtrip,
5329 order_released,
5330 OrderReleased,
5331 order_capnp::order_released::Builder,
5332 order_capnp::order_released::Reader
5333 );
5334 order_fixture_roundtrip_test!(
5335 order_updated_capnp_roundtrip,
5336 order_updated,
5337 OrderUpdated,
5338 order_capnp::order_updated::Builder,
5339 order_capnp::order_updated::Reader
5340 );
5341 order_fixture_roundtrip_test!(
5342 order_pending_update_capnp_roundtrip,
5343 order_pending_update,
5344 OrderPendingUpdate,
5345 order_capnp::order_pending_update::Builder,
5346 order_capnp::order_pending_update::Reader
5347 );
5348 order_fixture_roundtrip_test!(
5349 order_pending_cancel_capnp_roundtrip,
5350 order_pending_cancel,
5351 OrderPendingCancel,
5352 order_capnp::order_pending_cancel::Builder,
5353 order_capnp::order_pending_cancel::Reader
5354 );
5355 #[rstest]
5356 fn order_pending_update_none_account_capnp_roundtrip(order_pending_update: OrderPendingUpdate) {
5357 let event = OrderPendingUpdate {
5358 account_id: None,
5359 ..order_pending_update
5360 };
5361 assert_capnp_roundtrip!(
5362 event,
5363 order_capnp::order_pending_update::Builder,
5364 order_capnp::order_pending_update::Reader,
5365 OrderPendingUpdate
5366 );
5367 }
5368 #[rstest]
5369 fn order_pending_cancel_none_account_capnp_roundtrip(order_pending_cancel: OrderPendingCancel) {
5370 let event = OrderPendingCancel {
5371 account_id: None,
5372 ..order_pending_cancel
5373 };
5374 assert_capnp_roundtrip!(
5375 event,
5376 order_capnp::order_pending_cancel::Builder,
5377 order_capnp::order_pending_cancel::Reader,
5378 OrderPendingCancel
5379 );
5380 }
5381 order_fixture_roundtrip_test!(
5382 order_modify_rejected_capnp_roundtrip,
5383 order_modify_rejected,
5384 OrderModifyRejected,
5385 order_capnp::order_modify_rejected::Builder,
5386 order_capnp::order_modify_rejected::Reader
5387 );
5388 order_fixture_roundtrip_test!(
5389 order_accepted_capnp_roundtrip,
5390 order_accepted,
5391 OrderAccepted,
5392 order_capnp::order_accepted::Builder,
5393 order_capnp::order_accepted::Reader
5394 );
5395 order_fixture_roundtrip_test!(
5396 order_cancel_rejected_capnp_roundtrip,
5397 order_cancel_rejected,
5398 OrderCancelRejected,
5399 order_capnp::order_cancel_rejected::Builder,
5400 order_capnp::order_cancel_rejected::Reader
5401 );
5402 order_fixture_roundtrip_test!(
5403 order_expired_capnp_roundtrip,
5404 order_expired,
5405 OrderExpired,
5406 order_capnp::order_expired::Builder,
5407 order_capnp::order_expired::Reader
5408 );
5409 #[rstest]
5410 fn order_canceled_capnp_roundtrip() {
5411 assert_capnp_roundtrip!(
5412 sample_order_canceled(),
5413 order_capnp::order_canceled::Builder,
5414 order_capnp::order_canceled::Reader,
5415 OrderCanceled
5416 );
5417 }
5418
5419 #[rstest]
5420 fn order_canceled_none_reason_capnp_roundtrip() {
5421 let event = OrderCanceled {
5422 reason: None,
5423 ..sample_order_canceled()
5424 };
5425 assert_capnp_roundtrip!(
5426 event,
5427 order_capnp::order_canceled::Builder,
5428 order_capnp::order_canceled::Reader,
5429 OrderCanceled
5430 );
5431 }
5432
5433 #[rstest]
5435 fn position_opened_capnp_roundtrip() {
5436 assert_capnp_roundtrip!(
5437 sample_position_opened(),
5438 position_capnp::position_opened::Builder,
5439 position_capnp::position_opened::Reader,
5440 PositionOpened
5441 );
5442 }
5443
5444 #[rstest]
5445 fn position_opened_none_realized_pnl_capnp_roundtrip() {
5446 let event = PositionOpened {
5447 realized_pnl: None,
5448 ..sample_position_opened()
5449 };
5450 assert_capnp_roundtrip!(
5451 event,
5452 position_capnp::position_opened::Builder,
5453 position_capnp::position_opened::Reader,
5454 PositionOpened
5455 );
5456 }
5457
5458 #[rstest]
5459 fn position_changed_capnp_roundtrip() {
5460 assert_capnp_roundtrip!(
5461 sample_position_changed(),
5462 position_capnp::position_changed::Builder,
5463 position_capnp::position_changed::Reader,
5464 PositionChanged
5465 );
5466 }
5467
5468 #[rstest]
5469 fn position_closed_capnp_roundtrip() {
5470 assert_capnp_roundtrip!(
5471 sample_position_closed(),
5472 position_capnp::position_closed::Builder,
5473 position_capnp::position_closed::Reader,
5474 PositionClosed
5475 );
5476 }
5477
5478 #[rstest]
5479 fn position_adjusted_capnp_roundtrip() {
5480 assert_capnp_roundtrip!(
5481 sample_position_adjusted(),
5482 position_capnp::position_adjusted::Builder,
5483 position_capnp::position_adjusted::Reader,
5484 PositionAdjusted
5485 );
5486 }
5487
5488 fn sample_bar_specification() -> BarSpecification {
5489 BarSpecification::new(5, BarAggregation::Minute, PriceType::Last)
5490 }
5491
5492 fn sample_bar_type_standard() -> BarType {
5493 BarType::new(
5494 InstrumentId::from("AUDUSD.SIM"),
5495 sample_bar_specification(),
5496 AggregationSource::External,
5497 )
5498 }
5499
5500 fn sample_mark_price_update() -> MarkPriceUpdate {
5501 MarkPriceUpdate::new(
5502 InstrumentId::from("BTCUSD-PERP.BINANCE"),
5503 Price::from("42000.123"),
5504 UnixNanos::from(1),
5505 UnixNanos::from(2),
5506 )
5507 }
5508
5509 fn sample_index_price_update() -> IndexPriceUpdate {
5510 IndexPriceUpdate::new(
5511 InstrumentId::from("BTCUSD-PERP.BINANCE"),
5512 Price::from("41950.500"),
5513 UnixNanos::from(3),
5514 UnixNanos::from(4),
5515 )
5516 }
5517
5518 fn sample_funding_rate_update() -> FundingRateUpdate {
5519 FundingRateUpdate::new(
5520 InstrumentId::from("BTCUSD-PERP.BINANCE"),
5521 dec!(0.0001),
5522 Some(60),
5523 Some(UnixNanos::from(1_000_000)),
5524 UnixNanos::from(5),
5525 UnixNanos::from(6),
5526 )
5527 }
5528
5529 fn sample_option_greeks() -> OptionGreeks {
5530 OptionGreeks {
5531 instrument_id: InstrumentId::from("BTC-30JUN23-40000-C.DERIBIT"),
5532 convention: GreeksConvention::PriceAdjusted,
5533 greeks: OptionGreekValues {
5534 delta: 0.525,
5535 gamma: 0.00032,
5536 vega: 12.25,
5537 theta: -0.72,
5538 rho: 0.18,
5539 },
5540 mark_iv: Some(0.52),
5541 bid_iv: None,
5542 ask_iv: Some(0.54),
5543 underlying_price: Some(41_500.25),
5544 open_interest: None,
5545 ts_event: UnixNanos::from(7),
5546 ts_init: UnixNanos::from(8),
5547 }
5548 }
5549
5550 fn sample_option_greeks_black_scholes_zero_optional() -> OptionGreeks {
5551 OptionGreeks {
5552 instrument_id: InstrumentId::from("ETH-30JUN23-2000-C.DERIBIT"),
5553 convention: GreeksConvention::BlackScholes,
5554 greeks: OptionGreekValues {
5555 delta: 0.12,
5556 gamma: 0.002,
5557 vega: 8.0,
5558 theta: -0.45,
5559 rho: 0.06,
5560 },
5561 mark_iv: Some(0.0),
5562 bid_iv: Some(0.0),
5563 ask_iv: Some(0.0),
5564 underlying_price: Some(0.0),
5565 open_interest: Some(0.0),
5566 ts_event: UnixNanos::from(9),
5567 ts_init: UnixNanos::from(10),
5568 }
5569 }
5570
5571 fn sample_instrument_status_event() -> InstrumentStatus {
5572 InstrumentStatus::new(
5573 InstrumentId::from("MSFT.XNAS"),
5574 MarketStatusAction::Trading,
5575 UnixNanos::from(1),
5576 UnixNanos::from(2),
5577 Some(Ustr::from("Normal trading")),
5578 Some(Ustr::from("MARKET_OPEN")),
5579 Some(true),
5580 Some(true),
5581 Some(false),
5582 )
5583 }
5584
5585 fn sample_order_canceled() -> OrderCanceled {
5586 OrderCanceledSpec::builder()
5587 .strategy_id(strategy_id_ema_cross())
5588 .instrument_id(instrument_id_btc_usdt())
5589 .ts_event(UnixNanos::from(7))
5590 .ts_init(UnixNanos::from(8))
5591 .reconciliation(true)
5592 .venue_order_id(venue_order_id())
5593 .account_id(account_id())
5594 .reason(Ustr::from("not-enough-liquidity"))
5595 .build()
5596 }
5597
5598 fn sample_order_book_depth() -> OrderBookDepth {
5599 const LEVELS: usize = 10;
5600 let instrument_id = InstrumentId::from("AAPL.XNAS");
5601 let mut bids = [BookOrder::default(); LEVELS];
5602 let mut asks = [BookOrder::default(); LEVELS];
5603 for i in 0..LEVELS {
5604 bids[i] = BookOrder::new(
5605 OrderSide::Buy,
5606 Price::new(100.0 - i as f64, 2),
5607 Quantity::new(1.0 + i as f64, 2),
5608 0,
5609 );
5610 asks[i] = BookOrder::new(
5611 OrderSide::Sell,
5612 Price::new(101.0 + i as f64, 2),
5613 Quantity::new(1.0 + i as f64, 2),
5614 0,
5615 );
5616 }
5617 let bid_counts = [1_u32; LEVELS];
5618 let ask_counts = [1_u32; LEVELS];
5619 OrderBookDepth::new(
5620 instrument_id,
5621 bids,
5622 asks,
5623 bid_counts,
5624 ask_counts,
5625 0,
5626 1,
5627 UnixNanos::from(9),
5628 UnixNanos::from(10),
5629 )
5630 }
5631
5632 fn sample_position_opened() -> PositionOpened {
5633 PositionOpened {
5634 trader_id: trader_id(),
5635 strategy_id: strategy_id_ema_cross(),
5636 instrument_id: instrument_id_btc_usdt(),
5637 position_id: PositionId::from("P-OPEN"),
5638 account_id: account_id(),
5639 opening_order_id: client_order_id(),
5640 entry: OrderSide::Buy,
5641 side: PositionSide::Long,
5642 signed_qty: 100.0,
5643 quantity: Quantity::from("100"),
5644 last_qty: Quantity::from("100"),
5645 last_px: Price::from("20000"),
5646 currency: Currency::USD(),
5647 avg_px_open: 20000.0,
5648 realized_pnl: Some(Money::new(-0.5, Currency::USD())),
5649 event_id: uuid4(),
5650 ts_event: UnixNanos::from(9),
5651 ts_init: UnixNanos::from(10),
5652 }
5653 }
5654
5655 fn sample_position_changed() -> PositionChanged {
5656 PositionChanged {
5657 trader_id: trader_id(),
5658 strategy_id: strategy_id_ema_cross(),
5659 instrument_id: instrument_id_btc_usdt(),
5660 position_id: PositionId::from("P-CHANGED"),
5661 account_id: account_id(),
5662 opening_order_id: client_order_id(),
5663 entry: OrderSide::Buy,
5664 side: PositionSide::Long,
5665 signed_qty: 150.0,
5666 quantity: Quantity::from("150"),
5667 peak_quantity: Quantity::from("175"),
5668 last_qty: Quantity::from("50"),
5669 last_px: Price::from("20100"),
5670 currency: Currency::USD(),
5671 avg_px_open: 19950.0,
5672 avg_px_close: Some(20100.0),
5673 realized_return: 0.01,
5674 realized_pnl: Some(Money::new(150.0, Currency::USD())),
5675 unrealized_pnl: Money::new(75.0, Currency::USD()),
5676 event_id: uuid4(),
5677 ts_opened: UnixNanos::from(11),
5678 ts_event: UnixNanos::from(12),
5679 ts_init: UnixNanos::from(13),
5680 }
5681 }
5682
5683 fn sample_position_closed() -> PositionClosed {
5684 PositionClosed {
5685 trader_id: trader_id(),
5686 strategy_id: strategy_id_ema_cross(),
5687 instrument_id: instrument_id_btc_usdt(),
5688 position_id: PositionId::from("P-CLOSED"),
5689 account_id: account_id(),
5690 opening_order_id: client_order_id(),
5691 closing_order_id: Some(ClientOrderId::from("O-19700101-000000-001-001-9")),
5692 entry: OrderSide::Buy,
5693 side: PositionSide::Flat,
5694 signed_qty: 0.0,
5695 quantity: Quantity::from("0"),
5696 peak_quantity: Quantity::from("200"),
5697 last_qty: Quantity::from("200"),
5698 last_px: Price::from("20500"),
5699 currency: Currency::USD(),
5700 avg_px_open: 20000.0,
5701 avg_px_close: Some(20500.0),
5702 realized_return: 0.025,
5703 realized_pnl: Some(Money::new(1000.0, Currency::USD())),
5704 unrealized_pnl: Money::new(0.0, Currency::USD()),
5705 duration: DurationNanos::from_millis(1),
5706 event_id: uuid4(),
5707 ts_opened: UnixNanos::from(14),
5708 ts_closed: Some(UnixNanos::from(15)),
5709 ts_event: UnixNanos::from(15),
5710 ts_init: UnixNanos::from(16),
5711 }
5712 }
5713
5714 fn sample_position_adjusted() -> PositionAdjusted {
5715 PositionAdjusted::new(
5716 trader_id(),
5717 strategy_id_ema_cross(),
5718 instrument_id_btc_usdt(),
5719 PositionId::from("P-ADJUST"),
5720 account_id(),
5721 PositionAdjustmentType::Funding,
5722 Some(dec!(-0.001)),
5723 Some(Money::new(-5.5, Currency::USD())),
5724 Some(Ustr::from("funding_2024-01-15")),
5725 uuid4(),
5726 UnixNanos::from(17),
5727 UnixNanos::from(18),
5728 )
5729 }
5730}