flowsurface_data/chart/kline/indicators/core/
input.rs1use exchange::UnixMs;
2use std::collections::BTreeMap;
3
4#[derive(Debug, Clone, Default, PartialEq)]
10pub struct OpenInterestSeries {
11 pub values: BTreeMap<UnixMs, f64>,
12}
13
14impl OpenInterestSeries {
15 pub fn from_points(points: impl IntoIterator<Item = (UnixMs, f64)>) -> Self {
16 let mut series = Self::default();
17 series.extend(points);
18 series
19 }
20
21 pub fn extend(&mut self, points: impl IntoIterator<Item = (UnixMs, f64)>) {
22 for (time, value) in points {
23 if value.is_finite() {
24 self.values.insert(time, value);
25 }
26 }
27 }
28
29 pub fn merge(&mut self, other: &Self) {
30 self.extend(other.values.iter().map(|(&time, &value)| (time, value)));
31 }
32
33 pub fn value_at(&self, timestamp: UnixMs) -> Option<f64> {
34 self.values.get(×tamp).copied()
35 }
36
37 pub fn latest_at_or_before(&self, timestamp: UnixMs) -> Option<f64> {
38 self.values
39 .range(..=timestamp)
40 .next_back()
41 .map(|(_, value)| *value)
42 }
43
44 pub fn covered_range(&self) -> Option<(UnixMs, UnixMs)> {
45 Some((
46 *self.values.first_key_value()?.0,
47 *self.values.last_key_value()?.0,
48 ))
49 }
50
51 pub fn is_empty(&self) -> bool {
52 self.values.is_empty()
53 }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57pub enum IndicatorInputSource {
58 Klines,
59 DirectionalVolume,
60 Trades,
61 OpenInterest,
62}
63
64impl IndicatorInputSource {
65 pub const fn id(self) -> &'static str {
66 match self {
67 Self::Klines => "klines",
68 Self::DirectionalVolume => "directional_volume",
69 Self::Trades => "trades",
70 Self::OpenInterest => "open_interest",
71 }
72 }
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq)]
76pub struct IndicatorInputRequirement {
77 pub source: IndicatorInputSource,
78 required: bool,
79}
80
81impl IndicatorInputRequirement {
82 pub const fn required(source: IndicatorInputSource) -> Self {
83 Self {
84 source,
85 required: true,
86 }
87 }
88
89 pub const fn optional(source: IndicatorInputSource) -> Self {
90 Self {
91 source,
92 required: false,
93 }
94 }
95
96 pub const fn is_required(self) -> bool {
97 self.required
98 }
99
100 pub const fn id(self) -> &'static str {
101 self.source.id()
102 }
103}