digdigdig3_station/data/
agg_trade.rs1use digdigdig3::core::types::{StreamEvent, TradeSide};
2use serde::{Deserialize, Serialize};
3
4use crate::series::DataPoint;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct AggTradePoint {
9 pub ts_ms: i64,
10 pub price: f64,
11 pub quantity: f64,
12 pub side: u8,
13 pub agg_id: u64,
14}
15
16const SIZE: usize = 48;
17
18impl DataPoint for AggTradePoint {
19 const RECORD_SIZE: usize = SIZE;
20
21 fn encode(&self, out: &mut [u8]) {
22 out[0..8].copy_from_slice(&(self.ts_ms as u64).to_le_bytes());
23 out[8..16].copy_from_slice(&self.price.to_le_bytes());
24 out[16..24].copy_from_slice(&self.quantity.to_le_bytes());
25 out[24] = self.side;
26 out[25..33].copy_from_slice(&self.agg_id.to_le_bytes());
27 }
28
29 fn decode(bytes: &[u8]) -> Option<Self> {
30 if bytes.len() != SIZE { return None; }
31 Some(Self {
32 ts_ms: u64::from_le_bytes(bytes[0..8].try_into().ok()?) as i64,
33 price: f64::from_le_bytes(bytes[8..16].try_into().ok()?),
34 quantity: f64::from_le_bytes(bytes[16..24].try_into().ok()?),
35 side: bytes[24],
36 agg_id: u64::from_le_bytes(bytes[25..33].try_into().ok()?),
37 })
38 }
39
40 fn timestamp_ms(&self) -> i64 { self.ts_ms }
41
42 fn from_stream_event(ev: &StreamEvent) -> Option<Self> {
43 if let StreamEvent::AggTrade { price, quantity, side, timestamp, aggregate_id, .. } = ev {
44 let s = match side {
45 TradeSide::Buy => 0,
46 TradeSide::Sell => 1,
47 };
48 Some(Self {
49 ts_ms: *timestamp,
50 price: *price,
51 quantity: *quantity,
52 side: s,
53 agg_id: *aggregate_id as u64,
54 })
55 } else {
56 None
57 }
58 }
59}