Pārlūkot izejas kodu

proper way of handling ticksize

Berke 1 gadu atpakaļ
vecāks
revīzija
42b9660766
1 mainītis faili ar 65 papildinājumiem un 37 dzēšanām
  1. 65 37
      src/main.rs

+ 65 - 37
src/main.rs

@@ -189,7 +189,7 @@ pub enum Message {
     TimeframeSelected(Timeframe, pane_grid::Pane),
     ExchangeSelected(&'static str),
     MarketWsEvent(market_data::Event),
-    WsToggle(),
+    WsToggle,
     FetchEvent(Result<Vec<market_data::Kline>, std::string::String>, PaneId, Timeframe),
     
     // Pane grid
@@ -215,7 +215,8 @@ pub enum Message {
     ShowLayoutModal,
     HideLayoutModal,
 
-    TicksizeSelected(f32),
+    TicksizeSelected(u16),
+    SetMinTickSize(f32),
 }
 
 struct State {
@@ -246,7 +247,9 @@ struct State {
     sync_heatmap: bool,
 
     kline_stream: bool,
-    tick_size: Option<f32>,
+
+    tick_multiply: u16,
+    min_tick_size: Option<f32>,
 }
 
 impl State {
@@ -329,7 +332,8 @@ impl State {
             focus: None,
             first_pane,
             pane_lock: false,
-            tick_size: Some(1.0), 
+            tick_multiply: 1,
+            min_tick_size: None, 
         }
     }
 
@@ -360,6 +364,19 @@ impl State {
                 Task::none()
             },
 
+            Message::SetMinTickSize(min_tick_size) => {
+                self.min_tick_size = Some(min_tick_size);
+
+                if let Some(heatmap_chart) = &mut self.heatmap_chart {
+                    let copied_trades = heatmap_chart.get_raw_trades();
+
+                    if let Some(footprint_chart) = &mut self.footprint_chart {
+                        footprint_chart.change_tick_size(copied_trades, self.tick_multiply as f32 * self.min_tick_size.unwrap_or(1.0));
+                    }
+                }
+
+                Task::none()
+            },
             Message::TickerSelected(ticker) => {
                 self.selected_ticker = Some(ticker);
 
@@ -370,6 +387,19 @@ impl State {
 
                 Task::none()
             },
+            Message::TicksizeSelected(tick_multiply) => {
+                if let Some(heatmap_chart) = &mut self.heatmap_chart {
+                    let copied_trades = heatmap_chart.get_raw_trades();
+
+                    if let Some(footprint_chart) = &mut self.footprint_chart {
+                        footprint_chart.change_tick_size(copied_trades, tick_multiply as f32 * self.min_tick_size.unwrap_or(1.0));
+
+                        self.tick_multiply = tick_multiply;
+                    }
+                }
+
+                Task::none()
+            },
             Message::TimeframeSelected(timeframe, pane) => {
                 if !self.ws_running {
                     return Task::none();
@@ -417,39 +447,48 @@ impl State {
                 self.selected_exchange = Some(exchange);
                 Task::none()
             },
-            Message::WsToggle() => {
+            Message::WsToggle => {
                 self.ws_running = !self.ws_running;
 
                 if self.ws_running {  
-                    let mut Tasks = vec![];
-
-                    let first_pane = self.first_pane;
+                    let mut tasks: Vec<Task<Message>> = vec![];
         
-                    for (pane, pane_state) in self.panes.iter() {
+                    for (_, pane_state) in self.panes.iter() {
                         if pane_state.id == PaneId::HeatmapChart {
                             self.heatmap_chart = Some(Heatmap::new());
                         }
                         if pane_state.id == PaneId::TimeAndSales {
                             self.time_and_sales = Some(TimeAndSales::new());
                         }
+                        if pane_state.id == PaneId::FootprintChart {
+                            let fetch_ticksize: Task<Message> = Task::perform(
+                                market_data::fetch_ticksize(self.selected_ticker.unwrap_or(Ticker::BTCUSDT))
+                                    .map_err(|err| format!("{err}")), 
+                                move |ticksize: Result<f32, String>| {
+                                    Message::SetMinTickSize(ticksize.unwrap_or(1.0))
+                                }
+                            );
+                            tasks.push(fetch_ticksize);
+                        }
 
-                        let selected_timeframe = match pane_state.stream.1 {
+                        let selected_timeframe: Timeframe = match pane_state.stream.1 {
                             Some(timeframe) => timeframe,
                             None => Timeframe::M1,
                         };
 
-                        let pane_id = pane_state.id;
+                        let pane_id: PaneId = pane_state.id;
 
-                        let fetch_klines = Task::perform(
+                        let fetch_klines: Task<Message> = Task::perform(
                             market_data::fetch_klines(self.selected_ticker.unwrap_or(Ticker::BTCUSDT), selected_timeframe)
                                 .map_err(|err| format!("{err}")), 
                             move |klines: Result<Vec<market_data::Kline>, String>| {
                                 Message::FetchEvent(klines, pane_id, selected_timeframe)
                             }
                         );
-                        Tasks.push(fetch_klines);
-                    }
-                    Task::batch(Tasks)
+                        tasks.push(fetch_klines);
+                    };
+                    
+                    Task::batch(tasks)
 
                 } else {
                     self.ws_state = WsState::Disconnected;
@@ -486,7 +525,8 @@ impl State {
                                     }
 
                                     // get the latest 20 klines
-                                    let copied_klines = klines_raw.iter().rev().take(20).rev().copied().collect::<Vec<(i64, f32, f32, f32, f32, f32, f32)>>();
+                                    let copied_klines: Vec<(i64, f32, f32, f32, f32, f32, f32)> = 
+                                        klines_raw.iter().rev().take(20).rev().copied().collect::<Vec<(i64, f32, f32, f32, f32, f32, f32)>>();
 
                                     let timeframe_u16: u16 = match timeframe {
                                         Timeframe::M1 => 1,
@@ -496,7 +536,9 @@ impl State {
                                         Timeframe::M30 => 30,
                                     };
 
-                                    self.footprint_chart = Some(Footprint::new(timeframe_u16, self.tick_size.unwrap_or(1.0), copied_klines, copied_trades));
+                                    let tick_size = self.tick_multiply as f32 * self.min_tick_size.unwrap_or_default();
+
+                                    self.footprint_chart = Some(Footprint::new(timeframe_u16, tick_size, copied_klines, copied_trades));
                                 }
                             },
                             _ => {}
@@ -689,20 +731,6 @@ impl State {
                 self.show_layout_modal = false;
                 Task::none()
             },
-
-            Message::TicksizeSelected(ticksize) => {
-                if let Some(heatmap_chart) = &mut self.heatmap_chart {
-                    let copied_trades = heatmap_chart.get_raw_trades();
-
-                    if let Some(footprint_chart) = &mut self.footprint_chart {
-                        footprint_chart.change_tick_size(copied_trades, ticksize);
-
-                        self.tick_size = Some(ticksize);
-                    }
-                }
-
-                Task::none()
-            },
         }
     }
 
@@ -758,7 +786,7 @@ impl State {
                         total_panes,
                         is_maximized,
                         pane.stream.1.as_ref(),
-                        self.tick_size.as_ref(),
+                        self.tick_multiply,
                     ))
                     .padding(4)
                     .style(style::title_bar_focused);
@@ -804,7 +832,7 @@ impl State {
 
         let ws_button = if self.selected_ticker.is_some() {
             button(if self.ws_running { "Disconnect" } else { "Connect" })
-                .on_press(Message::WsToggle())
+                .on_press(Message::WsToggle)
         } else {
             button(if self.ws_running { "Disconnect" } else { "Connect" })
         };
@@ -1143,7 +1171,7 @@ fn view_controls<'a>(
     total_panes: usize,
     is_maximized: bool,
     selected_timeframe: Option<&'a Timeframe>,
-    selected_ticksize: Option<&'a f32>,
+    selected_ticksize: u16,
 ) -> Element<'a, Message> {
     let mut row = row![].spacing(5);
 
@@ -1163,10 +1191,10 @@ fn view_controls<'a>(
     }
     if pane_id == PaneId::FootprintChart {
         let ticksize_picker = pick_list(
-            [0.1, 0.5, 1.0, 5.0, 10.0, 25.0, 50.0],
-            selected_ticksize,
+            [1, 2, 5, 10, 25, 50, 100, 200],
+            Some(selected_ticksize),
             Message::TicksizeSelected,
-        ).placeholder("Choose a ticksize...").text_size(11).width(iced::Pixels(80.0));
+        ).placeholder("Ticksize multiplier...").text_size(11).width(iced::Pixels(80.0));
         row = row.push(ticksize_picker);
     }