digdigdig3_station/data/
bar.rs1use digdigdig3::core::types::{Kline, StreamEvent};
2use serde::{Deserialize, Serialize};
3
4use crate::series::DataPoint;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct BarPoint {
14 pub open_time: i64,
15 pub open: f64,
16 pub high: f64,
17 pub low: f64,
18 pub close: f64,
19 pub volume: f64,
20 pub quote_volume: f64,
21 pub trades_count: u64,
22}
23
24const SIZE: usize = 64;
25
26impl BarPoint {
27 pub fn from_kline(k: &Kline) -> Self {
28 Self {
29 open_time: k.open_time,
30 open: k.open,
31 high: k.high,
32 low: k.low,
33 close: k.close,
34 volume: k.volume,
35 quote_volume: k.quote_volume.unwrap_or(f64::NAN),
36 trades_count: k.trades.unwrap_or(0),
37 }
38 }
39}
40
41impl DataPoint for BarPoint {
42 const RECORD_SIZE: usize = SIZE;
43
44 fn encode(&self, out: &mut [u8]) {
45 out[0..8].copy_from_slice(&(self.open_time as u64).to_le_bytes());
46 out[8..16].copy_from_slice(&self.open.to_le_bytes());
47 out[16..24].copy_from_slice(&self.high.to_le_bytes());
48 out[24..32].copy_from_slice(&self.low.to_le_bytes());
49 out[32..40].copy_from_slice(&self.close.to_le_bytes());
50 out[40..48].copy_from_slice(&self.volume.to_le_bytes());
51 out[48..56].copy_from_slice(&self.quote_volume.to_le_bytes());
52 out[56..64].copy_from_slice(&self.trades_count.to_le_bytes());
53 }
54
55 fn decode(bytes: &[u8]) -> Option<Self> {
56 if bytes.len() != SIZE { return None; }
57 Some(Self {
58 open_time: u64::from_le_bytes(bytes[0..8].try_into().ok()?) as i64,
59 open: f64::from_le_bytes(bytes[8..16].try_into().ok()?),
60 high: f64::from_le_bytes(bytes[16..24].try_into().ok()?),
61 low: f64::from_le_bytes(bytes[24..32].try_into().ok()?),
62 close: f64::from_le_bytes(bytes[32..40].try_into().ok()?),
63 volume: f64::from_le_bytes(bytes[40..48].try_into().ok()?),
64 quote_volume: f64::from_le_bytes(bytes[48..56].try_into().ok()?),
65 trades_count: u64::from_le_bytes(bytes[56..64].try_into().ok()?),
66 })
67 }
68
69 fn timestamp_ms(&self) -> i64 { self.open_time }
70
71 fn from_stream_event(ev: &StreamEvent) -> Option<Self> {
72 if let StreamEvent::Kline { kline, .. } = ev {
73 Some(Self::from_kline(kline))
74 } else {
75 None
76 }
77 }
78}