flowsurface_data/
chart.rs1pub mod axis;
2pub mod heatmap;
3pub mod kline;
4pub mod ticks;
5pub mod value;
6
7use exchange::{Timeframe, unit::PriceStep};
8use serde::{Deserialize, Serialize};
9
10use super::aggr::{
11 self,
12 ticks::TickAggr,
13 time::{DataPoint, TimeSeries},
14};
15
16pub enum PlotData<D: DataPoint> {
21 TimeBased(TimeSeries<D>),
22 TickBased(TickAggr),
23}
24
25impl<D: DataPoint> PlotData<D> {
26 pub fn basis(&self) -> Basis {
28 match self {
29 Self::TimeBased(series) => Basis::Time(series.interval),
30 Self::TickBased(series) => Basis::Tick(series.interval),
31 }
32 }
33
34 pub fn tick_size(&self) -> PriceStep {
36 match self {
37 Self::TimeBased(series) => series.tick_size,
38 Self::TickBased(series) => series.tick_size,
39 }
40 }
41
42 pub fn len(&self) -> usize {
43 match self {
44 Self::TimeBased(series) => series.datapoints.len(),
45 Self::TickBased(series) => series.datapoints.len(),
46 }
47 }
48
49 pub fn is_empty(&self) -> bool {
50 self.len() == 0
51 }
52}
53
54#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
56pub enum Basis {
57 Time(exchange::Timeframe),
59
60 Tick(aggr::TickCount),
62}
63
64impl Basis {
65 pub fn is_time(&self) -> bool {
66 matches!(self, Basis::Time(_))
67 }
68
69 pub fn default_kline_time(
70 ticker_info: Option<exchange::TickerInfo>,
71 fallback: Timeframe,
72 ) -> Self {
73 let interval = ticker_info.map_or(fallback, |info| {
74 let exchange = info.exchange();
75
76 if exchange.supports_kline_timeframe(fallback) {
77 fallback
78 } else {
79 Timeframe::KLINE
80 .iter()
81 .copied()
82 .find(|tf| exchange.supports_kline_timeframe(*tf))
83 .unwrap_or(fallback)
84 }
85 });
86
87 interval.into()
88 }
89
90 pub fn default_heatmap_time(ticker_info: Option<exchange::TickerInfo>) -> Self {
91 let fallback = Timeframe::MS500;
92
93 let interval = ticker_info.map_or(fallback, |info| {
94 let ex = info.exchange();
95 Timeframe::HEATMAP
96 .iter()
97 .copied()
98 .find(|tf| ex.supports_heatmap_timeframe(*tf))
99 .unwrap_or(fallback)
100 });
101
102 interval.into()
103 }
104}
105
106impl std::fmt::Display for Basis {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 match self {
109 Basis::Time(timeframe) => write!(f, "{timeframe}"),
110 Basis::Tick(count) => write!(f, "{count}"),
111 }
112 }
113}
114
115impl From<exchange::Timeframe> for Basis {
116 fn from(timeframe: exchange::Timeframe) -> Self {
117 Self::Time(timeframe)
118 }
119}