sdb_core/postprocessing/
level.rs1use std::collections::{BTreeMap, HashMap};
6use crate::postprocessing::histogram::{Histogram, BinCount};
7use crate::utils::fill_digits;
8use crate::dtf::update::Update;
9
10type Price = u64;
11type Time = u32;
12type Size = f32;
13
14#[derive(Debug)]
16pub struct Levels {
17 levels: HashMap<Price, BTreeMap<Time, Size>>,
18}
19
20impl Levels {
21 pub fn from(ups: &[Update], step_bins: BinCount, tick_bins: BinCount, m: f64) -> Levels {
24 let (price_hist, step_hist) = Histogram::from(&ups, step_bins, tick_bins, m);
25 let mut map = HashMap::new();
29 for up in ups.iter() {
30 let price = price_hist.to_bin(up.price as f64);
31 let time = step_hist.to_bin((fill_digits(up.ts) / 1000) as f64);
32 match (price, time) {
33 (Some(p), Some(t)) => {
34 let price_level = map.entry(p.to_bits()).or_insert(
35 BTreeMap::<Time, Size>::new(),
36 );
37 (*price_level).insert(t as Time, up.size);
38 }
39 (None, _) => {
40 continue;
41 }
42 (_, None) => {
43 continue;
44 }
45 }
46 }
47
48 Levels { levels: map }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::dtf;
56 static FNAME: &str = "../../test/test-data/bt_btcnav.dtf";
57
58 #[test]
59 pub fn test_levels() {
60 let tick_bins = 10; let step_bins = 10;
63 let records = dtf::file_format::decode(FNAME, Some(100)).unwrap();
64 {
65 let prices = records
66 .iter()
67 .map(|up| up.price as f64)
68 .collect::<Vec<f64>>();
69 let price_hist = Histogram::new(&prices, tick_bins, 2.0);
70 let mut dict = BTreeMap::new();
71 for up in records.iter() {
72 if let Some(binned_val) = price_hist.to_bin(up.price as f64) {
73 let entry = dict.entry(binned_val.to_bits()).or_insert(0);
74 (*entry) += 1;
75 }
76 }
77 assert_eq!(price_hist.boundaries.len(), tick_bins);
78 assert_eq!(price_hist.bins.clone().unwrap().len(), tick_bins);
79
80 for (val, bin) in dict.values().zip(price_hist.bins.unwrap().iter()) {
81 assert_eq!(val, bin);
82 }
83 }
84
85 let levels = Levels::from(records.as_slice(), step_bins, tick_bins, 2.);
86 assert_eq!(
87 levels.levels.keys().collect::<Vec<_>>().len(),
88 tick_bins - 1
89 );
90 for level in levels.levels.values() {
91 assert!(level.keys().collect::<Vec<_>>().len() <= (step_bins - 1));
92 }
93
94 }
95}