Selaa lähdekoodia

use depth update time for smoother plot, instead of inv. trade times

Berke 1 vuosi sitten
vanhempi
commit
36a57fcdac
1 muutettua tiedostoa jossa 30 lisäystä ja 19 poistoa
  1. 30 19
      src/main.rs

+ 30 - 19
src/main.rs

@@ -155,10 +155,10 @@ impl Application for State {
                     self.ws_state = WsState::Disconnected;
                     Command::none()
                 }
-                ws_binance::Event::DepthReceived(bids, asks, trades_buffer) => {
+                ws_binance::Event::DepthReceived(depth_update, bids, _asks, trades_buffer) => {
                     let best_bid_price = bids.first().map(|(price, _)| *price).unwrap_or(0.0);
                     if let Some(chart) = &mut self.trades_chart {
-                        chart.update(trades_buffer, best_bid_price);
+                        chart.update(depth_update, trades_buffer, best_bid_price);
                     }
                     Command::none()
                 }
@@ -228,12 +228,10 @@ impl Application for State {
     }
 }
 
-
 struct CandlestickChart {
     cache: Cache,
     data_points: HashMap<DateTime<Utc>, (f32, f32, f32, f32)>,
 }
-
 impl CandlestickChart {
     fn new(klines: Vec<ws_binance::Kline>) -> Self {
         let mut data_points = HashMap::new();
@@ -272,7 +270,6 @@ impl CandlestickChart {
         chart.into()
     }
 }
-
 impl Chart<Message> for CandlestickChart {
     type State = ();
     #[inline]
@@ -293,7 +290,7 @@ impl Chart<Message> for CandlestickChart {
 
         let mut y_min = f32::MAX;
         let mut y_max = f32::MIN;
-        for (_time, (open, high, low, close)) in &self.data_points {
+        for (_time, (_open, high, low, _close)) in &self.data_points {
             y_min = y_min.min(*low);
             y_max = y_max.max(*high);
         }
@@ -341,24 +338,34 @@ impl Chart<Message> for CandlestickChart {
 struct LineChart {
     cache: Cache,
     data_points: VecDeque<(DateTime<Utc>, f32, f32, bool)>,
+    bid_prices: VecDeque<(DateTime<Utc>, f32)>,
 }
-
 impl LineChart {
     fn new() -> Self {
         Self {
             cache: Cache::new(),
             data_points: VecDeque::new(),
+            bid_prices: VecDeque::new(),
         }
     }
 
-    fn update(&mut self, mut trades_buffer: Vec<ws_binance::Trade>, _best_bid_price: f32) {
+    fn update(&mut self, depth_update: u64, mut trades_buffer: Vec<ws_binance::Trade>, best_bid_price: f32) {
+        let aggregate_time = 250; 
+        let depth_update_time = DateTime::<Utc>::from_utc(
+            NaiveDateTime::from_timestamp(
+                (depth_update / 1000) as i64, 
+                ((depth_update % 1000) / aggregate_time * aggregate_time * 1_000_000) as u32
+            ), 
+            Utc
+        );
+        self.bid_prices.push_back((depth_update_time, best_bid_price));
+
         for trade in trades_buffer.drain(..) {
-            let time = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(trade.time as i64 / 1000, 0), Utc);
-            self.data_points.push_back((time, trade.price, trade.qty, trade.is_sell));
+            self.data_points.push_back((depth_update_time, trade.price, trade.qty, trade.is_sell));
         }
-
         while self.data_points.len() > 6000 {
             self.data_points.pop_front();
+            self.bid_prices.pop_front();
         }
 
         self.cache.clear();
@@ -372,7 +379,6 @@ impl LineChart {
         chart.into()
     }
 }
-
 impl Chart<Message> for LineChart {
     type State = ();
     #[inline]
@@ -400,20 +406,25 @@ impl Chart<Message> for LineChart {
             let oldest_time = newest_time - chrono::Duration::seconds(30);
         
             // y-axis range, acquire price range within the time range
+            let mut y_min = f32::MAX;
+            let mut y_max = f32::MIN;
             let recent_data_points: Vec<_> = self.data_points.iter().filter_map(|&(time, price, qty, bool)| {
                 if time >= oldest_time && time <= newest_time {
+                    y_min = y_min.min(price);
+                    y_max = y_max.max(price);
                     Some((time, price, qty, bool))
                 } else {
                     None
                 }
             }).collect();
 
-            let mut y_min = f32::MAX;
-            let mut y_max = f32::MIN;
-            for (_, price, _, _) in &recent_data_points {
-                y_min = y_min.min(*price);
-                y_max = y_max.max(*price);
-            }
+            let recent_bid_prices: Vec<_> = self.bid_prices.iter().filter_map(|&(time, price)| {
+                if time >= oldest_time && time <= newest_time {
+                    Some((time, price))
+                } else {
+                    None
+                }
+            }).collect();
 
             let mut chart = chart
                 .x_label_area_size(28)
@@ -450,7 +461,7 @@ impl Chart<Message> for LineChart {
             chart
                 .draw_series(
                     AreaSeries::new(
-                        recent_data_points.iter().map(|&(time, price, _, _)| (time, price)),
+                        recent_bid_prices.iter().map(|&(time, price)| (time, price)),
                         0_f32,
                         PLOT_LINE_COLOR.mix(0.175),
                     )