quantwave_core/indicators/patterns/
cdlclosingmarubozu.rs1use crate::indicators::patterns::candle_settings::{
5 BODY_LONG, CandleWindow, RollingCandleAvg, SHADOW_VERY_SHORT, candle_color, lower_shadow,
6 real_body, upper_shadow,
7};
8use crate::traits::Next;
9
10const LOOKBACK: usize = 10; #[derive(Debug, Clone)]
13#[allow(non_camel_case_types)]
14pub struct CDLCLOSINGMARUBOZU {
15 bars_seen: usize,
16 window: CandleWindow,
17 body_long: RollingCandleAvg,
18 shadow_vs: RollingCandleAvg,
19}
20
21impl CDLCLOSINGMARUBOZU {
22 pub fn new() -> Self {
23 Self {
24 bars_seen: 0,
25 window: CandleWindow::new(1), body_long: RollingCandleAvg::new(BODY_LONG),
27 shadow_vs: RollingCandleAvg::new(SHADOW_VERY_SHORT),
28 }
29 }
30}
31
32impl Default for CDLCLOSINGMARUBOZU {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl Next<(f64, f64, f64, f64)> for CDLCLOSINGMARUBOZU {
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_long.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 long_body = real_body(curr.open, curr.close) > self.body_long.val(0);
54 let bull = long_body
55 && candle_color(curr.open, curr.close) == 1
56 && upper_shadow(curr.open, curr.high, curr.close) < self.shadow_vs.val(0);
57 let bear = long_body
58 && candle_color(curr.open, curr.close) == -1
59 && lower_shadow(curr.open, curr.low, curr.close) < self.shadow_vs.val(0);
60
61 ((bull as i32) * 100 - (bear as i32) * 100) as f64
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 crate::test_pattern_parity!(
69 test_cdlclosingmarubozu_parity,
70 CDLCLOSINGMARUBOZU,
71 talib_rs::pattern::cdl_closingmarubozu
72 );
73}