Skip to main content

quantwave_core/indicators/patterns/
cdlgravestonedoji.rs

1//! Native O(1) streaming CDLGRAVESTONEDOJI (matches `talib_rs::pattern::cdl_gravestonedoji`).
2//! Source: TA-Lib
3
4use crate::indicators::patterns::candle_settings::{
5    BODY_DOJI, CandleWindow, RollingCandleAvg, SHADOW_VERY_SHORT, lower_shadow, real_body,
6    upper_shadow,
7};
8use crate::traits::Next;
9
10const LOOKBACK: usize = 10; // max(10, 10)
11
12#[derive(Debug, Clone)]
13#[allow(non_camel_case_types)]
14pub struct CDLGRAVESTONEDOJI {
15    bars_seen: usize,
16    window: CandleWindow,
17    body_doji: RollingCandleAvg,
18    shadow_vs: RollingCandleAvg,
19}
20
21impl CDLGRAVESTONEDOJI {
22    pub fn new() -> Self {
23        Self {
24            bars_seen: 0,
25            window: CandleWindow::new(1),
26            body_doji: RollingCandleAvg::new(BODY_DOJI),
27            shadow_vs: RollingCandleAvg::new(SHADOW_VERY_SHORT),
28        }
29    }
30}
31
32impl Default for CDLGRAVESTONEDOJI {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl Next<(f64, f64, f64, f64)> for CDLGRAVESTONEDOJI {
39    type Output = f64;
40
41    fn next(&mut self, (open, high, low, close): (f64, f64, f64, f64)) -> Self::Output {
42        self.bars_seen += 1;
43        self.window.push(open, high, low, close);
44        self.body_doji.push(open, high, low, close);
45        self.shadow_vs.push(open, high, low, close);
46
47        if self.bars_seen <= LOOKBACK {
48            return 0.0;
49        }
50
51        let curr = self.window.bar(0);
52
53        let out = (real_body(curr.open, curr.close) <= self.body_doji.val(0)
54            && lower_shadow(curr.open, curr.low, curr.close) < self.shadow_vs.val(0)
55            && upper_shadow(curr.open, curr.high, curr.close) > self.shadow_vs.val(0))
56            as i32
57            * 100;
58
59        out as f64
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66    crate::test_pattern_parity!(
67        test_cdlgravestonedoji_parity,
68        CDLGRAVESTONEDOJI,
69        talib_rs::pattern::cdl_gravestonedoji,
70        |o: &mut Vec<f64>, h: &mut Vec<f64>, l: &mut Vec<f64>, c: &mut Vec<f64>| {
71            // Provide 11 bars to establish shadow/body averages
72            for _ in 0..11 {
73                o.push(100.0);
74                h.push(110.0);
75                l.push(90.0);
76                c.push(100.0);
77            }
78            // A gravestone doji: Open and close are equal and at the low of the bar,
79            // with a long upper shadow.
80            o.push(100.0);
81            h.push(150.0);
82            l.push(100.0);
83            c.push(100.0);
84        }
85    );
86}