use crate::value_estimation_team::indicators::ema::EmaData; #[derive(Debug, Clone)] pub struct EmaMacd { pub macd_value: f64, pub close_time: i64, } impl EmaMacd { fn new() -> EmaMacd { let a = EmaMacd { macd_value: 0.0, close_time: 0, }; a } } pub async fn ema_macd( fast_ema: &Vec, slow_ema: &Vec, signal_length: usize, ) -> Result, Box> { let mut macd = EmaMacd::new(); let mut macd_vec: Vec = Vec::new(); let mut macd_signal_vec: Vec = Vec::new(); let mut macd_oscil_vec: Vec = Vec::new(); if fast_ema.len() >= signal_length && slow_ema.len() >= signal_length { let result = fast_ema.binary_search_by_key( &slow_ema.first().unwrap().close_time, |&EmaData { ema_value, close_time, }| close_time, ); if result.is_ok() { let temp_vec = fast_ema.get(result.unwrap()..).unwrap(); let zipped = temp_vec.iter().zip(slow_ema); for element in zipped { macd.macd_value = element.0.ema_value - element.1.ema_value; macd.close_time = element.0.close_time; macd_vec.push(macd.clone()); } // making signal let macd_vec_window = macd_vec.windows(signal_length); for window in macd_vec_window { let mut sum_value = 0.0; for element in window { sum_value += element.macd_value; } macd.macd_value = sum_value / signal_length as f64; macd.close_time = window.last().unwrap().close_time; macd_signal_vec.push(macd.clone()); } let result = macd_vec.binary_search_by_key( &macd_signal_vec.first().unwrap().close_time, |&EmaMacd { macd_value, close_time, }| close_time, ); if result.is_ok() { let result = macd_vec.get(result.unwrap()..); if result.is_some() { if result.unwrap().len() == macd_signal_vec.len() { let zipped = result.unwrap().iter().zip(macd_signal_vec); for element in zipped { macd.macd_value = element.0.macd_value - element.1.macd_value; macd.close_time = element.0.close_time; macd_oscil_vec.push(macd.clone()); } } } } } } Ok(macd_oscil_vec) }