nautilus_infrastructure/sql/models/
orders.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 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
16use std::str::FromStr;
17
18use indexmap::IndexMap;
19use nautilus_core::{UUID4, UnixNanos};
20use nautilus_model::{
21    enums::{
22        ContingencyType, LiquiditySide, OrderSide, OrderStatus, OrderType, TimeInForce, TriggerType,
23    },
24    events::{
25        OrderAccepted, OrderCancelRejected, OrderCanceled, OrderDenied, OrderEmulated,
26        OrderEventAny, OrderExpired, OrderFilled, OrderInitialized, OrderModifyRejected,
27        OrderPendingCancel, OrderPendingUpdate, OrderRejected, OrderReleased, OrderSnapshot,
28        OrderSubmitted, OrderTriggered, OrderUpdated,
29    },
30    identifiers::{
31        AccountId, ClientOrderId, ExecAlgorithmId, InstrumentId, OrderListId, PositionId,
32        StrategyId, TradeId, TraderId, VenueOrderId,
33    },
34    types::{Currency, Money, Price, Quantity},
35};
36use rust_decimal::Decimal;
37use sqlx::{FromRow, Row, postgres::PgRow};
38use ustr::Ustr;
39
40use crate::sql::models::enums::TrailingOffsetTypeModel;
41
42#[derive(Debug)]
43pub struct OrderEventAnyModel(pub OrderEventAny);
44
45#[derive(Debug)]
46pub struct OrderAcceptedModel(pub OrderAccepted);
47
48#[derive(Debug)]
49pub struct OrderCancelRejectedModel(pub OrderCancelRejected);
50
51#[derive(Debug)]
52pub struct OrderCanceledModel(pub OrderCanceled);
53
54#[derive(Debug)]
55pub struct OrderDeniedModel(pub OrderDenied);
56
57#[derive(Debug)]
58pub struct OrderEmulatedModel(pub OrderEmulated);
59
60#[derive(Debug)]
61pub struct OrderExpiredModel(pub OrderExpired);
62
63#[derive(Debug)]
64pub struct OrderFilledModel(pub OrderFilled);
65
66#[derive(Debug)]
67pub struct OrderInitializedModel(pub OrderInitialized);
68
69#[derive(Debug)]
70pub struct OrderModifyRejectedModel(pub OrderModifyRejected);
71
72#[derive(Debug)]
73pub struct OrderPendingCancelModel(pub OrderPendingCancel);
74
75#[derive(Debug)]
76pub struct OrderPendingUpdateModel(pub OrderPendingUpdate);
77
78#[derive(Debug)]
79pub struct OrderRejectedModel(pub OrderRejected);
80
81#[derive(Debug)]
82pub struct OrderReleasedModel(pub OrderReleased);
83
84#[derive(Debug)]
85pub struct OrderSubmittedModel(pub OrderSubmitted);
86
87#[derive(Debug)]
88pub struct OrderTriggeredModel(pub OrderTriggered);
89
90#[derive(Debug)]
91pub struct OrderUpdatedModel(pub OrderUpdated);
92
93#[derive(Debug)]
94pub struct OrderSnapshotModel(pub OrderSnapshot);
95
96impl<'r> FromRow<'r, PgRow> for OrderEventAnyModel {
97    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
98        let kind = row.get::<String, _>("kind");
99        if kind == "OrderAccepted" {
100            let model = OrderAcceptedModel::from_row(row)?;
101            Ok(Self(OrderEventAny::Accepted(model.0)))
102        } else if kind == "OrderCancelRejected" {
103            let model = OrderCancelRejectedModel::from_row(row)?;
104            Ok(Self(OrderEventAny::CancelRejected(model.0)))
105        } else if kind == "OrderCanceled" {
106            let model = OrderCanceledModel::from_row(row)?;
107            Ok(Self(OrderEventAny::Canceled(model.0)))
108        } else if kind == "OrderDenied" {
109            let model = OrderDeniedModel::from_row(row)?;
110            Ok(Self(OrderEventAny::Denied(model.0)))
111        } else if kind == "OrderEmulated" {
112            let model = OrderEmulatedModel::from_row(row)?;
113            Ok(Self(OrderEventAny::Emulated(model.0)))
114        } else if kind == "OrderExpired" {
115            let model = OrderExpiredModel::from_row(row)?;
116            Ok(Self(OrderEventAny::Expired(model.0)))
117        } else if kind == "OrderFilled" {
118            let model = OrderFilledModel::from_row(row)?;
119            Ok(Self(OrderEventAny::Filled(model.0)))
120        } else if kind == "OrderInitialized" {
121            let model = OrderInitializedModel::from_row(row)?;
122            Ok(Self(OrderEventAny::Initialized(model.0)))
123        } else if kind == "OrderModifyRejected" {
124            let model = OrderModifyRejectedModel::from_row(row)?;
125            Ok(Self(OrderEventAny::ModifyRejected(model.0)))
126        } else if kind == "OrderPendingCancel" {
127            let model = OrderPendingCancelModel::from_row(row)?;
128            Ok(Self(OrderEventAny::PendingCancel(model.0)))
129        } else if kind == "OrderPendingUpdate" {
130            let model = OrderPendingUpdateModel::from_row(row)?;
131            Ok(Self(OrderEventAny::PendingUpdate(model.0)))
132        } else if kind == "OrderRejected" {
133            let model = OrderRejectedModel::from_row(row)?;
134            Ok(Self(OrderEventAny::Rejected(model.0)))
135        } else if kind == "OrderReleased" {
136            let model = OrderReleasedModel::from_row(row)?;
137            Ok(Self(OrderEventAny::Released(model.0)))
138        } else if kind == "OrderSubmitted" {
139            let model = OrderSubmittedModel::from_row(row)?;
140            Ok(Self(OrderEventAny::Submitted(model.0)))
141        } else if kind == "OrderTriggered" {
142            let model = OrderTriggeredModel::from_row(row)?;
143            Ok(Self(OrderEventAny::Triggered(model.0)))
144        } else if kind == "OrderUpdated" {
145            let model = OrderUpdatedModel::from_row(row)?;
146            Ok(Self(OrderEventAny::Updated(model.0)))
147        } else {
148            Err(sqlx::Error::Decode(
149                format!("Unknown order event kind: {kind} in Postgres transformation").into(),
150            ))
151        }
152    }
153}
154
155impl<'r> FromRow<'r, PgRow> for OrderInitializedModel {
156    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
157        let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
158        let client_order_id = row
159            .try_get::<&str, _>("client_order_id")
160            .map(ClientOrderId::from)?;
161        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
162        let strategy_id = row
163            .try_get::<&str, _>("strategy_id")
164            .map(StrategyId::from)?;
165        let instrument_id = row
166            .try_get::<&str, _>("instrument_id")
167            .map(InstrumentId::from)?;
168        let order_type = row
169            .try_get::<&str, _>("order_type")
170            .map(|x| OrderType::from_str(x).unwrap())?;
171        let order_side = row
172            .try_get::<&str, _>("order_side")
173            .map(|x| OrderSide::from_str(x).unwrap())?;
174        let quantity = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
175        let time_in_force = row
176            .try_get::<&str, _>("time_in_force")
177            .map(|x| TimeInForce::from_str(x).unwrap())?;
178        let post_only = row.try_get::<bool, _>("post_only")?;
179        let reduce_only = row.try_get::<bool, _>("reduce_only")?;
180        let quote_quantity = row.try_get::<bool, _>("quote_quantity")?;
181        let reconciliation = row.try_get::<bool, _>("reconciliation")?;
182        let ts_event = row.try_get::<String, _>("ts_event").map(UnixNanos::from)?;
183        let ts_init = row.try_get::<String, _>("ts_init").map(UnixNanos::from)?;
184        let price = row
185            .try_get::<Option<&str>, _>("price")
186            .ok()
187            .and_then(|x| x.map(Price::from));
188        let trigger_price = row
189            .try_get::<Option<&str>, _>("trigger_price")
190            .ok()
191            .and_then(|x| x.map(Price::from));
192        let trigger_type = row
193            .try_get::<Option<&str>, _>("trigger_type")
194            .ok()
195            .and_then(|x| x.map(|x| TriggerType::from_str(x).unwrap()));
196        let limit_offset = row
197            .try_get::<Option<&str>, _>("limit_offset")
198            .ok()
199            .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
200        let trailing_offset = row
201            .try_get::<Option<&str>, _>("trailing_offset")
202            .ok()
203            .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
204        let trailing_offset_type = row
205            .try_get::<Option<TrailingOffsetTypeModel>, _>("trailing_offset_type")
206            .ok()
207            .and_then(|x| x.map(|x| x.0));
208        let expire_time = row
209            .try_get::<Option<&str>, _>("expire_time")
210            .ok()
211            .and_then(|x| x.map(UnixNanos::from));
212        let display_qty = row
213            .try_get::<Option<&str>, _>("display_qty")
214            .ok()
215            .and_then(|x| x.map(Quantity::from));
216        let emulation_trigger = row
217            .try_get::<Option<&str>, _>("emulation_trigger")
218            .ok()
219            .and_then(|x| x.map(|x| TriggerType::from_str(x).unwrap()));
220        let trigger_instrument_id = row
221            .try_get::<Option<&str>, _>("trigger_instrument_id")
222            .ok()
223            .and_then(|x| x.map(InstrumentId::from));
224        let contingency_type = row
225            .try_get::<Option<&str>, _>("contingency_type")
226            .ok()
227            .and_then(|x| x.map(|x| ContingencyType::from_str(x).unwrap()));
228        let order_list_id = row
229            .try_get::<Option<&str>, _>("order_list_id")
230            .ok()
231            .and_then(|x| x.map(OrderListId::from));
232        let linked_order_ids = row
233            .try_get::<Vec<String>, _>("linked_order_ids")
234            .ok()
235            .map(|x| x.iter().map(|x| ClientOrderId::from(x.as_str())).collect());
236        let parent_order_id = row
237            .try_get::<Option<&str>, _>("parent_order_id")
238            .ok()
239            .and_then(|x| x.map(ClientOrderId::from));
240        let exec_algorithm_id = row
241            .try_get::<Option<&str>, _>("exec_algorithm_id")
242            .ok()
243            .and_then(|x| x.map(ExecAlgorithmId::from));
244        let exec_algorithm_params: Option<IndexMap<Ustr, Ustr>> = row
245            .try_get::<Option<serde_json::Value>, _>("exec_algorithm_params")
246            .ok()
247            .and_then(|x| x.map(|x| serde_json::from_value::<IndexMap<String, String>>(x).unwrap()))
248            .map(|x| {
249                x.into_iter()
250                    .map(|(k, v)| (Ustr::from(k.as_str()), Ustr::from(v.as_str())))
251                    .collect()
252            });
253        let exec_spawn_id = row
254            .try_get::<Option<&str>, _>("exec_spawn_id")
255            .ok()
256            .and_then(|x| x.map(ClientOrderId::from));
257        let tags: Option<Vec<Ustr>> = row
258            .try_get::<Option<serde_json::Value>, _>("tags")
259            .ok()
260            .and_then(|x| x.map(|x| serde_json::from_value::<Vec<String>>(x).unwrap()))
261            .map(|x| x.into_iter().map(|x| Ustr::from(x.as_str())).collect());
262        let order_event = OrderInitialized::new(
263            trader_id,
264            strategy_id,
265            instrument_id,
266            client_order_id,
267            order_side,
268            order_type,
269            quantity,
270            time_in_force,
271            post_only,
272            reduce_only,
273            quote_quantity,
274            reconciliation,
275            event_id,
276            ts_event,
277            ts_init,
278            price,
279            trigger_price,
280            trigger_type,
281            limit_offset,
282            trailing_offset,
283            trailing_offset_type,
284            expire_time,
285            display_qty,
286            emulation_trigger,
287            trigger_instrument_id,
288            contingency_type,
289            order_list_id,
290            linked_order_ids,
291            parent_order_id,
292            exec_algorithm_id,
293            exec_algorithm_params,
294            exec_spawn_id,
295            tags,
296        );
297        Ok(Self(order_event))
298    }
299}
300
301impl<'r> FromRow<'r, PgRow> for OrderAcceptedModel {
302    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
303        let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
304        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
305        let strategy_id = row
306            .try_get::<&str, _>("strategy_id")
307            .map(StrategyId::from)?;
308        let instrument_id = row
309            .try_get::<&str, _>("instrument_id")
310            .map(InstrumentId::from)?;
311        let client_order_id = row
312            .try_get::<&str, _>("client_order_id")
313            .map(ClientOrderId::from)?;
314        let venue_order_id = row
315            .try_get::<&str, _>("venue_order_id")
316            .map(VenueOrderId::from)?;
317        let account_id = row.try_get::<&str, _>("account_id").map(AccountId::from)?;
318        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
319        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
320        let order_event = OrderAccepted::new(
321            trader_id,
322            strategy_id,
323            instrument_id,
324            client_order_id,
325            venue_order_id,
326            account_id,
327            event_id,
328            ts_event,
329            ts_init,
330            false,
331        );
332        Ok(Self(order_event))
333    }
334}
335
336impl<'r> FromRow<'r, PgRow> for OrderCancelRejectedModel {
337    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
338        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
339        let strategy_id = row
340            .try_get::<&str, _>("strategy_id")
341            .map(StrategyId::from)?;
342        let instrument_id = row
343            .try_get::<&str, _>("instrument_id")
344            .map(InstrumentId::from)?;
345        let client_order_id = row
346            .try_get::<&str, _>("client_order_id")
347            .map(ClientOrderId::from)?;
348        let reason = row.try_get::<&str, _>("reason").map(Ustr::from)?;
349        let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
350        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
351        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
352        let reconciliation = row.try_get::<bool, _>("reconciliation")?;
353        let venue_order_id = row
354            .try_get::<Option<&str>, _>("venue_order_id")?
355            .map(Into::into);
356        let account_id = row
357            .try_get::<Option<&str>, _>("account_id")?
358            .map(Into::into);
359        let order_event = OrderCancelRejected::new(
360            trader_id,
361            strategy_id,
362            instrument_id,
363            client_order_id,
364            reason,
365            event_id,
366            ts_event,
367            ts_init,
368            reconciliation,
369            venue_order_id,
370            account_id,
371        );
372        Ok(Self(order_event))
373    }
374}
375
376impl<'r> FromRow<'r, PgRow> for OrderCanceledModel {
377    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
378        todo!()
379    }
380}
381
382impl<'r> FromRow<'r, PgRow> for OrderDeniedModel {
383    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
384        todo!()
385    }
386}
387
388impl<'r> FromRow<'r, PgRow> for OrderEmulatedModel {
389    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
390        todo!()
391    }
392}
393
394impl<'r> FromRow<'r, PgRow> for OrderExpiredModel {
395    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
396        todo!()
397    }
398}
399
400impl<'r> FromRow<'r, PgRow> for OrderFilledModel {
401    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
402        let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
403        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
404        let strategy_id = row
405            .try_get::<&str, _>("strategy_id")
406            .map(StrategyId::from)?;
407        let instrument_id = row
408            .try_get::<&str, _>("instrument_id")
409            .map(InstrumentId::from)?;
410        let client_order_id = row
411            .try_get::<&str, _>("client_order_id")
412            .map(ClientOrderId::from)?;
413        let venue_order_id = row
414            .try_get::<&str, _>("venue_order_id")
415            .map(VenueOrderId::from)?;
416        let account_id = row.try_get::<&str, _>("account_id").map(AccountId::from)?;
417        let trade_id = row.try_get::<&str, _>("trade_id").map(TradeId::from)?;
418        let order_side = row
419            .try_get::<&str, _>("order_side")
420            .map(|x| OrderSide::from_str(x).unwrap())?;
421        let order_type = row
422            .try_get::<&str, _>("order_type")
423            .map(|x| OrderType::from_str(x).unwrap())?;
424        let last_px = row.try_get::<&str, _>("last_px").map(Price::from)?;
425        let last_qty = row.try_get::<&str, _>("last_qty").map(Quantity::from)?;
426        let currency = row.try_get::<&str, _>("currency").map(Currency::from)?;
427        let liquidity_side = row
428            .try_get::<&str, _>("liquidity_side")
429            .map(|x| LiquiditySide::from_str(x).unwrap())?;
430        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
431        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
432        let position_id = row
433            .try_get::<Option<&str>, _>("position_id")
434            .map(|x| x.map(PositionId::from))?;
435        let commission = row
436            .try_get::<Option<&str>, _>("commission")
437            .map(|x| x.map(|x| Money::from_str(x).unwrap()))?;
438        let order_event = OrderFilled::new(
439            trader_id,
440            strategy_id,
441            instrument_id,
442            client_order_id,
443            venue_order_id,
444            account_id,
445            trade_id,
446            order_side,
447            order_type,
448            last_qty,
449            last_px,
450            currency,
451            liquidity_side,
452            event_id,
453            ts_event,
454            ts_init,
455            false,
456            position_id,
457            commission,
458        );
459        Ok(Self(order_event))
460    }
461}
462
463impl<'r> FromRow<'r, PgRow> for OrderModifyRejectedModel {
464    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
465        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
466        let strategy_id = row
467            .try_get::<&str, _>("strategy_id")
468            .map(StrategyId::from)?;
469        let instrument_id = row
470            .try_get::<&str, _>("instrument_id")
471            .map(InstrumentId::from)?;
472        let client_order_id = row
473            .try_get::<&str, _>("client_order_id")
474            .map(ClientOrderId::from)?;
475        let reason = row.try_get::<&str, _>("reason").map(Ustr::from)?;
476        let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
477        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
478        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
479        let reconciliation = row.try_get::<bool, _>("reconciliation")?;
480        let venue_order_id = row
481            .try_get::<Option<&str>, _>("venue_order_id")?
482            .map(Into::into);
483        let account_id = row
484            .try_get::<Option<&str>, _>("account_id")?
485            .map(Into::into);
486        let order_event = OrderModifyRejected::new(
487            trader_id,
488            strategy_id,
489            instrument_id,
490            client_order_id,
491            reason,
492            event_id,
493            ts_event,
494            ts_init,
495            reconciliation,
496            venue_order_id,
497            account_id,
498        );
499        Ok(Self(order_event))
500    }
501}
502
503impl<'r> FromRow<'r, PgRow> for OrderPendingCancelModel {
504    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
505        todo!()
506    }
507}
508
509impl<'r> FromRow<'r, PgRow> for OrderPendingUpdateModel {
510    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
511        todo!()
512    }
513}
514
515impl<'r> FromRow<'r, PgRow> for OrderRejectedModel {
516    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
517        todo!()
518    }
519}
520
521impl<'r> FromRow<'r, PgRow> for OrderReleasedModel {
522    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
523        todo!()
524    }
525}
526
527impl<'r> FromRow<'r, PgRow> for OrderSubmittedModel {
528    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
529        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
530        let strategy_id = row
531            .try_get::<&str, _>("strategy_id")
532            .map(StrategyId::from)?;
533        let instrument_id = row
534            .try_get::<&str, _>("instrument_id")
535            .map(InstrumentId::from)?;
536        let client_order_id = row
537            .try_get::<&str, _>("client_order_id")
538            .map(ClientOrderId::from)?;
539        let account_id = row.try_get::<&str, _>("account_id").map(AccountId::from)?;
540        let event_id = row.try_get::<&str, _>("id").map(UUID4::from)?;
541        let ts_event = row
542            .try_get::<String, _>("ts_event")
543            .map(|res| UnixNanos::from(res.as_str()))?;
544        let ts_init = row
545            .try_get::<String, _>("ts_init")
546            .map(|res| UnixNanos::from(res.as_str()))?;
547        let order_event = OrderSubmitted::new(
548            trader_id,
549            strategy_id,
550            instrument_id,
551            client_order_id,
552            account_id,
553            event_id,
554            ts_event,
555            ts_init,
556        );
557        Ok(Self(order_event))
558    }
559}
560
561impl<'r> FromRow<'r, PgRow> for OrderTriggeredModel {
562    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
563        todo!()
564    }
565}
566
567impl<'r> FromRow<'r, PgRow> for OrderUpdatedModel {
568    fn from_row(_row: &'r PgRow) -> Result<Self, sqlx::Error> {
569        todo!()
570    }
571}
572
573impl<'r> FromRow<'r, PgRow> for OrderSnapshotModel {
574    fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
575        let trader_id = row.try_get::<&str, _>("trader_id").map(TraderId::from)?;
576        let strategy_id = row
577            .try_get::<&str, _>("strategy_id")
578            .map(StrategyId::from)?;
579        let instrument_id = row
580            .try_get::<&str, _>("instrument_id")
581            .map(InstrumentId::from)?;
582        let client_order_id = row
583            .try_get::<&str, _>("client_order_id")
584            .map(ClientOrderId::from)?;
585        let venue_order_id = row
586            .try_get::<Option<&str>, _>("venue_order_id")
587            .ok()
588            .and_then(|x| x.map(VenueOrderId::from));
589        let position_id = row
590            .try_get::<Option<&str>, _>("position_id")
591            .ok()
592            .and_then(|x| x.map(PositionId::from));
593        let account_id = row
594            .try_get::<Option<&str>, _>("account_id")
595            .ok()
596            .and_then(|x| x.map(AccountId::from));
597        let last_trade_id = row
598            .try_get::<Option<&str>, _>("last_trade_id")
599            .ok()
600            .and_then(|x| x.map(TradeId::from));
601        let order_type = row
602            .try_get::<&str, _>("order_type")
603            .map(|x| OrderType::from_str(x).expect("Invalid `OrderType`"))?;
604        let order_side = row
605            .try_get::<&str, _>("order_side")
606            .map(|x| OrderSide::from_str(x).expect("Invalid `OrderSide`"))?;
607        let quantity = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
608        let price = row
609            .try_get::<Option<&str>, _>("price")
610            .ok()
611            .and_then(|x| x.map(Price::from));
612        let trigger_price = row
613            .try_get::<Option<&str>, _>("trigger_price")
614            .ok()
615            .and_then(|x| x.map(Price::from));
616        let trigger_type = row
617            .try_get::<Option<&str>, _>("trigger_type")
618            .ok()
619            .and_then(|x| x.map(|x| TriggerType::from_str(x).expect("Invalid `TriggerType`")));
620        let limit_offset = row
621            .try_get::<Option<&str>, _>("limit_offset")
622            .ok()
623            .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
624        let trailing_offset = row
625            .try_get::<Option<&str>, _>("trailing_offset")
626            .ok()
627            .and_then(|x| x.and_then(|s| Decimal::from_str(s).ok()));
628        let trailing_offset_type = row
629            .try_get::<Option<TrailingOffsetTypeModel>, _>("trailing_offset_type")
630            .ok()
631            .and_then(|x| x.map(|x| x.0));
632        let time_in_force = row
633            .try_get::<&str, _>("time_in_force")
634            .map(|x| TimeInForce::from_str(x).expect("Invalid `TimeInForce`"))?;
635        let expire_time = row
636            .try_get::<Option<&str>, _>("expire_time")
637            .ok()
638            .and_then(|x| x.map(UnixNanos::from));
639        let filled_qty = row.try_get::<&str, _>("filled_qty").map(Quantity::from)?;
640        let liquidity_side = row
641            .try_get::<Option<&str>, _>("liquidity_side")
642            .ok()
643            .and_then(|x| x.map(|x| LiquiditySide::from_str(x).expect("Invalid `LiquiditySide`")));
644        let avg_px = row.try_get::<Option<f64>, _>("avg_px").ok().flatten();
645        let slippage = row.try_get::<Option<f64>, _>("slippage").ok().flatten();
646        let commissions = row
647            .try_get::<Option<Vec<String>>, _>("commissions")?
648            .map_or_else(Vec::new, |c| {
649                c.into_iter().map(|s| Money::from(&s)).collect()
650            });
651        let status = row
652            .try_get::<&str, _>("status")
653            .map(|x| OrderStatus::from_str(x).expect("Invalid `OrderStatus`"))?;
654        let is_post_only = row.try_get::<bool, _>("is_post_only")?;
655        let is_reduce_only = row.try_get::<bool, _>("is_reduce_only")?;
656        let is_quote_quantity = row.try_get::<bool, _>("is_quote_quantity")?;
657        let display_qty = row
658            .try_get::<Option<&str>, _>("display_qty")
659            .ok()
660            .and_then(|x| x.map(Quantity::from));
661        let emulation_trigger = row
662            .try_get::<Option<&str>, _>("emulation_trigger")
663            .ok()
664            .and_then(|x| x.map(|x| TriggerType::from_str(x).expect("Invalid `TriggerType`")));
665        let trigger_instrument_id = row
666            .try_get::<Option<&str>, _>("trigger_instrument_id")
667            .ok()
668            .and_then(|x| x.map(InstrumentId::from));
669        let contingency_type = row
670            .try_get::<Option<&str>, _>("contingency_type")
671            .ok()
672            .and_then(|x| {
673                x.map(|x| ContingencyType::from_str(x).expect("Invalid `ContingencyType`"))
674            });
675        let order_list_id = row
676            .try_get::<Option<&str>, _>("order_list_id")
677            .ok()
678            .and_then(|x| x.map(OrderListId::from));
679        let linked_order_ids = row
680            .try_get::<Option<Vec<String>>, _>("linked_order_ids")
681            .ok()
682            .and_then(|ids| ids.map(|ids| ids.into_iter().map(ClientOrderId::from).collect()));
683        let parent_order_id = row
684            .try_get::<Option<&str>, _>("parent_order_id")
685            .ok()
686            .and_then(|x| x.map(ClientOrderId::from));
687        let exec_algorithm_id = row
688            .try_get::<Option<&str>, _>("exec_algorithm_id")
689            .ok()
690            .and_then(|x| x.map(ExecAlgorithmId::from));
691        let exec_algorithm_params: Option<IndexMap<Ustr, Ustr>> = row
692            .try_get::<Option<serde_json::Value>, _>("exec_algorithm_params")
693            .ok()
694            .and_then(|x| {
695                x.map(|x| {
696                    serde_json::from_value::<IndexMap<String, String>>(x)
697                        .expect("Invalid exec algorithm params")
698                })
699            })
700            .map(|x| {
701                x.into_iter()
702                    .map(|(k, v)| (Ustr::from(k.as_str()), Ustr::from(v.as_str())))
703                    .collect()
704            });
705        let exec_spawn_id = row
706            .try_get::<Option<&str>, _>("exec_spawn_id")
707            .ok()
708            .and_then(|x| x.map(ClientOrderId::from));
709        let tags = row
710            .try_get::<Option<serde_json::Value>, _>("tags")
711            .ok()
712            .flatten()
713            .and_then(|tags_value| {
714                serde_json::from_value::<Vec<String>>(tags_value)
715                    .ok()
716                    .map(|vec| {
717                        vec.into_iter()
718                            .map(|tag| Ustr::from(tag.as_str()))
719                            .collect::<Vec<Ustr>>()
720                    })
721            });
722        let init_id = row.try_get::<&str, _>("init_id").map(UUID4::from)?;
723        let ts_init = row.try_get::<String, _>("ts_init").map(UnixNanos::from)?;
724        let ts_last = row.try_get::<String, _>("ts_last").map(UnixNanos::from)?;
725
726        let snapshot = OrderSnapshot {
727            trader_id,
728            strategy_id,
729            instrument_id,
730            client_order_id,
731            venue_order_id,
732            position_id,
733            account_id,
734            last_trade_id,
735            order_type,
736            order_side,
737            quantity,
738            price,
739            trigger_price,
740            trigger_type,
741            limit_offset,
742            trailing_offset,
743            trailing_offset_type,
744            time_in_force,
745            expire_time,
746            filled_qty,
747            liquidity_side,
748            avg_px,
749            slippage,
750            commissions,
751            status,
752            is_post_only,
753            is_reduce_only,
754            is_quote_quantity,
755            display_qty,
756            emulation_trigger,
757            trigger_instrument_id,
758            contingency_type,
759            order_list_id,
760            linked_order_ids,
761            parent_order_id,
762            exec_algorithm_id,
763            exec_algorithm_params,
764            exec_spawn_id,
765            tags,
766            init_id,
767            ts_init,
768            ts_last,
769        };
770
771        Ok(Self(snapshot))
772    }
773}