1#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub struct BarInput {
15 pub index: usize,
16 pub timestamp_us: i64,
17 pub high: i64,
19 pub low: i64,
21 pub close: i64,
23 pub duration_us: Option<i64>,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30pub enum PivotKind {
31 High,
32 Low,
33}
34
35impl PivotKind {
36 #[must_use]
37 pub fn opposite(self) -> Self {
38 match self {
39 Self::High => Self::Low,
40 Self::Low => Self::High,
41 }
42 }
43}
44
45impl std::fmt::Display for PivotKind {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 match self {
48 Self::High => write!(f, "High"),
49 Self::Low => write!(f, "Low"),
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
60pub enum ConfirmationStatus {
61 Confirmed {
62 confirmed_at_bar: usize,
64 generation: u64,
66 },
67 Pending,
68}
69
70impl ConfirmationStatus {
71 #[must_use]
72 pub fn is_confirmed(&self) -> bool {
73 matches!(self, Self::Confirmed { .. })
74 }
75
76 #[must_use]
77 pub fn is_pending(&self) -> bool {
78 matches!(self, Self::Pending)
79 }
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
84#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
85pub struct Pivot {
86 pub bar_index: usize,
87 pub timestamp_us: i64,
88 pub price: i64,
90 pub kind: PivotKind,
91 pub status: ConfirmationStatus,
92}
93
94#[derive(Debug, Clone)]
96pub struct ZigZagOutput {
97 pub pending: Option<Pivot>,
99 pub newly_confirmed: Option<Pivot>,
101 pub pending_updated: bool,
103 pub completed_segment: Option<Segment>,
105}
106
107impl ZigZagOutput {
108 #[must_use]
109 pub fn has_event(&self) -> bool {
110 self.newly_confirmed.is_some() || self.pending_updated || self.completed_segment.is_some()
111 }
112}
113
114#[derive(Debug, Clone)]
118#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
119pub struct Segment {
120 pub l0: Pivot,
122 pub h1: Pivot,
124 pub l2: Pivot,
126 pub segment_size: i64,
128 pub z: f64,
131 pub base_class: BaseClass,
133}
134
135#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
142pub enum BaseClass {
143 EL,
144 HL,
145 LL,
146}
147
148impl std::fmt::Display for BaseClass {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 match self {
151 Self::EL => write!(f, "EL"),
152 Self::HL => write!(f, "HL"),
153 Self::LL => write!(f, "LL"),
154 }
155 }
156}