nautilus_serialization/capnp/
conversions.rs

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