#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PivotArtifact {
pub timestamp: i64,
pub price: f64,
pub is_high: bool,
pub confirmed: bool,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ZoneArtifact {
pub kind: String,
pub price_top: f64,
pub price_bottom: f64,
pub strength: f64,
pub touches: u32,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ProfileBin {
pub price_low: f64,
pub price_high: f64,
pub value: f64,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ProfileArtifact {
pub kind: String,
pub bins: Vec<ProfileBin>,
pub poc: f64,
pub value_area_high: f64,
pub value_area_low: f64,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ScenarioArtifact {
pub name: String,
pub stage: String,
pub progress: f64,
pub invalidated: bool,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Artifact {
Pivot(PivotArtifact),
Zone(ZoneArtifact),
Profile(ProfileArtifact),
Scenario(ScenarioArtifact),
}
impl From<PivotArtifact> for Artifact {
fn from(value: PivotArtifact) -> Self {
Artifact::Pivot(value)
}
}
impl From<ZoneArtifact> for Artifact {
fn from(value: ZoneArtifact) -> Self {
Artifact::Zone(value)
}
}
impl From<ProfileArtifact> for Artifact {
fn from(value: ProfileArtifact) -> Self {
Artifact::Profile(value)
}
}
impl From<ScenarioArtifact> for Artifact {
fn from(value: ScenarioArtifact) -> Self {
Artifact::Scenario(value)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_artifact_conversions() {
let pivot = PivotArtifact {
timestamp: 1_000,
price: 100.0,
is_high: true,
confirmed: true,
};
let artifact: Artifact = pivot.into();
assert!(matches!(artifact, Artifact::Pivot(p) if p.price == 100.0));
let zone = ZoneArtifact {
kind: "order_block".to_string(),
price_top: 105.0,
price_bottom: 100.0,
strength: 0.8,
touches: 2,
};
let artifact: Artifact = zone.into();
assert!(matches!(artifact, Artifact::Zone(z) if z.touches == 2));
}
}