| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- use chrono::NaiveDateTime;
- use iced::{
- alignment, Element, Length
- };
- use iced::widget::{Column, Row, Container, Text, container, Space};
- use crate::screen::dashboard::pane::Message;
- use crate::{style, data_providers::Trade};
- struct ConvertedTrade {
- time: NaiveDateTime,
- price: f32,
- qty: f32,
- is_sell: bool,
- }
- pub struct TimeAndSales {
- recent_trades: Vec<ConvertedTrade>,
- size_filter: f32,
- filter_sync_heatmap: bool,
- }
- impl TimeAndSales {
- pub fn new() -> Self {
- Self {
- recent_trades: Vec::new(),
- size_filter: 0.0,
- filter_sync_heatmap: false,
- }
- }
-
- pub fn set_size_filter(&mut self, value: f32) {
- self.size_filter = value;
- }
- pub fn get_size_filter(&self) -> f32 {
- self.size_filter
- }
- pub fn set_filter_sync_heatmap(&mut self, value: bool) {
- self.filter_sync_heatmap = value;
- }
- pub fn get_filter_sync_heatmap(&self) -> bool {
- self.filter_sync_heatmap
- }
- pub fn update(&mut self, trades_buffer: &[Trade]) {
- for trade in trades_buffer {
- let trade_time = NaiveDateTime::from_timestamp(trade.time / 1000, (trade.time % 1000) as u32 * 1_000_000);
- let converted_trade = ConvertedTrade {
- time: trade_time,
- price: trade.price,
- qty: trade.qty,
- is_sell: trade.is_sell,
- };
- self.recent_trades.push(converted_trade);
- }
- if self.recent_trades.len() > 2000 {
- let drain_to = self.recent_trades.len() - 2000;
- self.recent_trades.drain(0..drain_to);
- }
- }
- pub fn view(&self) -> Element<'_, Message> {
- let mut trades_column = Column::new()
- .height(Length::Fill)
- .padding(10);
- let filtered_trades: Vec<_> = self.recent_trades.iter().filter(|trade| (trade.qty*trade.price) >= self.size_filter).collect();
- let max_qty = filtered_trades.iter().map(|trade| trade.qty).fold(0.0, f32::max);
-
- if filtered_trades.is_empty() {
- trades_column = trades_column.push(
- Text::new("No trades")
- .width(Length::Fill)
- .height(Length::Fill)
- .size(16)
- );
- } else {
- for trade in filtered_trades.iter().rev().take(80) {
- let trade: &ConvertedTrade = trade;
- let trade_row = Row::new()
- .push(
- container(Text::new(format!("{}", trade.time.format("%M:%S.%3f"))).size(14))
- .width(Length::FillPortion(8)).align_x(alignment::Horizontal::Center)
- )
- .push(
- container(Text::new(format!("{}", trade.price)).size(14))
- .width(Length::FillPortion(6))
- )
- .push(
- container(Text::new(if trade.is_sell { "Sell" } else { "Buy" }).size(14))
- .width(Length::FillPortion(4)).align_x(alignment::Horizontal::Left)
- )
- .push(
- container(Text::new(format!("{}", trade.qty)).size(14))
- .width(Length::FillPortion(4))
- );
- let color_alpha = trade.qty / max_qty;
-
- trades_column = trades_column.push(container(trade_row)
- .style( move |_| if trade.is_sell { style::sell_side_red(color_alpha) } else { style::buy_side_green(color_alpha) }));
-
- trades_column = trades_column.push(Container::new(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))));
- }
- }
-
- trades_column.into()
- }
- }
|