Skip to main content

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