kestrel_chartkit/analytics/
position.rs1use crate::{Agreement, SignalDirection};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[cfg_attr(
6 feature = "serde",
7 derive(serde::Serialize),
8 serde(rename_all = "snake_case")
9)]
10pub enum PositionAlignment {
11 Aligned,
12 Opposed,
13 Neutral,
14 Conflict,
15 Unconfigured,
16}
17
18pub fn position_alignment(
19 position: SignalDirection,
20 recommendation: Option<&Agreement>,
21) -> PositionAlignment {
22 let Some(recommendation) = recommendation else {
23 return PositionAlignment::Unconfigured;
24 };
25 if recommendation.conflict {
26 PositionAlignment::Conflict
27 } else if recommendation.direction == SignalDirection::Neutral
28 || position == SignalDirection::Neutral
29 {
30 PositionAlignment::Neutral
31 } else if recommendation.direction == position {
32 PositionAlignment::Aligned
33 } else {
34 PositionAlignment::Opposed
35 }
36}
37
38pub fn atr_distance(entry: f64, current: f64, atr: f64) -> Option<f64> {
40 (atr > 0.0).then_some((current - entry).abs() / atr)
41}