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