1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
#![feature(external_doc)] use ema_rs::EMA; use ta_common::traits::Indicator; #[doc(include = "../README.md")] pub struct MACD { long_period: u32, short_ema: EMA, long_ema: EMA, signal_ema: EMA, current: u32, } impl MACD { pub fn new(short_period: u32, long_period: u32, signal_period: u32) -> MACD { Self { long_period, short_ema: EMA::new(short_period), long_ema: EMA::new(long_period), signal_ema: EMA::new(signal_period), current: 0, } } } impl Indicator<f64, Option<[f64; 3]>> for MACD { fn next(&mut self, input: f64) -> Option<[f64; 3]> { self.current = self.current + 1; let short = self.short_ema.next(input); let long = self.long_ema.next(input); return if self.current >= self.long_period { let macd = short - long; let signal = self.signal_ema.next(macd); let histogram = macd - signal; Some([macd, signal, histogram]) } else { None }; } fn reset(&mut self) { self.long_ema.reset(); self.short_ema.reset(); self.signal_ema.reset(); self.current = 0; } } #[cfg(test)] mod tests { use crate::MACD; use ta_common::traits::Indicator; #[test] fn it_works() { let mut macd = MACD::new(2, 5, 9); assert_eq!(macd.next(81.59), None); assert_eq!(macd.next(81.06), None); assert_eq!(macd.next(82.87), None); assert_eq!(macd.next(83.00), None); assert_eq!(macd.next(83.61), Some([0.6177777777777749, 0.6177777777777749, 0.00])); assert_eq!(macd.next(83.15), Some([0.3512757201646082, 0.5644773662551416, -0.21320164609053338])); assert_eq!(macd.next(82.84), Some([0.11065843621399551, 0.4737135802469124, -0.3630551440329169])); assert_eq!(macd.next(83.99), Some([0.41593049839961793, 0.46215696387745353, -0.0462264654778356])); assert_eq!(macd.next(84.55), Some([0.5780064014631705, 0.48532685139459697, 0.09267955006857354])); assert_eq!(macd.next(84.36), Some([0.4222440684854689, 0.4727102948127714, -0.050466226327302466])); assert_eq!(macd.next(85.53), Some([0.6837982014936586, 0.5149278761489489, 0.1688703253447097])); assert_eq!(macd.next(86.54), Some([0.9266328529413386, 0.5972688715074268, 0.32936398143391177])); assert_eq!(macd.next(86.89), Some([0.8913443637205063, 0.6560839699500427, 0.2352603937704636])); assert_eq!(macd.next(87.77), Some([0.9787592852891009, 0.7206190330178543, 0.2581402522712466])); assert_eq!(macd.next(87.29), Some([0.6206827600178713, 0.7006317784178577, -0.07994901839998647])); } }