Skip to main content

flowsurface_data/chart/
indicator.rs

1use std::fmt::{self, Debug, Display};
2
3use enum_map::Enum;
4use exchange::adapter::MarketKind;
5use serde::{Deserialize, Serialize};
6
7pub trait Indicator: PartialEq + Display + 'static {
8    fn for_market(market: MarketKind) -> &'static [Self]
9    where
10        Self: Sized;
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize, Eq, Enum)]
14pub enum KlineIndicator {
15    Volume,
16    CumulativeDelta,
17    OpenInterest,
18}
19
20impl Indicator for KlineIndicator {
21    fn for_market(market: MarketKind) -> &'static [Self] {
22        match market {
23            MarketKind::Spot => &Self::FOR_SPOT,
24            MarketKind::LinearPerps | MarketKind::InversePerps => &Self::FOR_PERPS,
25        }
26    }
27}
28
29impl KlineIndicator {
30    // Indicator togglers on UI menus depend on these arrays.
31    // Every variant needs to be in either SPOT, PERPS or both.
32    /// Indicators that can be used with spot market tickers
33    const FOR_SPOT: [KlineIndicator; 2] = [KlineIndicator::Volume, KlineIndicator::CumulativeDelta];
34    /// Indicators that can be used with perpetual swap market tickers
35    const FOR_PERPS: [KlineIndicator; 3] = [
36        KlineIndicator::Volume,
37        KlineIndicator::CumulativeDelta,
38        KlineIndicator::OpenInterest,
39    ];
40}
41
42impl Display for KlineIndicator {
43    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44        match self {
45            KlineIndicator::Volume => write!(f, "Volume"),
46            KlineIndicator::CumulativeDelta => write!(f, "CVD"),
47            KlineIndicator::OpenInterest => write!(f, "Open Interest"),
48        }
49    }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize, Eq, Enum)]
53pub enum HeatmapIndicator {
54    Volume,
55}
56
57impl Indicator for HeatmapIndicator {
58    fn for_market(market: MarketKind) -> &'static [Self] {
59        match market {
60            MarketKind::Spot => &Self::FOR_SPOT,
61            MarketKind::LinearPerps | MarketKind::InversePerps => &Self::FOR_PERPS,
62        }
63    }
64}
65
66impl HeatmapIndicator {
67    // Indicator togglers on UI menus depend on these arrays.
68    // Every variant needs to be in either SPOT, PERPS or both.
69    /// Indicators that can be used with spot market tickers
70    const FOR_SPOT: [HeatmapIndicator; 1] = [HeatmapIndicator::Volume];
71    /// Indicators that can be used with perpetual swap market tickers
72    const FOR_PERPS: [HeatmapIndicator; 1] = [HeatmapIndicator::Volume];
73}
74
75impl Display for HeatmapIndicator {
76    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77        match self {
78            HeatmapIndicator::Volume => write!(f, "Volume"),
79        }
80    }
81}
82
83#[derive(Debug, Clone, Copy)]
84/// Temporary workaround,
85/// represents any indicator type in the UI
86pub enum UiIndicator {
87    Heatmap(HeatmapIndicator),
88    Kline(KlineIndicator),
89}
90
91impl From<KlineIndicator> for UiIndicator {
92    fn from(k: KlineIndicator) -> Self {
93        UiIndicator::Kline(k)
94    }
95}
96
97impl From<HeatmapIndicator> for UiIndicator {
98    fn from(h: HeatmapIndicator) -> Self {
99        UiIndicator::Heatmap(h)
100    }
101}