Change MACD calculation

This commit is contained in:
Sik Yoon 2023-12-31 19:04:38 +09:00
parent 662d531bbd
commit d559e51c25
5 changed files with 143 additions and 63 deletions

View File

@ -18,7 +18,7 @@ use crate::value_estimation_team::indicators::ema::{ema, EmaData};
use crate::value_estimation_team::indicators::heatmap_volume::{ use crate::value_estimation_team::indicators::heatmap_volume::{
heatmap_volume, HeatMapLevel, HeatmapVolumeData, heatmap_volume, HeatMapLevel, HeatmapVolumeData,
}; };
use crate::value_estimation_team::indicators::macd::{ema_macd, EmaMacd}; use crate::value_estimation_team::indicators::macd::{ema_macd, MacdData};
use crate::value_estimation_team::indicators::rsi::{rsi, RsiData}; use crate::value_estimation_team::indicators::rsi::{rsi, RsiData};
use crate::value_estimation_team::indicators::sma::{sma, SmaData}; use crate::value_estimation_team::indicators::sma::{sma, SmaData};
use crate::value_estimation_team::indicators::stoch_rsi::{stoch_rsi, StochRsiData}; use crate::value_estimation_team::indicators::stoch_rsi::{stoch_rsi, StochRsiData};

View File

@ -37,6 +37,7 @@ pub async fn execute_list_up_for_buy(
// let all_data_c4 = all_data.clone(); // let all_data_c4 = all_data.clone();
let all_data_c5 = all_data.clone(); let all_data_c5 = all_data.clone();
let all_data_c6 = all_data.clone(); let all_data_c6 = all_data.clone();
let all_data_ct = all_data.clone();
// strategist_001(all_data).await?; // strategist_001(all_data).await?;
// strategist_002(all_data).await?; // strategist_002(all_data).await?;
// task_vec.push(tokio::spawn(async move { // task_vec.push(tokio::spawn(async move {
@ -51,6 +52,9 @@ pub async fn execute_list_up_for_buy(
task_vec.push(tokio::spawn(async move { task_vec.push(tokio::spawn(async move {
crate::strategy_team::strategy_006::list_up_for_buy(all_data_c6).await; crate::strategy_team::strategy_006::list_up_for_buy(all_data_c6).await;
})); }));
task_vec.push(tokio::spawn(async move {
crate::strategy_team::strategy_test::strategist_test(all_data_ct).await;
}));
try_join_all(task_vec).await?; try_join_all(task_vec).await?;
Ok(()) Ok(())

View File

@ -2,7 +2,7 @@ use super::{
dec, decimal_add, decimal_sub, ema, exists_record, insert_pre_suggested_coins, dec, decimal_add, decimal_sub, ema, exists_record, insert_pre_suggested_coins,
limit_order_sell, rsi, select_filled_buy_orders, stoch_rsi, supertrend, try_join_all, AllData, limit_order_sell, rsi, select_filled_buy_orders, stoch_rsi, supertrend, try_join_all, AllData,
Arc, Client, ClientBuilder, Decimal, EmaData, ExchangeInfo, FilteredData, Mutex, Arc, Client, ClientBuilder, Decimal, EmaData, ExchangeInfo, FilteredData, Mutex,
RealtimePriceData, RoundingStrategy, RsiData, StochRsiData, SupertrendData, TradeFee, update_record3, adx, AdxData RealtimePriceData, RoundingStrategy, RsiData, StochRsiData, SupertrendData, TradeFee, update_record3, adx, AdxData, MacdData, ema_macd
}; };
@ -25,7 +25,7 @@ pub async fn strategist_test(
// test_symbols.push(symbol_2); // test_symbols.push(symbol_2);
// test_symbols.push(symbol_3); // test_symbols.push(symbol_3);
let a = adx(10, 10, &alldata.rt_price_30m_vec, &test_symbols).await?; let a = ema_macd(3, 7, 3, &alldata.rt_price_1d_vec, &test_symbols).await?;
println!("{:?}", a); println!("{:?}", a);
Ok(()) Ok(())

View File

@ -2,7 +2,6 @@
#![allow(warnings)] #![allow(warnings)]
use crate::database_control::*; use crate::database_control::*;
use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; use crate::value_estimation_team::datapoints::price_data::RealtimePriceData;
use csv::{DeserializeRecordsIter, StringRecord};
use futures::future::try_join_all; use futures::future::try_join_all;
use serde::Deserialize; use serde::Deserialize;
use sqlx::FromRow; use sqlx::FromRow;

View File

@ -1,15 +1,38 @@
use crate::value_estimation_team::indicators::ema::EmaData; use crate::value_estimation_team::indicators::ema::{EmaData, ema};
use crate::value_estimation_team::datapoints::price_data::RealtimePriceData;
use super::FilteredData;
use std::sync::Arc;
use tokio::{fs::*, io::AsyncWriteExt, sync::Mutex, time::*};
use futures::future::try_join_all;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct EmaMacd { pub struct MacdData {
pub macd_value: f64, pub macd_value: f64,
pub signal_value: f64,
pub close_time: i64, pub close_time: i64,
} }
impl EmaMacd { impl MacdData {
fn new() -> EmaMacd { fn new() -> MacdData {
let a = EmaMacd { let a = MacdData {
macd_value: 0.0, macd_value: 0.0,
signal_value: 0.0,
close_time: 0,
};
a
}
}
#[derive(Debug, Clone)]
pub struct TempData {
pub value: f64,
pub close_time: i64,
}
impl TempData {
fn new() -> TempData {
let a = TempData {
value: 0.0,
close_time: 0, close_time: 0,
}; };
a a
@ -17,16 +40,32 @@ impl EmaMacd {
} }
pub async fn ema_macd( pub async fn ema_macd(
fast_ema: &Vec<EmaData>, fast_len: usize,
slow_ema: &Vec<EmaData>, slow_len: usize,
signal_length: usize, signal_smoothing: usize,
) -> Result<Vec<EmaMacd>, Box<dyn std::error::Error + Send + Sync>> { input_rt_data: &Vec<(String, Vec<RealtimePriceData>)>,
let mut macd = EmaMacd::new(); filtered_symbols: &Vec<FilteredData>
let mut macd_vec: Vec<EmaMacd> = Vec::new(); ) -> Result<Vec<(String, Vec<MacdData>)>, Box<dyn std::error::Error + Send + Sync>> {
let mut macd_signal_vec: Vec<EmaMacd> = Vec::new(); let mut macd_oscil_vec: Vec<(String, Vec<MacdData>)> = Vec::new();
let mut macd_oscil_vec: Vec<EmaMacd> = Vec::new();
if fast_ema.len() >= signal_length && slow_ema.len() >= signal_length { let fast_emas = ema(fast_len, input_rt_data, filtered_symbols).await?;
let slow_emas = ema(slow_len, input_rt_data, filtered_symbols).await?;
let mut macd_data_wrapper: Vec<(String, Vec<MacdData>)> = Vec::new();
let mut macd_data_wrapper_arc = Arc::new(Mutex::new(macd_data_wrapper));
let mut task_vec = Vec::new();
for filtered_elem in filtered_symbols {
let fast_emas_c = fast_emas.clone();
let slow_emas_c = slow_emas.clone();
let filtered_elem_c = filtered_elem.clone();
let macd_data_wrapper_arc_c = Arc::clone(&macd_data_wrapper_arc);
task_vec.push(tokio::spawn(async move {
let fast_search_result = fast_emas_c.iter().position(|x| x.0 == filtered_elem_c.symbol);
let slow_search_result = slow_emas_c.iter().position(|x| x.0 == filtered_elem_c.symbol);
if fast_search_result.is_some_and(|a| fast_emas_c[a].1.len() >= signal_smoothing) &&
slow_search_result.is_some_and(|a| slow_emas_c[a].1.len() >= signal_smoothing) {
let fast_ema = fast_emas_c[fast_search_result.unwrap()].1.clone();
let slow_ema = slow_emas_c[fast_search_result.unwrap()].1.clone();
let result = fast_ema.binary_search_by_key( let result = fast_ema.binary_search_by_key(
&slow_ema.first().unwrap().close_time, &slow_ema.first().unwrap().close_time,
|&EmaData { |&EmaData {
@ -35,49 +74,87 @@ pub async fn ema_macd(
}| close_time, }| close_time,
); );
if result.is_ok() { if result.is_ok() {
// making MACD
let temp_vec = fast_ema.get(result.unwrap()..).unwrap(); let temp_vec = fast_ema.get(result.unwrap()..).unwrap();
let zipped = temp_vec.iter().zip(slow_ema); let zipped = temp_vec.iter().zip(slow_ema);
let mut macd = TempData::new();
let mut macd_vec: Vec<TempData> = Vec::new();
for element in zipped { for element in zipped {
macd.macd_value = element.0.ema_value - element.1.ema_value; macd.value = element.0.ema_value - element.1.ema_value;
macd.close_time = element.0.close_time; macd.close_time = element.0.close_time;
macd_vec.push(macd.clone()); macd_vec.push(macd.clone());
} }
// making signal // making signal (smoothed MACD)
let macd_vec_window = macd_vec.windows(signal_length); // TODO: this should be calculated in EMA (currently, SMA)
for window in macd_vec_window { // let macd_vec_window = macd_vec.windows(signal_smoothing);
let mut sum_value = 0.0; // let mut macd_signal_vec: Vec<TempData> = Vec::new();
for element in window { // for window in macd_vec_window {
sum_value += element.macd_value; // let mut sum_value = 0.0;
// for element in window {
// sum_value += element.value;
// }
// macd.value = sum_value / signal_smoothing as f64;
// macd.close_time = window.last().unwrap().close_time;
// macd_signal_vec.push(macd.clone());
// }
let mut macd_signal = TempData::new();
let mut macd_signal_vec: Vec<TempData> = Vec::new();
let partial_vec1 = macd_vec.get(..signal_smoothing).unwrap();
let partial_vec2 = macd_vec.get(signal_smoothing..).unwrap();
let mut sma_for_initial_value = 0.0;
for element in partial_vec1 {
sma_for_initial_value += element.value;
} }
macd.macd_value = sum_value / signal_length as f64; sma_for_initial_value /= signal_smoothing as f64;
macd.close_time = window.last().unwrap().close_time;
macd_signal_vec.push(macd.clone()); macd_signal.value = sma_for_initial_value;
macd_signal.close_time = partial_vec1.last().unwrap().close_time;
macd_signal_vec.push(macd_signal.clone());
let alpha: f64 = 2.0 / (signal_smoothing as f64 + 1.0);
let mut ema_prev = sma_for_initial_value;
for element in partial_vec2 {
let ema_t = (1.0 - alpha) * ema_prev + alpha * element.value;
macd_signal.value = ema_t;
macd_signal.close_time = element.close_time;
macd_signal_vec.push(macd_signal.clone());
ema_prev = ema_t;
} }
let result = macd_vec.binary_search_by_key( let result = macd_vec.binary_search_by_key(
&macd_signal_vec.first().unwrap().close_time, &macd_signal_vec.first().unwrap().close_time,
|&EmaMacd { |&TempData {
macd_value, value,
close_time, close_time,
}| close_time, }| close_time,
); );
if result.is_ok() { if result.is_ok() {
let result = macd_vec.get(result.unwrap()..); let result = macd_vec.get(result.unwrap()..);
if result.is_some() { if result.is_some() {
if result.unwrap().len() == macd_signal_vec.len() {
let zipped = result.unwrap().iter().zip(macd_signal_vec); let zipped = result.unwrap().iter().zip(macd_signal_vec);
let mut macd_vec: Vec<MacdData> = Vec::new();
for element in zipped { for element in zipped {
macd.macd_value = element.0.macd_value - element.1.macd_value; let mut macd = MacdData::new();
macd.macd_value = element.0.value;
macd.signal_value = element.1.value;
macd.close_time = element.0.close_time; macd.close_time = element.0.close_time;
macd_oscil_vec.push(macd.clone()); macd_vec.push(macd);
}
let mut macd_data_wrapper_lock = macd_data_wrapper_arc_c.lock().await;
macd_data_wrapper_lock.push((filtered_elem_c.symbol.clone(), macd_vec.clone()));
} }
} }
} }
} }
}));
} }
} try_join_all(task_vec).await?;
let a = macd_data_wrapper_arc.lock().await.to_owned();
Ok(macd_oscil_vec) Ok(a)
} }