nautilus_infrastructure/sql/models/
data.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// -------------------------------------------------------------------------------------------------
//  Copyright (C) 2015-2024 Nautech Systems Pty Ltd. All rights reserved.
//  https://nautechsystems.io
//
//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
//  You may not use this file except in compliance with the License.
//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// -------------------------------------------------------------------------------------------------

use nautilus_core::nanos::UnixNanos;
use nautilus_model::{
    data::{
        bar::{Bar, BarSpecification, BarType},
        quote::QuoteTick,
        trade::TradeTick,
    },
    identifiers::{InstrumentId, TradeId},
    types::{price::Price, quantity::Quantity},
};
use sqlx::{postgres::PgRow, Error, FromRow, Row};

use crate::sql::models::enums::{
    AggregationSourceModel, AggressorSideModel, BarAggregationModel, PriceTypeModel,
};

pub struct QuoteTickModel(pub QuoteTick);
pub struct TradeTickModel(pub TradeTick);
pub struct BarModel(pub Bar);

impl<'r> FromRow<'r, PgRow> for QuoteTickModel {
    fn from_row(row: &'r PgRow) -> Result<Self, Error> {
        let instrument_id = row
            .try_get::<&str, _>("instrument_id")
            .map(InstrumentId::from)?;
        let bid_price = row.try_get::<&str, _>("bid_price").map(Price::from)?;
        let ask_price = row.try_get::<&str, _>("ask_price").map(Price::from)?;
        let bid_size = row.try_get::<&str, _>("bid_size").map(Quantity::from)?;
        let ask_size = row.try_get::<&str, _>("ask_size").map(Quantity::from)?;
        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
        let quote = QuoteTick::new(
            instrument_id,
            bid_price,
            ask_price,
            bid_size,
            ask_size,
            ts_event,
            ts_init,
        );
        Ok(QuoteTickModel(quote))
    }
}

impl<'r> FromRow<'r, PgRow> for TradeTickModel {
    fn from_row(row: &'r PgRow) -> Result<Self, Error> {
        let instrument_id = row
            .try_get::<&str, _>("instrument_id")
            .map(InstrumentId::from)?;
        let price = row.try_get::<&str, _>("price").map(Price::from)?;
        let size = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
        let aggressor_side = row
            .try_get::<AggressorSideModel, _>("aggressor_side")
            .map(|x| x.0)?;
        let trade_id = row
            .try_get::<&str, _>("venue_trade_id")
            .map(TradeId::from)?;
        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
        let trade = TradeTick::new(
            instrument_id,
            price,
            size,
            aggressor_side,
            trade_id,
            ts_event,
            ts_init,
        );
        Ok(TradeTickModel(trade))
    }
}

impl<'r> FromRow<'r, PgRow> for BarModel {
    fn from_row(row: &'r PgRow) -> Result<Self, Error> {
        let instrument_id = row
            .try_get::<&str, _>("instrument_id")
            .map(InstrumentId::from)?;
        let step = row.try_get::<i32, _>("step")?;
        let price_type = row
            .try_get::<PriceTypeModel, _>("price_type")
            .map(|x| x.0)?;
        let bar_aggregation = row
            .try_get::<BarAggregationModel, _>("bar_aggregation")
            .map(|x| x.0)?;
        let aggregation_source = row
            .try_get::<AggregationSourceModel, _>("aggregation_source")
            .map(|x| x.0)?;
        let bar_type = BarType::new(
            instrument_id,
            BarSpecification::new(step as usize, bar_aggregation, price_type),
            aggregation_source,
        );
        let open = row.try_get::<&str, _>("open").map(Price::from)?;
        let high = row.try_get::<&str, _>("high").map(Price::from)?;
        let low = row.try_get::<&str, _>("low").map(Price::from)?;
        let close = row.try_get::<&str, _>("close").map(Price::from)?;
        let volume = row.try_get::<&str, _>("volume").map(Quantity::from)?;
        let ts_event = row.try_get::<&str, _>("ts_event").map(UnixNanos::from)?;
        let ts_init = row.try_get::<&str, _>("ts_init").map(UnixNanos::from)?;
        let bar = Bar::new(bar_type, open, high, low, close, volume, ts_event, ts_init);
        Ok(BarModel(bar))
    }
}