nautilus_infrastructure/sql/models/
data.rs1use nautilus_core::UnixNanos;
17use nautilus_model::{
18 data::{Bar, BarSpecification, BarType, QuoteTick, TradeTick},
19 identifiers::{InstrumentId, TradeId},
20 types::{Price, Quantity},
21};
22use sqlx::{Error, FromRow, Row, postgres::PgRow};
23
24use crate::sql::models::enums::{
25 AggregationSourceModel, AggressorSideModel, BarAggregationModel, PriceTypeModel,
26};
27
28pub struct QuoteTickModel(pub QuoteTick);
29pub struct TradeTickModel(pub TradeTick);
30pub struct BarModel(pub Bar);
31
32impl<'r> FromRow<'r, PgRow> for QuoteTickModel {
33 fn from_row(row: &'r PgRow) -> Result<Self, Error> {
34 let instrument_id = row
35 .try_get::<&str, _>("instrument_id")
36 .map(InstrumentId::from)?;
37 let bid_price = row.try_get::<&str, _>("bid_price").map(Price::from)?;
38 let ask_price = row.try_get::<&str, _>("ask_price").map(Price::from)?;
39 let bid_size = row.try_get::<&str, _>("bid_size").map(Quantity::from)?;
40 let ask_size = row.try_get::<&str, _>("ask_size").map(Quantity::from)?;
41 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
42 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
43 let quote = QuoteTick::new(
44 instrument_id,
45 bid_price,
46 ask_price,
47 bid_size,
48 ask_size,
49 ts_event,
50 ts_init,
51 );
52 Ok(QuoteTickModel(quote))
53 }
54}
55
56impl<'r> FromRow<'r, PgRow> for TradeTickModel {
57 fn from_row(row: &'r PgRow) -> Result<Self, Error> {
58 let instrument_id = row
59 .try_get::<&str, _>("instrument_id")
60 .map(InstrumentId::from)?;
61 let price = row.try_get::<&str, _>("price").map(Price::from)?;
62 let size = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
63 let aggressor_side = row
64 .try_get::<AggressorSideModel, _>("aggressor_side")
65 .map(|x| x.0)?;
66 let trade_id = row
67 .try_get::<&str, _>("venue_trade_id")
68 .map(TradeId::from)?;
69 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
70 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
71 let trade = TradeTick::new(
72 instrument_id,
73 price,
74 size,
75 aggressor_side,
76 trade_id,
77 ts_event,
78 ts_init,
79 );
80 Ok(TradeTickModel(trade))
81 }
82}
83
84impl<'r> FromRow<'r, PgRow> for BarModel {
85 fn from_row(row: &'r PgRow) -> Result<Self, Error> {
86 let instrument_id = row
87 .try_get::<&str, _>("instrument_id")
88 .map(InstrumentId::from)?;
89 let step = row.try_get::<i32, _>("step")?;
90 let price_type = row
91 .try_get::<PriceTypeModel, _>("price_type")
92 .map(|x| x.0)?;
93 let bar_aggregation = row
94 .try_get::<BarAggregationModel, _>("bar_aggregation")
95 .map(|x| x.0)?;
96 let aggregation_source = row
97 .try_get::<AggregationSourceModel, _>("aggregation_source")
98 .map(|x| x.0)?;
99 let bar_type = BarType::new(
100 instrument_id,
101 BarSpecification::new(step as usize, bar_aggregation, price_type),
102 aggregation_source,
103 );
104 let open = row.try_get::<&str, _>("open").map(Price::from)?;
105 let high = row.try_get::<&str, _>("high").map(Price::from)?;
106 let low = row.try_get::<&str, _>("low").map(Price::from)?;
107 let close = row.try_get::<&str, _>("close").map(Price::from)?;
108 let volume = row.try_get::<&str, _>("volume").map(Quantity::from)?;
109 let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
110 let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
111 let bar = Bar::new(bar_type, open, high, low, close, volume, ts_event, ts_init);
112 Ok(BarModel(bar))
113 }
114}