Skip to main content

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