mantis_ta/indicators/support_resistance/
pivot_points.rs1use crate::indicators::Indicator;
2use crate::types::{Candle, PivotOutput};
3
4#[derive(Debug, Clone)]
32pub struct PivotPoints;
33
34impl PivotPoints {
35 pub fn new() -> Self {
36 Self
37 }
38}
39
40impl Default for PivotPoints {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46impl Indicator for PivotPoints {
47 type Output = PivotOutput;
48
49 fn next(&mut self, candle: &Candle) -> Option<Self::Output> {
50 let pp = (candle.high + candle.low + candle.close) / 3.0;
51 let r1 = 2.0 * pp - candle.low;
52 let s1 = 2.0 * pp - candle.high;
53 let r2 = pp + (candle.high - candle.low);
54 let s2 = pp - (candle.high - candle.low);
55 let r3 = candle.high + 2.0 * (pp - candle.low);
56 let s3 = candle.low - 2.0 * (candle.high - pp);
57
58 Some(PivotOutput {
59 pp,
60 r1,
61 r2,
62 r3,
63 s1,
64 s2,
65 s3,
66 })
67 }
68
69 fn reset(&mut self) {}
70
71 fn warmup_period(&self) -> usize {
72 0
73 }
74
75 fn clone_boxed(&self) -> Box<dyn Indicator<Output = Self::Output>> {
76 Box::new(self.clone())
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn computes_pivots() {
86 let mut pivots = PivotPoints::new();
87 let candle = Candle {
88 timestamp: 0,
89 open: 0.0,
90 high: 12.0,
91 low: 8.0,
92 close: 10.0,
93 volume: 0.0,
94 };
95 let out = pivots.next(&candle).unwrap();
96 assert_eq!(out.pp, 10.0);
97 assert_eq!(out.r1, 12.0);
98 assert_eq!(out.s1, 8.0);
99 }
100}