nautilus_infrastructure/sql/models/
orders.rs

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