Skip to main content

data_preprocess/
models.rs

1use chrono::NaiveDateTime;
2use serde::{Deserialize, Serialize};
3
4use crate::error::{DataError, Result};
5
6/// Supported bar timeframes.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub enum Timeframe {
9    M1,
10    M3,
11    M5,
12    M15,
13    M30,
14    H1,
15    H4,
16    D1,
17    W1,
18    MN1,
19}
20
21impl Timeframe {
22    /// Parse from CLI string. Accepts "1m","M1","3m","M3", etc.
23    pub fn parse(s: &str) -> Result<Self> {
24        match s.to_lowercase().as_str() {
25            "1m" | "m1" => Ok(Self::M1),
26            "3m" | "m3" => Ok(Self::M3),
27            "5m" | "m5" => Ok(Self::M5),
28            "15m" | "m15" => Ok(Self::M15),
29            "30m" | "m30" => Ok(Self::M30),
30            "1h" | "h1" => Ok(Self::H1),
31            "4h" | "h4" => Ok(Self::H4),
32            "1d" | "d1" => Ok(Self::D1),
33            "1w" | "w1" => Ok(Self::W1),
34            "1mn" | "mn1" | "1m0" | "mn" => Ok(Self::MN1),
35            _ => Err(DataError::InvalidTimeframe(s.to_string())),
36        }
37    }
38
39    /// Canonical short label for storage: "1m", "3m", "5m", ...
40    pub fn as_str(&self) -> &'static str {
41        match self {
42            Self::M1 => "1m",
43            Self::M3 => "3m",
44            Self::M5 => "5m",
45            Self::M15 => "15m",
46            Self::M30 => "30m",
47            Self::H1 => "1h",
48            Self::H4 => "4h",
49            Self::D1 => "1d",
50            Self::W1 => "1w",
51            Self::MN1 => "1M",
52        }
53    }
54}
55
56impl std::fmt::Display for Timeframe {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        f.write_str(self.as_str())
59    }
60}
61
62/// A single tick (bid/ask/last at a point in time).
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct Tick {
65    pub exchange: String,
66    pub symbol: String,
67    pub ts: NaiveDateTime,
68    pub bid: Option<f64>,
69    pub ask: Option<f64>,
70    pub last: Option<f64>,
71    pub volume: Option<f64>,
72    pub flags: Option<i32>,
73}
74
75/// A single OHLCV bar.
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct Bar {
78    pub exchange: String,
79    pub symbol: String,
80    pub timeframe: Timeframe,
81    pub ts: NaiveDateTime,
82    pub open: f64,
83    pub high: f64,
84    pub low: f64,
85    pub close: f64,
86    pub tick_vol: i64,
87    pub volume: i64,
88    pub spread: i32,
89}
90
91/// Summary row returned by stats queries.
92#[derive(Debug)]
93pub struct StatRow {
94    pub exchange: String,
95    pub symbol: String,
96    pub data_type: String,
97    pub count: u64,
98    pub ts_min: NaiveDateTime,
99    pub ts_max: NaiveDateTime,
100}
101
102/// Result of an import operation.
103#[derive(Debug)]
104pub struct ImportResult {
105    pub file: String,
106    pub exchange: String,
107    pub symbol: String,
108    pub rows_parsed: usize,
109    pub rows_inserted: usize,
110    pub rows_skipped: usize,
111    pub elapsed: std::time::Duration,
112}