#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BarInput {
pub index: usize,
pub timestamp_us: i64,
pub high: i64,
pub low: i64,
pub close: i64,
pub duration_us: Option<i64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PivotKind {
High,
Low,
}
impl PivotKind {
#[must_use]
pub fn opposite(self) -> Self {
match self {
Self::High => Self::Low,
Self::Low => Self::High,
}
}
}
impl std::fmt::Display for PivotKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::High => write!(f, "High"),
Self::Low => write!(f, "Low"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ConfirmationStatus {
Confirmed {
confirmed_at_bar: usize,
generation: u64,
},
Pending,
}
impl ConfirmationStatus {
#[must_use]
pub fn is_confirmed(&self) -> bool {
matches!(self, Self::Confirmed { .. })
}
#[must_use]
pub fn is_pending(&self) -> bool {
matches!(self, Self::Pending)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Pivot {
pub bar_index: usize,
pub timestamp_us: i64,
pub price: i64,
pub kind: PivotKind,
pub status: ConfirmationStatus,
}
#[derive(Debug, Clone)]
pub struct ZigZagOutput {
pub pending: Option<Pivot>,
pub newly_confirmed: Option<Pivot>,
pub pending_updated: bool,
pub completed_segment: Option<Segment>,
pub completed_formation: Option<Formation>,
}
impl ZigZagOutput {
#[must_use]
pub fn has_event(&self) -> bool {
self.newly_confirmed.is_some()
|| self.pending_updated
|| self.completed_segment.is_some()
|| self.completed_formation.is_some()
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Segment {
pub l0: Pivot,
pub h1: Pivot,
pub l2: Pivot,
pub segment_size: i64,
pub z: f64,
pub base_class: BaseClass,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BaseClass {
EL,
HL,
LL,
}
impl std::fmt::Display for BaseClass {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::EL => write!(f, "EL"),
Self::HL => write!(f, "HL"),
Self::LL => write!(f, "LL"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum HighClass {
HH,
EH,
LH,
}
impl std::fmt::Display for HighClass {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::HH => write!(f, "HH"),
Self::EH => write!(f, "EH"),
Self::LH => write!(f, "LH"),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Formation {
pub l0: Pivot,
pub h1: Pivot,
pub l2: Pivot,
pub h3: Pivot,
pub base_class: BaseClass,
pub high_class: HighClass,
pub z_low: f64,
pub z_high: f64,
pub first_leg_size: i64,
pub second_leg_size: i64,
}