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
1328pub fn serialize_instrument_id(id: &InstrumentId) -> Result<Vec<u8>, Box<dyn Error>> {
1329    let mut message = capnp::message::Builder::new_default();
1330    let builder = message.init_root::<identifiers_capnp::instrument_id::Builder>();
1331    id.to_capnp(builder);
1332
1333    let mut bytes = Vec::new();
1334    capnp::serialize::write_message(&mut bytes, &message)?;
1335    Ok(bytes)
1336}
1337
1338pub fn deserialize_instrument_id(bytes: &[u8]) -> Result<InstrumentId, Box<dyn Error>> {
1339    let reader =
1340        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1341    let root = reader.get_root::<identifiers_capnp::instrument_id::Reader>()?;
1342    InstrumentId::from_capnp(root)
1343}
1344
1345pub fn serialize_price(price: &Price) -> Result<Vec<u8>, Box<dyn Error>> {
1346    let mut message = capnp::message::Builder::new_default();
1347    let builder = message.init_root::<types_capnp::price::Builder>();
1348    price.to_capnp(builder);
1349
1350    let mut bytes = Vec::new();
1351    capnp::serialize::write_message(&mut bytes, &message)?;
1352    Ok(bytes)
1353}
1354
1355pub fn deserialize_price(bytes: &[u8]) -> Result<Price, Box<dyn Error>> {
1356    let reader =
1357        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1358    let root = reader.get_root::<types_capnp::price::Reader>()?;
1359    Price::from_capnp(root)
1360}
1361
1362pub fn serialize_quantity(qty: &Quantity) -> Result<Vec<u8>, Box<dyn Error>> {
1363    let mut message = capnp::message::Builder::new_default();
1364    let builder = message.init_root::<types_capnp::quantity::Builder>();
1365    qty.to_capnp(builder);
1366
1367    let mut bytes = Vec::new();
1368    capnp::serialize::write_message(&mut bytes, &message)?;
1369    Ok(bytes)
1370}
1371
1372pub fn deserialize_quantity(bytes: &[u8]) -> Result<Quantity, Box<dyn Error>> {
1373    let reader =
1374        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1375    let root = reader.get_root::<types_capnp::quantity::Reader>()?;
1376    Quantity::from_capnp(root)
1377}
1378
1379pub fn serialize_currency(currency: &Currency) -> Result<Vec<u8>, Box<dyn Error>> {
1380    let mut message = capnp::message::Builder::new_default();
1381    let builder = message.init_root::<types_capnp::currency::Builder>();
1382    currency.to_capnp(builder);
1383
1384    let mut bytes = Vec::new();
1385    capnp::serialize::write_message(&mut bytes, &message)?;
1386    Ok(bytes)
1387}
1388
1389pub fn deserialize_currency(bytes: &[u8]) -> Result<Currency, Box<dyn Error>> {
1390    let reader =
1391        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1392    let root = reader.get_root::<types_capnp::currency::Reader>()?;
1393    Currency::from_capnp(root)
1394}
1395
1396pub fn serialize_money(money: &Money) -> Result<Vec<u8>, Box<dyn Error>> {
1397    let mut message = capnp::message::Builder::new_default();
1398    let builder = message.init_root::<types_capnp::money::Builder>();
1399    money.to_capnp(builder);
1400
1401    let mut bytes = Vec::new();
1402    capnp::serialize::write_message(&mut bytes, &message)?;
1403    Ok(bytes)
1404}
1405
1406pub fn deserialize_money(bytes: &[u8]) -> Result<Money, Box<dyn Error>> {
1407    let reader =
1408        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1409    let root = reader.get_root::<types_capnp::money::Reader>()?;
1410    Money::from_capnp(root)
1411}
1412
1413pub fn serialize_account_balance(balance: &AccountBalance) -> Result<Vec<u8>, Box<dyn Error>> {
1414    let mut message = capnp::message::Builder::new_default();
1415    let builder = message.init_root::<types_capnp::account_balance::Builder>();
1416    balance.to_capnp(builder);
1417
1418    let mut bytes = Vec::new();
1419    capnp::serialize::write_message(&mut bytes, &message)?;
1420    Ok(bytes)
1421}
1422
1423pub fn deserialize_account_balance(bytes: &[u8]) -> Result<AccountBalance, Box<dyn Error>> {
1424    let reader =
1425        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1426    let root = reader.get_root::<types_capnp::account_balance::Reader>()?;
1427    AccountBalance::from_capnp(root)
1428}
1429
1430pub fn serialize_margin_balance(balance: &MarginBalance) -> Result<Vec<u8>, Box<dyn Error>> {
1431    let mut message = capnp::message::Builder::new_default();
1432    let builder = message.init_root::<types_capnp::margin_balance::Builder>();
1433    balance.to_capnp(builder);
1434
1435    let mut bytes = Vec::new();
1436    capnp::serialize::write_message(&mut bytes, &message)?;
1437    Ok(bytes)
1438}
1439
1440pub fn deserialize_margin_balance(bytes: &[u8]) -> Result<MarginBalance, Box<dyn Error>> {
1441    let reader =
1442        capnp::serialize::read_message(&mut &bytes[..], capnp::message::ReaderOptions::new())?;
1443    let root = reader.get_root::<types_capnp::margin_balance::Reader>()?;
1444    MarginBalance::from_capnp(root)
1445}
1446
1447impl<'a> ToCapnp<'a> for QuoteTick {
1448    type Builder = market_capnp::quote_tick::Builder<'a>;
1449
1450    fn to_capnp(&self, mut builder: Self::Builder) {
1451        let instrument_id_builder = builder.reborrow().init_instrument_id();
1452        self.instrument_id.to_capnp(instrument_id_builder);
1453
1454        let bid_price_builder = builder.reborrow().init_bid_price();
1455        self.bid_price.to_capnp(bid_price_builder);
1456
1457        let ask_price_builder = builder.reborrow().init_ask_price();
1458        self.ask_price.to_capnp(ask_price_builder);
1459
1460        let bid_size_builder = builder.reborrow().init_bid_size();
1461        self.bid_size.to_capnp(bid_size_builder);
1462
1463        let ask_size_builder = builder.reborrow().init_ask_size();
1464        self.ask_size.to_capnp(ask_size_builder);
1465
1466        let mut ts_event_builder = builder.reborrow().init_ts_event();
1467        ts_event_builder.set_value(*self.ts_event);
1468
1469        let mut ts_init_builder = builder.reborrow().init_ts_init();
1470        ts_init_builder.set_value(*self.ts_init);
1471    }
1472}
1473
1474impl<'a> FromCapnp<'a> for QuoteTick {
1475    type Reader = market_capnp::quote_tick::Reader<'a>;
1476
1477    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1478        let instrument_id_reader = reader.get_instrument_id()?;
1479        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1480
1481        let bid_price_reader = reader.get_bid_price()?;
1482        let bid_price = Price::from_capnp(bid_price_reader)?;
1483
1484        let ask_price_reader = reader.get_ask_price()?;
1485        let ask_price = Price::from_capnp(ask_price_reader)?;
1486
1487        let bid_size_reader = reader.get_bid_size()?;
1488        let bid_size = Quantity::from_capnp(bid_size_reader)?;
1489
1490        let ask_size_reader = reader.get_ask_size()?;
1491        let ask_size = Quantity::from_capnp(ask_size_reader)?;
1492
1493        let ts_event_reader = reader.get_ts_event()?;
1494        let ts_event = ts_event_reader.get_value();
1495
1496        let ts_init_reader = reader.get_ts_init()?;
1497        let ts_init = ts_init_reader.get_value();
1498
1499        Ok(Self {
1500            instrument_id,
1501            bid_price,
1502            ask_price,
1503            bid_size,
1504            ask_size,
1505            ts_event: ts_event.into(),
1506            ts_init: ts_init.into(),
1507        })
1508    }
1509}
1510
1511impl<'a> ToCapnp<'a> for TradeTick {
1512    type Builder = market_capnp::trade_tick::Builder<'a>;
1513
1514    fn to_capnp(&self, mut builder: Self::Builder) {
1515        let instrument_id_builder = builder.reborrow().init_instrument_id();
1516        self.instrument_id.to_capnp(instrument_id_builder);
1517
1518        let price_builder = builder.reborrow().init_price();
1519        self.price.to_capnp(price_builder);
1520
1521        let size_builder = builder.reborrow().init_size();
1522        self.size.to_capnp(size_builder);
1523
1524        builder.set_aggressor_side(aggressor_side_to_capnp(self.aggressor_side));
1525
1526        let trade_id_builder = builder.reborrow().init_trade_id();
1527        self.trade_id.to_capnp(trade_id_builder);
1528
1529        let mut ts_event_builder = builder.reborrow().init_ts_event();
1530        ts_event_builder.set_value(*self.ts_event);
1531
1532        let mut ts_init_builder = builder.reborrow().init_ts_init();
1533        ts_init_builder.set_value(*self.ts_init);
1534    }
1535}
1536
1537impl<'a> FromCapnp<'a> for TradeTick {
1538    type Reader = market_capnp::trade_tick::Reader<'a>;
1539
1540    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1541        let instrument_id_reader = reader.get_instrument_id()?;
1542        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1543
1544        let price_reader = reader.get_price()?;
1545        let price = Price::from_capnp(price_reader)?;
1546
1547        let size_reader = reader.get_size()?;
1548        let size = Quantity::from_capnp(size_reader)?;
1549
1550        let aggressor_side = aggressor_side_from_capnp(reader.get_aggressor_side()?);
1551
1552        let trade_id_reader = reader.get_trade_id()?;
1553        let trade_id = TradeId::from_capnp(trade_id_reader)?;
1554
1555        let ts_event_reader = reader.get_ts_event()?;
1556        let ts_event = ts_event_reader.get_value();
1557
1558        let ts_init_reader = reader.get_ts_init()?;
1559        let ts_init = ts_init_reader.get_value();
1560
1561        Ok(Self {
1562            instrument_id,
1563            price,
1564            size,
1565            aggressor_side,
1566            trade_id,
1567            ts_event: ts_event.into(),
1568            ts_init: ts_init.into(),
1569        })
1570    }
1571}
1572
1573impl<'a> ToCapnp<'a> for MarkPriceUpdate {
1574    type Builder = market_capnp::mark_price_update::Builder<'a>;
1575
1576    fn to_capnp(&self, mut builder: Self::Builder) {
1577        let instrument_id_builder = builder.reborrow().init_instrument_id();
1578        self.instrument_id.to_capnp(instrument_id_builder);
1579
1580        let mark_price_builder = builder.reborrow().init_mark_price();
1581        self.value.to_capnp(mark_price_builder);
1582
1583        let mut ts_event_builder = builder.reborrow().init_ts_event();
1584        ts_event_builder.set_value(*self.ts_event);
1585
1586        let mut ts_init_builder = builder.reborrow().init_ts_init();
1587        ts_init_builder.set_value(*self.ts_init);
1588    }
1589}
1590
1591impl<'a> FromCapnp<'a> for MarkPriceUpdate {
1592    type Reader = market_capnp::mark_price_update::Reader<'a>;
1593
1594    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1595        let instrument_id_reader = reader.get_instrument_id()?;
1596        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1597
1598        let mark_price_reader = reader.get_mark_price()?;
1599        let value = Price::from_capnp(mark_price_reader)?;
1600
1601        let ts_event_reader = reader.get_ts_event()?;
1602        let ts_event = ts_event_reader.get_value();
1603
1604        let ts_init_reader = reader.get_ts_init()?;
1605        let ts_init = ts_init_reader.get_value();
1606
1607        Ok(Self {
1608            instrument_id,
1609            value,
1610            ts_event: ts_event.into(),
1611            ts_init: ts_init.into(),
1612        })
1613    }
1614}
1615
1616impl<'a> ToCapnp<'a> for IndexPriceUpdate {
1617    type Builder = market_capnp::index_price_update::Builder<'a>;
1618
1619    fn to_capnp(&self, mut builder: Self::Builder) {
1620        let instrument_id_builder = builder.reborrow().init_instrument_id();
1621        self.instrument_id.to_capnp(instrument_id_builder);
1622
1623        let index_price_builder = builder.reborrow().init_index_price();
1624        self.value.to_capnp(index_price_builder);
1625
1626        let mut ts_event_builder = builder.reborrow().init_ts_event();
1627        ts_event_builder.set_value(*self.ts_event);
1628
1629        let mut ts_init_builder = builder.reborrow().init_ts_init();
1630        ts_init_builder.set_value(*self.ts_init);
1631    }
1632}
1633
1634impl<'a> FromCapnp<'a> for IndexPriceUpdate {
1635    type Reader = market_capnp::index_price_update::Reader<'a>;
1636
1637    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1638        let instrument_id_reader = reader.get_instrument_id()?;
1639        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1640
1641        let index_price_reader = reader.get_index_price()?;
1642        let value = Price::from_capnp(index_price_reader)?;
1643
1644        let ts_event_reader = reader.get_ts_event()?;
1645        let ts_event = ts_event_reader.get_value();
1646
1647        let ts_init_reader = reader.get_ts_init()?;
1648        let ts_init = ts_init_reader.get_value();
1649
1650        Ok(Self {
1651            instrument_id,
1652            value,
1653            ts_event: ts_event.into(),
1654            ts_init: ts_init.into(),
1655        })
1656    }
1657}
1658
1659impl<'a> ToCapnp<'a> for FundingRateUpdate {
1660    type Builder = market_capnp::funding_rate_update::Builder<'a>;
1661
1662    fn to_capnp(&self, mut builder: Self::Builder) {
1663        let instrument_id_builder = builder.reborrow().init_instrument_id();
1664        self.instrument_id.to_capnp(instrument_id_builder);
1665
1666        let rate_builder = builder.reborrow().init_rate();
1667        self.rate.to_capnp(rate_builder);
1668
1669        let mut next_funding_time_builder = builder.reborrow().init_next_funding_time();
1670        next_funding_time_builder.set_value(self.next_funding_ns.map_or(0, |ns| *ns));
1671
1672        let mut ts_event_builder = builder.reborrow().init_ts_event();
1673        ts_event_builder.set_value(*self.ts_event);
1674
1675        let mut ts_init_builder = builder.reborrow().init_ts_init();
1676        ts_init_builder.set_value(*self.ts_init);
1677    }
1678}
1679
1680impl<'a> FromCapnp<'a> for FundingRateUpdate {
1681    type Reader = market_capnp::funding_rate_update::Reader<'a>;
1682
1683    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1684        let instrument_id_reader = reader.get_instrument_id()?;
1685        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1686
1687        let rate_reader = reader.get_rate()?;
1688        let rate = Decimal::from_capnp(rate_reader)?;
1689
1690        let next_funding_time_reader = reader.get_next_funding_time()?;
1691        let next_funding_time_value = next_funding_time_reader.get_value();
1692        let next_funding_ns = if next_funding_time_value == 0 {
1693            None
1694        } else {
1695            Some(next_funding_time_value.into())
1696        };
1697
1698        let ts_event_reader = reader.get_ts_event()?;
1699        let ts_event = ts_event_reader.get_value();
1700
1701        let ts_init_reader = reader.get_ts_init()?;
1702        let ts_init = ts_init_reader.get_value();
1703
1704        Ok(Self {
1705            instrument_id,
1706            rate,
1707            next_funding_ns,
1708            ts_event: ts_event.into(),
1709            ts_init: ts_init.into(),
1710        })
1711    }
1712}
1713
1714impl<'a> ToCapnp<'a> for InstrumentClose {
1715    type Builder = market_capnp::instrument_close::Builder<'a>;
1716
1717    fn to_capnp(&self, mut builder: Self::Builder) {
1718        let instrument_id_builder = builder.reborrow().init_instrument_id();
1719        self.instrument_id.to_capnp(instrument_id_builder);
1720
1721        let close_price_builder = builder.reborrow().init_close_price();
1722        self.close_price.to_capnp(close_price_builder);
1723
1724        builder.set_close_type(instrument_close_type_to_capnp(self.close_type));
1725
1726        let mut ts_event_builder = builder.reborrow().init_ts_event();
1727        ts_event_builder.set_value(*self.ts_event);
1728
1729        let mut ts_init_builder = builder.reborrow().init_ts_init();
1730        ts_init_builder.set_value(*self.ts_init);
1731    }
1732}
1733
1734impl<'a> FromCapnp<'a> for InstrumentClose {
1735    type Reader = market_capnp::instrument_close::Reader<'a>;
1736
1737    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1738        let instrument_id_reader = reader.get_instrument_id()?;
1739        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1740
1741        let close_price_reader = reader.get_close_price()?;
1742        let close_price = Price::from_capnp(close_price_reader)?;
1743
1744        let close_type = instrument_close_type_from_capnp(reader.get_close_type()?);
1745
1746        let ts_event_reader = reader.get_ts_event()?;
1747        let ts_event = ts_event_reader.get_value();
1748
1749        let ts_init_reader = reader.get_ts_init()?;
1750        let ts_init = ts_init_reader.get_value();
1751
1752        Ok(Self {
1753            instrument_id,
1754            close_price,
1755            close_type,
1756            ts_event: ts_event.into(),
1757            ts_init: ts_init.into(),
1758        })
1759    }
1760}
1761
1762impl<'a> ToCapnp<'a> for InstrumentStatus {
1763    type Builder = market_capnp::instrument_status::Builder<'a>;
1764
1765    fn to_capnp(&self, mut builder: Self::Builder) {
1766        let instrument_id_builder = builder.reborrow().init_instrument_id();
1767        self.instrument_id.to_capnp(instrument_id_builder);
1768
1769        builder.set_action(market_status_action_to_capnp(self.action));
1770        builder.set_reason(self.reason.as_ref().map_or("", |s| s.as_str()));
1771        builder.set_trading_event(self.trading_event.as_ref().map_or("", |s| s.as_str()));
1772        builder.set_is_trading(self.is_trading.unwrap_or(false));
1773        builder.set_is_quoting(self.is_quoting.unwrap_or(false));
1774        builder.set_is_short_sell_restricted(self.is_short_sell_restricted.unwrap_or(false));
1775
1776        let mut ts_event_builder = builder.reborrow().init_ts_event();
1777        ts_event_builder.set_value(*self.ts_event);
1778
1779        let mut ts_init_builder = builder.reborrow().init_ts_init();
1780        ts_init_builder.set_value(*self.ts_init);
1781    }
1782}
1783
1784impl<'a> FromCapnp<'a> for InstrumentStatus {
1785    type Reader = market_capnp::instrument_status::Reader<'a>;
1786
1787    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1788        let instrument_id_reader = reader.get_instrument_id()?;
1789        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1790
1791        let action = market_status_action_from_capnp(reader.get_action()?);
1792
1793        let reason_str = reader.get_reason()?.to_str()?;
1794        let reason = if reason_str.is_empty() {
1795            None
1796        } else {
1797            Some(Ustr::from(reason_str))
1798        };
1799
1800        let trading_event_str = reader.get_trading_event()?.to_str()?;
1801        let trading_event = if trading_event_str.is_empty() {
1802            None
1803        } else {
1804            Some(Ustr::from(trading_event_str))
1805        };
1806
1807        let is_trading = Some(reader.get_is_trading());
1808        let is_quoting = Some(reader.get_is_quoting());
1809        let is_short_sell_restricted = Some(reader.get_is_short_sell_restricted());
1810
1811        let ts_event_reader = reader.get_ts_event()?;
1812        let ts_event = ts_event_reader.get_value();
1813
1814        let ts_init_reader = reader.get_ts_init()?;
1815        let ts_init = ts_init_reader.get_value();
1816
1817        Ok(Self {
1818            instrument_id,
1819            action,
1820            ts_event: ts_event.into(),
1821            ts_init: ts_init.into(),
1822            reason,
1823            trading_event,
1824            is_trading,
1825            is_quoting,
1826            is_short_sell_restricted,
1827        })
1828    }
1829}
1830
1831impl<'a> ToCapnp<'a> for BarSpecification {
1832    type Builder = market_capnp::bar_spec::Builder<'a>;
1833
1834    fn to_capnp(&self, mut builder: Self::Builder) {
1835        builder.set_step(self.step.get() as u32);
1836        builder.set_aggregation(bar_aggregation_to_capnp(self.aggregation));
1837        builder.set_price_type(price_type_to_capnp(self.price_type));
1838    }
1839}
1840
1841impl<'a> FromCapnp<'a> for BarSpecification {
1842    type Reader = market_capnp::bar_spec::Reader<'a>;
1843
1844    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1845        use std::num::NonZero;
1846
1847        let step = reader.get_step();
1848        let step = NonZero::new(step as usize).ok_or("BarSpecification step must be non-zero")?;
1849
1850        let aggregation = bar_aggregation_from_capnp(reader.get_aggregation()?);
1851        let price_type = price_type_from_capnp(reader.get_price_type()?);
1852
1853        Ok(Self {
1854            step,
1855            aggregation,
1856            price_type,
1857        })
1858    }
1859}
1860
1861impl<'a> ToCapnp<'a> for BarType {
1862    type Builder = market_capnp::bar_type::Builder<'a>;
1863
1864    fn to_capnp(&self, mut builder: Self::Builder) {
1865        let instrument_id_builder = builder.reborrow().init_instrument_id();
1866        self.instrument_id().to_capnp(instrument_id_builder);
1867
1868        let spec_builder = builder.reborrow().init_spec();
1869        self.spec().to_capnp(spec_builder);
1870
1871        builder.set_aggregation_source(aggregation_source_to_capnp(self.aggregation_source()));
1872    }
1873}
1874
1875impl<'a> FromCapnp<'a> for BarType {
1876    type Reader = market_capnp::bar_type::Reader<'a>;
1877
1878    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1879        let instrument_id_reader = reader.get_instrument_id()?;
1880        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
1881
1882        let spec_reader = reader.get_spec()?;
1883        let spec = BarSpecification::from_capnp(spec_reader)?;
1884
1885        let aggregation_source = aggregation_source_from_capnp(reader.get_aggregation_source()?);
1886
1887        Ok(Self::new(instrument_id, spec, aggregation_source))
1888    }
1889}
1890
1891impl<'a> ToCapnp<'a> for Bar {
1892    type Builder = market_capnp::bar::Builder<'a>;
1893
1894    fn to_capnp(&self, mut builder: Self::Builder) {
1895        let bar_type_builder = builder.reborrow().init_bar_type();
1896        self.bar_type.to_capnp(bar_type_builder);
1897
1898        let open_builder = builder.reborrow().init_open();
1899        self.open.to_capnp(open_builder);
1900
1901        let high_builder = builder.reborrow().init_high();
1902        self.high.to_capnp(high_builder);
1903
1904        let low_builder = builder.reborrow().init_low();
1905        self.low.to_capnp(low_builder);
1906
1907        let close_builder = builder.reborrow().init_close();
1908        self.close.to_capnp(close_builder);
1909
1910        let volume_builder = builder.reborrow().init_volume();
1911        self.volume.to_capnp(volume_builder);
1912
1913        let mut ts_event_builder = builder.reborrow().init_ts_event();
1914        ts_event_builder.set_value(*self.ts_event);
1915
1916        let mut ts_init_builder = builder.reborrow().init_ts_init();
1917        ts_init_builder.set_value(*self.ts_init);
1918    }
1919}
1920
1921impl<'a> FromCapnp<'a> for Bar {
1922    type Reader = market_capnp::bar::Reader<'a>;
1923
1924    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1925        let bar_type_reader = reader.get_bar_type()?;
1926        let bar_type = BarType::from_capnp(bar_type_reader)?;
1927
1928        let open_reader = reader.get_open()?;
1929        let open = Price::from_capnp(open_reader)?;
1930
1931        let high_reader = reader.get_high()?;
1932        let high = Price::from_capnp(high_reader)?;
1933
1934        let low_reader = reader.get_low()?;
1935        let low = Price::from_capnp(low_reader)?;
1936
1937        let close_reader = reader.get_close()?;
1938        let close = Price::from_capnp(close_reader)?;
1939
1940        let volume_reader = reader.get_volume()?;
1941        let volume = Quantity::from_capnp(volume_reader)?;
1942
1943        let ts_event_reader = reader.get_ts_event()?;
1944        let ts_event = ts_event_reader.get_value();
1945
1946        let ts_init_reader = reader.get_ts_init()?;
1947        let ts_init = ts_init_reader.get_value();
1948
1949        Ok(Self {
1950            bar_type,
1951            open,
1952            high,
1953            low,
1954            close,
1955            volume,
1956            ts_event: ts_event.into(),
1957            ts_init: ts_init.into(),
1958        })
1959    }
1960}
1961
1962impl<'a> ToCapnp<'a> for BookOrder {
1963    type Builder = market_capnp::book_order::Builder<'a>;
1964
1965    fn to_capnp(&self, mut builder: Self::Builder) {
1966        let price_builder = builder.reborrow().init_price();
1967        self.price.to_capnp(price_builder);
1968
1969        let size_builder = builder.reborrow().init_size();
1970        self.size.to_capnp(size_builder);
1971
1972        builder.set_side(order_side_to_capnp(self.side));
1973        builder.set_order_id(self.order_id);
1974    }
1975}
1976
1977impl<'a> FromCapnp<'a> for BookOrder {
1978    type Reader = market_capnp::book_order::Reader<'a>;
1979
1980    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
1981        let price_reader = reader.get_price()?;
1982        let price = Price::from_capnp(price_reader)?;
1983
1984        let size_reader = reader.get_size()?;
1985        let size = Quantity::from_capnp(size_reader)?;
1986
1987        let side = order_side_from_capnp(reader.get_side()?);
1988        let order_id = reader.get_order_id();
1989
1990        Ok(Self {
1991            side,
1992            price,
1993            size,
1994            order_id,
1995        })
1996    }
1997}
1998
1999impl<'a> ToCapnp<'a> for OrderBookDelta {
2000    type Builder = market_capnp::order_book_delta::Builder<'a>;
2001
2002    fn to_capnp(&self, mut builder: Self::Builder) {
2003        let instrument_id_builder = builder.reborrow().init_instrument_id();
2004        self.instrument_id.to_capnp(instrument_id_builder);
2005
2006        builder.set_action(book_action_to_capnp(self.action));
2007
2008        let order_builder = builder.reborrow().init_order();
2009        self.order.to_capnp(order_builder);
2010
2011        builder.set_flags(self.flags);
2012        builder.set_sequence(self.sequence);
2013
2014        let mut ts_event_builder = builder.reborrow().init_ts_event();
2015        ts_event_builder.set_value(*self.ts_event);
2016
2017        let mut ts_init_builder = builder.reborrow().init_ts_init();
2018        ts_init_builder.set_value(*self.ts_init);
2019    }
2020}
2021
2022impl<'a> FromCapnp<'a> for OrderBookDelta {
2023    type Reader = market_capnp::order_book_delta::Reader<'a>;
2024
2025    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2026        let instrument_id_reader = reader.get_instrument_id()?;
2027        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2028
2029        let action = book_action_from_capnp(reader.get_action()?);
2030
2031        let order_reader = reader.get_order()?;
2032        let order = BookOrder::from_capnp(order_reader)?;
2033
2034        let flags = reader.get_flags();
2035        let sequence = reader.get_sequence();
2036
2037        let ts_event_reader = reader.get_ts_event()?;
2038        let ts_event = ts_event_reader.get_value();
2039
2040        let ts_init_reader = reader.get_ts_init()?;
2041        let ts_init = ts_init_reader.get_value();
2042
2043        Ok(Self {
2044            instrument_id,
2045            action,
2046            order,
2047            flags,
2048            sequence,
2049            ts_event: ts_event.into(),
2050            ts_init: ts_init.into(),
2051        })
2052    }
2053}
2054
2055impl<'a> ToCapnp<'a> for OrderBookDeltas {
2056    type Builder = market_capnp::order_book_deltas::Builder<'a>;
2057
2058    fn to_capnp(&self, mut builder: Self::Builder) {
2059        let instrument_id_builder = builder.reborrow().init_instrument_id();
2060        self.instrument_id.to_capnp(instrument_id_builder);
2061
2062        let mut deltas_builder = builder.reborrow().init_deltas(self.deltas.len() as u32);
2063        for (i, delta) in self.deltas.iter().enumerate() {
2064            let delta_builder = deltas_builder.reborrow().get(i as u32);
2065            delta.to_capnp(delta_builder);
2066        }
2067
2068        builder.set_flags(self.flags);
2069        builder.set_sequence(self.sequence);
2070
2071        let mut ts_event_builder = builder.reborrow().init_ts_event();
2072        ts_event_builder.set_value(*self.ts_event);
2073
2074        let mut ts_init_builder = builder.reborrow().init_ts_init();
2075        ts_init_builder.set_value(*self.ts_init);
2076    }
2077}
2078
2079impl<'a> FromCapnp<'a> for OrderBookDeltas {
2080    type Reader = market_capnp::order_book_deltas::Reader<'a>;
2081
2082    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2083        let instrument_id_reader = reader.get_instrument_id()?;
2084        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2085
2086        let deltas_reader = reader.get_deltas()?;
2087        let mut deltas = Vec::with_capacity(deltas_reader.len() as usize);
2088        for delta_reader in deltas_reader {
2089            let delta = OrderBookDelta::from_capnp(delta_reader)?;
2090            deltas.push(delta);
2091        }
2092
2093        let flags = reader.get_flags();
2094        let sequence = reader.get_sequence();
2095
2096        let ts_event_reader = reader.get_ts_event()?;
2097        let ts_event = ts_event_reader.get_value();
2098
2099        let ts_init_reader = reader.get_ts_init()?;
2100        let ts_init = ts_init_reader.get_value();
2101
2102        Ok(Self {
2103            instrument_id,
2104            deltas,
2105            flags,
2106            sequence,
2107            ts_event: ts_event.into(),
2108            ts_init: ts_init.into(),
2109        })
2110    }
2111}
2112
2113impl<'a> ToCapnp<'a> for OrderBookDepth10 {
2114    type Builder = market_capnp::order_book_depth10::Builder<'a>;
2115
2116    fn to_capnp(&self, mut builder: Self::Builder) {
2117        let instrument_id_builder = builder.reborrow().init_instrument_id();
2118        self.instrument_id.to_capnp(instrument_id_builder);
2119
2120        // Convert bids (BookOrder array to BookLevel list)
2121        let mut bids_builder = builder.reborrow().init_bids(self.bids.len() as u32);
2122        for (i, bid) in self.bids.iter().enumerate() {
2123            let mut level_builder = bids_builder.reborrow().get(i as u32);
2124            let price_builder = level_builder.reborrow().init_price();
2125            bid.price.to_capnp(price_builder);
2126            let size_builder = level_builder.init_size();
2127            bid.size.to_capnp(size_builder);
2128        }
2129
2130        // Convert asks (BookOrder array to BookLevel list)
2131        let mut asks_builder = builder.reborrow().init_asks(self.asks.len() as u32);
2132        for (i, ask) in self.asks.iter().enumerate() {
2133            let mut level_builder = asks_builder.reborrow().get(i as u32);
2134            let price_builder = level_builder.reborrow().init_price();
2135            ask.price.to_capnp(price_builder);
2136            let size_builder = level_builder.init_size();
2137            ask.size.to_capnp(size_builder);
2138        }
2139
2140        // Convert counts
2141        let mut bid_counts_builder = builder
2142            .reborrow()
2143            .init_bid_counts(self.bid_counts.len() as u32);
2144        for (i, &count) in self.bid_counts.iter().enumerate() {
2145            bid_counts_builder.set(i as u32, count);
2146        }
2147
2148        let mut ask_counts_builder = builder
2149            .reborrow()
2150            .init_ask_counts(self.ask_counts.len() as u32);
2151        for (i, &count) in self.ask_counts.iter().enumerate() {
2152            ask_counts_builder.set(i as u32, count);
2153        }
2154
2155        builder.set_flags(self.flags);
2156        builder.set_sequence(self.sequence);
2157
2158        let mut ts_event_builder = builder.reborrow().init_ts_event();
2159        ts_event_builder.set_value(*self.ts_event);
2160
2161        let mut ts_init_builder = builder.reborrow().init_ts_init();
2162        ts_init_builder.set_value(*self.ts_init);
2163    }
2164}
2165
2166impl<'a> FromCapnp<'a> for OrderBookDepth10 {
2167    type Reader = market_capnp::order_book_depth10::Reader<'a>;
2168
2169    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2170        use nautilus_model::data::order::NULL_ORDER;
2171
2172        let instrument_id_reader = reader.get_instrument_id()?;
2173        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2174
2175        // Convert bids (BookLevel list to BookOrder array)
2176        let bids_reader = reader.get_bids()?;
2177        let mut bids = [NULL_ORDER; 10];
2178        for (i, level_reader) in bids_reader.iter().enumerate().take(10) {
2179            let price_reader = level_reader.get_price()?;
2180            let price = Price::from_capnp(price_reader)?;
2181
2182            let size_reader = level_reader.get_size()?;
2183            let size = Quantity::from_capnp(size_reader)?;
2184
2185            bids[i] = BookOrder::new(OrderSide::Buy, price, size, 0);
2186        }
2187
2188        // Convert asks (BookLevel list to BookOrder array)
2189        let asks_reader = reader.get_asks()?;
2190        let mut asks = [NULL_ORDER; 10];
2191        for (i, level_reader) in asks_reader.iter().enumerate().take(10) {
2192            let price_reader = level_reader.get_price()?;
2193            let price = Price::from_capnp(price_reader)?;
2194
2195            let size_reader = level_reader.get_size()?;
2196            let size = Quantity::from_capnp(size_reader)?;
2197
2198            asks[i] = BookOrder::new(OrderSide::Sell, price, size, 0);
2199        }
2200
2201        // Convert counts
2202        let bid_counts_reader = reader.get_bid_counts()?;
2203        let mut bid_counts = [0u32; 10];
2204        for (i, count) in bid_counts_reader.iter().enumerate().take(10) {
2205            bid_counts[i] = count;
2206        }
2207
2208        let ask_counts_reader = reader.get_ask_counts()?;
2209        let mut ask_counts = [0u32; 10];
2210        for (i, count) in ask_counts_reader.iter().enumerate().take(10) {
2211            ask_counts[i] = count;
2212        }
2213
2214        let flags = reader.get_flags();
2215        let sequence = reader.get_sequence();
2216
2217        let ts_event_reader = reader.get_ts_event()?;
2218        let ts_event = ts_event_reader.get_value();
2219
2220        let ts_init_reader = reader.get_ts_init()?;
2221        let ts_init = ts_init_reader.get_value();
2222
2223        Ok(Self {
2224            instrument_id,
2225            bids,
2226            asks,
2227            bid_counts,
2228            ask_counts,
2229            flags,
2230            sequence,
2231            ts_event: ts_event.into(),
2232            ts_init: ts_init.into(),
2233        })
2234    }
2235}
2236
2237impl<'a> ToCapnp<'a> for OrderDenied {
2238    type Builder = order_capnp::order_denied::Builder<'a>;
2239
2240    fn to_capnp(&self, mut builder: Self::Builder) {
2241        let trader_id_builder = builder.reborrow().init_trader_id();
2242        self.trader_id.to_capnp(trader_id_builder);
2243
2244        let strategy_id_builder = builder.reborrow().init_strategy_id();
2245        self.strategy_id.to_capnp(strategy_id_builder);
2246
2247        let instrument_id_builder = builder.reborrow().init_instrument_id();
2248        self.instrument_id.to_capnp(instrument_id_builder);
2249
2250        let client_order_id_builder = builder.reborrow().init_client_order_id();
2251        self.client_order_id.to_capnp(client_order_id_builder);
2252
2253        builder.set_reason(self.reason.as_str());
2254
2255        let event_id_builder = builder.reborrow().init_event_id();
2256        self.event_id.to_capnp(event_id_builder);
2257
2258        let mut ts_init_builder = builder.reborrow().init_ts_init();
2259        ts_init_builder.set_value(*self.ts_init);
2260    }
2261}
2262
2263impl<'a> FromCapnp<'a> for OrderDenied {
2264    type Reader = order_capnp::order_denied::Reader<'a>;
2265
2266    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2267        let trader_id_reader = reader.get_trader_id()?;
2268        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2269
2270        let strategy_id_reader = reader.get_strategy_id()?;
2271        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2272
2273        let instrument_id_reader = reader.get_instrument_id()?;
2274        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2275
2276        let client_order_id_reader = reader.get_client_order_id()?;
2277        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2278
2279        let reason = Ustr::from(reader.get_reason()?.to_str()?);
2280
2281        let event_id_reader = reader.get_event_id()?;
2282        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2283
2284        let ts_init_reader = reader.get_ts_init()?;
2285        let ts_init = ts_init_reader.get_value();
2286
2287        Ok(Self {
2288            trader_id,
2289            strategy_id,
2290            instrument_id,
2291            client_order_id,
2292            reason,
2293            event_id,
2294            ts_event: ts_init.into(), // System event - ts_event = ts_init
2295            ts_init: ts_init.into(),
2296        })
2297    }
2298}
2299
2300impl<'a> ToCapnp<'a> for OrderEmulated {
2301    type Builder = order_capnp::order_emulated::Builder<'a>;
2302
2303    fn to_capnp(&self, mut builder: Self::Builder) {
2304        let trader_id_builder = builder.reborrow().init_trader_id();
2305        self.trader_id.to_capnp(trader_id_builder);
2306
2307        let strategy_id_builder = builder.reborrow().init_strategy_id();
2308        self.strategy_id.to_capnp(strategy_id_builder);
2309
2310        let instrument_id_builder = builder.reborrow().init_instrument_id();
2311        self.instrument_id.to_capnp(instrument_id_builder);
2312
2313        let client_order_id_builder = builder.reborrow().init_client_order_id();
2314        self.client_order_id.to_capnp(client_order_id_builder);
2315
2316        let event_id_builder = builder.reborrow().init_event_id();
2317        self.event_id.to_capnp(event_id_builder);
2318
2319        let mut ts_init_builder = builder.reborrow().init_ts_init();
2320        ts_init_builder.set_value(*self.ts_init);
2321    }
2322}
2323
2324impl<'a> FromCapnp<'a> for OrderEmulated {
2325    type Reader = order_capnp::order_emulated::Reader<'a>;
2326
2327    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2328        let trader_id_reader = reader.get_trader_id()?;
2329        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2330
2331        let strategy_id_reader = reader.get_strategy_id()?;
2332        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2333
2334        let instrument_id_reader = reader.get_instrument_id()?;
2335        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2336
2337        let client_order_id_reader = reader.get_client_order_id()?;
2338        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2339
2340        let event_id_reader = reader.get_event_id()?;
2341        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2342
2343        let ts_init_reader = reader.get_ts_init()?;
2344        let ts_init = ts_init_reader.get_value();
2345
2346        Ok(Self {
2347            trader_id,
2348            strategy_id,
2349            instrument_id,
2350            client_order_id,
2351            event_id,
2352            ts_event: ts_init.into(), // System event - ts_event = ts_init
2353            ts_init: ts_init.into(),
2354        })
2355    }
2356}
2357
2358impl<'a> ToCapnp<'a> for OrderReleased {
2359    type Builder = order_capnp::order_released::Builder<'a>;
2360
2361    fn to_capnp(&self, mut builder: Self::Builder) {
2362        let trader_id_builder = builder.reborrow().init_trader_id();
2363        self.trader_id.to_capnp(trader_id_builder);
2364
2365        let strategy_id_builder = builder.reborrow().init_strategy_id();
2366        self.strategy_id.to_capnp(strategy_id_builder);
2367
2368        let instrument_id_builder = builder.reborrow().init_instrument_id();
2369        self.instrument_id.to_capnp(instrument_id_builder);
2370
2371        let client_order_id_builder = builder.reborrow().init_client_order_id();
2372        self.client_order_id.to_capnp(client_order_id_builder);
2373
2374        let released_price_builder = builder.reborrow().init_released_price();
2375        self.released_price.to_capnp(released_price_builder);
2376
2377        let event_id_builder = builder.reborrow().init_event_id();
2378        self.event_id.to_capnp(event_id_builder);
2379
2380        let mut ts_init_builder = builder.reborrow().init_ts_init();
2381        ts_init_builder.set_value(*self.ts_init);
2382    }
2383}
2384
2385impl<'a> FromCapnp<'a> for OrderReleased {
2386    type Reader = order_capnp::order_released::Reader<'a>;
2387
2388    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2389        let trader_id_reader = reader.get_trader_id()?;
2390        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2391
2392        let strategy_id_reader = reader.get_strategy_id()?;
2393        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2394
2395        let instrument_id_reader = reader.get_instrument_id()?;
2396        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2397
2398        let client_order_id_reader = reader.get_client_order_id()?;
2399        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2400
2401        let released_price_reader = reader.get_released_price()?;
2402        let released_price = Price::from_capnp(released_price_reader)?;
2403
2404        let event_id_reader = reader.get_event_id()?;
2405        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2406
2407        let ts_init_reader = reader.get_ts_init()?;
2408        let ts_init = ts_init_reader.get_value();
2409
2410        Ok(Self {
2411            trader_id,
2412            strategy_id,
2413            instrument_id,
2414            client_order_id,
2415            released_price,
2416            event_id,
2417            ts_event: ts_init.into(), // System event - ts_event = ts_init
2418            ts_init: ts_init.into(),
2419        })
2420    }
2421}
2422
2423// OrderSubmitted
2424impl<'a> ToCapnp<'a> for OrderSubmitted {
2425    type Builder = order_capnp::order_submitted::Builder<'a>;
2426
2427    fn to_capnp(&self, mut builder: Self::Builder) {
2428        let trader_id_builder = builder.reborrow().init_trader_id();
2429        self.trader_id.to_capnp(trader_id_builder);
2430
2431        let strategy_id_builder = builder.reborrow().init_strategy_id();
2432        self.strategy_id.to_capnp(strategy_id_builder);
2433
2434        let instrument_id_builder = builder.reborrow().init_instrument_id();
2435        self.instrument_id.to_capnp(instrument_id_builder);
2436
2437        let client_order_id_builder = builder.reborrow().init_client_order_id();
2438        self.client_order_id.to_capnp(client_order_id_builder);
2439
2440        self.account_id
2441            .write_capnp(|| builder.reborrow().init_account_id());
2442
2443        let event_id_builder = builder.reborrow().init_event_id();
2444        self.event_id.to_capnp(event_id_builder);
2445
2446        let mut ts_event_builder = builder.reborrow().init_ts_event();
2447        ts_event_builder.set_value(*self.ts_event);
2448
2449        let mut ts_init_builder = builder.reborrow().init_ts_init();
2450        ts_init_builder.set_value(*self.ts_init);
2451    }
2452}
2453
2454impl<'a> FromCapnp<'a> for OrderSubmitted {
2455    type Reader = order_capnp::order_submitted::Reader<'a>;
2456
2457    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2458        let trader_id_reader = reader.get_trader_id()?;
2459        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2460
2461        let strategy_id_reader = reader.get_strategy_id()?;
2462        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2463
2464        let instrument_id_reader = reader.get_instrument_id()?;
2465        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2466
2467        let client_order_id_reader = reader.get_client_order_id()?;
2468        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2469
2470        let account_id_reader = reader.get_account_id()?;
2471        let account_id = AccountId::from_capnp(account_id_reader)?;
2472
2473        let event_id_reader = reader.get_event_id()?;
2474        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2475
2476        let ts_event_reader = reader.get_ts_event()?;
2477        let ts_event = ts_event_reader.get_value();
2478
2479        let ts_init_reader = reader.get_ts_init()?;
2480        let ts_init = ts_init_reader.get_value();
2481
2482        Ok(Self {
2483            trader_id,
2484            strategy_id,
2485            instrument_id,
2486            client_order_id,
2487            account_id,
2488            event_id,
2489            ts_event: ts_event.into(),
2490            ts_init: ts_init.into(),
2491        })
2492    }
2493}
2494
2495// OrderAccepted
2496impl<'a> ToCapnp<'a> for OrderAccepted {
2497    type Builder = order_capnp::order_accepted::Builder<'a>;
2498
2499    fn to_capnp(&self, mut builder: Self::Builder) {
2500        let trader_id_builder = builder.reborrow().init_trader_id();
2501        self.trader_id.to_capnp(trader_id_builder);
2502
2503        let strategy_id_builder = builder.reborrow().init_strategy_id();
2504        self.strategy_id.to_capnp(strategy_id_builder);
2505
2506        let instrument_id_builder = builder.reborrow().init_instrument_id();
2507        self.instrument_id.to_capnp(instrument_id_builder);
2508
2509        let client_order_id_builder = builder.reborrow().init_client_order_id();
2510        self.client_order_id.to_capnp(client_order_id_builder);
2511
2512        self.venue_order_id
2513            .write_capnp(|| builder.reborrow().init_venue_order_id());
2514        self.account_id
2515            .write_capnp(|| builder.reborrow().init_account_id());
2516
2517        let event_id_builder = builder.reborrow().init_event_id();
2518        self.event_id.to_capnp(event_id_builder);
2519
2520        let mut ts_event_builder = builder.reborrow().init_ts_event();
2521        ts_event_builder.set_value(*self.ts_event);
2522
2523        let mut ts_init_builder = builder.reborrow().init_ts_init();
2524        ts_init_builder.set_value(*self.ts_init);
2525
2526        builder.set_reconciliation(self.reconciliation != 0);
2527    }
2528}
2529
2530impl<'a> FromCapnp<'a> for OrderAccepted {
2531    type Reader = order_capnp::order_accepted::Reader<'a>;
2532
2533    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2534        let trader_id_reader = reader.get_trader_id()?;
2535        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2536
2537        let strategy_id_reader = reader.get_strategy_id()?;
2538        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2539
2540        let instrument_id_reader = reader.get_instrument_id()?;
2541        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2542
2543        let client_order_id_reader = reader.get_client_order_id()?;
2544        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2545
2546        let venue_order_id_reader = reader.get_venue_order_id()?;
2547        let venue_order_id = VenueOrderId::from_capnp(venue_order_id_reader)?;
2548
2549        let account_id_reader = reader.get_account_id()?;
2550        let account_id = AccountId::from_capnp(account_id_reader)?;
2551
2552        let event_id_reader = reader.get_event_id()?;
2553        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2554
2555        let ts_event_reader = reader.get_ts_event()?;
2556        let ts_event = ts_event_reader.get_value();
2557
2558        let ts_init_reader = reader.get_ts_init()?;
2559        let ts_init = ts_init_reader.get_value();
2560
2561        let reconciliation = reader.get_reconciliation() as u8;
2562
2563        Ok(Self {
2564            trader_id,
2565            strategy_id,
2566            instrument_id,
2567            client_order_id,
2568            venue_order_id,
2569            account_id,
2570            event_id,
2571            ts_event: ts_event.into(),
2572            ts_init: ts_init.into(),
2573            reconciliation,
2574        })
2575    }
2576}
2577
2578// OrderRejected
2579impl<'a> ToCapnp<'a> for OrderRejected {
2580    type Builder = order_capnp::order_rejected::Builder<'a>;
2581
2582    fn to_capnp(&self, mut builder: Self::Builder) {
2583        let trader_id_builder = builder.reborrow().init_trader_id();
2584        self.trader_id.to_capnp(trader_id_builder);
2585
2586        let strategy_id_builder = builder.reborrow().init_strategy_id();
2587        self.strategy_id.to_capnp(strategy_id_builder);
2588
2589        let instrument_id_builder = builder.reborrow().init_instrument_id();
2590        self.instrument_id.to_capnp(instrument_id_builder);
2591
2592        let client_order_id_builder = builder.reborrow().init_client_order_id();
2593        self.client_order_id.to_capnp(client_order_id_builder);
2594
2595        self.account_id
2596            .write_capnp(|| builder.reborrow().init_account_id());
2597
2598        builder.set_reason(self.reason.as_str());
2599
2600        let event_id_builder = builder.reborrow().init_event_id();
2601        self.event_id.to_capnp(event_id_builder);
2602
2603        let mut ts_event_builder = builder.reborrow().init_ts_event();
2604        ts_event_builder.set_value(*self.ts_event);
2605
2606        let mut ts_init_builder = builder.reborrow().init_ts_init();
2607        ts_init_builder.set_value(*self.ts_init);
2608
2609        builder.set_reconciliation(self.reconciliation != 0);
2610        builder.set_due_post_only(self.due_post_only != 0);
2611    }
2612}
2613
2614impl<'a> FromCapnp<'a> for OrderRejected {
2615    type Reader = order_capnp::order_rejected::Reader<'a>;
2616
2617    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2618        let trader_id_reader = reader.get_trader_id()?;
2619        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2620
2621        let strategy_id_reader = reader.get_strategy_id()?;
2622        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2623
2624        let instrument_id_reader = reader.get_instrument_id()?;
2625        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2626
2627        let client_order_id_reader = reader.get_client_order_id()?;
2628        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2629
2630        let account_id_reader = reader.get_account_id()?;
2631        let account_id = AccountId::from_capnp(account_id_reader)?;
2632
2633        let reason = Ustr::from(reader.get_reason()?.to_str()?);
2634
2635        let event_id_reader = reader.get_event_id()?;
2636        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2637
2638        let ts_event_reader = reader.get_ts_event()?;
2639        let ts_event = ts_event_reader.get_value();
2640
2641        let ts_init_reader = reader.get_ts_init()?;
2642        let ts_init = ts_init_reader.get_value();
2643
2644        let reconciliation = reader.get_reconciliation() as u8;
2645        let due_post_only = reader.get_due_post_only() as u8;
2646
2647        Ok(Self {
2648            trader_id,
2649            strategy_id,
2650            instrument_id,
2651            client_order_id,
2652            account_id,
2653            reason,
2654            event_id,
2655            ts_event: ts_event.into(),
2656            ts_init: ts_init.into(),
2657            reconciliation,
2658            due_post_only,
2659        })
2660    }
2661}
2662
2663// OrderCanceled
2664impl<'a> ToCapnp<'a> for OrderCanceled {
2665    type Builder = order_capnp::order_canceled::Builder<'a>;
2666
2667    fn to_capnp(&self, mut builder: Self::Builder) {
2668        let trader_id_builder = builder.reborrow().init_trader_id();
2669        self.trader_id.to_capnp(trader_id_builder);
2670
2671        let strategy_id_builder = builder.reborrow().init_strategy_id();
2672        self.strategy_id.to_capnp(strategy_id_builder);
2673
2674        let instrument_id_builder = builder.reborrow().init_instrument_id();
2675        self.instrument_id.to_capnp(instrument_id_builder);
2676
2677        let client_order_id_builder = builder.reborrow().init_client_order_id();
2678        self.client_order_id.to_capnp(client_order_id_builder);
2679
2680        if let Some(ref venue_order_id) = self.venue_order_id {
2681            let venue_order_id_builder = builder.reborrow().init_venue_order_id();
2682            venue_order_id.to_capnp(venue_order_id_builder);
2683        }
2684
2685        self.account_id
2686            .write_capnp(|| builder.reborrow().init_account_id());
2687
2688        let event_id_builder = builder.reborrow().init_event_id();
2689        self.event_id.to_capnp(event_id_builder);
2690
2691        let mut ts_event_builder = builder.reborrow().init_ts_event();
2692        ts_event_builder.set_value(*self.ts_event);
2693
2694        let mut ts_init_builder = builder.reborrow().init_ts_init();
2695        ts_init_builder.set_value(*self.ts_init);
2696
2697        builder.set_reconciliation(self.reconciliation != 0);
2698    }
2699}
2700
2701impl<'a> FromCapnp<'a> for OrderCanceled {
2702    type Reader = order_capnp::order_canceled::Reader<'a>;
2703
2704    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2705        let trader_id_reader = reader.get_trader_id()?;
2706        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2707
2708        let strategy_id_reader = reader.get_strategy_id()?;
2709        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2710
2711        let instrument_id_reader = reader.get_instrument_id()?;
2712        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2713
2714        let client_order_id_reader = reader.get_client_order_id()?;
2715        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2716
2717        let venue_order_id = read_optional_from_capnp(
2718            || reader.has_venue_order_id(),
2719            || reader.get_venue_order_id(),
2720        )?;
2721
2722        let account_id =
2723            read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
2724
2725        let event_id_reader = reader.get_event_id()?;
2726        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2727
2728        let ts_event_reader = reader.get_ts_event()?;
2729        let ts_event = ts_event_reader.get_value();
2730
2731        let ts_init_reader = reader.get_ts_init()?;
2732        let ts_init = ts_init_reader.get_value();
2733
2734        let reconciliation = reader.get_reconciliation() as u8;
2735
2736        Ok(Self {
2737            trader_id,
2738            strategy_id,
2739            instrument_id,
2740            client_order_id,
2741            venue_order_id,
2742            account_id,
2743            event_id,
2744            ts_event: ts_event.into(),
2745            ts_init: ts_init.into(),
2746            reconciliation,
2747        })
2748    }
2749}
2750
2751// OrderExpired
2752impl<'a> ToCapnp<'a> for OrderExpired {
2753    type Builder = order_capnp::order_expired::Builder<'a>;
2754
2755    fn to_capnp(&self, mut builder: Self::Builder) {
2756        let trader_id_builder = builder.reborrow().init_trader_id();
2757        self.trader_id.to_capnp(trader_id_builder);
2758
2759        let strategy_id_builder = builder.reborrow().init_strategy_id();
2760        self.strategy_id.to_capnp(strategy_id_builder);
2761
2762        let instrument_id_builder = builder.reborrow().init_instrument_id();
2763        self.instrument_id.to_capnp(instrument_id_builder);
2764
2765        let client_order_id_builder = builder.reborrow().init_client_order_id();
2766        self.client_order_id.to_capnp(client_order_id_builder);
2767
2768        if let Some(ref venue_order_id) = self.venue_order_id {
2769            let venue_order_id_builder = builder.reborrow().init_venue_order_id();
2770            venue_order_id.to_capnp(venue_order_id_builder);
2771        }
2772
2773        self.account_id
2774            .write_capnp(|| builder.reborrow().init_account_id());
2775
2776        let event_id_builder = builder.reborrow().init_event_id();
2777        self.event_id.to_capnp(event_id_builder);
2778
2779        let mut ts_event_builder = builder.reborrow().init_ts_event();
2780        ts_event_builder.set_value(*self.ts_event);
2781
2782        let mut ts_init_builder = builder.reborrow().init_ts_init();
2783        ts_init_builder.set_value(*self.ts_init);
2784
2785        builder.set_reconciliation(self.reconciliation != 0);
2786    }
2787}
2788
2789impl<'a> FromCapnp<'a> for OrderExpired {
2790    type Reader = order_capnp::order_expired::Reader<'a>;
2791
2792    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2793        let trader_id_reader = reader.get_trader_id()?;
2794        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2795
2796        let strategy_id_reader = reader.get_strategy_id()?;
2797        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2798
2799        let instrument_id_reader = reader.get_instrument_id()?;
2800        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2801
2802        let client_order_id_reader = reader.get_client_order_id()?;
2803        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2804
2805        let venue_order_id = read_optional_from_capnp(
2806            || reader.has_venue_order_id(),
2807            || reader.get_venue_order_id(),
2808        )?;
2809
2810        let account_id =
2811            read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
2812
2813        let event_id_reader = reader.get_event_id()?;
2814        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2815
2816        let ts_event_reader = reader.get_ts_event()?;
2817        let ts_event = ts_event_reader.get_value();
2818
2819        let ts_init_reader = reader.get_ts_init()?;
2820        let ts_init = ts_init_reader.get_value();
2821
2822        let reconciliation = reader.get_reconciliation() as u8;
2823
2824        Ok(Self {
2825            trader_id,
2826            strategy_id,
2827            instrument_id,
2828            client_order_id,
2829            venue_order_id,
2830            account_id,
2831            event_id,
2832            ts_event: ts_event.into(),
2833            ts_init: ts_init.into(),
2834            reconciliation,
2835        })
2836    }
2837}
2838
2839// OrderTriggered
2840impl<'a> ToCapnp<'a> for OrderTriggered {
2841    type Builder = order_capnp::order_triggered::Builder<'a>;
2842
2843    fn to_capnp(&self, mut builder: Self::Builder) {
2844        let trader_id_builder = builder.reborrow().init_trader_id();
2845        self.trader_id.to_capnp(trader_id_builder);
2846
2847        let strategy_id_builder = builder.reborrow().init_strategy_id();
2848        self.strategy_id.to_capnp(strategy_id_builder);
2849
2850        let instrument_id_builder = builder.reborrow().init_instrument_id();
2851        self.instrument_id.to_capnp(instrument_id_builder);
2852
2853        let client_order_id_builder = builder.reborrow().init_client_order_id();
2854        self.client_order_id.to_capnp(client_order_id_builder);
2855
2856        if let Some(ref venue_order_id) = self.venue_order_id {
2857            let venue_order_id_builder = builder.reborrow().init_venue_order_id();
2858            venue_order_id.to_capnp(venue_order_id_builder);
2859        }
2860
2861        self.account_id
2862            .write_capnp(|| builder.reborrow().init_account_id());
2863
2864        let event_id_builder = builder.reborrow().init_event_id();
2865        self.event_id.to_capnp(event_id_builder);
2866
2867        let mut ts_event_builder = builder.reborrow().init_ts_event();
2868        ts_event_builder.set_value(*self.ts_event);
2869
2870        let mut ts_init_builder = builder.reborrow().init_ts_init();
2871        ts_init_builder.set_value(*self.ts_init);
2872
2873        builder.set_reconciliation(self.reconciliation != 0);
2874    }
2875}
2876
2877impl<'a> FromCapnp<'a> for OrderTriggered {
2878    type Reader = order_capnp::order_triggered::Reader<'a>;
2879
2880    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2881        let trader_id_reader = reader.get_trader_id()?;
2882        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2883
2884        let strategy_id_reader = reader.get_strategy_id()?;
2885        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2886
2887        let instrument_id_reader = reader.get_instrument_id()?;
2888        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2889
2890        let client_order_id_reader = reader.get_client_order_id()?;
2891        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2892
2893        let venue_order_id = read_optional_from_capnp(
2894            || reader.has_venue_order_id(),
2895            || reader.get_venue_order_id(),
2896        )?;
2897
2898        let account_id =
2899            read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
2900
2901        let event_id_reader = reader.get_event_id()?;
2902        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2903
2904        let ts_event_reader = reader.get_ts_event()?;
2905        let ts_event = ts_event_reader.get_value();
2906
2907        let ts_init_reader = reader.get_ts_init()?;
2908        let ts_init = ts_init_reader.get_value();
2909
2910        let reconciliation = reader.get_reconciliation() as u8;
2911
2912        Ok(Self {
2913            trader_id,
2914            strategy_id,
2915            instrument_id,
2916            client_order_id,
2917            venue_order_id,
2918            account_id,
2919            event_id,
2920            ts_event: ts_event.into(),
2921            ts_init: ts_init.into(),
2922            reconciliation,
2923        })
2924    }
2925}
2926
2927// OrderPendingUpdate
2928impl<'a> ToCapnp<'a> for OrderPendingUpdate {
2929    type Builder = order_capnp::order_pending_update::Builder<'a>;
2930
2931    fn to_capnp(&self, mut builder: Self::Builder) {
2932        let trader_id_builder = builder.reborrow().init_trader_id();
2933        self.trader_id.to_capnp(trader_id_builder);
2934
2935        let strategy_id_builder = builder.reborrow().init_strategy_id();
2936        self.strategy_id.to_capnp(strategy_id_builder);
2937
2938        let instrument_id_builder = builder.reborrow().init_instrument_id();
2939        self.instrument_id.to_capnp(instrument_id_builder);
2940
2941        let client_order_id_builder = builder.reborrow().init_client_order_id();
2942        self.client_order_id.to_capnp(client_order_id_builder);
2943
2944        if let Some(ref venue_order_id) = self.venue_order_id {
2945            let venue_order_id_builder = builder.reborrow().init_venue_order_id();
2946            venue_order_id.to_capnp(venue_order_id_builder);
2947        }
2948
2949        let account_id_builder = builder.reborrow().init_account_id();
2950        self.account_id.to_capnp(account_id_builder);
2951
2952        let event_id_builder = builder.reborrow().init_event_id();
2953        self.event_id.to_capnp(event_id_builder);
2954
2955        let mut ts_event_builder = builder.reborrow().init_ts_event();
2956        ts_event_builder.set_value(*self.ts_event);
2957
2958        let mut ts_init_builder = builder.reborrow().init_ts_init();
2959        ts_init_builder.set_value(*self.ts_init);
2960
2961        builder.set_reconciliation(self.reconciliation != 0);
2962    }
2963}
2964
2965impl<'a> FromCapnp<'a> for OrderPendingUpdate {
2966    type Reader = order_capnp::order_pending_update::Reader<'a>;
2967
2968    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
2969        let trader_id_reader = reader.get_trader_id()?;
2970        let trader_id = TraderId::from_capnp(trader_id_reader)?;
2971
2972        let strategy_id_reader = reader.get_strategy_id()?;
2973        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
2974
2975        let instrument_id_reader = reader.get_instrument_id()?;
2976        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
2977
2978        let client_order_id_reader = reader.get_client_order_id()?;
2979        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
2980
2981        let venue_order_id = if reader.has_venue_order_id() {
2982            let venue_order_id_reader = reader.get_venue_order_id()?;
2983            Some(VenueOrderId::from_capnp(venue_order_id_reader)?)
2984        } else {
2985            None
2986        };
2987
2988        let account_id_reader = reader.get_account_id()?;
2989        let account_id = AccountId::from_capnp(account_id_reader)?;
2990
2991        let event_id_reader = reader.get_event_id()?;
2992        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
2993
2994        let ts_event_reader = reader.get_ts_event()?;
2995        let ts_event = ts_event_reader.get_value();
2996
2997        let ts_init_reader = reader.get_ts_init()?;
2998        let ts_init = ts_init_reader.get_value();
2999
3000        let reconciliation = reader.get_reconciliation() as u8;
3001
3002        Ok(Self {
3003            trader_id,
3004            strategy_id,
3005            instrument_id,
3006            client_order_id,
3007            venue_order_id,
3008            account_id,
3009            event_id,
3010            ts_event: ts_event.into(),
3011            ts_init: ts_init.into(),
3012            reconciliation,
3013        })
3014    }
3015}
3016
3017// OrderPendingCancel
3018impl<'a> ToCapnp<'a> for OrderPendingCancel {
3019    type Builder = order_capnp::order_pending_cancel::Builder<'a>;
3020
3021    fn to_capnp(&self, mut builder: Self::Builder) {
3022        let trader_id_builder = builder.reborrow().init_trader_id();
3023        self.trader_id.to_capnp(trader_id_builder);
3024
3025        let strategy_id_builder = builder.reborrow().init_strategy_id();
3026        self.strategy_id.to_capnp(strategy_id_builder);
3027
3028        let instrument_id_builder = builder.reborrow().init_instrument_id();
3029        self.instrument_id.to_capnp(instrument_id_builder);
3030
3031        let client_order_id_builder = builder.reborrow().init_client_order_id();
3032        self.client_order_id.to_capnp(client_order_id_builder);
3033
3034        if let Some(ref venue_order_id) = self.venue_order_id {
3035            let venue_order_id_builder = builder.reborrow().init_venue_order_id();
3036            venue_order_id.to_capnp(venue_order_id_builder);
3037        }
3038
3039        let account_id_builder = builder.reborrow().init_account_id();
3040        self.account_id.to_capnp(account_id_builder);
3041
3042        let event_id_builder = builder.reborrow().init_event_id();
3043        self.event_id.to_capnp(event_id_builder);
3044
3045        let mut ts_event_builder = builder.reborrow().init_ts_event();
3046        ts_event_builder.set_value(*self.ts_event);
3047
3048        let mut ts_init_builder = builder.reborrow().init_ts_init();
3049        ts_init_builder.set_value(*self.ts_init);
3050
3051        builder.set_reconciliation(self.reconciliation != 0);
3052    }
3053}
3054
3055impl<'a> FromCapnp<'a> for OrderPendingCancel {
3056    type Reader = order_capnp::order_pending_cancel::Reader<'a>;
3057
3058    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3059        let trader_id_reader = reader.get_trader_id()?;
3060        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3061
3062        let strategy_id_reader = reader.get_strategy_id()?;
3063        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3064
3065        let instrument_id_reader = reader.get_instrument_id()?;
3066        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3067
3068        let client_order_id_reader = reader.get_client_order_id()?;
3069        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3070
3071        let venue_order_id = if reader.has_venue_order_id() {
3072            let venue_order_id_reader = reader.get_venue_order_id()?;
3073            Some(VenueOrderId::from_capnp(venue_order_id_reader)?)
3074        } else {
3075            None
3076        };
3077
3078        let account_id_reader = reader.get_account_id()?;
3079        let account_id = AccountId::from_capnp(account_id_reader)?;
3080
3081        let event_id_reader = reader.get_event_id()?;
3082        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3083
3084        let ts_event_reader = reader.get_ts_event()?;
3085        let ts_event = ts_event_reader.get_value();
3086
3087        let ts_init_reader = reader.get_ts_init()?;
3088        let ts_init = ts_init_reader.get_value();
3089
3090        let reconciliation = reader.get_reconciliation() as u8;
3091
3092        Ok(Self {
3093            trader_id,
3094            strategy_id,
3095            instrument_id,
3096            client_order_id,
3097            venue_order_id,
3098            account_id,
3099            event_id,
3100            ts_event: ts_event.into(),
3101            ts_init: ts_init.into(),
3102            reconciliation,
3103        })
3104    }
3105}
3106
3107// OrderModifyRejected
3108impl<'a> ToCapnp<'a> for OrderModifyRejected {
3109    type Builder = order_capnp::order_modify_rejected::Builder<'a>;
3110
3111    fn to_capnp(&self, mut builder: Self::Builder) {
3112        let trader_id_builder = builder.reborrow().init_trader_id();
3113        self.trader_id.to_capnp(trader_id_builder);
3114
3115        let strategy_id_builder = builder.reborrow().init_strategy_id();
3116        self.strategy_id.to_capnp(strategy_id_builder);
3117
3118        let instrument_id_builder = builder.reborrow().init_instrument_id();
3119        self.instrument_id.to_capnp(instrument_id_builder);
3120
3121        let client_order_id_builder = builder.reborrow().init_client_order_id();
3122        self.client_order_id.to_capnp(client_order_id_builder);
3123
3124        self.venue_order_id
3125            .write_capnp(|| builder.reborrow().init_venue_order_id());
3126        self.account_id
3127            .write_capnp(|| builder.reborrow().init_account_id());
3128
3129        builder.set_reason(self.reason.as_str());
3130
3131        let event_id_builder = builder.reborrow().init_event_id();
3132        self.event_id.to_capnp(event_id_builder);
3133
3134        let mut ts_event_builder = builder.reborrow().init_ts_event();
3135        ts_event_builder.set_value(*self.ts_event);
3136
3137        let mut ts_init_builder = builder.reborrow().init_ts_init();
3138        ts_init_builder.set_value(*self.ts_init);
3139
3140        builder.set_reconciliation(self.reconciliation != 0);
3141    }
3142}
3143
3144impl<'a> FromCapnp<'a> for OrderModifyRejected {
3145    type Reader = order_capnp::order_modify_rejected::Reader<'a>;
3146
3147    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3148        let trader_id_reader = reader.get_trader_id()?;
3149        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3150
3151        let strategy_id_reader = reader.get_strategy_id()?;
3152        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3153
3154        let instrument_id_reader = reader.get_instrument_id()?;
3155        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3156
3157        let client_order_id_reader = reader.get_client_order_id()?;
3158        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3159
3160        let venue_order_id = read_optional_from_capnp(
3161            || reader.has_venue_order_id(),
3162            || reader.get_venue_order_id(),
3163        )?;
3164
3165        let account_id =
3166            read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3167
3168        let reason = Ustr::from(reader.get_reason()?.to_str()?);
3169
3170        let event_id_reader = reader.get_event_id()?;
3171        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3172
3173        let ts_event_reader = reader.get_ts_event()?;
3174        let ts_event = ts_event_reader.get_value();
3175
3176        let ts_init_reader = reader.get_ts_init()?;
3177        let ts_init = ts_init_reader.get_value();
3178
3179        let reconciliation = reader.get_reconciliation() as u8;
3180
3181        Ok(Self {
3182            trader_id,
3183            strategy_id,
3184            instrument_id,
3185            client_order_id,
3186            venue_order_id,
3187            account_id,
3188            reason,
3189            event_id,
3190            ts_event: ts_event.into(),
3191            ts_init: ts_init.into(),
3192            reconciliation,
3193        })
3194    }
3195}
3196
3197// OrderCancelRejected
3198impl<'a> ToCapnp<'a> for OrderCancelRejected {
3199    type Builder = order_capnp::order_cancel_rejected::Builder<'a>;
3200
3201    fn to_capnp(&self, mut builder: Self::Builder) {
3202        let trader_id_builder = builder.reborrow().init_trader_id();
3203        self.trader_id.to_capnp(trader_id_builder);
3204
3205        let strategy_id_builder = builder.reborrow().init_strategy_id();
3206        self.strategy_id.to_capnp(strategy_id_builder);
3207
3208        let instrument_id_builder = builder.reborrow().init_instrument_id();
3209        self.instrument_id.to_capnp(instrument_id_builder);
3210
3211        let client_order_id_builder = builder.reborrow().init_client_order_id();
3212        self.client_order_id.to_capnp(client_order_id_builder);
3213
3214        self.venue_order_id
3215            .write_capnp(|| builder.reborrow().init_venue_order_id());
3216        self.account_id
3217            .write_capnp(|| builder.reborrow().init_account_id());
3218
3219        builder.set_reason(self.reason.as_str());
3220
3221        let event_id_builder = builder.reborrow().init_event_id();
3222        self.event_id.to_capnp(event_id_builder);
3223
3224        let mut ts_event_builder = builder.reborrow().init_ts_event();
3225        ts_event_builder.set_value(*self.ts_event);
3226
3227        let mut ts_init_builder = builder.reborrow().init_ts_init();
3228        ts_init_builder.set_value(*self.ts_init);
3229
3230        builder.set_reconciliation(self.reconciliation != 0);
3231    }
3232}
3233
3234impl<'a> FromCapnp<'a> for OrderCancelRejected {
3235    type Reader = order_capnp::order_cancel_rejected::Reader<'a>;
3236
3237    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3238        let trader_id_reader = reader.get_trader_id()?;
3239        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3240
3241        let strategy_id_reader = reader.get_strategy_id()?;
3242        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3243
3244        let instrument_id_reader = reader.get_instrument_id()?;
3245        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3246
3247        let client_order_id_reader = reader.get_client_order_id()?;
3248        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3249
3250        let venue_order_id = read_optional_from_capnp(
3251            || reader.has_venue_order_id(),
3252            || reader.get_venue_order_id(),
3253        )?;
3254
3255        let account_id =
3256            read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3257
3258        let reason = Ustr::from(reader.get_reason()?.to_str()?);
3259
3260        let event_id_reader = reader.get_event_id()?;
3261        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3262
3263        let ts_event_reader = reader.get_ts_event()?;
3264        let ts_event = ts_event_reader.get_value();
3265
3266        let ts_init_reader = reader.get_ts_init()?;
3267        let ts_init = ts_init_reader.get_value();
3268
3269        let reconciliation = reader.get_reconciliation() as u8;
3270
3271        Ok(Self {
3272            trader_id,
3273            strategy_id,
3274            instrument_id,
3275            client_order_id,
3276            venue_order_id,
3277            account_id,
3278            reason,
3279            event_id,
3280            ts_event: ts_event.into(),
3281            ts_init: ts_init.into(),
3282            reconciliation,
3283        })
3284    }
3285}
3286
3287// OrderUpdated
3288impl<'a> ToCapnp<'a> for OrderUpdated {
3289    type Builder = order_capnp::order_updated::Builder<'a>;
3290
3291    fn to_capnp(&self, mut builder: Self::Builder) {
3292        let trader_id_builder = builder.reborrow().init_trader_id();
3293        self.trader_id.to_capnp(trader_id_builder);
3294
3295        let strategy_id_builder = builder.reborrow().init_strategy_id();
3296        self.strategy_id.to_capnp(strategy_id_builder);
3297
3298        let instrument_id_builder = builder.reborrow().init_instrument_id();
3299        self.instrument_id.to_capnp(instrument_id_builder);
3300
3301        let client_order_id_builder = builder.reborrow().init_client_order_id();
3302        self.client_order_id.to_capnp(client_order_id_builder);
3303
3304        self.venue_order_id
3305            .write_capnp(|| builder.reborrow().init_venue_order_id());
3306        self.account_id
3307            .write_capnp(|| builder.reborrow().init_account_id());
3308
3309        let quantity_builder = builder.reborrow().init_quantity();
3310        self.quantity.to_capnp(quantity_builder);
3311
3312        if let Some(price) = self.price {
3313            let price_builder = builder.reborrow().init_price();
3314            price.to_capnp(price_builder);
3315        }
3316
3317        if let Some(trigger_price) = self.trigger_price {
3318            let trigger_price_builder = builder.reborrow().init_trigger_price();
3319            trigger_price.to_capnp(trigger_price_builder);
3320        }
3321
3322        if let Some(protection_price) = self.protection_price {
3323            let protection_price_builder = builder.reborrow().init_protection_price();
3324            protection_price.to_capnp(protection_price_builder);
3325        }
3326
3327        let event_id_builder = builder.reborrow().init_event_id();
3328        self.event_id.to_capnp(event_id_builder);
3329
3330        let mut ts_event_builder = builder.reborrow().init_ts_event();
3331        ts_event_builder.set_value(*self.ts_event);
3332
3333        let mut ts_init_builder = builder.reborrow().init_ts_init();
3334        ts_init_builder.set_value(*self.ts_init);
3335
3336        builder.set_reconciliation(self.reconciliation != 0);
3337    }
3338}
3339
3340impl<'a> FromCapnp<'a> for OrderUpdated {
3341    type Reader = order_capnp::order_updated::Reader<'a>;
3342
3343    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3344        let trader_id_reader = reader.get_trader_id()?;
3345        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3346
3347        let strategy_id_reader = reader.get_strategy_id()?;
3348        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3349
3350        let instrument_id_reader = reader.get_instrument_id()?;
3351        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3352
3353        let client_order_id_reader = reader.get_client_order_id()?;
3354        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3355
3356        let venue_order_id = read_optional_from_capnp(
3357            || reader.has_venue_order_id(),
3358            || reader.get_venue_order_id(),
3359        )?;
3360
3361        let account_id =
3362            read_optional_from_capnp(|| reader.has_account_id(), || reader.get_account_id())?;
3363
3364        let quantity_reader = reader.get_quantity()?;
3365        let quantity = Quantity::from_capnp(quantity_reader)?;
3366
3367        let price = if reader.has_price() {
3368            let price_reader = reader.get_price()?;
3369            Some(Price::from_capnp(price_reader)?)
3370        } else {
3371            None
3372        };
3373
3374        let trigger_price = if reader.has_trigger_price() {
3375            let trigger_price_reader = reader.get_trigger_price()?;
3376            Some(Price::from_capnp(trigger_price_reader)?)
3377        } else {
3378            None
3379        };
3380
3381        let protection_price = if reader.has_protection_price() {
3382            let protection_price_reader = reader.get_protection_price()?;
3383            Some(Price::from_capnp(protection_price_reader)?)
3384        } else {
3385            None
3386        };
3387
3388        let event_id_reader = reader.get_event_id()?;
3389        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3390
3391        let ts_event_reader = reader.get_ts_event()?;
3392        let ts_event = ts_event_reader.get_value();
3393
3394        let ts_init_reader = reader.get_ts_init()?;
3395        let ts_init = ts_init_reader.get_value();
3396
3397        let reconciliation = reader.get_reconciliation() as u8;
3398
3399        Ok(Self {
3400            trader_id,
3401            strategy_id,
3402            instrument_id,
3403            client_order_id,
3404            venue_order_id,
3405            account_id,
3406            quantity,
3407            price,
3408            trigger_price,
3409            protection_price,
3410            event_id,
3411            ts_event: ts_event.into(),
3412            ts_init: ts_init.into(),
3413            reconciliation,
3414        })
3415    }
3416}
3417
3418// OrderFilled
3419impl<'a> ToCapnp<'a> for OrderFilled {
3420    type Builder = order_capnp::order_filled::Builder<'a>;
3421
3422    fn to_capnp(&self, mut builder: Self::Builder) {
3423        let trader_id_builder = builder.reborrow().init_trader_id();
3424        self.trader_id.to_capnp(trader_id_builder);
3425
3426        let strategy_id_builder = builder.reborrow().init_strategy_id();
3427        self.strategy_id.to_capnp(strategy_id_builder);
3428
3429        let instrument_id_builder = builder.reborrow().init_instrument_id();
3430        self.instrument_id.to_capnp(instrument_id_builder);
3431
3432        let client_order_id_builder = builder.reborrow().init_client_order_id();
3433        self.client_order_id.to_capnp(client_order_id_builder);
3434
3435        let venue_order_id_builder = builder.reborrow().init_venue_order_id();
3436        self.venue_order_id.to_capnp(venue_order_id_builder);
3437
3438        let account_id_builder = builder.reborrow().init_account_id();
3439        self.account_id.to_capnp(account_id_builder);
3440
3441        let trade_id_builder = builder.reborrow().init_trade_id();
3442        self.trade_id.to_capnp(trade_id_builder);
3443
3444        builder.set_order_side(order_side_to_capnp(self.order_side));
3445        builder.set_order_type(order_type_to_capnp(self.order_type));
3446
3447        let last_qty_builder = builder.reborrow().init_last_qty();
3448        self.last_qty.to_capnp(last_qty_builder);
3449
3450        let last_px_builder = builder.reborrow().init_last_px();
3451        self.last_px.to_capnp(last_px_builder);
3452
3453        let currency_builder = builder.reborrow().init_currency();
3454        self.currency.to_capnp(currency_builder);
3455
3456        builder.set_liquidity_side(liquidity_side_to_capnp(self.liquidity_side));
3457
3458        let event_id_builder = builder.reborrow().init_event_id();
3459        self.event_id.to_capnp(event_id_builder);
3460
3461        let mut ts_event_builder = builder.reborrow().init_ts_event();
3462        ts_event_builder.set_value(*self.ts_event);
3463
3464        let mut ts_init_builder = builder.reborrow().init_ts_init();
3465        ts_init_builder.set_value(*self.ts_init);
3466
3467        builder.set_reconciliation(self.reconciliation);
3468
3469        if let Some(position_id) = &self.position_id {
3470            let position_id_builder = builder.reborrow().init_position_id();
3471            position_id.to_capnp(position_id_builder);
3472        }
3473
3474        if let Some(commission) = &self.commission {
3475            let commission_builder = builder.reborrow().init_commission();
3476            commission.to_capnp(commission_builder);
3477        }
3478    }
3479}
3480
3481impl<'a> FromCapnp<'a> for OrderFilled {
3482    type Reader = order_capnp::order_filled::Reader<'a>;
3483
3484    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3485        let trader_id_reader = reader.get_trader_id()?;
3486        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3487
3488        let strategy_id_reader = reader.get_strategy_id()?;
3489        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3490
3491        let instrument_id_reader = reader.get_instrument_id()?;
3492        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3493
3494        let client_order_id_reader = reader.get_client_order_id()?;
3495        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3496
3497        let venue_order_id_reader = reader.get_venue_order_id()?;
3498        let venue_order_id = VenueOrderId::from_capnp(venue_order_id_reader)?;
3499
3500        let account_id_reader = reader.get_account_id()?;
3501        let account_id = AccountId::from_capnp(account_id_reader)?;
3502
3503        let trade_id_reader = reader.get_trade_id()?;
3504        let trade_id = TradeId::from_capnp(trade_id_reader)?;
3505
3506        let order_side = order_side_from_capnp(reader.get_order_side()?);
3507        let order_type = order_type_from_capnp(reader.get_order_type()?);
3508
3509        let last_qty_reader = reader.get_last_qty()?;
3510        let last_qty = Quantity::from_capnp(last_qty_reader)?;
3511
3512        let last_px_reader = reader.get_last_px()?;
3513        let last_px = Price::from_capnp(last_px_reader)?;
3514
3515        let currency_reader = reader.get_currency()?;
3516        let currency = Currency::from_capnp(currency_reader)?;
3517
3518        let liquidity_side = liquidity_side_from_capnp(reader.get_liquidity_side()?);
3519
3520        let event_id_reader = reader.get_event_id()?;
3521        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3522
3523        let ts_event_reader = reader.get_ts_event()?;
3524        let ts_event = ts_event_reader.get_value();
3525
3526        let ts_init_reader = reader.get_ts_init()?;
3527        let ts_init = ts_init_reader.get_value();
3528
3529        let reconciliation = reader.get_reconciliation();
3530
3531        let position_id = if reader.has_position_id() {
3532            let position_id_reader = reader.get_position_id()?;
3533            Some(PositionId::from_capnp(position_id_reader)?)
3534        } else {
3535            None
3536        };
3537
3538        let commission = if reader.has_commission() {
3539            let commission_reader = reader.get_commission()?;
3540            Some(Money::from_capnp(commission_reader)?)
3541        } else {
3542            None
3543        };
3544
3545        Ok(Self {
3546            trader_id,
3547            strategy_id,
3548            instrument_id,
3549            client_order_id,
3550            venue_order_id,
3551            account_id,
3552            trade_id,
3553            order_side,
3554            order_type,
3555            last_qty,
3556            last_px,
3557            currency,
3558            liquidity_side,
3559            event_id,
3560            ts_event: ts_event.into(),
3561            ts_init: ts_init.into(),
3562            reconciliation,
3563            position_id,
3564            commission,
3565        })
3566    }
3567}
3568
3569// OrderInitialized - seed event
3570impl<'a> ToCapnp<'a> for OrderInitialized {
3571    type Builder = order_capnp::order_initialized::Builder<'a>;
3572
3573    fn to_capnp(&self, mut builder: Self::Builder) {
3574        let trader_id_builder = builder.reborrow().init_trader_id();
3575        self.trader_id.to_capnp(trader_id_builder);
3576
3577        let strategy_id_builder = builder.reborrow().init_strategy_id();
3578        self.strategy_id.to_capnp(strategy_id_builder);
3579
3580        let instrument_id_builder = builder.reborrow().init_instrument_id();
3581        self.instrument_id.to_capnp(instrument_id_builder);
3582
3583        let client_order_id_builder = builder.reborrow().init_client_order_id();
3584        self.client_order_id.to_capnp(client_order_id_builder);
3585
3586        builder.set_order_side(order_side_to_capnp(self.order_side));
3587        builder.set_order_type(order_type_to_capnp(self.order_type));
3588
3589        let quantity_builder = builder.reborrow().init_quantity();
3590        self.quantity.to_capnp(quantity_builder);
3591
3592        builder.set_time_in_force(time_in_force_to_capnp(self.time_in_force));
3593        builder.set_post_only(self.post_only);
3594        builder.set_reduce_only(self.reduce_only);
3595        builder.set_quote_quantity(self.quote_quantity);
3596        builder.set_reconciliation(self.reconciliation);
3597
3598        let event_id_builder = builder.reborrow().init_event_id();
3599        self.event_id.to_capnp(event_id_builder);
3600
3601        let mut ts_event_builder = builder.reborrow().init_ts_event();
3602        ts_event_builder.set_value(*self.ts_event);
3603
3604        let mut ts_init_builder = builder.reborrow().init_ts_init();
3605        ts_init_builder.set_value(*self.ts_init);
3606
3607        // Optional fields
3608        if let Some(price) = self.price {
3609            let price_builder = builder.reborrow().init_price();
3610            price.to_capnp(price_builder);
3611        }
3612
3613        if let Some(trigger_price) = self.trigger_price {
3614            let trigger_price_builder = builder.reborrow().init_trigger_price();
3615            trigger_price.to_capnp(trigger_price_builder);
3616        }
3617
3618        if let Some(trigger_type) = self.trigger_type {
3619            builder.set_trigger_type(trigger_type_to_capnp(trigger_type));
3620        }
3621
3622        if let Some(limit_offset) = self.limit_offset {
3623            let limit_offset_builder = builder.reborrow().init_limit_offset();
3624            limit_offset.to_capnp(limit_offset_builder);
3625        }
3626
3627        if let Some(trailing_offset) = self.trailing_offset {
3628            let trailing_offset_builder = builder.reborrow().init_trailing_offset();
3629            trailing_offset.to_capnp(trailing_offset_builder);
3630        }
3631
3632        if let Some(trailing_offset_type) = self.trailing_offset_type {
3633            builder.set_trailing_offset_type(trailing_offset_type_to_capnp(trailing_offset_type));
3634        }
3635
3636        if let Some(expire_time) = self.expire_time {
3637            let mut expire_time_builder = builder.reborrow().init_expire_time();
3638            expire_time_builder.set_value(*expire_time);
3639        }
3640
3641        if let Some(display_qty) = self.display_qty {
3642            let display_qty_builder = builder.reborrow().init_display_qty();
3643            display_qty.to_capnp(display_qty_builder);
3644        }
3645
3646        if let Some(emulation_trigger) = self.emulation_trigger {
3647            builder.set_emulation_trigger(trigger_type_to_capnp(emulation_trigger));
3648        }
3649
3650        if let Some(trigger_instrument_id) = &self.trigger_instrument_id {
3651            let trigger_instrument_id_builder = builder.reborrow().init_trigger_instrument_id();
3652            trigger_instrument_id.to_capnp(trigger_instrument_id_builder);
3653        }
3654
3655        if let Some(contingency_type) = self.contingency_type {
3656            builder.set_contingency_type(contingency_type_to_capnp(contingency_type));
3657        }
3658
3659        if let Some(order_list_id) = &self.order_list_id {
3660            let order_list_id_builder = builder.reborrow().init_order_list_id();
3661            order_list_id.to_capnp(order_list_id_builder);
3662        }
3663
3664        if let Some(linked_order_ids) = &self.linked_order_ids {
3665            let mut linked_order_ids_builder = builder
3666                .reborrow()
3667                .init_linked_order_ids(linked_order_ids.len() as u32);
3668            for (i, order_id) in linked_order_ids.iter().enumerate() {
3669                let order_id_builder = linked_order_ids_builder.reborrow().get(i as u32);
3670                order_id.to_capnp(order_id_builder);
3671            }
3672        }
3673
3674        if let Some(parent_order_id) = &self.parent_order_id {
3675            let parent_order_id_builder = builder.reborrow().init_parent_order_id();
3676            parent_order_id.to_capnp(parent_order_id_builder);
3677        }
3678
3679        if let Some(exec_algorithm_id) = &self.exec_algorithm_id {
3680            let exec_algorithm_id_builder = builder.reborrow().init_exec_algorithm_id();
3681            exec_algorithm_id.to_capnp(exec_algorithm_id_builder);
3682        }
3683
3684        if let Some(exec_algorithm_params) = &self.exec_algorithm_params {
3685            let mut params_builder = builder.reborrow().init_exec_algorithm_params();
3686            let mut entries_builder = params_builder
3687                .reborrow()
3688                .init_entries(exec_algorithm_params.len() as u32);
3689            for (i, (key, value)) in exec_algorithm_params.iter().enumerate() {
3690                let mut entry_builder = entries_builder.reborrow().get(i as u32);
3691                entry_builder.set_key(key.as_str());
3692                entry_builder.set_value(value.as_str());
3693            }
3694        }
3695
3696        if let Some(exec_spawn_id) = &self.exec_spawn_id {
3697            let exec_spawn_id_builder = builder.reborrow().init_exec_spawn_id();
3698            exec_spawn_id.to_capnp(exec_spawn_id_builder);
3699        }
3700
3701        if let Some(tags) = &self.tags {
3702            let mut tags_builder = builder.reborrow().init_tags(tags.len() as u32);
3703            for (i, tag) in tags.iter().enumerate() {
3704                tags_builder.set(i as u32, tag.as_str());
3705            }
3706        }
3707    }
3708}
3709
3710impl<'a> FromCapnp<'a> for OrderInitialized {
3711    type Reader = order_capnp::order_initialized::Reader<'a>;
3712
3713    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3714        let trader_id_reader = reader.get_trader_id()?;
3715        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3716
3717        let strategy_id_reader = reader.get_strategy_id()?;
3718        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3719
3720        let instrument_id_reader = reader.get_instrument_id()?;
3721        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3722
3723        let client_order_id_reader = reader.get_client_order_id()?;
3724        let client_order_id = ClientOrderId::from_capnp(client_order_id_reader)?;
3725
3726        let order_side = order_side_from_capnp(reader.get_order_side()?);
3727        let order_type = order_type_from_capnp(reader.get_order_type()?);
3728
3729        let quantity_reader = reader.get_quantity()?;
3730        let quantity = Quantity::from_capnp(quantity_reader)?;
3731
3732        let time_in_force = time_in_force_from_capnp(reader.get_time_in_force()?);
3733        let post_only = reader.get_post_only();
3734        let reduce_only = reader.get_reduce_only();
3735        let quote_quantity = reader.get_quote_quantity();
3736        let reconciliation = reader.get_reconciliation();
3737
3738        let event_id_reader = reader.get_event_id()?;
3739        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
3740
3741        let ts_event_reader = reader.get_ts_event()?;
3742        let ts_event = ts_event_reader.get_value();
3743
3744        let ts_init_reader = reader.get_ts_init()?;
3745        let ts_init = ts_init_reader.get_value();
3746
3747        // Optional fields
3748        let price = if reader.has_price() {
3749            let price_reader = reader.get_price()?;
3750            Some(Price::from_capnp(price_reader)?)
3751        } else {
3752            None
3753        };
3754
3755        let trigger_price = if reader.has_trigger_price() {
3756            let trigger_price_reader = reader.get_trigger_price()?;
3757            Some(Price::from_capnp(trigger_price_reader)?)
3758        } else {
3759            None
3760        };
3761
3762        let trigger_type = match reader.get_trigger_type()? {
3763            enums_capnp::TriggerType::NoTrigger => None,
3764            other => Some(trigger_type_from_capnp(other)),
3765        };
3766
3767        let limit_offset = if reader.has_limit_offset() {
3768            let limit_offset_reader = reader.get_limit_offset()?;
3769            Some(Decimal::from_capnp(limit_offset_reader)?)
3770        } else {
3771            None
3772        };
3773
3774        let trailing_offset = if reader.has_trailing_offset() {
3775            let trailing_offset_reader = reader.get_trailing_offset()?;
3776            Some(Decimal::from_capnp(trailing_offset_reader)?)
3777        } else {
3778            None
3779        };
3780
3781        let trailing_offset_type = match reader.get_trailing_offset_type()? {
3782            enums_capnp::TrailingOffsetType::NoTrailingOffset => None,
3783            other => Some(trailing_offset_type_from_capnp(other)),
3784        };
3785
3786        let expire_time = if reader.has_expire_time() {
3787            let expire_time_reader = reader.get_expire_time()?;
3788            let value = expire_time_reader.get_value();
3789            Some(value.into())
3790        } else {
3791            None
3792        };
3793
3794        let display_qty = if reader.has_display_qty() {
3795            let display_qty_reader = reader.get_display_qty()?;
3796            Some(Quantity::from_capnp(display_qty_reader)?)
3797        } else {
3798            None
3799        };
3800
3801        let emulation_trigger = match reader.get_emulation_trigger()? {
3802            enums_capnp::TriggerType::NoTrigger => None,
3803            other => Some(trigger_type_from_capnp(other)),
3804        };
3805
3806        let trigger_instrument_id = if reader.has_trigger_instrument_id() {
3807            let trigger_instrument_id_reader = reader.get_trigger_instrument_id()?;
3808            Some(InstrumentId::from_capnp(trigger_instrument_id_reader)?)
3809        } else {
3810            None
3811        };
3812
3813        let contingency_type = match reader.get_contingency_type()? {
3814            enums_capnp::ContingencyType::NoContingency => None,
3815            other => Some(contingency_type_from_capnp(other)),
3816        };
3817
3818        let order_list_id = if reader.has_order_list_id() {
3819            let order_list_id_reader = reader.get_order_list_id()?;
3820            Some(OrderListId::from_capnp(order_list_id_reader)?)
3821        } else {
3822            None
3823        };
3824
3825        let linked_order_ids = if reader.has_linked_order_ids() {
3826            let linked_order_ids_reader = reader.get_linked_order_ids()?;
3827            let mut linked_order_ids = Vec::new();
3828            for order_id_reader in linked_order_ids_reader {
3829                linked_order_ids.push(ClientOrderId::from_capnp(order_id_reader)?);
3830            }
3831            Some(linked_order_ids)
3832        } else {
3833            None
3834        };
3835
3836        let parent_order_id = if reader.has_parent_order_id() {
3837            let parent_order_id_reader = reader.get_parent_order_id()?;
3838            Some(ClientOrderId::from_capnp(parent_order_id_reader)?)
3839        } else {
3840            None
3841        };
3842
3843        let exec_algorithm_id = if reader.has_exec_algorithm_id() {
3844            let exec_algorithm_id_reader = reader.get_exec_algorithm_id()?;
3845            Some(ExecAlgorithmId::from_capnp(exec_algorithm_id_reader)?)
3846        } else {
3847            None
3848        };
3849
3850        let exec_algorithm_params = if reader.has_exec_algorithm_params() {
3851            let params_reader = reader.get_exec_algorithm_params()?;
3852            let entries_reader = params_reader.get_entries()?;
3853            let mut params = IndexMap::new();
3854            for entry_reader in entries_reader {
3855                let key = Ustr::from(entry_reader.get_key()?.to_str()?);
3856                let value = Ustr::from(entry_reader.get_value()?.to_str()?);
3857                params.insert(key, value);
3858            }
3859            Some(params)
3860        } else {
3861            None
3862        };
3863
3864        let exec_spawn_id = if reader.has_exec_spawn_id() {
3865            let exec_spawn_id_reader = reader.get_exec_spawn_id()?;
3866            Some(ClientOrderId::from_capnp(exec_spawn_id_reader)?)
3867        } else {
3868            None
3869        };
3870
3871        let tags = if reader.has_tags() {
3872            let tags_reader = reader.get_tags()?;
3873            let mut tags = Vec::new();
3874            for tag in tags_reader {
3875                tags.push(Ustr::from(tag?.to_str()?));
3876            }
3877            Some(tags)
3878        } else {
3879            None
3880        };
3881
3882        Ok(Self {
3883            trader_id,
3884            strategy_id,
3885            instrument_id,
3886            client_order_id,
3887            order_side,
3888            order_type,
3889            quantity,
3890            time_in_force,
3891            post_only,
3892            reduce_only,
3893            quote_quantity,
3894            reconciliation,
3895            event_id,
3896            ts_event: ts_event.into(),
3897            ts_init: ts_init.into(),
3898            price,
3899            trigger_price,
3900            trigger_type,
3901            limit_offset,
3902            trailing_offset,
3903            trailing_offset_type,
3904            expire_time,
3905            display_qty,
3906            emulation_trigger,
3907            trigger_instrument_id,
3908            contingency_type,
3909            order_list_id,
3910            linked_order_ids,
3911            parent_order_id,
3912            exec_algorithm_id,
3913            exec_algorithm_params,
3914            exec_spawn_id,
3915            tags,
3916        })
3917    }
3918}
3919
3920// PositionOpened
3921impl<'a> ToCapnp<'a> for PositionOpened {
3922    type Builder = position_capnp::position_opened::Builder<'a>;
3923
3924    fn to_capnp(&self, mut builder: Self::Builder) {
3925        let trader_id_builder = builder.reborrow().init_trader_id();
3926        self.trader_id.to_capnp(trader_id_builder);
3927
3928        let strategy_id_builder = builder.reborrow().init_strategy_id();
3929        self.strategy_id.to_capnp(strategy_id_builder);
3930
3931        let instrument_id_builder = builder.reborrow().init_instrument_id();
3932        self.instrument_id.to_capnp(instrument_id_builder);
3933
3934        let position_id_builder = builder.reborrow().init_position_id();
3935        self.position_id.to_capnp(position_id_builder);
3936
3937        let account_id_builder = builder.reborrow().init_account_id();
3938        self.account_id.to_capnp(account_id_builder);
3939
3940        let opening_order_id_builder = builder.reborrow().init_opening_order_id();
3941        self.opening_order_id.to_capnp(opening_order_id_builder);
3942
3943        builder.set_entry(order_side_to_capnp(self.entry));
3944        builder.set_side(position_side_to_capnp(self.side));
3945        builder.set_signed_qty(self.signed_qty);
3946
3947        let quantity_builder = builder.reborrow().init_quantity();
3948        self.quantity.to_capnp(quantity_builder);
3949
3950        let last_qty_builder = builder.reborrow().init_last_qty();
3951        self.last_qty.to_capnp(last_qty_builder);
3952
3953        let last_px_builder = builder.reborrow().init_last_px();
3954        self.last_px.to_capnp(last_px_builder);
3955
3956        let currency_builder = builder.reborrow().init_currency();
3957        self.currency.to_capnp(currency_builder);
3958
3959        builder.set_avg_px_open(self.avg_px_open);
3960
3961        let event_id_builder = builder.reborrow().init_event_id();
3962        self.event_id.to_capnp(event_id_builder);
3963
3964        let mut ts_event_builder = builder.reborrow().init_ts_event();
3965        ts_event_builder.set_value(*self.ts_event);
3966
3967        let mut ts_init_builder = builder.reborrow().init_ts_init();
3968        ts_init_builder.set_value(*self.ts_init);
3969    }
3970}
3971
3972impl<'a> FromCapnp<'a> for PositionOpened {
3973    type Reader = position_capnp::position_opened::Reader<'a>;
3974
3975    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
3976        let trader_id_reader = reader.get_trader_id()?;
3977        let trader_id = TraderId::from_capnp(trader_id_reader)?;
3978
3979        let strategy_id_reader = reader.get_strategy_id()?;
3980        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
3981
3982        let instrument_id_reader = reader.get_instrument_id()?;
3983        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
3984
3985        let position_id_reader = reader.get_position_id()?;
3986        let position_id = PositionId::from_capnp(position_id_reader)?;
3987
3988        let account_id_reader = reader.get_account_id()?;
3989        let account_id = AccountId::from_capnp(account_id_reader)?;
3990
3991        let opening_order_id_reader = reader.get_opening_order_id()?;
3992        let opening_order_id = ClientOrderId::from_capnp(opening_order_id_reader)?;
3993
3994        let entry = order_side_from_capnp(reader.get_entry()?);
3995        let side = position_side_from_capnp(reader.get_side()?);
3996        let signed_qty = reader.get_signed_qty();
3997
3998        let quantity_reader = reader.get_quantity()?;
3999        let quantity = Quantity::from_capnp(quantity_reader)?;
4000
4001        let last_qty_reader = reader.get_last_qty()?;
4002        let last_qty = Quantity::from_capnp(last_qty_reader)?;
4003
4004        let last_px_reader = reader.get_last_px()?;
4005        let last_px = Price::from_capnp(last_px_reader)?;
4006
4007        let currency_reader = reader.get_currency()?;
4008        let currency = Currency::from_capnp(currency_reader)?;
4009
4010        let avg_px_open = reader.get_avg_px_open();
4011
4012        let event_id_reader = reader.get_event_id()?;
4013        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4014
4015        let ts_event_reader = reader.get_ts_event()?;
4016        let ts_event = ts_event_reader.get_value();
4017
4018        let ts_init_reader = reader.get_ts_init()?;
4019        let ts_init = ts_init_reader.get_value();
4020
4021        Ok(Self {
4022            trader_id,
4023            strategy_id,
4024            instrument_id,
4025            position_id,
4026            account_id,
4027            opening_order_id,
4028            entry,
4029            side,
4030            signed_qty,
4031            quantity,
4032            last_qty,
4033            last_px,
4034            currency,
4035            avg_px_open,
4036            event_id,
4037            ts_event: ts_event.into(),
4038            ts_init: ts_init.into(),
4039        })
4040    }
4041}
4042
4043// PositionChanged
4044impl<'a> ToCapnp<'a> for PositionChanged {
4045    type Builder = position_capnp::position_changed::Builder<'a>;
4046
4047    fn to_capnp(&self, mut builder: Self::Builder) {
4048        let trader_id_builder = builder.reborrow().init_trader_id();
4049        self.trader_id.to_capnp(trader_id_builder);
4050
4051        let strategy_id_builder = builder.reborrow().init_strategy_id();
4052        self.strategy_id.to_capnp(strategy_id_builder);
4053
4054        let instrument_id_builder = builder.reborrow().init_instrument_id();
4055        self.instrument_id.to_capnp(instrument_id_builder);
4056
4057        let position_id_builder = builder.reborrow().init_position_id();
4058        self.position_id.to_capnp(position_id_builder);
4059
4060        let account_id_builder = builder.reborrow().init_account_id();
4061        self.account_id.to_capnp(account_id_builder);
4062
4063        let opening_order_id_builder = builder.reborrow().init_opening_order_id();
4064        self.opening_order_id.to_capnp(opening_order_id_builder);
4065
4066        builder.set_entry(order_side_to_capnp(self.entry));
4067        builder.set_side(position_side_to_capnp(self.side));
4068        builder.set_signed_qty(self.signed_qty);
4069
4070        let quantity_builder = builder.reborrow().init_quantity();
4071        self.quantity.to_capnp(quantity_builder);
4072
4073        let peak_quantity_builder = builder.reborrow().init_peak_quantity();
4074        self.peak_quantity.to_capnp(peak_quantity_builder);
4075
4076        let last_qty_builder = builder.reborrow().init_last_qty();
4077        self.last_qty.to_capnp(last_qty_builder);
4078
4079        let last_px_builder = builder.reborrow().init_last_px();
4080        self.last_px.to_capnp(last_px_builder);
4081
4082        let currency_builder = builder.reborrow().init_currency();
4083        self.currency.to_capnp(currency_builder);
4084
4085        builder.set_avg_px_open(self.avg_px_open);
4086        builder.set_avg_px_close(self.avg_px_close.unwrap_or(f64::NAN));
4087        builder.set_realized_return(self.realized_return);
4088
4089        self.realized_pnl
4090            .write_capnp(|| builder.reborrow().init_realized_pnl());
4091
4092        let unrealized_pnl_builder = builder.reborrow().init_unrealized_pnl();
4093        self.unrealized_pnl.to_capnp(unrealized_pnl_builder);
4094
4095        let event_id_builder = builder.reborrow().init_event_id();
4096        self.event_id.to_capnp(event_id_builder);
4097
4098        let mut ts_opened_builder = builder.reborrow().init_ts_opened();
4099        ts_opened_builder.set_value(*self.ts_opened);
4100
4101        let mut ts_event_builder = builder.reborrow().init_ts_event();
4102        ts_event_builder.set_value(*self.ts_event);
4103
4104        let mut ts_init_builder = builder.reborrow().init_ts_init();
4105        ts_init_builder.set_value(*self.ts_init);
4106    }
4107}
4108
4109impl<'a> FromCapnp<'a> for PositionChanged {
4110    type Reader = position_capnp::position_changed::Reader<'a>;
4111
4112    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4113        let trader_id_reader = reader.get_trader_id()?;
4114        let trader_id = TraderId::from_capnp(trader_id_reader)?;
4115
4116        let strategy_id_reader = reader.get_strategy_id()?;
4117        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4118
4119        let instrument_id_reader = reader.get_instrument_id()?;
4120        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4121
4122        let position_id_reader = reader.get_position_id()?;
4123        let position_id = PositionId::from_capnp(position_id_reader)?;
4124
4125        let account_id_reader = reader.get_account_id()?;
4126        let account_id = AccountId::from_capnp(account_id_reader)?;
4127
4128        let opening_order_id_reader = reader.get_opening_order_id()?;
4129        let opening_order_id = ClientOrderId::from_capnp(opening_order_id_reader)?;
4130
4131        let entry = order_side_from_capnp(reader.get_entry()?);
4132        let side = position_side_from_capnp(reader.get_side()?);
4133        let signed_qty = reader.get_signed_qty();
4134
4135        let quantity_reader = reader.get_quantity()?;
4136        let quantity = Quantity::from_capnp(quantity_reader)?;
4137
4138        let peak_quantity_reader = reader.get_peak_quantity()?;
4139        let peak_quantity = Quantity::from_capnp(peak_quantity_reader)?;
4140
4141        let last_qty_reader = reader.get_last_qty()?;
4142        let last_qty = Quantity::from_capnp(last_qty_reader)?;
4143
4144        let last_px_reader = reader.get_last_px()?;
4145        let last_px = Price::from_capnp(last_px_reader)?;
4146
4147        let currency_reader = reader.get_currency()?;
4148        let currency = Currency::from_capnp(currency_reader)?;
4149
4150        let avg_px_open = reader.get_avg_px_open();
4151        let avg_px_close = {
4152            let value = reader.get_avg_px_close();
4153            if value.is_nan() { None } else { Some(value) }
4154        };
4155        let realized_return = reader.get_realized_return();
4156
4157        let realized_pnl = if reader.has_realized_pnl() {
4158            let realized_pnl_reader = reader.get_realized_pnl()?;
4159            Some(Money::from_capnp(realized_pnl_reader)?)
4160        } else {
4161            None
4162        };
4163
4164        let unrealized_pnl_reader = reader.get_unrealized_pnl()?;
4165        let unrealized_pnl = Money::from_capnp(unrealized_pnl_reader)?;
4166
4167        let event_id_reader = reader.get_event_id()?;
4168        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4169
4170        let ts_opened_reader = reader.get_ts_opened()?;
4171        let ts_opened = ts_opened_reader.get_value();
4172
4173        let ts_event_reader = reader.get_ts_event()?;
4174        let ts_event = ts_event_reader.get_value();
4175
4176        let ts_init_reader = reader.get_ts_init()?;
4177        let ts_init = ts_init_reader.get_value();
4178
4179        Ok(Self {
4180            trader_id,
4181            strategy_id,
4182            instrument_id,
4183            position_id,
4184            account_id,
4185            opening_order_id,
4186            entry,
4187            side,
4188            signed_qty,
4189            quantity,
4190            peak_quantity,
4191            last_qty,
4192            last_px,
4193            currency,
4194            avg_px_open,
4195            avg_px_close,
4196            realized_return,
4197            realized_pnl,
4198            unrealized_pnl,
4199            event_id,
4200            ts_opened: ts_opened.into(),
4201            ts_event: ts_event.into(),
4202            ts_init: ts_init.into(),
4203        })
4204    }
4205}
4206
4207// PositionClosed
4208impl<'a> ToCapnp<'a> for PositionClosed {
4209    type Builder = position_capnp::position_closed::Builder<'a>;
4210
4211    fn to_capnp(&self, mut builder: Self::Builder) {
4212        let trader_id_builder = builder.reborrow().init_trader_id();
4213        self.trader_id.to_capnp(trader_id_builder);
4214
4215        let strategy_id_builder = builder.reborrow().init_strategy_id();
4216        self.strategy_id.to_capnp(strategy_id_builder);
4217
4218        let instrument_id_builder = builder.reborrow().init_instrument_id();
4219        self.instrument_id.to_capnp(instrument_id_builder);
4220
4221        let position_id_builder = builder.reborrow().init_position_id();
4222        self.position_id.to_capnp(position_id_builder);
4223
4224        let account_id_builder = builder.reborrow().init_account_id();
4225        self.account_id.to_capnp(account_id_builder);
4226
4227        let opening_order_id_builder = builder.reborrow().init_opening_order_id();
4228        self.opening_order_id.to_capnp(opening_order_id_builder);
4229
4230        self.closing_order_id
4231            .write_capnp(|| builder.reborrow().init_closing_order_id());
4232
4233        builder.set_entry(order_side_to_capnp(self.entry));
4234        builder.set_side(position_side_to_capnp(self.side));
4235        builder.set_signed_qty(self.signed_qty);
4236
4237        let quantity_builder = builder.reborrow().init_quantity();
4238        self.quantity.to_capnp(quantity_builder);
4239
4240        let peak_quantity_builder = builder.reborrow().init_peak_quantity();
4241        self.peak_quantity.to_capnp(peak_quantity_builder);
4242
4243        let last_qty_builder = builder.reborrow().init_last_qty();
4244        self.last_qty.to_capnp(last_qty_builder);
4245
4246        let last_px_builder = builder.reborrow().init_last_px();
4247        self.last_px.to_capnp(last_px_builder);
4248
4249        let currency_builder = builder.reborrow().init_currency();
4250        self.currency.to_capnp(currency_builder);
4251
4252        builder.set_avg_px_open(self.avg_px_open);
4253        builder.set_avg_px_close(self.avg_px_close.unwrap_or(f64::NAN));
4254        builder.set_realized_return(self.realized_return);
4255
4256        self.realized_pnl
4257            .write_capnp(|| builder.reborrow().init_realized_pnl());
4258
4259        let unrealized_pnl_builder = builder.reborrow().init_unrealized_pnl();
4260        self.unrealized_pnl.to_capnp(unrealized_pnl_builder);
4261
4262        builder.set_duration(self.duration);
4263
4264        let event_id_builder = builder.reborrow().init_event_id();
4265        self.event_id.to_capnp(event_id_builder);
4266
4267        let mut ts_opened_builder = builder.reborrow().init_ts_opened();
4268        ts_opened_builder.set_value(*self.ts_opened);
4269
4270        if let Some(ts_closed) = self.ts_closed {
4271            let mut ts_closed_builder = builder.reborrow().init_ts_closed();
4272            ts_closed_builder.set_value(*ts_closed);
4273        }
4274
4275        let mut ts_event_builder = builder.reborrow().init_ts_event();
4276        ts_event_builder.set_value(*self.ts_event);
4277
4278        let mut ts_init_builder = builder.reborrow().init_ts_init();
4279        ts_init_builder.set_value(*self.ts_init);
4280    }
4281}
4282
4283impl<'a> FromCapnp<'a> for PositionClosed {
4284    type Reader = position_capnp::position_closed::Reader<'a>;
4285
4286    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4287        let trader_id_reader = reader.get_trader_id()?;
4288        let trader_id = TraderId::from_capnp(trader_id_reader)?;
4289
4290        let strategy_id_reader = reader.get_strategy_id()?;
4291        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4292
4293        let instrument_id_reader = reader.get_instrument_id()?;
4294        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4295
4296        let position_id_reader = reader.get_position_id()?;
4297        let position_id = PositionId::from_capnp(position_id_reader)?;
4298
4299        let account_id_reader = reader.get_account_id()?;
4300        let account_id = AccountId::from_capnp(account_id_reader)?;
4301
4302        let opening_order_id_reader = reader.get_opening_order_id()?;
4303        let opening_order_id = ClientOrderId::from_capnp(opening_order_id_reader)?;
4304
4305        let closing_order_id = read_optional_from_capnp(
4306            || reader.has_closing_order_id(),
4307            || reader.get_closing_order_id(),
4308        )?;
4309
4310        let entry = order_side_from_capnp(reader.get_entry()?);
4311        let side = position_side_from_capnp(reader.get_side()?);
4312        let signed_qty = reader.get_signed_qty();
4313
4314        let quantity_reader = reader.get_quantity()?;
4315        let quantity = Quantity::from_capnp(quantity_reader)?;
4316
4317        let peak_quantity_reader = reader.get_peak_quantity()?;
4318        let peak_quantity = Quantity::from_capnp(peak_quantity_reader)?;
4319
4320        let last_qty_reader = reader.get_last_qty()?;
4321        let last_qty = Quantity::from_capnp(last_qty_reader)?;
4322
4323        let last_px_reader = reader.get_last_px()?;
4324        let last_px = Price::from_capnp(last_px_reader)?;
4325
4326        let currency_reader = reader.get_currency()?;
4327        let currency = Currency::from_capnp(currency_reader)?;
4328
4329        let avg_px_open = reader.get_avg_px_open();
4330        let avg_px_close = {
4331            let value = reader.get_avg_px_close();
4332            if value.is_nan() { None } else { Some(value) }
4333        };
4334        let realized_return = reader.get_realized_return();
4335
4336        let realized_pnl = if reader.has_realized_pnl() {
4337            let realized_pnl_reader = reader.get_realized_pnl()?;
4338            Some(Money::from_capnp(realized_pnl_reader)?)
4339        } else {
4340            None
4341        };
4342
4343        let unrealized_pnl_reader = reader.get_unrealized_pnl()?;
4344        let unrealized_pnl = Money::from_capnp(unrealized_pnl_reader)?;
4345
4346        let duration = reader.get_duration();
4347
4348        let event_id_reader = reader.get_event_id()?;
4349        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4350
4351        let ts_opened_reader = reader.get_ts_opened()?;
4352        let ts_opened = ts_opened_reader.get_value();
4353
4354        let ts_closed = if reader.has_ts_closed() {
4355            let ts_closed_reader = reader.get_ts_closed()?;
4356            Some(ts_closed_reader.get_value().into())
4357        } else {
4358            None
4359        };
4360
4361        let ts_event_reader = reader.get_ts_event()?;
4362        let ts_event = ts_event_reader.get_value();
4363
4364        let ts_init_reader = reader.get_ts_init()?;
4365        let ts_init = ts_init_reader.get_value();
4366
4367        Ok(Self {
4368            trader_id,
4369            strategy_id,
4370            instrument_id,
4371            position_id,
4372            account_id,
4373            opening_order_id,
4374            closing_order_id,
4375            entry,
4376            side,
4377            signed_qty,
4378            quantity,
4379            peak_quantity,
4380            last_qty,
4381            last_px,
4382            currency,
4383            avg_px_open,
4384            avg_px_close,
4385            realized_return,
4386            realized_pnl,
4387            unrealized_pnl,
4388            duration,
4389            event_id,
4390            ts_opened: ts_opened.into(),
4391            ts_closed,
4392            ts_event: ts_event.into(),
4393            ts_init: ts_init.into(),
4394        })
4395    }
4396}
4397
4398// PositionAdjusted
4399impl<'a> ToCapnp<'a> for PositionAdjusted {
4400    type Builder = position_capnp::position_adjusted::Builder<'a>;
4401
4402    fn to_capnp(&self, mut builder: Self::Builder) {
4403        let trader_id_builder = builder.reborrow().init_trader_id();
4404        self.trader_id.to_capnp(trader_id_builder);
4405
4406        let strategy_id_builder = builder.reborrow().init_strategy_id();
4407        self.strategy_id.to_capnp(strategy_id_builder);
4408
4409        let instrument_id_builder = builder.reborrow().init_instrument_id();
4410        self.instrument_id.to_capnp(instrument_id_builder);
4411
4412        let position_id_builder = builder.reborrow().init_position_id();
4413        self.position_id.to_capnp(position_id_builder);
4414
4415        let account_id_builder = builder.reborrow().init_account_id();
4416        self.account_id.to_capnp(account_id_builder);
4417
4418        builder.set_adjustment_type(position_adjustment_type_to_capnp(self.adjustment_type));
4419
4420        if let Some(qty_change) = self.quantity_change {
4421            let (lo, mid, hi, flags) = decimal_to_parts(&qty_change);
4422            let mut qty_change_builder = builder.reborrow().init_quantity_change();
4423            qty_change_builder.set_lo(lo);
4424            qty_change_builder.set_mid(mid);
4425            qty_change_builder.set_hi(hi);
4426            qty_change_builder.set_flags(flags);
4427        }
4428
4429        if let Some(ref pnl) = self.pnl_change {
4430            let pnl_change_builder = builder.reborrow().init_pnl_change();
4431            pnl.to_capnp(pnl_change_builder);
4432        }
4433
4434        if let Some(reason) = self.reason {
4435            builder.set_reason(reason.as_str());
4436        }
4437
4438        let event_id_builder = builder.reborrow().init_event_id();
4439        self.event_id.to_capnp(event_id_builder);
4440
4441        let mut ts_event_builder = builder.reborrow().init_ts_event();
4442        ts_event_builder.set_value(*self.ts_event);
4443
4444        let mut ts_init_builder = builder.reborrow().init_ts_init();
4445        ts_init_builder.set_value(*self.ts_init);
4446    }
4447}
4448
4449impl<'a> FromCapnp<'a> for PositionAdjusted {
4450    type Reader = position_capnp::position_adjusted::Reader<'a>;
4451
4452    fn from_capnp(reader: Self::Reader) -> Result<Self, Box<dyn Error>> {
4453        let trader_id_reader = reader.get_trader_id()?;
4454        let trader_id = TraderId::from_capnp(trader_id_reader)?;
4455
4456        let strategy_id_reader = reader.get_strategy_id()?;
4457        let strategy_id = StrategyId::from_capnp(strategy_id_reader)?;
4458
4459        let instrument_id_reader = reader.get_instrument_id()?;
4460        let instrument_id = InstrumentId::from_capnp(instrument_id_reader)?;
4461
4462        let position_id_reader = reader.get_position_id()?;
4463        let position_id = PositionId::from_capnp(position_id_reader)?;
4464
4465        let account_id_reader = reader.get_account_id()?;
4466        let account_id = AccountId::from_capnp(account_id_reader)?;
4467
4468        let adjustment_type = position_adjustment_type_from_capnp(reader.get_adjustment_type()?);
4469
4470        let quantity_change = if reader.has_quantity_change() {
4471            let qty_change_reader = reader.get_quantity_change()?;
4472            Some(decimal_from_parts(
4473                qty_change_reader.get_lo(),
4474                qty_change_reader.get_mid(),
4475                qty_change_reader.get_hi(),
4476                qty_change_reader.get_flags(),
4477            ))
4478        } else {
4479            None
4480        };
4481
4482        let pnl_change = if reader.has_pnl_change() {
4483            let pnl_change_reader = reader.get_pnl_change()?;
4484            Some(Money::from_capnp(pnl_change_reader)?)
4485        } else {
4486            None
4487        };
4488
4489        let reason = if reader.has_reason() {
4490            let reason_reader = reader.get_reason()?;
4491            let text = reason_reader.to_str()?;
4492            if text.is_empty() {
4493                None
4494            } else {
4495                Some(Ustr::from(text))
4496            }
4497        } else {
4498            None
4499        };
4500
4501        let event_id_reader = reader.get_event_id()?;
4502        let event_id = nautilus_core::UUID4::from_capnp(event_id_reader)?;
4503
4504        let ts_event_reader = reader.get_ts_event()?;
4505        let ts_event = ts_event_reader.get_value();
4506
4507        let ts_init_reader = reader.get_ts_init()?;
4508        let ts_init = ts_init_reader.get_value();
4509
4510        Ok(Self {
4511            trader_id,
4512            strategy_id,
4513            instrument_id,
4514            position_id,
4515            account_id,
4516            adjustment_type,
4517            quantity_change,
4518            pnl_change,
4519            reason,
4520            event_id,
4521            ts_event: ts_event.into(),
4522            ts_init: ts_init.into(),
4523        })
4524    }
4525}
4526
4527#[cfg(test)]
4528mod tests {
4529    use capnp::message::Builder;
4530    use nautilus_core::UnixNanos;
4531    use nautilus_model::{data::stubs::*, events::order::stubs::*};
4532    use rstest::rstest;
4533    use rust_decimal::Decimal;
4534    use rust_decimal_macros::dec;
4535
4536    use super::*;
4537
4538    macro_rules! assert_capnp_roundtrip {
4539        ($value:expr, $builder:path, $reader:path, $ty:ty) => {{
4540            let expected: $ty = $value;
4541            let mut message = Builder::new_default();
4542            {
4543                let builder = message.init_root::<$builder>();
4544                expected.to_capnp(builder);
4545            }
4546            let reader = message
4547                .get_root_as_reader::<$reader>()
4548                .expect("capnp reader");
4549            let decoded = <$ty>::from_capnp(reader).expect("capnp decode");
4550            assert_eq!(expected, decoded);
4551        }};
4552    }
4553
4554    macro_rules! capnp_simple_roundtrip_test {
4555        ($name:ident, $value:expr, $builder:path, $reader:path, $ty:ty) => {
4556            #[rstest]
4557            fn $name() {
4558                assert_capnp_roundtrip!($value, $builder, $reader, $ty);
4559            }
4560        };
4561    }
4562
4563    macro_rules! order_fixture_roundtrip_test {
4564        ($name:ident, $fixture:ident, $ty:ty, $builder:path, $reader:path) => {
4565            #[rstest]
4566            fn $name($fixture: $ty) {
4567                assert_capnp_roundtrip!($fixture, $builder, $reader, $ty);
4568            }
4569        };
4570    }
4571
4572    #[rstest]
4573    fn test_instrument_id_roundtrip() {
4574        let instrument_id = InstrumentId::from("AAPL.NASDAQ");
4575        let bytes = serialize_instrument_id(&instrument_id).unwrap();
4576        let decoded = deserialize_instrument_id(&bytes).unwrap();
4577        assert_eq!(instrument_id, decoded);
4578    }
4579
4580    #[rstest]
4581    fn test_price_roundtrip() {
4582        let price = Price::from("123.45");
4583        let bytes = serialize_price(&price).unwrap();
4584        let decoded = deserialize_price(&bytes).unwrap();
4585        assert_eq!(price, decoded);
4586    }
4587
4588    #[rstest]
4589    fn test_quantity_roundtrip() {
4590        let qty = Quantity::from("100.5");
4591        let bytes = serialize_quantity(&qty).unwrap();
4592        let decoded = deserialize_quantity(&bytes).unwrap();
4593        assert_eq!(qty, decoded);
4594    }
4595
4596    #[rstest]
4597    fn test_currency_roundtrip() {
4598        let currency = Currency::USD();
4599        let bytes = serialize_currency(&currency).unwrap();
4600        let decoded = deserialize_currency(&bytes).unwrap();
4601        assert_eq!(currency, decoded);
4602    }
4603
4604    #[rstest]
4605    fn test_currency_crypto_roundtrip() {
4606        let currency = Currency::BTC();
4607        let bytes = serialize_currency(&currency).unwrap();
4608        let decoded = deserialize_currency(&bytes).unwrap();
4609        assert_eq!(currency, decoded);
4610    }
4611
4612    #[rstest]
4613    fn test_money_roundtrip() {
4614        let money = Money::from_raw(100_000_000, Currency::USD());
4615        let bytes = serialize_money(&money).unwrap();
4616        let decoded = deserialize_money(&bytes).unwrap();
4617        assert_eq!(money, decoded);
4618    }
4619
4620    #[rstest]
4621    fn test_money_negative() {
4622        let money = Money::from_raw(-50_000_000, Currency::USD());
4623        let bytes = serialize_money(&money).unwrap();
4624        let decoded = deserialize_money(&bytes).unwrap();
4625        assert_eq!(money, decoded);
4626    }
4627
4628    #[rstest]
4629    fn test_money_zero() {
4630        let money = Money::from_raw(0, Currency::USD());
4631        let bytes = serialize_money(&money).unwrap();
4632        let decoded = deserialize_money(&bytes).unwrap();
4633        assert_eq!(money, decoded);
4634    }
4635
4636    #[rstest]
4637    fn test_decimal_serialization_layout() {
4638        let decimal = Decimal::from_parts(
4639            0x89ab_cdef,
4640            0x0123_4567,
4641            0x0fed_cba9,
4642            true, // negative to ensure sign bit set
4643            6,    // add some scale metadata
4644        );
4645        let mut message = capnp::message::Builder::new_default();
4646        {
4647            let builder = message.init_root::<types_capnp::decimal::Builder>();
4648            decimal.to_capnp(builder);
4649        }
4650
4651        let reader = message
4652            .get_root_as_reader::<types_capnp::decimal::Reader>()
4653            .expect("reader");
4654
4655        let serialized = decimal.serialize();
4656        let expected_flags = u32::from_le_bytes(serialized[0..4].try_into().expect("flags slice"));
4657
4658        assert_eq!(reader.get_flags(), expected_flags);
4659        assert_eq!(reader.get_lo(), 0x89ab_cdef);
4660        assert_eq!(reader.get_mid(), 0x0123_4567);
4661        assert_eq!(reader.get_hi(), 0x0fed_cba9);
4662    }
4663
4664    #[rstest]
4665    fn test_decimal_roundtrip_preserves_scale_and_sign() {
4666        let decimal = Decimal::from_parts(0xffff_ffff, 0x7fff_ffff, 0x0000_00ff, false, 9);
4667
4668        let mut message = capnp::message::Builder::new_default();
4669        {
4670            let builder = message.init_root::<types_capnp::decimal::Builder>();
4671            decimal.to_capnp(builder);
4672        }
4673
4674        let reader = message
4675            .get_root_as_reader::<types_capnp::decimal::Reader>()
4676            .expect("reader");
4677        let decoded = Decimal::from_capnp(reader).expect("decoded decimal");
4678        assert_eq!(decimal, decoded);
4679    }
4680
4681    #[rstest]
4682    fn test_account_balance_roundtrip() {
4683        let total = Money::new(100.0, Currency::USD());
4684        let locked = Money::new(10.0, Currency::USD());
4685        let free = Money::new(90.0, Currency::USD());
4686        let balance = AccountBalance::new(total, locked, free);
4687        let bytes = serialize_account_balance(&balance).unwrap();
4688        let decoded = deserialize_account_balance(&bytes).unwrap();
4689        assert_eq!(balance, decoded);
4690    }
4691
4692    #[rstest]
4693    fn test_margin_balance_roundtrip() {
4694        let initial = Money::new(500.0, Currency::USD());
4695        let maintenance = Money::new(250.0, Currency::USD());
4696        let instrument_id = InstrumentId::from("BTC-USD-PERP.BINANCE");
4697        let balance = MarginBalance::new(initial, maintenance, instrument_id);
4698        let bytes = serialize_margin_balance(&balance).unwrap();
4699        let decoded = deserialize_margin_balance(&bytes).unwrap();
4700        assert_eq!(balance, decoded);
4701    }
4702
4703    // Identifier round-trip coverage
4704    capnp_simple_roundtrip_test!(
4705        trader_id_capnp_roundtrip,
4706        TraderId::from("TRADER-CAPNP"),
4707        identifiers_capnp::trader_id::Builder,
4708        identifiers_capnp::trader_id::Reader,
4709        TraderId
4710    );
4711    capnp_simple_roundtrip_test!(
4712        strategy_id_capnp_roundtrip,
4713        StrategyId::from("STRATEGY-CAPNP"),
4714        identifiers_capnp::strategy_id::Builder,
4715        identifiers_capnp::strategy_id::Reader,
4716        StrategyId
4717    );
4718    capnp_simple_roundtrip_test!(
4719        actor_id_capnp_roundtrip,
4720        ActorId::from("ACTOR-CAPNP"),
4721        identifiers_capnp::actor_id::Builder,
4722        identifiers_capnp::actor_id::Reader,
4723        ActorId
4724    );
4725    capnp_simple_roundtrip_test!(
4726        account_id_capnp_roundtrip,
4727        AccountId::from("ACCOUNT-CAPNP"),
4728        identifiers_capnp::account_id::Builder,
4729        identifiers_capnp::account_id::Reader,
4730        AccountId
4731    );
4732    capnp_simple_roundtrip_test!(
4733        client_id_capnp_roundtrip,
4734        ClientId::from("CLIENT-CAPNP"),
4735        identifiers_capnp::client_id::Builder,
4736        identifiers_capnp::client_id::Reader,
4737        ClientId
4738    );
4739    capnp_simple_roundtrip_test!(
4740        client_order_id_capnp_roundtrip,
4741        ClientOrderId::from("O-20240101-000000-001-001-1"),
4742        identifiers_capnp::client_order_id::Builder,
4743        identifiers_capnp::client_order_id::Reader,
4744        ClientOrderId
4745    );
4746    capnp_simple_roundtrip_test!(
4747        venue_order_id_capnp_roundtrip,
4748        VenueOrderId::from("V-ORDER-1"),
4749        identifiers_capnp::venue_order_id::Builder,
4750        identifiers_capnp::venue_order_id::Reader,
4751        VenueOrderId
4752    );
4753    capnp_simple_roundtrip_test!(
4754        trade_id_capnp_roundtrip,
4755        TradeId::from("TRADE-12345"),
4756        identifiers_capnp::trade_id::Builder,
4757        identifiers_capnp::trade_id::Reader,
4758        TradeId
4759    );
4760    capnp_simple_roundtrip_test!(
4761        position_id_capnp_roundtrip,
4762        PositionId::from("POSITION-1"),
4763        identifiers_capnp::position_id::Builder,
4764        identifiers_capnp::position_id::Reader,
4765        PositionId
4766    );
4767    capnp_simple_roundtrip_test!(
4768        exec_algorithm_id_capnp_roundtrip,
4769        ExecAlgorithmId::from("EXEC-1"),
4770        identifiers_capnp::exec_algorithm_id::Builder,
4771        identifiers_capnp::exec_algorithm_id::Reader,
4772        ExecAlgorithmId
4773    );
4774    capnp_simple_roundtrip_test!(
4775        component_id_capnp_roundtrip,
4776        ComponentId::from("COMPONENT-RISK"),
4777        identifiers_capnp::component_id::Builder,
4778        identifiers_capnp::component_id::Reader,
4779        ComponentId
4780    );
4781    capnp_simple_roundtrip_test!(
4782        order_list_id_capnp_roundtrip,
4783        OrderListId::from("LIST-1"),
4784        identifiers_capnp::order_list_id::Builder,
4785        identifiers_capnp::order_list_id::Reader,
4786        OrderListId
4787    );
4788    capnp_simple_roundtrip_test!(
4789        symbol_capnp_roundtrip,
4790        Symbol::from("ETH-PERP"),
4791        identifiers_capnp::symbol::Builder,
4792        identifiers_capnp::symbol::Reader,
4793        Symbol
4794    );
4795    capnp_simple_roundtrip_test!(
4796        venue_capnp_roundtrip,
4797        Venue::from("BINANCE"),
4798        identifiers_capnp::venue::Builder,
4799        identifiers_capnp::venue::Reader,
4800        Venue
4801    );
4802    capnp_simple_roundtrip_test!(
4803        uuid4_capnp_roundtrip,
4804        uuid4(),
4805        base_capnp::u_u_i_d4::Builder,
4806        base_capnp::u_u_i_d4::Reader,
4807        nautilus_core::UUID4
4808    );
4809
4810    // Market data structures
4811    capnp_simple_roundtrip_test!(
4812        quote_tick_capnp_roundtrip,
4813        quote_ethusdt_binance(),
4814        market_capnp::quote_tick::Builder,
4815        market_capnp::quote_tick::Reader,
4816        QuoteTick
4817    );
4818    capnp_simple_roundtrip_test!(
4819        trade_tick_capnp_roundtrip,
4820        stub_trade_ethusdt_buyer(),
4821        market_capnp::trade_tick::Builder,
4822        market_capnp::trade_tick::Reader,
4823        TradeTick
4824    );
4825    capnp_simple_roundtrip_test!(
4826        bar_specification_capnp_roundtrip,
4827        sample_bar_specification(),
4828        market_capnp::bar_spec::Builder,
4829        market_capnp::bar_spec::Reader,
4830        BarSpecification
4831    );
4832    capnp_simple_roundtrip_test!(
4833        bar_type_standard_capnp_roundtrip,
4834        sample_bar_type_standard(),
4835        market_capnp::bar_type::Builder,
4836        market_capnp::bar_type::Reader,
4837        BarType
4838    );
4839    capnp_simple_roundtrip_test!(
4840        bar_capnp_roundtrip,
4841        stub_bar(),
4842        market_capnp::bar::Builder,
4843        market_capnp::bar::Reader,
4844        Bar
4845    );
4846    capnp_simple_roundtrip_test!(
4847        book_order_capnp_roundtrip,
4848        stub_book_order(),
4849        market_capnp::book_order::Builder,
4850        market_capnp::book_order::Reader,
4851        BookOrder
4852    );
4853    capnp_simple_roundtrip_test!(
4854        order_book_delta_capnp_roundtrip,
4855        stub_delta(),
4856        market_capnp::order_book_delta::Builder,
4857        market_capnp::order_book_delta::Reader,
4858        OrderBookDelta
4859    );
4860    capnp_simple_roundtrip_test!(
4861        order_book_deltas_capnp_roundtrip,
4862        stub_deltas(),
4863        market_capnp::order_book_deltas::Builder,
4864        market_capnp::order_book_deltas::Reader,
4865        OrderBookDeltas
4866    );
4867    capnp_simple_roundtrip_test!(
4868        order_book_depth10_capnp_roundtrip,
4869        sample_order_book_depth10(),
4870        market_capnp::order_book_depth10::Builder,
4871        market_capnp::order_book_depth10::Reader,
4872        OrderBookDepth10
4873    );
4874    capnp_simple_roundtrip_test!(
4875        mark_price_update_capnp_roundtrip,
4876        sample_mark_price_update(),
4877        market_capnp::mark_price_update::Builder,
4878        market_capnp::mark_price_update::Reader,
4879        MarkPriceUpdate
4880    );
4881    capnp_simple_roundtrip_test!(
4882        index_price_update_capnp_roundtrip,
4883        sample_index_price_update(),
4884        market_capnp::index_price_update::Builder,
4885        market_capnp::index_price_update::Reader,
4886        IndexPriceUpdate
4887    );
4888    capnp_simple_roundtrip_test!(
4889        funding_rate_update_capnp_roundtrip,
4890        sample_funding_rate_update(),
4891        market_capnp::funding_rate_update::Builder,
4892        market_capnp::funding_rate_update::Reader,
4893        FundingRateUpdate
4894    );
4895    capnp_simple_roundtrip_test!(
4896        instrument_close_capnp_roundtrip,
4897        stub_instrument_close(),
4898        market_capnp::instrument_close::Builder,
4899        market_capnp::instrument_close::Reader,
4900        InstrumentClose
4901    );
4902    capnp_simple_roundtrip_test!(
4903        instrument_status_capnp_roundtrip,
4904        sample_instrument_status_event(),
4905        market_capnp::instrument_status::Builder,
4906        market_capnp::instrument_status::Reader,
4907        InstrumentStatus
4908    );
4909
4910    // Order-event coverage through fixtures
4911    order_fixture_roundtrip_test!(
4912        order_filled_capnp_roundtrip,
4913        order_filled,
4914        OrderFilled,
4915        order_capnp::order_filled::Builder,
4916        order_capnp::order_filled::Reader
4917    );
4918    order_fixture_roundtrip_test!(
4919        order_denied_capnp_roundtrip,
4920        order_denied_max_submitted_rate,
4921        OrderDenied,
4922        order_capnp::order_denied::Builder,
4923        order_capnp::order_denied::Reader
4924    );
4925    order_fixture_roundtrip_test!(
4926        order_rejected_capnp_roundtrip,
4927        order_rejected_insufficient_margin,
4928        OrderRejected,
4929        order_capnp::order_rejected::Builder,
4930        order_capnp::order_rejected::Reader
4931    );
4932    order_fixture_roundtrip_test!(
4933        order_initialized_capnp_roundtrip,
4934        order_initialized_buy_limit,
4935        OrderInitialized,
4936        order_capnp::order_initialized::Builder,
4937        order_capnp::order_initialized::Reader
4938    );
4939    order_fixture_roundtrip_test!(
4940        order_submitted_capnp_roundtrip,
4941        order_submitted,
4942        OrderSubmitted,
4943        order_capnp::order_submitted::Builder,
4944        order_capnp::order_submitted::Reader
4945    );
4946    order_fixture_roundtrip_test!(
4947        order_triggered_capnp_roundtrip,
4948        order_triggered,
4949        OrderTriggered,
4950        order_capnp::order_triggered::Builder,
4951        order_capnp::order_triggered::Reader
4952    );
4953    order_fixture_roundtrip_test!(
4954        order_emulated_capnp_roundtrip,
4955        order_emulated,
4956        OrderEmulated,
4957        order_capnp::order_emulated::Builder,
4958        order_capnp::order_emulated::Reader
4959    );
4960    order_fixture_roundtrip_test!(
4961        order_released_capnp_roundtrip,
4962        order_released,
4963        OrderReleased,
4964        order_capnp::order_released::Builder,
4965        order_capnp::order_released::Reader
4966    );
4967    order_fixture_roundtrip_test!(
4968        order_updated_capnp_roundtrip,
4969        order_updated,
4970        OrderUpdated,
4971        order_capnp::order_updated::Builder,
4972        order_capnp::order_updated::Reader
4973    );
4974    order_fixture_roundtrip_test!(
4975        order_pending_update_capnp_roundtrip,
4976        order_pending_update,
4977        OrderPendingUpdate,
4978        order_capnp::order_pending_update::Builder,
4979        order_capnp::order_pending_update::Reader
4980    );
4981    order_fixture_roundtrip_test!(
4982        order_pending_cancel_capnp_roundtrip,
4983        order_pending_cancel,
4984        OrderPendingCancel,
4985        order_capnp::order_pending_cancel::Builder,
4986        order_capnp::order_pending_cancel::Reader
4987    );
4988    order_fixture_roundtrip_test!(
4989        order_modify_rejected_capnp_roundtrip,
4990        order_modify_rejected,
4991        OrderModifyRejected,
4992        order_capnp::order_modify_rejected::Builder,
4993        order_capnp::order_modify_rejected::Reader
4994    );
4995    order_fixture_roundtrip_test!(
4996        order_accepted_capnp_roundtrip,
4997        order_accepted,
4998        OrderAccepted,
4999        order_capnp::order_accepted::Builder,
5000        order_capnp::order_accepted::Reader
5001    );
5002    order_fixture_roundtrip_test!(
5003        order_cancel_rejected_capnp_roundtrip,
5004        order_cancel_rejected,
5005        OrderCancelRejected,
5006        order_capnp::order_cancel_rejected::Builder,
5007        order_capnp::order_cancel_rejected::Reader
5008    );
5009    order_fixture_roundtrip_test!(
5010        order_expired_capnp_roundtrip,
5011        order_expired,
5012        OrderExpired,
5013        order_capnp::order_expired::Builder,
5014        order_capnp::order_expired::Reader
5015    );
5016    #[rstest]
5017    fn order_canceled_capnp_roundtrip() {
5018        assert_capnp_roundtrip!(
5019            sample_order_canceled(),
5020            order_capnp::order_canceled::Builder,
5021            order_capnp::order_canceled::Reader,
5022            OrderCanceled
5023        );
5024    }
5025
5026    // Position event coverage
5027    #[rstest]
5028    fn position_opened_capnp_roundtrip() {
5029        assert_capnp_roundtrip!(
5030            sample_position_opened(),
5031            position_capnp::position_opened::Builder,
5032            position_capnp::position_opened::Reader,
5033            PositionOpened
5034        );
5035    }
5036
5037    #[rstest]
5038    fn position_changed_capnp_roundtrip() {
5039        assert_capnp_roundtrip!(
5040            sample_position_changed(),
5041            position_capnp::position_changed::Builder,
5042            position_capnp::position_changed::Reader,
5043            PositionChanged
5044        );
5045    }
5046
5047    #[rstest]
5048    fn position_closed_capnp_roundtrip() {
5049        assert_capnp_roundtrip!(
5050            sample_position_closed(),
5051            position_capnp::position_closed::Builder,
5052            position_capnp::position_closed::Reader,
5053            PositionClosed
5054        );
5055    }
5056
5057    #[rstest]
5058    fn position_adjusted_capnp_roundtrip() {
5059        assert_capnp_roundtrip!(
5060            sample_position_adjusted(),
5061            position_capnp::position_adjusted::Builder,
5062            position_capnp::position_adjusted::Reader,
5063            PositionAdjusted
5064        );
5065    }
5066
5067    fn sample_bar_specification() -> BarSpecification {
5068        BarSpecification::new(5, BarAggregation::Minute, PriceType::Last)
5069    }
5070
5071    fn sample_bar_type_standard() -> BarType {
5072        BarType::new(
5073            InstrumentId::from("AUDUSD.SIM"),
5074            sample_bar_specification(),
5075            AggregationSource::External,
5076        )
5077    }
5078
5079    fn sample_mark_price_update() -> MarkPriceUpdate {
5080        MarkPriceUpdate::new(
5081            InstrumentId::from("BTCUSD-PERP.BINANCE"),
5082            Price::from("42000.123"),
5083            UnixNanos::from(1),
5084            UnixNanos::from(2),
5085        )
5086    }
5087
5088    fn sample_index_price_update() -> IndexPriceUpdate {
5089        IndexPriceUpdate::new(
5090            InstrumentId::from("BTCUSD-PERP.BINANCE"),
5091            Price::from("41950.500"),
5092            UnixNanos::from(3),
5093            UnixNanos::from(4),
5094        )
5095    }
5096
5097    fn sample_funding_rate_update() -> FundingRateUpdate {
5098        FundingRateUpdate::new(
5099            InstrumentId::from("BTCUSD-PERP.BINANCE"),
5100            dec!(0.0001),
5101            Some(UnixNanos::from(1_000_000)),
5102            UnixNanos::from(5),
5103            UnixNanos::from(6),
5104        )
5105    }
5106
5107    fn sample_instrument_status_event() -> InstrumentStatus {
5108        InstrumentStatus::new(
5109            InstrumentId::from("MSFT.XNAS"),
5110            MarketStatusAction::Trading,
5111            UnixNanos::from(1),
5112            UnixNanos::from(2),
5113            Some(Ustr::from("Normal trading")),
5114            Some(Ustr::from("MARKET_OPEN")),
5115            Some(true),
5116            Some(true),
5117            Some(false),
5118        )
5119    }
5120
5121    fn sample_order_canceled() -> OrderCanceled {
5122        OrderCanceled::new(
5123            trader_id(),
5124            strategy_id_ema_cross(),
5125            instrument_id_btc_usdt(),
5126            client_order_id(),
5127            uuid4(),
5128            UnixNanos::from(7),
5129            UnixNanos::from(8),
5130            true,
5131            Some(venue_order_id()),
5132            Some(account_id()),
5133        )
5134    }
5135
5136    fn sample_order_book_depth10() -> OrderBookDepth10 {
5137        const LEVELS: usize = 10;
5138        let instrument_id = InstrumentId::from("AAPL.XNAS");
5139        let mut bids = [BookOrder::default(); LEVELS];
5140        let mut asks = [BookOrder::default(); LEVELS];
5141        for i in 0..LEVELS {
5142            bids[i] = BookOrder::new(
5143                OrderSide::Buy,
5144                Price::new(100.0 - i as f64, 2),
5145                Quantity::new(1.0 + i as f64, 2),
5146                0,
5147            );
5148            asks[i] = BookOrder::new(
5149                OrderSide::Sell,
5150                Price::new(101.0 + i as f64, 2),
5151                Quantity::new(1.0 + i as f64, 2),
5152                0,
5153            );
5154        }
5155        let bid_counts = [1_u32; LEVELS];
5156        let ask_counts = [1_u32; LEVELS];
5157        OrderBookDepth10::new(
5158            instrument_id,
5159            bids,
5160            asks,
5161            bid_counts,
5162            ask_counts,
5163            0,
5164            1,
5165            UnixNanos::from(9),
5166            UnixNanos::from(10),
5167        )
5168    }
5169
5170    fn sample_position_opened() -> PositionOpened {
5171        PositionOpened {
5172            trader_id: trader_id(),
5173            strategy_id: strategy_id_ema_cross(),
5174            instrument_id: instrument_id_btc_usdt(),
5175            position_id: PositionId::from("P-OPEN"),
5176            account_id: account_id(),
5177            opening_order_id: client_order_id(),
5178            entry: OrderSide::Buy,
5179            side: PositionSide::Long,
5180            signed_qty: 100.0,
5181            quantity: Quantity::from("100"),
5182            last_qty: Quantity::from("100"),
5183            last_px: Price::from("20000"),
5184            currency: Currency::USD(),
5185            avg_px_open: 20000.0,
5186            event_id: uuid4(),
5187            ts_event: UnixNanos::from(9),
5188            ts_init: UnixNanos::from(10),
5189        }
5190    }
5191
5192    fn sample_position_changed() -> PositionChanged {
5193        PositionChanged {
5194            trader_id: trader_id(),
5195            strategy_id: strategy_id_ema_cross(),
5196            instrument_id: instrument_id_btc_usdt(),
5197            position_id: PositionId::from("P-CHANGED"),
5198            account_id: account_id(),
5199            opening_order_id: client_order_id(),
5200            entry: OrderSide::Buy,
5201            side: PositionSide::Long,
5202            signed_qty: 150.0,
5203            quantity: Quantity::from("150"),
5204            peak_quantity: Quantity::from("175"),
5205            last_qty: Quantity::from("50"),
5206            last_px: Price::from("20100"),
5207            currency: Currency::USD(),
5208            avg_px_open: 19950.0,
5209            avg_px_close: Some(20100.0),
5210            realized_return: 0.01,
5211            realized_pnl: Some(Money::new(150.0, Currency::USD())),
5212            unrealized_pnl: Money::new(75.0, Currency::USD()),
5213            event_id: uuid4(),
5214            ts_opened: UnixNanos::from(11),
5215            ts_event: UnixNanos::from(12),
5216            ts_init: UnixNanos::from(13),
5217        }
5218    }
5219
5220    fn sample_position_closed() -> PositionClosed {
5221        PositionClosed {
5222            trader_id: trader_id(),
5223            strategy_id: strategy_id_ema_cross(),
5224            instrument_id: instrument_id_btc_usdt(),
5225            position_id: PositionId::from("P-CLOSED"),
5226            account_id: account_id(),
5227            opening_order_id: client_order_id(),
5228            closing_order_id: Some(ClientOrderId::from("O-19700101-000000-001-001-9")),
5229            entry: OrderSide::Buy,
5230            side: PositionSide::Flat,
5231            signed_qty: 0.0,
5232            quantity: Quantity::from("0"),
5233            peak_quantity: Quantity::from("200"),
5234            last_qty: Quantity::from("200"),
5235            last_px: Price::from("20500"),
5236            currency: Currency::USD(),
5237            avg_px_open: 20000.0,
5238            avg_px_close: Some(20500.0),
5239            realized_return: 0.025,
5240            realized_pnl: Some(Money::new(1000.0, Currency::USD())),
5241            unrealized_pnl: Money::new(0.0, Currency::USD()),
5242            duration: 1_000_000,
5243            event_id: uuid4(),
5244            ts_opened: UnixNanos::from(14),
5245            ts_closed: Some(UnixNanos::from(15)),
5246            ts_event: UnixNanos::from(15),
5247            ts_init: UnixNanos::from(16),
5248        }
5249    }
5250
5251    fn sample_position_adjusted() -> PositionAdjusted {
5252        PositionAdjusted::new(
5253            trader_id(),
5254            strategy_id_ema_cross(),
5255            instrument_id_btc_usdt(),
5256            PositionId::from("P-ADJUST"),
5257            account_id(),
5258            PositionAdjustmentType::Funding,
5259            Some(dec!(-0.001)),
5260            Some(Money::new(-5.5, Currency::USD())),
5261            Some(Ustr::from("funding_2024-01-15")),
5262            uuid4(),
5263            UnixNanos::from(17),
5264            UnixNanos::from(18),
5265        )
5266    }
5267}