use core::fmt;
use anyhow::Ok;
use crate::{model::binance_model::{Kline, Klines}, utils};
pub fn ema(prices : &[f64], period : usize) -> Vec<f64> {
let k = 2.0 / ( period as f64 + 1.0);
let mut ema_values = Vec::new();
let sma: f64 = prices[..period].iter().sum::<f64>() / period as f64;
ema_values.push(sma);
for price in prices.iter() {
let prev_ema = *ema_values.last().unwrap();
let ema = (price * k) + (prev_ema * (1.0 - k));
ema_values.push(ema);
}
ema_values.remove(0);
return ema_values;
}
#[derive(Clone, serde::Serialize, Default)]
pub struct EMA {
open_time: u64,
close_time: u64,
period: usize,
ema_data: f64,
pub idx: usize,
}
impl EMA {
pub fn new(open_time: u64, close_time: u64, period: usize, ema_data: f64, idx: usize) -> Self {
Self {
open_time,
close_time,
period,
ema_data,
idx
}
}
pub fn get_ema_data(&self) -> f64 {
self.ema_data
}
}
impl fmt::Debug for EMA {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let open_time = utils::timestamp_to_local(self.open_time as i64).map_err(|e| std::fmt::Error)?;
let close_time = utils::timestamp_to_local(self.close_time as i64).map_err(|e| std::fmt::Error)?;
write!(f, "EMA: {{\n open_time: {},\n close_time: {},\n period: {},\n ema_data: {}\n}}", open_time, close_time, self.period, self.ema_data)
}
}
pub fn ema_kline(prices : Klines, period : usize) -> Vec<EMA> {
let k = 2.0 / ( period as f64 + 1.0);
let mut ema_values = Vec::new();
let sma: f64 = prices.kline_list[..period].iter().map(|k| {
k.close
}).sum::<f64>() / period as f64;
ema_values.push(EMA::new(0, 0, 0, sma, 0));
for (idx, kline) in prices.kline_list.iter().enumerate() {
let prev_ema = ema_values.last().unwrap().ema_data;
let ema = (kline.close * k) + (prev_ema * (1.0 - k));
ema_values.push(EMA::new(kline.open_time, kline.close_time, period, ema, idx));
}
ema_values.remove(0);
return ema_values;
}
pub fn calculate_disparity(ema: f64, price: f64) -> f64 {
(price - ema) / price * 100.0
}