diff --git a/src/strategy_team/mod.rs b/src/strategy_team/mod.rs index 88f7703..e5dc6ca 100644 --- a/src/strategy_team/mod.rs +++ b/src/strategy_team/mod.rs @@ -30,6 +30,9 @@ use crate::value_estimation_team::indicators::supertrend::{ supertrend, SuperTrendArea, SuperTrendSignal, SupertrendData, }; use crate::value_estimation_team::indicators::tema::{tema, TemaData}; +use crate::value_estimation_team::indicators::wiliams_percent_r::{ + wiliams_percent_r, WiliamsPercentR, +}; use futures::future::try_join_all; use reqwest::{Client, ClientBuilder}; use rust_decimal::{prelude::FromPrimitive, prelude::ToPrimitive, Decimal, RoundingStrategy}; diff --git a/src/strategy_team/strategy_008.rs b/src/strategy_team/strategy_008.rs index 00d2c3b..bafaaa1 100644 --- a/src/strategy_team/strategy_008.rs +++ b/src/strategy_team/strategy_008.rs @@ -1,12 +1,14 @@ +use crate::value_estimation_team::indicators::wiliams_percent_r; + use super::{ adx, dec, decimal_add, decimal_div, decimal_mul, decimal_sub, dema, duplicate_filter, ema, ema_macd, exists_record, get_current_price, get_server_epoch, heatmap_volume, insert_pre_suggested_coins, limit_order_sell, remove_keys, rsi, select_filled_buy_orders, - stoch_rsi, supertrend, tema, try_join_all, update_record3, AdxData, AllData, Arc, - BollingerBandData, Client, ClientBuilder, Decimal, DemaData, EmaData, ExchangeInfo, + stoch_rsi, supertrend, tema, try_join_all, update_record3, wiliams_percent_r, AdxData, AllData, + Arc, BollingerBandData, Client, ClientBuilder, Decimal, DemaData, EmaData, ExchangeInfo, FilteredDataValue, HashMap, HashSet, HeatMapLevel, HeatmapVolumeData, MacdData, Mutex, RealtimePriceData, RoundingStrategy, RsiData, StochRsiData, SuperTrendArea, SuperTrendSignal, - SupertrendData, TemaData, ToPrimitive, TradeFee, + SupertrendData, TemaData, ToPrimitive, TradeFee, WiliamsPercentR, }; // BUY conditions @@ -49,6 +51,25 @@ pub async fn list_up_for_buy( // } // remove_keys(&mut filtered_data, keys_to_remove).await; + // Wiliams %R < -50.0 + let mut keys_to_remove: HashSet = HashSet::new(); + let mut wprs = wiliams_percent_r(200, &alldata.rt_price_30m_vec, &filtered_data).await?; + let server_epoch = get_server_epoch().await; + for (symbol, values) in &mut filtered_data { + if let Some(wpr_vec) = wprs.get(symbol) { + if wpr_vec.len() > 15 + && wpr_vec.last().unwrap().close_time > server_epoch + && wpr_vec.last().unwrap().r_value < -50.0 + { + } else { + keys_to_remove.insert(symbol.clone()); + } + } else { + keys_to_remove.insert(symbol.clone()); + } + } + remove_keys(&mut filtered_data, keys_to_remove).await; + // current Tema(300) < current Tema(200) < current Tema(100) // previous Tema(300) < previous Tema(100) // previous Tema(200) < previous Tema(100) @@ -62,24 +83,30 @@ pub async fn list_up_for_buy( if let (Some(tema100_vec), Some(tema200_vec), Some(tema300_vec)) = ( tema_100.get(symbol), tema_200.get(symbol), - tema_300.get(symbol) + tema_300.get(symbol), ) { - if (tema100_vec.len() > 15 - && tema200_vec.len() > 15 - && tema300_vec.len() > 15) + if (tema100_vec.len() > 15 && tema200_vec.len() > 15 && tema300_vec.len() > 15) && tema100_vec.last().unwrap().close_time == tema200_vec.last().unwrap().close_time && tema200_vec.last().unwrap().close_time == tema300_vec.last().unwrap().close_time && tema100_vec.last().unwrap().close_time > server_epoch { if tema100_vec.last().unwrap().tema_value > tema300_vec.last().unwrap().tema_value - && tema200_vec.last().unwrap().tema_value > tema300_vec.last().unwrap().tema_value - && tema200_vec.last().unwrap().tema_value < tema100_vec.last().unwrap().tema_value - && tema100_vec[tema100_vec.len() - 2].tema_value > tema300_vec[tema300_vec.len() - 2].tema_value - && tema200_vec[tema200_vec.len() - 2].tema_value < tema300_vec[tema300_vec.len() - 2].tema_value - && tema200_vec[tema200_vec.len() - 2].tema_value < tema100_vec[tema100_vec.len() - 2].tema_value - && tema100_vec[tema100_vec.len() - 3].tema_value > tema300_vec[tema300_vec.len() - 3].tema_value - && tema200_vec[tema200_vec.len() - 3].tema_value < tema300_vec[tema300_vec.len() - 3].tema_value - && tema200_vec[tema200_vec.len() - 3].tema_value < tema100_vec[tema100_vec.len() - 3].tema_value + && tema200_vec.last().unwrap().tema_value + > tema300_vec.last().unwrap().tema_value + && tema200_vec.last().unwrap().tema_value + < tema100_vec.last().unwrap().tema_value + && tema100_vec[tema100_vec.len() - 2].tema_value + > tema300_vec[tema300_vec.len() - 2].tema_value + && tema200_vec[tema200_vec.len() - 2].tema_value + < tema300_vec[tema300_vec.len() - 2].tema_value + && tema200_vec[tema200_vec.len() - 2].tema_value + < tema100_vec[tema100_vec.len() - 2].tema_value + && tema100_vec[tema100_vec.len() - 3].tema_value + > tema300_vec[tema300_vec.len() - 3].tema_value + && tema200_vec[tema200_vec.len() - 3].tema_value + < tema300_vec[tema300_vec.len() - 3].tema_value + && tema200_vec[tema200_vec.len() - 3].tema_value + < tema100_vec[tema100_vec.len() - 3].tema_value { } else { keys_to_remove.insert(symbol.clone()); @@ -174,29 +201,29 @@ pub async fn list_up_for_buy( // remove_keys(&mut filtered_data, keys_to_remove).await; // StochRSI (RSI_len: 200, StochRSI_len: 200, K: 3, D: 3) K_current < 70, K_prev < 70, K_prev_1 < 70 - let mut keys_to_remove: HashSet = HashSet::new(); - let stoch_rsis = stoch_rsi(200, 200, 3, 3, &alldata.rt_price_30m_vec, &filtered_data).await?; - for (symbol, values) in &mut filtered_data { - if stoch_rsis.contains_key(symbol) { - let stoch_rsi_vec = stoch_rsis.get(symbol).unwrap(); - let search_result = stoch_rsi_vec - .iter() - .position(|x| x.close_time == values.closetime); - if stoch_rsi_vec.len() > 10 - && search_result.is_some_and(|a| { - stoch_rsi_vec[a].k < 70.0 - && stoch_rsi_vec[a - 1].k < 70.0 - && stoch_rsi_vec[a - 2].k < 70.0 - }) - { - } else { - keys_to_remove.insert(symbol.clone()); - } - } else { - keys_to_remove.insert(symbol.clone()); - } - } - remove_keys(&mut filtered_data, keys_to_remove).await; + // let mut keys_to_remove: HashSet = HashSet::new(); + // let stoch_rsis = stoch_rsi(200, 200, 3, 3, &alldata.rt_price_30m_vec, &filtered_data).await?; + // for (symbol, values) in &mut filtered_data { + // if stoch_rsis.contains_key(symbol) { + // let stoch_rsi_vec = stoch_rsis.get(symbol).unwrap(); + // let search_result = stoch_rsi_vec + // .iter() + // .position(|x| x.close_time == values.closetime); + // if stoch_rsi_vec.len() > 10 + // && search_result.is_some_and(|a| { + // stoch_rsi_vec[a].k < 70.0 + // && stoch_rsi_vec[a - 1].k < 70.0 + // && stoch_rsi_vec[a - 2].k < 70.0 + // }) + // { + // } else { + // keys_to_remove.insert(symbol.clone()); + // } + // } else { + // keys_to_remove.insert(symbol.clone()); + // } + // } + // remove_keys(&mut filtered_data, keys_to_remove).await; // Heatmap volume: filtering close price with Extra High is over the previous candle from 30 previous candles let mut keys_to_remove: HashSet = HashSet::new(); @@ -212,8 +239,7 @@ pub async fn list_up_for_buy( ) .await?; for (symbol, values) in &mut filtered_data { - if stoch_rsis.contains_key(symbol) { - let heatmap_volume_vec = heatmap_volumes.get(symbol).unwrap(); + if let Some(heatmap_volume_vec) = heatmap_volumes.get(symbol) { if heatmap_volume_vec.len() > 50 { let heatmap_volume_trunc = heatmap_volume_vec .get(heatmap_volume_vec.len() - 31..heatmap_volume_vec.len() - 1) diff --git a/src/value_estimation_team/indicators/mod.rs b/src/value_estimation_team/indicators/mod.rs index 82aac14..ba2252e 100644 --- a/src/value_estimation_team/indicators/mod.rs +++ b/src/value_estimation_team/indicators/mod.rs @@ -9,6 +9,7 @@ pub mod sma; pub mod stoch_rsi; pub mod supertrend; pub mod tema; +pub mod wiliams_percent_r; use crate::strategy_team::FilteredDataValue; use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; diff --git a/src/value_estimation_team/indicators/wiliams_percent_r.rs b/src/value_estimation_team/indicators/wiliams_percent_r.rs new file mode 100644 index 0000000..ab7aa60 --- /dev/null +++ b/src/value_estimation_team/indicators/wiliams_percent_r.rs @@ -0,0 +1,83 @@ +#![allow(unused)] +#![allow(warnings)] + +use super::HashMap; +use crate::database_control::*; +use crate::strategy_team::FilteredDataValue; +use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; +use futures::future::try_join_all; +use serde::Deserialize; +use sqlx::FromRow; +use std::sync::Arc; +use tokio::{fs::*, io::AsyncWriteExt, sync::Mutex, time::*}; + +#[derive(Clone, Debug)] +pub struct WiliamsPercentR { + pub r_value: f64, + pub close_time: i64, +} +impl WiliamsPercentR { + fn new() -> WiliamsPercentR { + let a = WiliamsPercentR { + r_value: 0.0, + close_time: 0, + }; + a + } +} + +// Binance Wiliams %R +pub async fn wiliams_percent_r( + period: usize, + input_rt_data: &HashMap>, + filtered_symbols: &HashMap, +) -> Result>, Box> { + if filtered_symbols.is_empty() { + Err("Err")?; + } + + let mut wpr_data_wrapper: HashMap> = HashMap::new(); + let mut wpr_data_wrapper_arc = Arc::new(Mutex::new(wpr_data_wrapper)); + + let mut task_vec = Vec::new(); + for (symbol, filtered_data) in filtered_symbols { + if let Some(vec) = input_rt_data.get(symbol) { + let wpr_data_wrapper_arc_c = Arc::clone(&wpr_data_wrapper_arc); + let symbol_c = symbol.clone(); + let rt_price_data = vec.clone(); + task_vec.push(tokio::spawn(async move { + let mut wpr_data = WiliamsPercentR::new(); + let mut wpr_data_vec: Vec = Vec::new(); + + if rt_price_data.len() >= period { + let mut iter = rt_price_data.windows(period); + for buffer in iter { + let highest_high = buffer + .iter() + .max_by(|x, y| x.high_price.partial_cmp(&y.high_price).unwrap()) + .unwrap() + .high_price; + let lowest_low = buffer + .iter() + .min_by(|x, y| x.low_price.partial_cmp(&y.low_price).unwrap()) + .unwrap() + .low_price; + + let close_price = buffer.last().unwrap().close_price; + let wpr = + (highest_high - close_price) / (highest_high - lowest_low) * -100.0; + + wpr_data.r_value = wpr; + wpr_data.close_time = buffer.last().unwrap().close_time; + wpr_data_vec.push(wpr_data.clone()); + } + } + let mut wpr_data_wrapper_lock = wpr_data_wrapper_arc_c.lock().await; + wpr_data_wrapper_lock.insert(symbol_c, wpr_data_vec.clone()); + })); + } + } + try_join_all(task_vec).await?; + let a = wpr_data_wrapper_arc.lock().await.to_owned(); + Ok(a) +}