use crate::coex::exchange_team::*; use crate::coex::order_team::*; use crate::coin_health_check_team::request_others::CoinPriceData; use crate::database_control::*; use crate::value_estimation_team; use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; use crate::value_estimation_team::indicators::bollingerband::BollingerBandData; use crate::value_estimation_team::indicators::ema::EmaData; use crate::value_estimation_team::indicators::heatmap_volume::{ heatmap_volume, HeatMapLevel, HeatmapVolumeData, }; use crate::value_estimation_team::indicators::macd::{ema_macd, EmaMacd}; use crate::value_estimation_team::indicators::rsi::RsiData; use crate::value_estimation_team::indicators::sma::SmaData; use crate::value_estimation_team::indicators::stoch_rsi::{StochRsiDData, StochRsiKData}; use crate::value_estimation_team::indicators::supertrend::{supertrend, SupertrendData}; use csv::{DeserializeRecordsIter, StringRecord}; use futures::future::try_join_all; use rust_decimal::prelude::ToPrimitive; use rust_decimal::Decimal; use serde::Deserialize; use sqlx::FromRow; use std::{cmp::Ordering, sync::Arc}; use tokio::sync::Mutex; use tokio::time::{sleep, Duration, Instant}; use crate::signal_association::signal_decision::*; #[derive(PartialEq)] pub enum MA { Sma, Ema, Tema, } #[derive(Debug)] pub struct AllData { pub valid_symbol_vec: Vec, pub rt_price_1m_vec: Vec<(String, Vec)>, pub rt_price_30m_vec: Vec<(String, Vec)>, pub rt_price_1d_vec: Vec<(String, Vec)>, pub rt_price_1w_vec: Vec<(String, Vec)>, pub rt_price_1mon_vec: Vec<(String, Vec)>, // pub sma3_1m_data: Vec<(String, Vec)>, // pub sma3_30m_data: Vec<(String, Vec)>, // pub sma3_1d_data: Vec<(String, Vec)>, // pub sma3_1w_data: Vec<(String, Vec)>, // pub sma3_1mon_data: Vec<(String, Vec)>, // pub sma10_1m_data: Vec<(String, Vec)>, // pub sma10_30m_data: Vec<(String, Vec)>, // pub sma10_1d_data: Vec<(String, Vec)>, // pub sma10_1w_data: Vec<(String, Vec)>, // pub sma10_1mon_data: Vec<(String, Vec)>, // pub sma30_1m_data: Vec<(String, Vec)>, // pub sma30_30m_data: Vec<(String, Vec)>, // pub sma30_1d_data: Vec<(String, Vec)>, // pub sma30_1w_data: Vec<(String, Vec)>, // pub sma30_1mon_data: Vec<(String, Vec)>, // pub ema3_1m_data: Vec<(String, Vec)>, // pub ema3_30m_data: Vec<(String, Vec)>, // pub ema3_1d_data: Vec<(String, Vec)>, // pub ema3_1w_data: Vec<(String, Vec)>, // pub ema3_1mon_data: Vec<(String, Vec)>, // pub ema10_1m_data: Vec<(String, Vec)>, // pub ema10_30m_data: Vec<(String, Vec)>, // pub ema10_1d_data: Vec<(String, Vec)>, // pub ema10_1w_data: Vec<(String, Vec)>, // pub ema10_1mon_data: Vec<(String, Vec)>, // pub ema30_1m_data: Vec<(String, Vec)>, // pub ema30_30m_data: Vec<(String, Vec)>, // pub ema30_1d_data: Vec<(String, Vec)>, // pub ema30_1w_data: Vec<(String, Vec)>, // pub ema30_1mon_data: Vec<(String, Vec)>, // pub rsi3_1m_data: Vec<(String, Vec)>, // pub rsi3_30m_data: Vec<(String, Vec)>, // pub rsi3_1d_data: Vec<(String, Vec)>, // pub rsi3_1w_data: Vec<(String, Vec)>, // pub rsi3_1mon_data: Vec<(String, Vec)>, // pub rsi10_1m_data: Vec<(String, Vec)>, // pub rsi10_30m_data: Vec<(String, Vec)>, // pub rsi10_1d_data: Vec<(String, Vec)>, // pub rsi10_1w_data: Vec<(String, Vec)>, // pub rsi10_1mon_data: Vec<(String, Vec)>, // pub rsi30_1m_data: Vec<(String, Vec)>, // pub rsi30_30m_data: Vec<(String, Vec)>, // pub rsi30_1d_data: Vec<(String, Vec)>, // pub rsi30_1w_data: Vec<(String, Vec)>, // pub rsi30_1mon_data: Vec<(String, Vec)>, // pub stoch_rsi3_1m_3_k_data: Vec<(String, Vec)>, // pub stoch_rsi3_1m_3_d_data: Vec<(String, Vec)>, // pub stoch_rsi30_1m_30_k_data: Vec<(String, Vec)>, // pub stoch_rsi30_1m_30_d_data: Vec<(String, Vec)>, // pub bb3_1m_data: Vec<(String, Vec)>, // pub bb3_30m_data: Vec<(String, Vec)>, // pub bb3_1d_data: Vec<(String, Vec)>, // pub bb3_1w_data: Vec<(String, Vec)>, // pub bb3_1mon_data: Vec<(String, Vec)>, // pub bb10_1m_data: Vec<(String, Vec)>, // pub bb10_30m_data: Vec<(String, Vec)>, to be deleted // pub bb10_1d_data: Vec<(String, Vec)>, // pub bb10_1w_data: Vec<(String, Vec)>, // pub bb10_1mon_data: Vec<(String, Vec)>, // pub bb30_1m_data: Vec<(String, Vec)>, // pub bb30_30m_data: Vec<(String, Vec)>, // pub bb30_1d_data: Vec<(String, Vec)>, // pub bb30_1w_data: Vec<(String, Vec)>, // pub bb30_1mon_data: Vec<(String, Vec)>, } impl AllData { pub fn new() -> AllData { let a = AllData { valid_symbol_vec: Vec::new(), rt_price_1m_vec: Vec::new(), rt_price_30m_vec: Vec::new(), rt_price_1d_vec: Vec::new(), rt_price_1w_vec: Vec::new(), rt_price_1mon_vec: Vec::new(), // sma3_1m_data: Vec::new(), // sma3_30m_data: Vec::new(), // sma3_1d_data: Vec::new(), // sma3_1w_data: Vec::new(), // sma3_1mon_data: Vec::new(), // sma10_1m_data: Vec::new(), // sma10_30m_data: Vec::new(), // sma10_1d_data: Vec::new(), // sma10_1w_data: Vec::new(), // sma10_1mon_data: Vec::new(), // sma30_1m_data: Vec::new(), // sma30_30m_data: Vec::new(), // sma30_1d_data: Vec::new(), // sma30_1w_data: Vec::new(), // sma30_1mon_data: Vec::new(), // ema3_1m_data: Vec::new(), // ema3_30m_data: Vec::new(), // ema3_1d_data: Vec::new(), // ema3_1w_data: Vec::new(), // ema3_1mon_data: Vec::new(), // ema10_1m_data: Vec::new(), // ema10_30m_data: Vec::new(), // ema10_1d_data: Vec::new(), // ema10_1w_data: Vec::new(), // ema10_1mon_data: Vec::new(), // ema30_1m_data: Vec::new(), // ema30_30m_data: Vec::new(), // ema30_1d_data: Vec::new(), // ema30_1w_data: Vec::new(), // ema30_1mon_data: Vec::new(), // rsi3_1m_data: Vec::new(), // rsi3_30m_data: Vec::new(), // rsi3_1d_data: Vec::new(), // rsi3_1w_data: Vec::new(), // rsi3_1mon_data: Vec::new(), // rsi10_1m_data: Vec::new(), // rsi10_30m_data: Vec::new(), // rsi10_1d_data: Vec::new(), // rsi10_1w_data: Vec::new(), // rsi10_1mon_data: Vec::new(), // rsi30_1m_data: Vec::new(), // rsi30_30m_data: Vec::new(), // rsi30_1d_data: Vec::new(), // rsi30_1w_data: Vec::new(), // rsi30_1mon_data: Vec::new(), // stoch_rsi3_1m_3_k_data: Vec::new(), // stoch_rsi3_1m_3_d_data: Vec::new(), // stoch_rsi30_1m_30_k_data: Vec::new(), // stoch_rsi30_1m_30_d_data: Vec::new(), // bb3_1m_data: Vec::new(), // bb3_30m_data: Vec::new(), // bb3_1d_data: Vec::new(), // bb3_1w_data: Vec::new(), // bb3_1mon_data: Vec::new(), // bb10_1m_data: Vec::new(), // bb10_30m_data: Vec::new(), to be deleted // bb10_1d_data: Vec::new(), // bb10_1w_data: Vec::new(), // bb10_1mon_data: Vec::new(), // bb30_1m_data: Vec::new(), // bb30_30m_data: Vec::new(), // bb30_1d_data: Vec::new(), // bb30_1w_data: Vec::new(), // bb30_1mon_data: Vec::new(), }; a } } #[derive(Debug, Deserialize, Clone)] struct OpcloData { price: f64, server_epoch: u64, usdt_volume: f64, up_down: String, } #[derive(Debug, Deserialize, Clone)] struct PriceData { opclo_price: f64, open_price: f64, close_price: f64, high_price: f64, low_price: f64, close_time: u64, quote_asset_volume: f64, candle_type: String, } #[derive(Debug, FromRow)] pub struct TimeData { pub server_epoch: u64, pub local_epoch: u64, pub epoch_difference: i64, pub server_ymdhs: String, pub local_ymdhs: String, pub last_server_epoch: u64, pub last_server_ymdhs: String, } #[derive(Debug, FromRow)] struct ServerEpoch { server_epoch: u64, } #[derive(Debug, FromRow)] struct Record { symbol: String, suggested_price: Decimal, close_time: u64, registered_server_epoch: u64, registerer: u16, is_long: u8, } pub async fn execute_strategists( all_data: &AllData, ) -> Result<(), Box> { // strategist_001(all_data).await; // strategist_002(all_data).await; // strategist_003(all_data).await; // strategist_004(all_data).await; // strategist_005(all_data).await; // strategist_006(all_data).await; // strategist_007().await; // strategist_008().await; // strategist_009().await; // strategist_010().await; // strategist_011().await; // strategist_012().await; // strategist_013(all_data).await; // strategist_014(all_data).await; // strategist_015(all_data).await; // strategist_016(all_data).await; execute_strategist_for_test_temp(all_data).await?; // execute_strategist_for_test1(all_data).await; // execute_strategist_for_test2(all_data).await; Ok(()) } // pub async fn execute_strategist_for_test(alldata: &AllData) -> Result<(), Box> { // let inspect_table_name_1 = String::from("buy_ordered_coin_list"); // let inspect_table_name_2 = String::from("sell_ordered_coin_list"); // let inspect_table_name_3 = String::from("pre_suggested_coin_list"); // let inspect_table_name_4 = String::from("suggested_coin_list"); // let market_cap_index = select_marketcap().await; // let mut filtered_symbols: Vec = Vec::new(); // // filtered_symbols.push(String::from("BNBUSDT")); // filtered_symbols.push(String::from("BTCUSDT")); // // filtered_symbols.push(String::from("ETHUSDT")); // // filtered_symbols.push(String::from("LTCUSDT")); // // filtered_symbols.push(String::from("XRPUSDT")); // // filtered_symbols.push(String::from("TRXUSDT")); // let current_price = get_current_price(&filtered_symbols.first().unwrap(), &alldata.price_vec).await.unwrap(); // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi30_1m_vec: Vec = Vec::new(); // let mut stoch_rsi3_1m_k_vec: Vec = Vec::new(); // let mut stoch_rsi3_1m_d_vec: Vec = Vec::new(); // let mut stoch_rsi30_1m_k_vec: Vec = Vec::new(); // let mut stoch_rsi30_1m_d_vec: Vec = Vec::new(); // let mut opclo_1m_vec: Vec = Vec::new(); // let mut sma10_1m_vec: Vec = Vec::new(); // let mut ema3_1m_vec: Vec = Vec::new(); // let mut ema10_1m_vec: Vec = Vec::new(); // let mut ema30_1m_vec: Vec = Vec::new(); // let mut cnt = 0; // for symbol in filtered_symbols { // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); // let stoch_rsi3_1m_k_option = alldata.stoch_rsi3_1m_3_k_data.iter().position(|x| *x.0 == *symbol); // let stoch_rsi3_1m_d_option = alldata.stoch_rsi3_1m_3_d_data.iter().position(|x| *x.0 == *symbol); // let stoch_rsi30_1m_k_option = alldata.stoch_rsi30_1m_30_k_data.iter().position(|x| *x.0 == *symbol); // let stoch_rsi30_1m_d_option = alldata.stoch_rsi30_1m_30_d_data.iter().position(|x| *x.0 == *symbol); // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let sma10_1m_option = alldata.sma10_1m_data.iter().position(|x| *x.0 == *symbol); // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); // let ema30_1m_option = alldata.ema30_1m_data.iter().position(|x| *x.0 == *symbol); // if rsi3_1m_option.is_some() && rsi30_1m_option.is_some() && opclo_1m_option.is_some() && sma10_1m_option.is_some() && ema3_1m_option.is_some() && ema10_1m_option.is_some() && ema30_1m_option.is_some() && stoch_rsi3_1m_k_option.is_some() && stoch_rsi3_1m_d_option.is_some() && stoch_rsi30_1m_k_option.is_some() && stoch_rsi30_1m_d_option.is_some() { // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi30_1m_vec = alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1.clone(); // stoch_rsi3_1m_k_vec = alldata.stoch_rsi3_1m_3_k_data[stoch_rsi3_1m_k_option.unwrap()].1.clone(); // stoch_rsi3_1m_d_vec = alldata.stoch_rsi3_1m_3_d_data[stoch_rsi3_1m_d_option.unwrap()].1.clone(); // stoch_rsi30_1m_k_vec = alldata.stoch_rsi30_1m_30_k_data[stoch_rsi30_1m_k_option.unwrap()].1.clone(); // stoch_rsi30_1m_d_vec = alldata.stoch_rsi30_1m_30_d_data[stoch_rsi30_1m_d_option.unwrap()].1.clone(); // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // sma10_1m_vec = alldata.sma10_1m_data[sma10_1m_option.unwrap()].1.clone(); // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // ema10_1m_vec = alldata.ema10_1m_data[ema10_1m_option.unwrap()].1.clone(); // ema30_1m_vec = alldata.ema30_1m_data[ema30_1m_option.unwrap()].1.clone(); // if rsi3_1m_vec.len() >= 3 && opclo_1m_vec.len() >= 3 && sma10_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 30 && ema10_1m_vec.len() >= 3 && ema30_1m_vec.len() >= 30 && stoch_rsi3_1m_k_vec.len() >= 5 && stoch_rsi3_1m_d_vec.len() >= 5 && stoch_rsi30_1m_k_vec.len() >= 5 && stoch_rsi30_1m_d_vec.len() >= 5 { // opclo_1m_vec.reverse(); // opclo_1m_vec.truncate(3); // opclo_1m_vec.reverse(); // stoch_rsi3_1m_k_vec.reverse(); // stoch_rsi3_1m_k_vec.truncate(5); // stoch_rsi3_1m_k_vec.reverse(); // stoch_rsi3_1m_d_vec.reverse(); // stoch_rsi3_1m_d_vec.truncate(5); // stoch_rsi3_1m_d_vec.reverse(); // stoch_rsi30_1m_k_vec.reverse(); // stoch_rsi30_1m_k_vec.truncate(5); // stoch_rsi30_1m_k_vec.reverse(); // stoch_rsi30_1m_d_vec.reverse(); // stoch_rsi30_1m_d_vec.truncate(5); // stoch_rsi30_1m_d_vec.reverse(); // let supertrend_vec = supertrend(&symbol, &alldata.rt_price_1m_vec, 60, 1.0, true).await; // let macd_vec = ema_macd(&ema10_1m_vec, &ema30_1m_vec, 30).await?; // let macd_search_result = macd_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaMacd{macd_value, close_time}|close_time); // if macd_search_result.is_ok() { // if macd_vec[macd_search_result.unwrap()].macd_value > 0.0 { // //check duplicate records // let mut exists_condition_build = String::from("symbol=\'"); // exists_condition_build.push_str(symbol.as_str()); // exists_condition_build.push_str("\' AND close_time="); // exists_condition_build.push_str(opclo_1m_vec.last().unwrap().close_time.to_string().as_str()); // let exists_condition = Some(exists_condition_build); // let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; // let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; // let inspect_result_3 = exists_record(&inspect_table_name_3, &exists_condition).await; // let inspect_result_4 = exists_record(&inspect_table_name_4, &exists_condition).await; // if inspect_result_1 == false && inspect_result_2 == false && inspect_result_3 == false && inspect_result_4 == false { // let mut sum_stoch_rsi30_1m_k = 0.0; // for element in &stoch_rsi30_1m_k_vec { // sum_stoch_rsi30_1m_k += element.stoch_rsi_k_value; // } // let average_stoch_rsi30_1m_k = sum_stoch_rsi30_1m_k / 5.0; // let ema3_3_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaData{ema_value, close_time}|close_time); // let ema3_2_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); // let ema3_1_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&EmaData{ema_value, close_time}|close_time); // let ema10_result = ema10_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaData{ema_value, close_time}|close_time); // let sma10_result = sma10_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&SmaData{sma_value, close_time}|close_time); // if ema3_3_result.is_ok() && ema3_2_result.is_ok() && ema3_1_result.is_ok() && ema10_result.is_ok() && sma10_result.is_ok() { // if sma10_1m_vec[sma10_result.unwrap()].sma_value < ema3_1m_vec[ema3_3_result.unwrap()].ema_value { // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // if k_result.is_ok() && k_prev_result.is_ok() { // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value > 5.0 // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value < 80.0 // && stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 96.0 // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0 { // if current_price <= opclo_1m_vec[1].opclo_price * ((((opclo_1m_vec[1].high_price / opclo_1m_vec[1].low_price) - 1.0) / 2.0) + 1.0) { // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // } // } // } // } // // if ema10_1m_vec[ema10_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value { // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema10_1m_vec[ema10_result.unwrap()].ema_value { // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema3_1m_vec[ema3_2_result.unwrap()].ema_value // // && ema3_1m_vec[ema3_2_result.unwrap()].ema_value > ema3_1m_vec[ema3_1_result.unwrap()].ema_value // // { // // if average_stoch_rsi30_1m_k < 80.0 { // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let k_prev2_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // if k_result.is_ok() && d_result.is_ok() && k_prev_result.is_ok() && k_prev2_result.is_ok() { // // if // // (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) > 3.0 // // && stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 96.0 // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev2_result.unwrap()].stoch_rsi_k_value) // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) < 25.0 // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) > 3.0 // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0) // // // (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value > 5.0) && // // // ((stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value <= 80.0) // // // || (((opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0) && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value))) // // { // // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0 { // // // if (opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 // // // { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // } else { // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // if opclo_1m_vec[1].candle_type == "DOWN" && opclo_1m_vec[1].opclo_price >= opclo_1m_vec[2].close_price { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } else if opclo_1m_vec[1].candle_type == "UP" { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // } // // // else { // // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); // // // if result.is_ok() { // // // if rsi3_1m_vec[result.unwrap()].rsi_value < 20.0 && cnt >= 2 && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // } // // // } // // // } else { // // // if cnt >= 2 { // // // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); // // // match result { // // // Ok(T) => { // // // if ema3_1m_vec[T].ema_value > opclo_1m_vec[1].opclo_price { // // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); // // // match result { // // // Ok(T) => { // // // if rsi3_1m_vec[T].rsi_value < 15.0 { // // // let k_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // let d_result = stoch_rsi10_1m_d_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // if k_result.is_ok() && d_result.is_ok() { // // // if stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value <= stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value { // // // if current_price < opclo_1m_vec[1].opclo_price { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // } // // // } // // // } // // // }, // // // Err(E) => {} // // // } // // // } // // // }, // // // Err(E) => {} // // // } // // // } // // // } // // } // // } else { // // let k_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let k_prev_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let k_prev2_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let d_result = stoch_rsi10_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // if k_result.is_ok() && d_result.is_ok() && k_prev_result.is_ok() && k_prev2_result.is_ok() { // // if (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) > 3.0 // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev2_result.unwrap()].stoch_rsi_k_value // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value < 30.0 // // && stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 95.0 // // { // // // if stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0 { // // // if (opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 // // // { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // } else { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // } // // } // // } // // } // // } // // // else { // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // if k_result.is_ok() && k_prev_result.is_ok() { // // // if (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) > 5.0 // // // { // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value < ema3_1m_vec[ema3_2_result.unwrap()].ema_value { // // // // if opclo_1m_vec[1].candle_type == "DOWN" && opclo_1m_vec[1].open_price > ema3_1m_vec[ema3_2_result.unwrap()].ema_value // // // // && opclo_1m_vec[2].open_price < ema3_1m_vec[ema3_3_result.unwrap()].ema_value // // // // && opclo_1m_vec[2].high_price < ema3_1m_vec[ema3_3_result.unwrap()].ema_value // // // // && opclo_1m_vec[2].candle_type == "UP" { // // // // if (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value < stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) // // // // { // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // } // // // // } // // // // } else if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema3_1m_vec[ema3_2_result.unwrap()].ema_value // // // // { // // // // if opclo_1m_vec[1].candle_type == "UP" // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) { // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // } // // // // } // // // } // // // } // // } // } // } // } // // else if macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value && macd_vec[macd_search_result.unwrap()].macd_value > -3.0{ // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // if k_result.is_ok() && k_prev_result.is_ok() && d_result.is_ok() { // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0{ // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // } // // } // // } // } // } // } // } // // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // // if market_cap_index.first().unwrap().negative_buy_signal == 1 || (market_cap_index.first().unwrap().liquidation_signal == 0 && market_cap_index.first().unwrap().market_cap_index <= 20.0 && market_cap_index.first().unwrap().market_cap_index >= 0.0) { // // let mut rsi3_1m_vec: Vec = Vec::new(); // // let mut opclo_1m_vec: Vec = Vec::new(); // // let mut ema3_1m_vec: Vec = Vec::new(); // // let mut cnt = 0; // // for symbol in filtered_symbols { // // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // // if rsi3_1m_option.is_some() && opclo_1m_option.is_some() && ema3_1m_option.is_some() { // // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // // if rsi3_1m_vec.len() >= 3 && opclo_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 3 { // // opclo_1m_vec.reverse(); // // opclo_1m_vec.truncate(3); // // opclo_1m_vec.reverse(); // // if opclo_1m_vec.last().unwrap().candle_type == "UP" { // // cnt = 0; // // for element in &opclo_1m_vec { // // if element.candle_type == "DOWN" { // // cnt += 1; // // } // // } // // if cnt >= 2 { // // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if ema3_1m_vec[T].ema_value > opclo_1m_vec[1].opclo_price { // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi3_1m_vec[T].rsi_value < 30.0 { // // if current_price < opclo_1m_vec[1].opclo_price { // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // } // // } // // } else if market_cap_index.first().unwrap().liquidation_signal == 1 && market_cap_index.first().unwrap().market_cap_index < - 10.0 { // // let mut rsi3_1m_vec: Vec = Vec::new(); // // let mut rsi10_1m_vec: Vec = Vec::new(); // // let mut rsi30_1m_vec: Vec = Vec::new(); // // let mut op_low_1m_vec: Vec = Vec::new(); // // let mut ema3_1m_vec: Vec = Vec::new(); // // let mut bb30_1m_vec: Vec = Vec::new(); // // let mut cnt = 0; // // for symbol in filtered_symbols { // // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // // let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); // // let op_low_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); // // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && rsi30_1m_option.is_some() && op_low_1m_option.is_some() && ema3_1m_option.is_some() && bb30_1m_option.is_some() { // // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // // rsi30_1m_vec = alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1.clone(); // // op_low_1m_vec = alldata.rt_price_1m_vec[op_low_1m_option.unwrap()].1.clone(); // // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); // // if rsi3_1m_vec.len() >= 3 && rsi10_1m_vec.len() >= 3 && rsi30_1m_vec.len() >= 3 && op_low_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 3 && bb30_1m_vec.len() >= 3 { // // op_low_1m_vec.reverse(); // // op_low_1m_vec.truncate(5); // // op_low_1m_vec.reverse(); // // if op_low_1m_vec.last().unwrap().candle_type == "DOWN" { // // cnt = 0; // // for element in &op_low_1m_vec { // // if element.candle_type == "DOWN" { // // cnt += 1; // // } // // } // // if cnt >= 4 { // // let result = ema3_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if ema3_1m_vec[T].ema_value > (op_low_1m_vec.last().unwrap().open_price + op_low_1m_vec.last().unwrap().low_price) / 2.0 { // // let result = rsi3_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi3_1m_vec[T].rsi_value < 10.0 { // // let result = rsi10_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi10_1m_vec[T].rsi_value < 15.0 { // // let result = rsi30_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi30_1m_vec[T].rsi_value < 35.0 { // // let result = bb30_1m_vec.binary_search_by_key(&op_low_1m_vec.first().unwrap().close_time, |&BollingerBandData{sma, upperband, lowerband, close_time}|close_time); // // match result { // // Ok(T) => { // // if bb30_1m_vec[T].lowerband > (op_low_1m_vec.last().unwrap().open_price + op_low_1m_vec.last().unwrap().low_price) / 2.0 { // // filtered_2nd_symbols.push((symbol, op_low_1m_vec.last().unwrap().close_time)); // // } // // }, // // Err(E) => {}, // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // } // // } // // } // insert_pre_suggested_coins(1, &filtered_2nd_symbols, alldata).await; // Ok(()) // } // pub async fn execute_strategist_for_test( // alldata: &AllData, // ) -> Result<(), Box> { // // 1st filtering: supertrend(ATR period 10, multiplier: 1.3, 30m close price), the area should be in SELL area. // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // let mut opclo_30m_vec: Vec = Vec::new(); // let mut supertrend_vec: Vec = Vec::new(); // for symbol in &alldata.valid_symbol_vec { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let supertrend_option_30m = // supertrend(&symbol, &alldata.rt_price_30m_vec, 10, 1.3, true).await; // if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // supertrend_vec = supertrend_option_30m.unwrap(); // if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { // let supertrend_search_result = supertrend_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |SupertrendData { // band_value, // signal, // area, // close_time, // }| *close_time, // ); // if supertrend_search_result.is_ok() { // if supertrend_vec[supertrend_search_result.unwrap()] // .area // .contains("DOWN") // { // filtered_2nd_symbols // .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); // } // } // } // } // } // // 2nd filtering: lookup tables if the tradepair is already there // let inspect_table_name_1 = String::from("buy_ordered_coin_list"); // let inspect_table_name_2 = String::from("sell_ordered_coin_list"); // let inspect_table_name_3 = String::from("pre_suggested_coin_list"); // let inspect_table_name_4 = String::from("suggested_coin_list"); // let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for element in filtered_2nd_symbols { // let mut exists_condition_build = String::from("symbol=\'"); // exists_condition_build.push_str(element.0.as_str()); // exists_condition_build.push_str("\' AND close_time="); // exists_condition_build.push_str(element.1.to_string().as_str()); // let exists_condition = Some(exists_condition_build); // let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; // let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; // let inspect_result_3 = exists_record(&inspect_table_name_3, &exists_condition).await; // let inspect_result_4 = exists_record(&inspect_table_name_4, &exists_condition).await; // if inspect_result_1 == false // && inspect_result_2 == false // && inspect_result_3 == false // && inspect_result_4 == false // { // filtered_3rd_symbols.push(element); // } // } // // 3rd filtering: BollingerBand (length 10, stddev: 3.0, 30m close price) the current price should be under the lowerband of BB. // let mut bb10_30m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for element in filtered_3rd_symbols { // let bb10_30m_option = alldata.bb10_30m_data.iter().position(|x| *x.0 == element.0); // if bb10_30m_option.is_some() { // bb10_30m_vec = alldata.bb10_30m_data[bb10_30m_option.unwrap()].1.clone(); // if bb10_30m_vec.len() >= 3 { // let bb_search_result = bb10_30m_vec.binary_search_by_key( // &element.1, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // if bb_search_result.is_ok() { // let current_price = get_current_price(&element.0, &alldata.price_vec) // .await // .unwrap(); // if bb10_30m_vec[bb_search_result.unwrap()].lowerband > current_price { // filtered_4th_symbols.push(element); // } // } // } // } // } // // 4th filtering: RSI (length: 10, 30m close price) the current index should be lower than 30. // let mut rsi10_30m_vec: Vec = Vec::new(); // let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for element in filtered_4th_symbols { // let rsi10_30m_option = alldata // .rsi10_30m_data // .iter() // .position(|x| *x.0 == element.0); // if rsi10_30m_option.is_some() { // rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); // if rsi10_30m_vec.len() >= 3 { // let rsi_search_result = rsi10_30m_vec.binary_search_by_key( // &element.1, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // if rsi_search_result.is_ok() { // if rsi10_30m_vec[rsi_search_result.unwrap()].rsi_value <= 30.0 { // filtered_5th_symbols.push(element); // } // } // } // } // } // // 5th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least. // let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for element in filtered_5th_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == element.0); // if opclo_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if opclo_30m_vec.len() >= 3 { // let heatmap_volume_option = heatmap_volume( // &element.0, // &alldata.rt_price_30m_vec, // 10, // 10, // 4.0, // 2.5, // 1.0, // -0.5, // ) // .await; // if heatmap_volume_option.is_some() { // let heatmap_volume_vec = heatmap_volume_option.unwrap(); // let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( // &element.1, // |HeatmapVolumeData { // heatmap_value, // heatmap_level, // close_time, // }| *close_time, // ); // if heatmap_search_result.is_ok() { // if heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::Medium // || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::High // || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::ExtraHigh // { // filtered_6th_symbols.push(element); // } // } // } // } // } // } // // 6th filtering condition: MACD // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut ema3_1d_vec: &Vec = &Vec::new(); // // let mut ema10_1d_vec: &Vec = &Vec::new(); // // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // // for element in filtered_6th_symbols { // // let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0); // // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0); // // if ema3_1d_option.is_some() && ema10_1d_option.is_some() { // // ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1; // // ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1; // // if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { // // let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; // // // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); // // // if macd_search_result.is_ok() { // // if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 { // // filtered_7th_symbols.push(element); // // } // // // } // // } // // } // // } // insert_pre_suggested_coins(1, &filtered_6th_symbols, alldata).await; // Ok(()) // } pub async fn execute_strategist_for_test_temp( alldata: &AllData, ) -> Result<(), Box> { // print rt_price for debugging // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); // 1st filtering: supertrend(ATR period 10, multiplier: 1.3, 30m close price), the area should be in SELL area. let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); let mut filtered_2nd_symbols_arc: Arc>> = Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) let mut task_vec = Vec::new(); let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); for symbol in valid_symbol_vec_c { let mut opclo_30m_vec: Vec = Vec::new(); let mut supertrend_vec: Vec = Vec::new(); let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); task_vec.push(tokio::spawn(async move { let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); let supertrend_option_30m = supertrend(&symbol, &rt_price_30m_vec_c, 10, 1.3, true).await; if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); supertrend_vec = supertrend_option_30m.unwrap(); if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { let supertrend_search_result = supertrend_vec.binary_search_by_key( &opclo_30m_vec.last().unwrap().close_time, |SupertrendData { band_value, signal, area, close_time, }| *close_time, ); if supertrend_search_result.is_ok() { if supertrend_vec[supertrend_search_result.unwrap()] .area .contains("DOWN") { let mut filtered_2nd_symbols_lock = filtered_2nd_symbols_arc_c.lock().await; filtered_2nd_symbols_lock .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); } } } } })); } try_join_all(task_vec).await?; // 2nd filtering: lookup tables if the tradepair is already there let inspect_table_name_1 = String::from("buy_ordered_coin_list"); let inspect_table_name_2 = String::from("sell_ordered_coin_list"); let inspect_table_name_3 = String::from("pre_suggested_coin_list"); let inspect_table_name_4 = String::from("suggested_coin_list"); let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); let mut filtered_3rd_symbols_arc: Arc>> = Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) let mut task_vec = Vec::new(); let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); for element in filtered_2nd_iter { let mut exists_condition_build = String::from("symbol=\'"); exists_condition_build.push_str(element.0.as_str()); exists_condition_build.push_str("\' AND close_time="); exists_condition_build.push_str(element.1.to_string().as_str()); let exists_condition = Some(exists_condition_build); let exists_condition_c = exists_condition.clone(); let inspect_table_name_1_c = inspect_table_name_1.clone(); let inspect_table_name_2_c = inspect_table_name_2.clone(); let inspect_table_name_3_c = inspect_table_name_3.clone(); let inspect_table_name_4_c = inspect_table_name_4.clone(); let element_c = element.clone(); let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); task_vec.push(tokio::spawn(async move { let inspect_result_1 = exists_record(&inspect_table_name_1_c, &exists_condition_c).await; let inspect_result_2 = exists_record(&inspect_table_name_2_c, &exists_condition_c).await; let inspect_result_3 = exists_record(&inspect_table_name_3_c, &exists_condition_c).await; let inspect_result_4 = exists_record(&inspect_table_name_4_c, &exists_condition_c).await; if inspect_result_1 == false && inspect_result_2 == false && inspect_result_3 == false && inspect_result_4 == false { let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; filtered_3rd_symbols_lock.push(element_c); } })); } try_join_all(task_vec).await?; // 3rd filtering: BollingerBand (length 10, stddev: 2.5, 30m close price) the current price should be under the lowerband of BB. let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); let sma10_30m_data: Vec<(String, Vec)> = value_estimation_team::indicators::sma::sma( 10, &alldata.rt_price_30m_vec, &filtered_3rd_symbols_c, ) .await?; let bb10_30m_data: Vec<(String, Vec)> = value_estimation_team::indicators::bollingerband::bollingerband( 10, 2.5, &sma10_30m_data, &alldata.rt_price_30m_vec, &filtered_3rd_symbols_c, ) .await?; let mut task_vec = Vec::new(); let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); let mut filtered_4th_symbols_arc: Arc>> = Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) for element in filtered_3rd_symbols_c { let mut bb10_30m_vec: Vec = Vec::new(); let bb10_30m_option = bb10_30m_data.iter().position(|x| *x.0 == element.0); let bb10_30m_option_c = bb10_30m_option.clone(); let element_c = element.clone(); let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); if bb10_30m_option_c.is_some() { bb10_30m_vec = bb10_30m_data[bb10_30m_option_c.unwrap()].1.clone(); if bb10_30m_vec.len() >= 3 { let bb10_30m_vec_c = bb10_30m_vec.clone(); let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec) .await .unwrap(); task_vec.push(tokio::spawn(async move { let bb_search_result = bb10_30m_vec_c.binary_search_by_key( &element_c.1, |&BollingerBandData { sma, upperband, lowerband, close_time, }| close_time, ); if bb_search_result.is_ok() { if bb10_30m_vec_c[bb_search_result.unwrap()].lowerband > current_price { let mut filtered_4th_symbols_lock = filtered_4th_symbols_arc_c.lock().await; filtered_4th_symbols_lock.push(element_c); } } })); } } } try_join_all(task_vec).await?; // 4th filtering: RSI (length: 10, 30m close price) the current index should be lower than 30. let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone(); let mut rsi10_30m_data: Vec<(String, Vec)> = Vec::new(); value_estimation_team::indicators::rsi::rsi( 10, &alldata.rt_price_30m_vec, &mut rsi10_30m_data, &filtered_4th_symbol_c, ) .await?; let mut rsi10_30m_vec: Vec = Vec::new(); let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) for element in filtered_4th_symbol_c { let rsi10_30m_option = rsi10_30m_data.iter().position(|x| *x.0 == element.0); if rsi10_30m_option.is_some() { rsi10_30m_vec = rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); if rsi10_30m_vec.len() >= 3 { let rsi_search_result = rsi10_30m_vec.binary_search_by_key( &element.1, |&RsiData { rsi_value, close_time, }| close_time, ); if rsi_search_result.is_ok() { if rsi10_30m_vec[rsi_search_result.unwrap()].rsi_value <= 30.0 { filtered_5th_symbols.push(element); } } } } } // 5th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least. let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) for element in filtered_5th_symbols { let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); if opclo_30m_option.is_some() { let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); if opclo_30m_vec.len() >= 3 { let heatmap_volume_option = heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) .await; if heatmap_volume_option.is_some() { let heatmap_volume_vec = heatmap_volume_option.unwrap(); let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( &element.1, |HeatmapVolumeData { heatmap_value, heatmap_level, close_time, }| *close_time, ); if heatmap_search_result.is_ok() { if heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level == HeatMapLevel::Medium || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level == HeatMapLevel::High || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level == HeatMapLevel::ExtraHigh { filtered_6th_symbols.push(element); } } } } } } // final job: adding price information to filtered results let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); let mut task_vec = Vec::new(); for element in filtered_6th_symbols { let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); let elememt_c = element.clone(); task_vec.push(tokio::spawn(async move { let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); if opclo_30m_option.is_some() { if rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.last().is_some() { let mut filtered_symbols_lock: tokio::sync::MutexGuard<'_, Vec<(String, i64, f64)>> = filtered_symbols_arc_c.lock().await; filtered_symbols_lock.push((elememt_c.0, elememt_c.1, rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.last().unwrap().close_price)); } } })); } try_join_all(task_vec).await?; // 6th filtering condition: MACD // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_1d_vec: &Vec = &Vec::new(); // let mut ema10_1d_vec: &Vec = &Vec::new(); // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for element in filtered_6th_symbols { // let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0); // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0); // if ema3_1d_option.is_some() && ema10_1d_option.is_some() { // ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1; // ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1; // if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { // let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; // // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); // // if macd_search_result.is_ok() { // if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 { // filtered_7th_symbols.push(element); // } // // } // } // } // } let a = filtered_symbols_arc.lock().await.clone(); insert_pre_suggested_coins(1, &a, alldata).await; Ok(()) } // pub async fn execute_strategist_for_test1( // alldata: &AllData, // ) -> Result<(), Box> { // let inspect_table_name_1 = String::from("buy_ordered_coin_list"); // let inspect_table_name_2 = String::from("sell_ordered_coin_list"); // let inspect_table_name_3 = String::from("pre_suggested_coin_list"); // let inspect_table_name_4 = String::from("suggested_coin_list"); // let market_cap_index = select_marketcap().await; // let mut filtered_symbols: Vec = Vec::new(); // // filtered_symbols.push(String::from("BNBUSDT")); // filtered_symbols.push(String::from("BTCUSDT")); // // filtered_symbols.push(String::from("ETHUSDT")); // // filtered_symbols.push(String::from("LTCUSDT")); // // filtered_symbols.push(String::from("XRPUSDT")); // // filtered_symbols.push(String::from("TRXUSDT")); // // let current_price = get_current_price(&filtered_symbols.first().unwrap(), &alldata.price_vec).await.unwrap(); // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // let mut ema3_1m_vec: &Vec = &Vec::new(); // let mut ema3_30m_vec: &Vec = &Vec::new(); // let mut ema10_1m_vec: &Vec = &Vec::new(); // let mut ema30_1m_vec: &Vec = &Vec::new(); // let mut sma10_1m_vec: &Vec = &Vec::new(); // let mut sma3_30m_vec: &Vec = &Vec::new(); // let mut sma30_1m_vec: &Vec = &Vec::new(); // let mut rsi3_1m_vec: &Vec = &Vec::new(); // let mut rsi30_1m_vec: &Vec = &Vec::new(); // let mut stoch_rsi3_1m_k_vec: &Vec = &Vec::new(); // let mut stoch_rsi3_1m_d_vec: &Vec = &Vec::new(); // let mut stoch_rsi30_1m_k_vec: &Vec = &Vec::new(); // let mut stoch_rsi30_1m_d_vec: &Vec = &Vec::new(); // let mut rt_price_1m_vec: &Vec = &Vec::new(); // let mut is_filtering_passed: bool = false; // let mut cnt = 0; // let exists_condition = Some(String::from("used_usdt >= 10.0 AND registerer = 1")); // let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; // let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; // let mut is_buy_period_30m = false; // if inspect_result_1 == false && inspect_result_2 == false { // for symbol in filtered_symbols { // is_filtering_passed = false; // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); // let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); // let ema30_1m_option = alldata.ema30_1m_data.iter().position(|x| *x.0 == *symbol); // let sma10_1m_option = alldata.sma10_1m_data.iter().position(|x| *x.0 == *symbol); // let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); // let sma30_1m_option = alldata.sma30_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); // let stoch_rsi3_1m_k_option = alldata // .stoch_rsi3_1m_3_k_data // .iter() // .position(|x| *x.0 == *symbol); // let stoch_rsi3_1m_d_option = alldata // .stoch_rsi3_1m_3_d_data // .iter() // .position(|x| *x.0 == *symbol); // let stoch_rsi30_1m_k_option = alldata // .stoch_rsi30_1m_30_k_data // .iter() // .position(|x| *x.0 == *symbol); // let stoch_rsi30_1m_d_option = alldata // .stoch_rsi30_1m_30_d_data // .iter() // .position(|x| *x.0 == *symbol); // let rt_price_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let supertrend_option_30m = // supertrend(&symbol, &alldata.rt_price_30m_vec, 3, 0.5, true).await; // if supertrend_option_30m.is_some() { // let supertrend_vec = supertrend_option_30m.unwrap(); // if supertrend_vec.last().unwrap().area.contains("UP") { // is_buy_period_30m = true; // } // } // if is_buy_period_30m == true // && ema3_1m_option.is_some() // && ema3_30m_option.is_some() // && ema10_1m_option.is_some() // && ema30_1m_option.is_some() // && sma10_1m_option.is_some() // && sma3_30m_option.is_some() // && sma30_1m_option.is_some() // && rsi3_1m_option.is_some() // && rsi30_1m_option.is_some() // && stoch_rsi3_1m_k_option.is_some() // && stoch_rsi3_1m_d_option.is_some() // && stoch_rsi30_1m_k_option.is_some() // && stoch_rsi30_1m_d_option.is_some() // && rt_price_1m_option.is_some() // { // ema3_1m_vec = &alldata.ema3_1m_data[ema3_1m_option.unwrap()].1; // ema3_30m_vec = &alldata.ema3_30m_data[ema3_30m_option.unwrap()].1; // ema10_1m_vec = &alldata.ema10_1m_data[ema10_1m_option.unwrap()].1; // ema30_1m_vec = &alldata.ema30_1m_data[ema30_1m_option.unwrap()].1; // sma10_1m_vec = &alldata.sma10_1m_data[sma10_1m_option.unwrap()].1; // sma3_30m_vec = &alldata.sma3_30m_data[sma3_30m_option.unwrap()].1; // sma30_1m_vec = &alldata.sma30_1m_data[sma30_1m_option.unwrap()].1; // rsi3_1m_vec = &alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1; // rsi30_1m_vec = &alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1; // stoch_rsi3_1m_k_vec = // &alldata.stoch_rsi3_1m_3_k_data[stoch_rsi3_1m_k_option.unwrap()].1; // stoch_rsi3_1m_d_vec = // &alldata.stoch_rsi3_1m_3_d_data[stoch_rsi3_1m_d_option.unwrap()].1; // stoch_rsi30_1m_k_vec = // &alldata.stoch_rsi30_1m_30_k_data[stoch_rsi30_1m_k_option.unwrap()].1; // stoch_rsi30_1m_d_vec = // &alldata.stoch_rsi30_1m_30_d_data[stoch_rsi30_1m_d_option.unwrap()].1; // rt_price_1m_vec = &alldata.rt_price_1m_vec[rt_price_1m_option.unwrap()].1; // // filtering condition: data are ready // if ema3_1m_vec.len() >= 3 // && ema3_30m_vec.len() >= 3 // && ema10_1m_vec.len() >= 3 // && ema30_1m_vec.len() >= 3 // && sma10_1m_vec.len() >= 3 // && sma3_30m_vec.len() >= 3 // && sma30_1m_vec.len() >= 3 // && rsi3_1m_vec.len() >= 3 // && rsi30_1m_vec.len() >= 3 // && stoch_rsi3_1m_k_vec.len() >= 5 // && stoch_rsi3_1m_d_vec.len() >= 5 // && stoch_rsi30_1m_k_vec.len() >= 5 // && stoch_rsi30_1m_d_vec.len() >= 5 // && rt_price_1m_vec.len() >= 50 // { // is_filtering_passed = true; // } // // // filtering condition: SuperTrend & EMA & SMA // // if is_filtering_passed == true { // // let supertrend_option = supertrend(&symbol, &alldata.rt_price_1m_vec, 10, 1.0, false).await; // // if supertrend_option.is_some() { // // let supertrend_vec = supertrend_option.unwrap(); // // let supertrend_result = supertrend_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |SupertrendData{band_value, signal, area, close_time}| *close_time); // // let ema3_result = ema3_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // let sma10_result = sma10_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); // // if supertrend_vec.last().unwrap().signal.is_some() && ema3_result.is_ok() && sma10_result.is_ok() { // // if (((supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) && rt_price_1m_vec.last().unwrap().close_price <= supertrend_vec[supertrend_vec.len()-2].band_value * 1.0005) // // || (supertrend_vec.last().unwrap().area.contains("UP") && ema3_1m_vec[ema3_result.unwrap()-1].ema_value < sma10_1m_vec[sma10_result.unwrap()-1].sma_value && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value)) // // && sma10_1m_vec[sma10_result.unwrap()-2].sma_value < sma10_1m_vec[sma10_result.unwrap()].sma_value { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } else { is_filtering_passed = false; } // // } else { is_filtering_passed = false; } // // } // // filtering condition: SuperTrend // if is_filtering_passed == true { // let supertrend_option = // supertrend(&symbol, &alldata.rt_price_1m_vec, 30, 1.5, false).await; // if supertrend_option.is_some() { // let supertrend_vec = supertrend_option.unwrap(); // let supertrend_result = supertrend_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |SupertrendData { // band_value, // signal, // area, // close_time, // }| *close_time, // ); // if supertrend_result.is_ok() { // if supertrend_vec[supertrend_result.unwrap()] // .signal // .as_ref() // .is_some() // { // if supertrend_vec[supertrend_result.unwrap()] // .signal // .as_ref() // .unwrap() // .contains("BUY") // && supertrend_vec[supertrend_result.unwrap() - 1].band_value // + ((rt_price_1m_vec[rt_price_1m_vec.len() - 2].high_price // - rt_price_1m_vec[rt_price_1m_vec.len() - 2].low_price) // * 0.1) // > rt_price_1m_vec.last().unwrap().close_price // { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: SMA & EMA // if is_filtering_passed == true { // let sma10_1m_result = sma10_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // let sma30_1m_result = sma30_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // let ema3_1m_result = ema3_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // let ema3_30m_result = ema3_30m_vec.binary_search_by_key( // &sma3_30m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // let ema10_1m_result = ema10_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // let ema30_1m_result = ema30_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // if sma10_1m_result.is_ok() // && sma30_1m_result.is_ok() // && ema3_1m_result.is_ok() // && ema10_1m_result.is_ok() // && ema30_1m_result.is_ok() // && ema3_30m_result.is_ok() // { // if ema3_1m_vec[ema3_1m_result.unwrap()].ema_value // >= ema10_1m_vec[ema10_1m_result.unwrap()].ema_value // { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: current price limitation // // if is_filtering_passed == true { // // if rt_price_1m_vec[rt_price_1m_vec.len()-2].close_price + ((rt_price_1m_vec[rt_price_1m_vec.len()-2].high_price - rt_price_1m_vec[rt_price_1m_vec.len()-2].low_price) * 0.1) > rt_price_1m_vec.last().unwrap().close_price { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } // // filtering condition: Heatmap Volume // // if is_filtering_passed == true { // // let heatmap_volume_option = heatmap_volume(&symbol, &alldata.rt_price_1m_vec, 30, 30, 4.0, 2.5, 1.0, -0.5).await; // // if heatmap_volume_option.is_some() { // // let heatmap_volume_vec = heatmap_volume_option.unwrap(); // // let heatmap_search_result = heatmap_volume_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |HeatmapVolumeData{heatmap_value, heatmap_level, close_time}|*close_time); // // if heatmap_search_result.is_ok() { // // let heatmap_volume_trunc_vec_option = heatmap_volume_vec.get(heatmap_search_result.unwrap()-11..heatmap_search_result.unwrap()-1); // // if heatmap_volume_trunc_vec_option.is_some() { // // let heatmap_volume_trunc_vec = heatmap_volume_trunc_vec_option.unwrap(); // // let mut heat_value_summation = 0.0; // // for element in heatmap_volume_trunc_vec { // // if element.heatmap_level == HeatMapLevel::ExtraHigh { // // heat_value_summation += 2.0; // // } else if element.heatmap_level == HeatMapLevel::High { // // heat_value_summation += 1.5; // // } else if element.heatmap_level == HeatMapLevel::Medium { // // heat_value_summation += 1.0; // // } else if element.heatmap_level == HeatMapLevel::Normal { // // heat_value_summation += 0.5; // // } else { // // heat_value_summation += 0.0; // // } // // } // // if heat_value_summation >= 2.0 { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } // // } // // } else { is_filtering_passed = false; } // // } // // filtering condition: Stoch RSI // if is_filtering_passed == true { // // let sample_length: usize = 5; // // stoch_rsi10_1m_k_vec.reverse(); // // stoch_rsi10_1m_k_vec.truncate(5); // // stoch_rsi10_1m_k_vec.reverse(); // // stoch_rsi10_1m_d_vec.reverse(); // // stoch_rsi10_1m_d_vec.truncate(5); // // stoch_rsi10_1m_d_vec.reverse(); // let rsi3_k_result = stoch_rsi3_1m_k_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&StochRsiKData { // stoch_rsi_k_value, // close_time, // }| close_time, // ); // let rsi3_d_result = stoch_rsi3_1m_d_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&StochRsiDData { // stoch_rsi_d_value, // close_time, // }| close_time, // ); // let rsi30_k_result = stoch_rsi30_1m_k_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&StochRsiKData { // stoch_rsi_k_value, // close_time, // }| close_time, // ); // let rsi30_d_result = stoch_rsi30_1m_d_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&StochRsiDData { // stoch_rsi_d_value, // close_time, // }| close_time, // ); // if rsi30_k_result.is_ok() // && rsi30_d_result.is_ok() // && rsi3_k_result.is_ok() // && rsi3_d_result.is_ok() // { // if stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value // >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap() - 1].stoch_rsi_k_value // >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap() - 1] // .stoch_rsi_d_value // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value // <= 50.0 // // (stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value // // && stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value > stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // // || // // && (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= 60.0 // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-2].stoch_rsi_k_value >= stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi3_1m_d_vec[rsi3_d_result.unwrap()-1].stoch_rsi_d_value // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value) // // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // // || (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: MACD // if is_filtering_passed == true { // let macd_vec = ema_macd(&ema3_1m_vec, &ema10_1m_vec, 10).await?; // let macd_search_result = macd_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaMacd { // macd_value, // close_time, // }| close_time, // ); // if macd_search_result.is_ok() { // if macd_vec[macd_search_result.unwrap()].macd_value // > macd_vec[macd_search_result.unwrap() - 1].macd_value // { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: Ratio between amplitude and body of candles // if is_filtering_passed == true { // let sample_length: usize = 5; // 5 candle samsples // let rt_price_1m_partial_vec_option = rt_price_1m_vec // .get(rt_price_1m_vec.len() - sample_length - 1..rt_price_1m_vec.len() - 1); // if rt_price_1m_partial_vec_option.is_some() { // let rt_price_1m_partial_vec = rt_price_1m_partial_vec_option.unwrap(); // let mut sum_ratio_amp_body = 0.0; // for element in rt_price_1m_partial_vec { // sum_ratio_amp_body += (element.close_price - element.open_price).abs() // / (element.high_price - element.low_price); // } // let average_ratio_amp_body = sum_ratio_amp_body / sample_length as f64; // if average_ratio_amp_body > 0.3 { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // check all filterings are passed // if is_filtering_passed == true { // filtered_2nd_symbols.push((symbol, rt_price_1m_vec.last().unwrap().close_time)); // } // // if ema3_1m_vec.len() >= 3 && ema10_1m_vec.len() >= 3 && ema30_1m_vec.len() >= 3 && sma10_1m_vec.len() >= 3 && rsi3_1m_vec.len() >= 3 && stoch_rsi10_1m_k_vec.len() >= 5 && stoch_rsi10_1m_d_vec.len() >= 5 && stoch_rsi30_1m_k_vec.len() >= 5 && stoch_rsi30_1m_d_vec.len() >= 5 && rt_price_1m_vec.len() >= 10 { // // stoch_rsi10_1m_k_vec.reverse(); // // stoch_rsi10_1m_k_vec.truncate(5); // // stoch_rsi10_1m_k_vec.reverse(); // // stoch_rsi10_1m_d_vec.reverse(); // // stoch_rsi10_1m_d_vec.truncate(5); // // stoch_rsi10_1m_d_vec.reverse(); // // stoch_rsi30_1m_k_vec.reverse(); // // stoch_rsi30_1m_k_vec.truncate(5); // // stoch_rsi30_1m_k_vec.reverse(); // // stoch_rsi30_1m_d_vec.reverse(); // // stoch_rsi30_1m_d_vec.truncate(5); // // stoch_rsi30_1m_d_vec.reverse(); // // let supertrend_option = supertrend(&symbol, &alldata.rt_price_1m_vec, 10, 1.0, false).await; // // let heatmap_volume_option = heatmap_volume(&symbol, &alldata.rt_price_1m_vec, 30, 30, 4.0, 2.5, 1.0, -0.5).await; // // let macd_vec = ema_macd(&ema10_1m_vec, &ema30_1m_vec, 30).await?; // // if supertrend_option.is_some() && heatmap_volume_option.is_some() { // // let supertrend_vec = supertrend_option.unwrap(); // // let heatmap_volume_vec = heatmap_volume_option.unwrap(); // // let heatmap_search_result = heatmap_volume_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |HeatmapVolumeData{heatmap_value, heatmap_level, close_time}|*close_time); // // let macd_search_result = macd_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaMacd{macd_value, close_time}|close_time); // // let ema3_result = ema3_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // let ema10_result = ema10_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // let ema30_result = ema30_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // let sma10_result = sma10_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); // // if supertrend_vec.last().unwrap().signal.is_some() && heatmap_search_result.is_ok() && macd_search_result.is_ok() && ema3_result.is_ok() && ema10_result.is_ok() && ema30_result.is_ok() && sma10_result.is_ok() { // // // if supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") // // // && macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value { // // // { // // if ((supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) && current_price <= supertrend_vec[supertrend_vec.len()-2].band_value * 1.0005) // // || (supertrend_vec.last().unwrap().area.contains("UP") && ema3_1m_vec[ema3_result.unwrap()-1].ema_value < sma10_1m_vec[sma10_result.unwrap()-1].sma_value && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) // // // && current_price >= ema30_1m_vec[ema30_result.unwrap()].ema_value // // // && ema10_1m_vec[ema10_result.unwrap()-1].ema_value < ema10_1m_vec[ema10_result.unwrap()].ema_value // // // && ema10_1m_vec[ema10_result.unwrap()].ema_value >= ema30_1m_vec[ema30_result.unwrap()].ema_value // // { // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // if k_result.is_ok() && d_result.is_ok() { // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value { // // let heatmap_volume_trunc_vec_option = heatmap_volume_vec.get(heatmap_search_result.unwrap()-11..heatmap_search_result.unwrap()-1); // // if heatmap_volume_trunc_vec_option.is_some() { // // let heatmap_volume_trunc_vec = heatmap_volume_trunc_vec_option.unwrap(); // // let mut heat_value_summation = 0.0; // // for element in heatmap_volume_trunc_vec { // // if element.heatmap_level == HeatMapLevel::ExtraHigh { // // heat_value_summation += 2.0; // // } else if element.heatmap_level == HeatMapLevel::High { // // heat_value_summation += 1.5; // // } else if element.heatmap_level == HeatMapLevel::Medium { // // heat_value_summation += 1.0; // // } else if element.heatmap_level == HeatMapLevel::Normal { // // heat_value_summation += 0.5; // // } else { // // heat_value_summation += 0.0; // // } // // } // // if heat_value_summation >= 3.0 { // // filtered_2nd_symbols.push((symbol, supertrend_vec.last().unwrap().close_time)); // // } // // } // // } // // } // // } // // // } // // } // // } // // // if macd_search_result.is_ok() { // // // if macd_vec[macd_search_result.unwrap()].macd_value > 0.0 { // // // //check duplicate records // // // let mut exists_condition_build = String::from("symbol=\'"); // // // exists_condition_build.push_str(symbol.as_str()); // // // exists_condition_build.push_str("\' AND close_time="); // // // exists_condition_build.push_str(opclo_1m_vec.last().unwrap().close_time.to_string().as_str()); // // // let exists_condition = Some(exists_condition_build); // // // let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; // // // let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; // // // let inspect_result_3 = exists_record(&inspect_table_name_3, &exists_condition).await; // // // let inspect_result_4 = exists_record(&inspect_table_name_4, &exists_condition).await; // // // if inspect_result_1 == false && inspect_result_2 == false && inspect_result_3 == false && inspect_result_4 == false { // // // let mut sum_stoch_rsi30_1m_k = 0.0; // // // for element in &stoch_rsi30_1m_k_vec { // // // sum_stoch_rsi30_1m_k += element.stoch_rsi_k_value; // // // } // // // let average_stoch_rsi30_1m_k = sum_stoch_rsi30_1m_k / 5.0; // // // let ema3_3_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaData{ema_value, close_time}|close_time); // // // let ema3_2_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); // // // let ema3_1_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&EmaData{ema_value, close_time}|close_time); // // // let ema10_result = ema10_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaData{ema_value, close_time}|close_time); // // // let sma10_result = sma10_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&SmaData{sma_value, close_time}|close_time); // // // if ema3_3_result.is_ok() && ema3_2_result.is_ok() && ema3_1_result.is_ok() && ema10_result.is_ok() && sma10_result.is_ok() { // // // if sma10_1m_vec[sma10_result.unwrap()].sma_value < ema3_1m_vec[ema3_3_result.unwrap()].ema_value { // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // if k_result.is_ok() && k_prev_result.is_ok() { // // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value > 5.0 // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value < 80.0 // // // && stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 96.0 // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0 { // // // if current_price <= opclo_1m_vec[1].opclo_price * ((((opclo_1m_vec[1].high_price / opclo_1m_vec[1].low_price) - 1.0) / 2.0) + 1.0) { // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // } // // // } // // // } // // // } // // // // if ema10_1m_vec[ema10_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value { // // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema10_1m_vec[ema10_result.unwrap()].ema_value { // // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema3_1m_vec[ema3_2_result.unwrap()].ema_value // // // // && ema3_1m_vec[ema3_2_result.unwrap()].ema_value > ema3_1m_vec[ema3_1_result.unwrap()].ema_value // // // // { // // // // if average_stoch_rsi30_1m_k < 80.0 { // // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let k_prev2_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // // if k_result.is_ok() && d_result.is_ok() && k_prev_result.is_ok() && k_prev2_result.is_ok() { // // // // if // // // // (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) > 3.0 // // // // && stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 96.0 // // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev2_result.unwrap()].stoch_rsi_k_value) // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) < 25.0 // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) > 3.0 // // // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0) // // // // // (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value > 5.0) && // // // // // ((stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value <= 80.0) // // // // // || (((opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0) && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value))) // // // // { // // // // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0 { // // // // // if (opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 // // // // // { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // // } else { // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // if opclo_1m_vec[1].candle_type == "DOWN" && opclo_1m_vec[1].opclo_price >= opclo_1m_vec[2].close_price { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } else if opclo_1m_vec[1].candle_type == "UP" { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // } // // // // // else { // // // // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); // // // // // if result.is_ok() { // // // // // if rsi3_1m_vec[result.unwrap()].rsi_value < 20.0 && cnt >= 2 && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // // } // // // // // } // // // // // } else { // // // // // if cnt >= 2 { // // // // // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); // // // // // match result { // // // // // Ok(T) => { // // // // // if ema3_1m_vec[T].ema_value > opclo_1m_vec[1].opclo_price { // // // // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); // // // // // match result { // // // // // Ok(T) => { // // // // // if rsi3_1m_vec[T].rsi_value < 15.0 { // // // // // let k_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // // let d_result = stoch_rsi10_1m_d_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // // // if k_result.is_ok() && d_result.is_ok() { // // // // // if stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value <= stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value { // // // // // if current_price < opclo_1m_vec[1].opclo_price { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // // } // // // // // } // // // // // } // // // // // }, // // // // // Err(E) => {} // // // // // } // // // // // } // // // // // }, // // // // // Err(E) => {} // // // // // } // // // // // } // // // // // } // // // // } // // // // } else { // // // // let k_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let k_prev_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let k_prev2_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let d_result = stoch_rsi10_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // // if k_result.is_ok() && d_result.is_ok() && k_prev_result.is_ok() && k_prev2_result.is_ok() { // // // // if (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) // // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) > 3.0 // // // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev2_result.unwrap()].stoch_rsi_k_value // // // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value // // // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value < 30.0 // // // // && stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 95.0 // // // // { // // // // // if stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0 { // // // // // if (opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 // // // // // { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // // } else { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // } // // // // } // // // // } // // // // } // // // // } // // // // // else { // // // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // // // if k_result.is_ok() && k_prev_result.is_ok() { // // // // // if (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) // // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) > 5.0 // // // // // { // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // } // // // // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value < ema3_1m_vec[ema3_2_result.unwrap()].ema_value { // // // // // // if opclo_1m_vec[1].candle_type == "DOWN" && opclo_1m_vec[1].open_price > ema3_1m_vec[ema3_2_result.unwrap()].ema_value // // // // // // && opclo_1m_vec[2].open_price < ema3_1m_vec[ema3_3_result.unwrap()].ema_value // // // // // // && opclo_1m_vec[2].high_price < ema3_1m_vec[ema3_3_result.unwrap()].ema_value // // // // // // && opclo_1m_vec[2].candle_type == "UP" { // // // // // // if (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value < stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) // // // // // // { // // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // // } // // // // // // } // // // // // // } else if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema3_1m_vec[ema3_2_result.unwrap()].ema_value // // // // // // { // // // // // // if opclo_1m_vec[1].candle_type == "UP" // // // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) { // // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // // // } // // // // // // } // // // // // } // // // // // } // // // // } // // // } // // // } // // // } // // // // else if macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value && macd_vec[macd_search_result.unwrap()].macd_value > -3.0{ // // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // // // if k_result.is_ok() && k_prev_result.is_ok() && d_result.is_ok() { // // // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value // // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value // // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0{ // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // // // } // // // // } // // // // } // // // } // // } // } // } // } // // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // // if market_cap_index.first().unwrap().negative_buy_signal == 1 || (market_cap_index.first().unwrap().liquidation_signal == 0 && market_cap_index.first().unwrap().market_cap_index <= 20.0 && market_cap_index.first().unwrap().market_cap_index >= 0.0) { // // let mut rsi3_1m_vec: Vec = Vec::new(); // // let mut opclo_1m_vec: Vec = Vec::new(); // // let mut ema3_1m_vec: Vec = Vec::new(); // // let mut cnt = 0; // // for symbol in filtered_symbols { // // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // // if rsi3_1m_option.is_some() && opclo_1m_option.is_some() && ema3_1m_option.is_some() { // // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // // if rsi3_1m_vec.len() >= 3 && opclo_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 3 { // // opclo_1m_vec.reverse(); // // opclo_1m_vec.truncate(3); // // opclo_1m_vec.reverse(); // // if opclo_1m_vec.last().unwrap().candle_type == "UP" { // // cnt = 0; // // for element in &opclo_1m_vec { // // if element.candle_type == "DOWN" { // // cnt += 1; // // } // // } // // if cnt >= 2 { // // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if ema3_1m_vec[T].ema_value > opclo_1m_vec[1].opclo_price { // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi3_1m_vec[T].rsi_value < 30.0 { // // if current_price < opclo_1m_vec[1].opclo_price { // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // } // // } // // } else if market_cap_index.first().unwrap().liquidation_signal == 1 && market_cap_index.first().unwrap().market_cap_index < - 10.0 { // // let mut rsi3_1m_vec: Vec = Vec::new(); // // let mut rsi10_1m_vec: Vec = Vec::new(); // // let mut rsi30_1m_vec: Vec = Vec::new(); // // let mut op_low_1m_vec: Vec = Vec::new(); // // let mut ema3_1m_vec: Vec = Vec::new(); // // let mut bb30_1m_vec: Vec = Vec::new(); // // let mut cnt = 0; // // for symbol in filtered_symbols { // // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // // let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); // // let op_low_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); // // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && rsi30_1m_option.is_some() && op_low_1m_option.is_some() && ema3_1m_option.is_some() && bb30_1m_option.is_some() { // // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // // rsi30_1m_vec = alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1.clone(); // // op_low_1m_vec = alldata.rt_price_1m_vec[op_low_1m_option.unwrap()].1.clone(); // // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); // // if rsi3_1m_vec.len() >= 3 && rsi10_1m_vec.len() >= 3 && rsi30_1m_vec.len() >= 3 && op_low_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 3 && bb30_1m_vec.len() >= 3 { // // op_low_1m_vec.reverse(); // // op_low_1m_vec.truncate(5); // // op_low_1m_vec.reverse(); // // if op_low_1m_vec.last().unwrap().candle_type == "DOWN" { // // cnt = 0; // // for element in &op_low_1m_vec { // // if element.candle_type == "DOWN" { // // cnt += 1; // // } // // } // // if cnt >= 4 { // // let result = ema3_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if ema3_1m_vec[T].ema_value > (op_low_1m_vec.last().unwrap().open_price + op_low_1m_vec.last().unwrap().low_price) / 2.0 { // // let result = rsi3_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi3_1m_vec[T].rsi_value < 10.0 { // // let result = rsi10_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi10_1m_vec[T].rsi_value < 15.0 { // // let result = rsi30_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi30_1m_vec[T].rsi_value < 35.0 { // // let result = bb30_1m_vec.binary_search_by_key(&op_low_1m_vec.first().unwrap().close_time, |&BollingerBandData{sma, upperband, lowerband, close_time}|close_time); // // match result { // // Ok(T) => { // // if bb30_1m_vec[T].lowerband > (op_low_1m_vec.last().unwrap().open_price + op_low_1m_vec.last().unwrap().low_price) / 2.0 { // // filtered_2nd_symbols.push((symbol, op_low_1m_vec.last().unwrap().close_time)); // // } // // }, // // Err(E) => {}, // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // } // // } // // } // insert_pre_suggested_coins(1, &filtered_2nd_symbols, alldata).await; // Ok(()) // } // Supertrend UP area에서 이득보기 // pub async fn execute_strategist_for_test2( // alldata: &AllData, // ) -> Result<(), Box> { // let inspect_table_name_1 = String::from("buy_ordered_coin_list"); // let inspect_table_name_2 = String::from("sell_ordered_coin_list"); // let inspect_table_name_3 = String::from("pre_suggested_coin_list"); // let inspect_table_name_4 = String::from("suggested_coin_list"); // let market_cap_index = select_marketcap().await; // let mut filtered_symbols: Vec = Vec::new(); // filtered_symbols.push(String::from("BTCUSDT")); // let current_price = get_current_price(&filtered_symbols.first().unwrap(), &alldata.price_vec) // .await // .unwrap(); // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // let mut ema3_1m_vec: &Vec = &Vec::new(); // let mut ema3_30m_vec: &Vec = &Vec::new(); // let mut ema10_1m_vec: &Vec = &Vec::new(); // let mut ema30_1m_vec: &Vec = &Vec::new(); // let mut sma3_1m_vec: &Vec = &Vec::new(); // let mut sma10_1m_vec: &Vec = &Vec::new(); // let mut sma3_30m_vec: &Vec = &Vec::new(); // let mut sma30_1m_vec: &Vec = &Vec::new(); // let mut rsi3_1m_vec: &Vec = &Vec::new(); // let mut rsi30_1m_vec: &Vec = &Vec::new(); // let mut stoch_rsi3_1m_k_vec: &Vec = &Vec::new(); // let mut stoch_rsi3_1m_d_vec: &Vec = &Vec::new(); // let mut stoch_rsi30_1m_k_vec: &Vec = &Vec::new(); // let mut stoch_rsi30_1m_d_vec: &Vec = &Vec::new(); // let mut rt_price_1m_vec: &Vec = &Vec::new(); // let mut is_filtering_passed: bool = false; // let mut cnt = 0; // let exists_condition = Some(String::from("used_usdt >= 10.0 AND registerer = 2")); // let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; // let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; // let inspect_result_4 = exists_record(&inspect_table_name_4, &None).await; // let mut is_buy_period_30m = false; // if inspect_result_1 == false && inspect_result_2 == false && inspect_result_4 == false { // for symbol in filtered_symbols { // is_filtering_passed = false; // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); // let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); // let ema30_1m_option = alldata.ema30_1m_data.iter().position(|x| *x.0 == *symbol); // let sma3_1m_option = alldata.sma3_1m_data.iter().position(|x| *x.0 == *symbol); // let sma10_1m_option = alldata.sma10_1m_data.iter().position(|x| *x.0 == *symbol); // let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); // let sma30_1m_option = alldata.sma30_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); // let stoch_rsi3_1m_k_option = alldata // .stoch_rsi3_1m_3_k_data // .iter() // .position(|x| *x.0 == *symbol); // let stoch_rsi3_1m_d_option = alldata // .stoch_rsi3_1m_3_d_data // .iter() // .position(|x| *x.0 == *symbol); // let stoch_rsi30_1m_k_option = alldata // .stoch_rsi30_1m_30_k_data // .iter() // .position(|x| *x.0 == *symbol); // let stoch_rsi30_1m_d_option = alldata // .stoch_rsi30_1m_30_d_data // .iter() // .position(|x| *x.0 == *symbol); // let rt_price_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // if ema3_1m_option.is_some() // && ema3_30m_option.is_some() // && ema10_1m_option.is_some() // && ema30_1m_option.is_some() // && sma3_1m_option.is_some() // && sma10_1m_option.is_some() // && sma3_30m_option.is_some() // && sma30_1m_option.is_some() // && rsi3_1m_option.is_some() // && rsi30_1m_option.is_some() // && stoch_rsi3_1m_k_option.is_some() // && stoch_rsi3_1m_d_option.is_some() // && stoch_rsi30_1m_k_option.is_some() // && stoch_rsi30_1m_d_option.is_some() // && rt_price_1m_option.is_some() // { // ema3_1m_vec = &alldata.ema3_1m_data[ema3_1m_option.unwrap()].1; // ema3_30m_vec = &alldata.ema3_30m_data[ema3_30m_option.unwrap()].1; // ema10_1m_vec = &alldata.ema10_1m_data[ema10_1m_option.unwrap()].1; // ema30_1m_vec = &alldata.ema30_1m_data[ema30_1m_option.unwrap()].1; // sma3_1m_vec = &alldata.sma3_1m_data[sma3_1m_option.unwrap()].1; // sma10_1m_vec = &alldata.sma10_1m_data[sma10_1m_option.unwrap()].1; // sma3_30m_vec = &alldata.sma3_30m_data[sma3_30m_option.unwrap()].1; // sma30_1m_vec = &alldata.sma30_1m_data[sma30_1m_option.unwrap()].1; // rsi3_1m_vec = &alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1; // rsi30_1m_vec = &alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1; // stoch_rsi3_1m_k_vec = // &alldata.stoch_rsi3_1m_3_k_data[stoch_rsi3_1m_k_option.unwrap()].1; // stoch_rsi3_1m_d_vec = // &alldata.stoch_rsi3_1m_3_d_data[stoch_rsi3_1m_d_option.unwrap()].1; // stoch_rsi30_1m_k_vec = // &alldata.stoch_rsi30_1m_30_k_data[stoch_rsi30_1m_k_option.unwrap()].1; // stoch_rsi30_1m_d_vec = // &alldata.stoch_rsi30_1m_30_d_data[stoch_rsi30_1m_d_option.unwrap()].1; // rt_price_1m_vec = &alldata.rt_price_1m_vec[rt_price_1m_option.unwrap()].1; // // filtering condition: data are ready // if ema3_1m_vec.len() >= 3 // && ema3_30m_vec.len() >= 3 // && ema10_1m_vec.len() >= 3 // && ema30_1m_vec.len() >= 3 // && sma3_1m_vec.len() >= 3 // && sma10_1m_vec.len() >= 3 // && sma3_30m_vec.len() >= 3 // && sma30_1m_vec.len() >= 3 // && rsi3_1m_vec.len() >= 3 // && rsi30_1m_vec.len() >= 3 // && stoch_rsi3_1m_k_vec.len() >= 5 // && stoch_rsi3_1m_d_vec.len() >= 5 // && stoch_rsi30_1m_k_vec.len() >= 5 // && stoch_rsi30_1m_d_vec.len() >= 5 // && rt_price_1m_vec.len() >= 50 // { // is_filtering_passed = true; // } // // // filtering condition: SuperTrend & EMA & SMA // // if is_filtering_passed == true { // // let supertrend_option = supertrend(&symbol, &alldata.rt_price_1m_vec, 10, 1.0, false).await; // // if supertrend_option.is_some() { // // let supertrend_vec = supertrend_option.unwrap(); // // let supertrend_result = supertrend_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |SupertrendData{band_value, signal, area, close_time}| *close_time); // // let ema3_result = ema3_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // // let sma10_result = sma10_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); // // if supertrend_vec.last().unwrap().signal.is_some() && ema3_result.is_ok() && sma10_result.is_ok() { // // if (((supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) && rt_price_1m_vec.last().unwrap().close_price <= supertrend_vec[supertrend_vec.len()-2].band_value * 1.0005) // // || (supertrend_vec.last().unwrap().area.contains("UP") && ema3_1m_vec[ema3_result.unwrap()-1].ema_value < sma10_1m_vec[sma10_result.unwrap()-1].sma_value && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value)) // // && sma10_1m_vec[sma10_result.unwrap()-2].sma_value < sma10_1m_vec[sma10_result.unwrap()].sma_value { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } else { is_filtering_passed = false; } // // } else { is_filtering_passed = false; } // // } // // filtering condition: SuperTrend // if is_filtering_passed == true { // let supertrend_option = // supertrend(&symbol, &alldata.rt_price_1m_vec, 3, 1.0, false).await; // if supertrend_option.is_some() { // let supertrend_vec = supertrend_option.unwrap(); // let supertrend_result = supertrend_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |SupertrendData { // band_value, // signal, // area, // close_time, // }| *close_time, // ); // if supertrend_result.is_ok() { // if supertrend_vec[supertrend_result.unwrap()] // .signal // .as_ref() // .is_some() // { // if supertrend_vec[supertrend_result.unwrap()] // .signal // .as_ref() // .unwrap() // .contains("BUY") // { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: SMA & EMA // if is_filtering_passed == true { // let sma3_1m_result = sma3_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // let sma10_1m_result = sma10_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // let sma30_1m_result = sma30_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // let ema3_1m_result = ema3_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // let ema3_30m_result = ema3_30m_vec.binary_search_by_key( // &sma3_30m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // let ema10_1m_result = ema10_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // let ema30_1m_result = ema30_1m_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // if sma10_1m_result.is_ok() // && sma30_1m_result.is_ok() // && ema3_1m_result.is_ok() // && ema10_1m_result.is_ok() // && ema30_1m_result.is_ok() // && ema3_30m_result.is_ok() // { // if sma3_1m_vec[sma3_1m_result.unwrap()].sma_value // > sma3_1m_vec[sma3_1m_result.unwrap() - 1].sma_value // && sma3_1m_vec[sma3_1m_result.unwrap()].sma_value // > sma3_1m_vec[sma3_1m_result.unwrap() - 2].sma_value // && sma3_1m_vec[sma3_1m_result.unwrap() - 1].sma_value // > sma3_1m_vec[sma3_1m_result.unwrap() - 2].sma_value // && sma30_1m_vec[sma30_1m_result.unwrap()].sma_value // > rt_price_1m_vec.last().unwrap().close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 1].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 2].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 2].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 3].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 3].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 4].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 4].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 5].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 5].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 6].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 6].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 7].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 7].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 8].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 8].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 9].close_price // && sma30_1m_vec[sma30_1m_result.unwrap() - 9].sma_value // > rt_price_1m_vec[rt_price_1m_vec.len() - 10].close_price // // ema10_1m_vec[ema10_1m_result.unwrap()].ema_value > sma10_1m_vec[sma10_1m_result.unwrap()].sma_value // // ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value <= sma10_1m_vec[sma10_1m_result.unwrap()-1].sma_value // // (sma10_1m_vec[sma10_1m_result.unwrap()].sma_value - ema10_1m_vec[ema10_1m_result.unwrap()].ema_value).abs() >= (sma10_1m_vec[sma10_1m_result.unwrap()-1].sma_value - ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value).abs() // // && ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value < ema10_1m_vec[ema10_1m_result.unwrap()].ema_value // // && ema10_1m_vec[ema10_1m_result.unwrap()-2].ema_value < ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value // // && sma10_1m_vec[sma10_1m_result.unwrap()].sma_value > ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-1].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-2].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-3].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-4].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-5].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-2].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-1].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-3].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-2].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-4].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-3].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-5].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-4].ema_value // // && ema30_1m_vec[ema30_1m_result.unwrap()-5].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // // && rt_price_1m_vec.last().unwrap().close_price > ema30_1m_vec[ema30_1m_result.unwrap()].ema_value // { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: current price limitation // // if is_filtering_passed == true { // // if rt_price_1m_vec[rt_price_1m_vec.len()-2].close_price + ((rt_price_1m_vec[rt_price_1m_vec.len()-2].high_price - rt_price_1m_vec[rt_price_1m_vec.len()-2].low_price) * 0.5) > rt_price_1m_vec.last().unwrap().close_price { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } // // filtering condition: Heatmap Volume // if is_filtering_passed == true { // let heatmap_volume_option = heatmap_volume( // &symbol, // &alldata.rt_price_1m_vec, // 30, // 30, // 4.0, // 2.5, // 1.0, // -0.5, // ) // .await; // if heatmap_volume_option.is_some() { // let heatmap_volume_vec = heatmap_volume_option.unwrap(); // let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( // &rt_price_1m_vec.last().unwrap().close_time, // |HeatmapVolumeData { // heatmap_value, // heatmap_level, // close_time, // }| *close_time, // ); // if heatmap_search_result.is_ok() { // let heatmap_volume_trunc_vec_option = heatmap_volume_vec.get( // heatmap_search_result.unwrap() - 11 // ..heatmap_search_result.unwrap() - 1, // ); // if heatmap_volume_trunc_vec_option.is_some() { // let heatmap_volume_trunc_vec = // heatmap_volume_trunc_vec_option.unwrap(); // let mut heat_value_summation = 0.0; // for element in heatmap_volume_trunc_vec { // if element.heatmap_level == HeatMapLevel::ExtraHigh { // heat_value_summation += 2.0; // } else if element.heatmap_level == HeatMapLevel::High { // heat_value_summation += 1.5; // } else if element.heatmap_level == HeatMapLevel::Medium { // heat_value_summation += 1.0; // } else if element.heatmap_level == HeatMapLevel::Normal { // heat_value_summation += 0.5; // } else { // heat_value_summation += 0.0; // } // } // if heat_value_summation >= 1.5 { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } // } // } else { // is_filtering_passed = false; // } // } // // filtering condition: Stoch RSI // // if is_filtering_passed == true { // // // let sample_length: usize = 5; // // // stoch_rsi10_1m_k_vec.reverse(); // // // stoch_rsi10_1m_k_vec.truncate(5); // // // stoch_rsi10_1m_k_vec.reverse(); // // // stoch_rsi10_1m_d_vec.reverse(); // // // stoch_rsi10_1m_d_vec.truncate(5); // // // stoch_rsi10_1m_d_vec.reverse(); // // let rsi3_k_result = stoch_rsi3_1m_k_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let rsi3_d_result = stoch_rsi3_1m_d_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // let rsi30_k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); // // let rsi30_d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); // // if rsi30_k_result.is_ok() && rsi30_d_result.is_ok() && rsi3_k_result.is_ok() && rsi3_d_result.is_ok() { // // if // // // stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value <= 80.0 || stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value <= 80.0 // // // (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi3_1m_d_vec[rsi3_d_result.unwrap()].stoch_rsi_d_value) // // (stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()-1].stoch_rsi_k_value // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // // // (stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value // // // && stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value > stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value // // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // // // || // // || (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= 60.0 // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-2].stoch_rsi_k_value >= stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi3_1m_d_vec[rsi3_d_result.unwrap()-1].stoch_rsi_d_value // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value) // // // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // // // || (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 // // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 // // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value // // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) // // { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } else { is_filtering_passed = false; } // // } // // // filtering condition: MACD // // if is_filtering_passed == true { // // let macd_vec = ema_macd(&ema3_1m_vec, &ema10_1m_vec, 10).await?; // // let macd_search_result = macd_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&EmaMacd{macd_value, close_time}|close_time); // // if macd_search_result.is_ok() { // // if macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value { // // is_filtering_passed = true; // // } else { is_filtering_passed = false; } // // } else { is_filtering_passed = false; } // // } // // filtering condition: Ratio between amplitude and body of candles // if is_filtering_passed == true { // let sample_length: usize = 5; // 5 candle samsples // let rt_price_1m_partial_vec_option = rt_price_1m_vec // .get(rt_price_1m_vec.len() - sample_length - 1..rt_price_1m_vec.len() - 1); // if rt_price_1m_partial_vec_option.is_some() { // let rt_price_1m_partial_vec = rt_price_1m_partial_vec_option.unwrap(); // let mut sum_ratio_amp_body = 0.0; // for element in rt_price_1m_partial_vec { // sum_ratio_amp_body += (element.close_price - element.open_price).abs() // / (element.high_price - element.low_price); // } // let average_ratio_amp_body = sum_ratio_amp_body / sample_length as f64; // if average_ratio_amp_body > 0.3 { // is_filtering_passed = true; // } else { // is_filtering_passed = false; // } // } else { // is_filtering_passed = false; // } // } // // check all filterings are passed // if is_filtering_passed == true { // filtered_2nd_symbols.push((symbol, rt_price_1m_vec.last().unwrap().close_time)); // } // } // } // } // insert_pre_suggested_coins(2, &filtered_2nd_symbols, alldata).await; // Ok(()) // } // pub async fn strategist_001 (alldata: &AllData) -> Result<(), Box> { // // [strategist_001 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) // // 3. 2nd filtering symbols (opclo_30m price at the previous candle < bb_sma30_30m lowerband) // // 4. insert or update record into [strategist_001_table] // // 5. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] // // 1. retrieve all usdttrade symbols // let signal_decision = select_signal_decision().await; // // 3. 1st filtering symbols: 5 samples of candle 30m has 4 DOWN candles at least && the latest candle 30m < SMA3 // let mut opclo_30m_vec: Vec = Vec::new(); // let mut sma3_30m_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // let mut cnt = 0; // for symbol in &alldata.valid_symbol_vec { // let opclo_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == *symbol); // let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); // // read 1d csv file & bollingerband sma30 csv file // if opclo_30m_option.is_some() & sma3_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()].1.clone(); // sma3_30m_vec = alldata.sma3_30m_data[sma3_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 && sma3_30m_vec.len() >= 1 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // opclo_30m_vec.reverse(); // cnt = 0; // for element in &opclo_30m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 4 { // let result = sma3_30m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); // match result { // Ok(T) => { // if sma3_30m_vec[T].sma_value > opclo_30m_vec.last().unwrap().opclo_price { // filtered_1st_symbols.push(symbol.clone()); // } // }, // Err(E) => {} // } // } // } // } // } // // 4. 2nd filtering symbols: 30m RSI 3 < 15, 30m RSI 10 < 25 // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for symbol in filtered_1st_symbols { // let rsi3_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == *symbol); // if rsi3_option.is_some() && rsi10_option.is_some() && opclo_30m_option.is_some() { // rsi3_vec = alldata.rsi3_30m_data[rsi3_option.unwrap()].1.clone(); // rsi10_vec = alldata.rsi10_30m_data[rsi10_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()].1.clone(); // if rsi3_vec.len() >= 1 && rsi10_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // let result = rsi3_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // match result { // Ok(T) => { // if rsi3_vec[T].rsi_value < 15.0 { // let result = rsi10_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // match result { // Ok(T) => { // if rsi10_vec[T].rsi_value < 25.0 { // filtered_2nd_symbols.push(symbol); // } // }, // Err(E) => {} // } // } // }, // Err(E) => {} // } // } // } // } // // 3. 3rd filtering symbols: 5 samples of candle 1m has 4 DOWN candles at least && the latest candle 1m < EMA3 // let mut opclo_1m_vec: Vec = Vec::new(); // let mut ema3_1m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // let mut cnt = 0; // for symbol in filtered_2nd_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // // read 1d csv file & bollingerband sma30 csv file // if opclo_1m_option.is_some() & ema3_1m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // if opclo_1m_vec.len() >= 5 && ema3_1m_vec.len() >= 1 { // opclo_1m_vec.reverse(); // opclo_1m_vec.truncate(5); // opclo_1m_vec.reverse(); // cnt = 0; // for element in &opclo_1m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 4 { // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); // match result { // Ok(T) => { // if ema3_1m_vec[T].ema_value > opclo_1m_vec.last().unwrap().opclo_price { // filtered_3rd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); // } // }, // Err(E) => {} // } // } // } // } // } // // // 2. 2nd filtering symbols: candle 1m price avg < candle 30m price avg // // let mut opclo_1m_vec: Vec = Vec::new(); // // let mut opclo_1m_price_avg = 0.0; // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut opclo_30m_price_avg = 0.0; // // let mut filtered_2nd_symbols: Vec = Vec::new(); // // for element in filtered_1st_symbols { // // // initialize avgs // // opclo_1m_price_avg = 0.0; // // opclo_30m_price_avg = 0.0; // // let opclo_1m_result = read_price_into_vector("1m", &element).await; // // let opclo_30m_result = read_price_into_vector("30m", &element).await; // // // read 1d csv file // // if opclo_1m_result.is_ok() && opclo_30m_result.is_ok() { // // let opclo_1m_option = opclo_1m_result?; // // let opclo_30m_option = opclo_30m_result?; // // if opclo_1m_option.is_some() && opclo_30m_option.is_some() { // // opclo_1m_vec = opclo_1m_option.unwrap(); // // opclo_30m_vec = opclo_30m_option.unwrap(); // // if opclo_1m_vec.len() >= 10 && opclo_30m_vec.len() >= 4 { // // opclo_1m_vec.reverse(); // // opclo_1m_vec.split_off(10); // // opclo_30m_vec.reverse(); // // opclo_30m_vec.split_off(4); // // // calculate opclo 1m price average // // for element in &opclo_1m_vec { // // opclo_1m_price_avg += element.opclo_price; // // } // // opclo_1m_price_avg /= opclo_1m_vec.len() as f64; // // // calculate opclo 30m price average // // for element in &opclo_30m_vec { // // opclo_30m_price_avg += element.opclo_price; // // } // // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // // campare both prices // // if opclo_1m_price_avg < opclo_30m_price_avg * 0.98 { // // filtered_2nd_symbols.push(element); // // } // // } // // } // // } // // } // // // 3. 2nd filtering symbols: 85% of BB SMA10 MA price > candle 1d price yesterday avg // // let mut opclo_1d_vec: Vec = Vec::new(); // // let mut read_bb_vec: Vec = Vec::new(); // // let mut filtered_2nd_symbols: Vec = Vec::new(); // // for element in filtered_1st_symbols { // // let opclo_1d_result = read_price_into_vector("1d", &element).await; // // let read_bb_result = read_bb_into_vector("sma10", "1d", &element).await; // // // read 1d csv file & bollingerband sma30 csv file // // if opclo_1d_result.is_ok() & read_bb_result.is_ok() { // // let opclo_1d_option = opclo_1d_result?; // // let read_bb_option = read_bb_result?; // // if opclo_1d_option.is_some() && read_bb_option.is_some() { // // opclo_1d_vec = opclo_1d_option.unwrap(); // // read_bb_vec = read_bb_option.unwrap(); // // if opclo_1d_vec.len() > 1 && read_bb_vec.len() > 1 { // // opclo_1d_vec.pop(); // // read_bb_vec.pop(); // // let result = read_bb_vec.binary_search_by_key(&opclo_1d_vec.last().unwrap().close_time, |&BBData{ma_price, upperband, lowerband, close_time}|close_time); // // match result { // // Ok(T) => { // // if read_bb_vec[T].ma_price > opclo_1d_vec.last().unwrap().opclo_price { // // filtered_2nd_symbols.push(element); // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // } // // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price // // let mut read_bb_vec: Vec = Vec::new(); // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // for element in filtered_2nd_symbols { // // // read 30m csv file & bollingerband sma30 csv file // // let opclo_30m_result = read_price_into_vector("30m", &element).await; // // let bb_result = read_bb_into_vector("sma30", "30m", &element).await; // // if opclo_30m_result.is_ok() && bb_result.is_ok() { // // let opclo_30m_option = opclo_30m_result?; // // let read_bb_option = bb_result?; // // if opclo_30m_option.is_some() && read_bb_option.is_some() { // // opclo_30m_vec = opclo_30m_option.unwrap(); // // read_bb_vec = read_bb_option.unwrap(); // // // 2nd filtering symbols // // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&BBData{ma_price, upperband, lowerband, close_time}|close_time); // // match result { // // Ok(T) => { // // if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().opclo_price { // // filtered_3rd_symbols.push((element, read_bb_vec[T].close_time)); // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(1, &filtered_3rd_symbols, alldata).await; // // println!("strategist_001 완료"); // Ok(()) // } // pub async fn strategist_002( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_002 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) // // 3. 2nd filtering symbols (sma30 price > opclo_30m price, check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample) // // 4. if the two conditions are right, upload the filtered symbols into [strategist_002_table] // // 5. monitor price of symbols in [strategist_002_table], and upload them into [suggested_coin_list] when price seems to become high // let signal_decision = select_signal_decision().await; // if signal_decision[0].decision.contains("UP") { // // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg // let mut opclo_1m_vec: Vec = Vec::new(); // let mut opclo_1m_price_avg = 0.0; // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_30m_price_avg = 0.0; // let mut filtered_1st_symbols: Vec = Vec::new(); // for symbol in &alldata.valid_symbol_vec { // // initialize avgs // opclo_1m_price_avg = 0.0; // opclo_30m_price_avg = 0.0; // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // // read 1d csv file // if opclo_1m_option.is_some() && opclo_30m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if opclo_1m_vec.len() >= 10 && opclo_30m_vec.len() >= 4 { // opclo_1m_vec.reverse(); // opclo_1m_vec.split_off(10); // opclo_30m_vec.reverse(); // opclo_30m_vec.split_off(4); // // calculate opclo 1m price average // for element in &opclo_1m_vec { // opclo_1m_price_avg += element.opclo_price; // } // opclo_1m_price_avg /= opclo_1m_vec.len() as f64; // // calculate opclo 30m price average // for element in &opclo_30m_vec { // opclo_30m_price_avg += element.opclo_price; // } // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // campare both prices // if opclo_1m_price_avg < opclo_30m_price_avg * 0.97 { // filtered_1st_symbols.push(symbol.clone()); // } // } // } // } // // 3. 2nd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.2 of the middle sample // let mut sma10_30m_vec: Vec = Vec::new(); // let mut rsi30_30m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_1st_symbols { // // read 30m opclo, SMA30, rsi30 csv file // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let sma10_30m_option = alldata.sma10_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi30_30m_option = alldata.rsi30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() // && sma10_30m_option.is_some() // && rsi30_30m_option.is_some() // { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // sma10_30m_vec = alldata.sma10_30m_data[sma10_30m_option.unwrap()].1.clone(); // rsi30_30m_vec = alldata.rsi30_30m_data[rsi30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 && sma10_30m_vec.len() >= 5 && rsi30_30m_vec.len() >= 5 // { // opclo_30m_vec.pop(); // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // // 2nd filtering symbols // let result = sma10_30m_vec.binary_search_by_key( // &opclo_30m_vec.first().unwrap().close_time, // |SmaData { // sma_value, // close_time, // }| *close_time, // ); // match result { // Ok(T) => { // if sma10_30m_vec[T].sma_value > opclo_30m_vec[0].opclo_price { // let index_of_min: Option = opclo_30m_vec // .iter() // .enumerate() // .min_by(|(_, a), (_, b)| { // a.opclo_price // .partial_cmp(&b.opclo_price) // .expect("Nan was forbidden.") // }) // .map(|(index, _)| index); // // index 1 means the middle index of 5 element in a vec, assuming the latest price is included but removed in the vec. // if index_of_min == Some(0) { // let result = rsi30_30m_vec.binary_search_by_key( // &opclo_30m_vec[0].close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi30_30m_vec[T].rsi_value < 20.0 { // filtered_2nd_symbols.push(( // symbol, // opclo_30m_vec.last().unwrap().close_time, // )); // } // } // Err(e) => {} // } // } // } // } // Err(E) => {} // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(2, &filtered_2nd_symbols, alldata).await; // } // // println!("strategist_002 완료"); // Ok(()) // } // pub async fn strategist_003( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_003 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) // // 3. 2nd filtering symbols (opclo_30m price at the previous candle < bb_sma30_30m lowerband) // // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI30 is lower than 0.25 of the middle sample) // // 5. if the two conditions are right, upload the filtered symbols into [suggested_coin_list] // let signal_decision = select_signal_decision().await; // if signal_decision[0].decision.contains("UP") { // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols: yesterday and today's candle 1d opclo price < EMA10 // let mut opclo_1d_vec: Vec = Vec::new(); // let mut ema10_1d_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // for symbol in &alldata.valid_symbol_vec { // // read 1d csv file // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1d_option = alldata.rsi10_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && ema10_1d_option.is_some() && rsi10_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // ema10_1d_vec = alldata.ema10_1d_data[ema10_1d_option.unwrap()].1.clone(); // rsi10_vec = alldata.rsi10_1d_data[rsi10_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && ema10_1d_vec.len() >= 2 && rsi10_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.split_off(2); // ema10_1d_vec.reverse(); // ema10_1d_vec.split_off(2); // rsi10_vec.reverse(); // rsi10_vec.split_off(2); // let result = ema10_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |EmaData { // ema_value, // close_time, // }| *close_time, // ); // match result { // Ok(T) => { // if ema10_1d_vec[T].ema_value > opclo_1d_vec[1].opclo_price { // let result = rsi10_vec.binary_search_by_key( // &opclo_1d_vec[1].close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_vec[T].rsi_value < 20.0 { // let result = ema10_1d_vec.binary_search_by_key(&opclo_1d_vec.first().unwrap().close_time, |EmaData{ema_value, close_time}| *close_time); // match result { // Ok(T) => { // if ema10_1d_vec[T].ema_value // > opclo_1d_vec[0].opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(e) => {} // } // } // } // Err(e) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price // let mut opclo_30m_vec: Vec = Vec::new(); // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // (symbol, closetime) // for symbol in filtered_1st_symbols { // // read 30m csv file // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && bb30_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // read_bb_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 1 && read_bb_vec.len() >= 1 { // let result = read_bb_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().opclo_price // { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // } // // 4. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample // let mut low_1m_vec: Vec = Vec::new(); // let mut bb30_1m_vec: Vec = Vec::new(); // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_2nd_symbols { // let low_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // if low_1m_option.is_some() // && bb30_1m_option.is_some() // && rsi3_1m_option.is_some() // && rsi10_1m_option.is_some() // { // low_1m_vec = alldata.rt_price_1m_vec[low_1m_option.unwrap()].1.clone(); // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); // rsi3_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // if low_1m_vec.len() >= 1 // && bb30_1m_vec.len() >= 1 // && rsi3_vec.len() >= 1 // && rsi10_vec.len() >= 1 // { // let result = bb30_1m_vec.binary_search_by_key( // &low_1m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1m_vec[T].lowerband > low_1m_vec.last().unwrap().low_price { // let result = rsi3_vec.binary_search_by_key( // &low_1m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_vec[T].rsi_value < 15.0 { // let result = rsi10_vec.binary_search_by_key(&low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // match result { // Ok(T) => { // if rsi10_vec[T].rsi_value < 20.0 { // filtered_3rd_symbols.push(( // symbol, // low_1m_vec.last().unwrap().close_time, // )); // } // } // Err(e) => {} // } // } // } // Err(e) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(3, &filtered_3rd_symbols, alldata).await; // } // // println!("strategist_003 완료"); // Ok(()) // } // pub async fn strategist_004( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_004 procedure] // // 1st filtering: opclo_30m price < bb30_30m lowerband // // 2nd filtering: opclo_1m price < bb30_1m lowerband // // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 // let signal_decision = select_signal_decision().await; // if signal_decision[0].decision.contains("UP") { // // 1st filtering: (opclo_30m price < bb30 lowerband) // let mut opclo_30m_vec: Vec = Vec::new(); // let mut bb30_30m_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // for symbol in &alldata.valid_symbol_vec { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && bb30_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 1 && bb30_30m_vec.len() >= 1 { // let result = bb30_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_30m_vec[T].lowerband > opclo_30m_vec.last().unwrap().opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // } // // 2nd filtering: (opclo_1m price < bb30_1m lowerband) // let mut opclo_1m_vec: Vec = Vec::new(); // let mut bb30_1m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for symbol in filtered_1st_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); // if opclo_1m_option.is_some() && bb30_1m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); // if opclo_1m_vec.len() >= 1 && bb30_1m_vec.len() >= 1 { // let result = bb30_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1m_vec[T].lowerband > opclo_1m_vec.last().unwrap().opclo_price { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // } // // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 // let mut opclo_1m_vec: Vec = Vec::new(); // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi10_1m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_2nd_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // if opclo_1m_option.is_some() && rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // } // if opclo_1m_vec.len() >= 1 && rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { // let result = rsi3_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_1m_vec[T].rsi_value < 10.0 { // let result = rsi10_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_1m_vec[T].rsi_value < 25.0 { // filtered_3rd_symbols.push(( // symbol, // opclo_1m_vec.last().unwrap().close_time, // )); // } // } // Err(e) => {} // } // } // } // Err(e) => {} // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(4, &filtered_3rd_symbols, alldata).await; // } // // println!("strategist_004 완료"); // Ok(()) // } // // for ultra-short // pub async fn strategist_005( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_005 procedure] // // 1st filtering: sampling the least 1m 5 tickers, check DOWN ticker at least 2, check the quote vol of the last ticker > 2X the counterpart of the previous 2 tickers. // // 2nd filtering: opclo_1m price < sma3_1m // // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 // // 4th filtering: check the latest and previous 30m candles are UPs // let signal_decision = select_signal_decision().await; // if signal_decision[0].decision.contains("UP") { // // 1st filtering: sampling the least 1m 5 tickers, check DOWN ticker at least 2, check the quote vol of the last ticker > 2X the counterpart of the previous 2 tickers. // let mut opclo_1m_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // for symbol in &alldata.valid_symbol_vec { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // if opclo_1m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // if opclo_1m_vec.len() >= 5 { // opclo_1m_vec.reverse(); // opclo_1m_vec.truncate(5); // opclo_1m_vec.reverse(); // let mut cnt = 0; // for element in &opclo_1m_vec { // if element.candle_type == "DOWN" // && element.opclo_price > opclo_1m_vec.last().unwrap().opclo_price // { // cnt += 1; // } // } // if cnt >= 2 && opclo_1m_vec.last().unwrap().candle_type == "DOWN" { // let mut vec_cmp = opclo_1m_vec.to_vec(); // vec_cmp.pop(); // vec_cmp.reverse(); // let mut vec_iter = vec_cmp.iter(); // for _ in 0..2 { // let temp = vec_iter.next(); // if temp.is_some() { // if (temp.unwrap().quote_asset_volume != 0.0) // && (temp.unwrap().quote_asset_volume * 2.0 // < opclo_1m_vec.last().unwrap().quote_asset_volume) // { // filtered_1st_symbols.push(symbol.clone()); // break; // } // } // } // } // } // } // } // // 2nd filtering: opclo_1m price < sma3_1m // let mut sma3_1m_vec: Vec = Vec::new(); // let mut opclo_1m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for symbol in filtered_1st_symbols { // let sma3_1m_option = alldata.sma3_1m_data.iter().position(|x| *x.0 == *symbol); // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // if sma3_1m_option.is_some() && opclo_1m_option.is_some() { // sma3_1m_vec = alldata.sma3_1m_data[sma3_1m_option.unwrap()].1.clone(); // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // if sma3_1m_vec.len() >= 1 && opclo_1m_vec.len() >= 1 { // let result = sma3_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma3_1m_vec[T].sma_value > opclo_1m_vec.last().unwrap().opclo_price { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // } // // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 // let mut opclo_1m_vec: Vec = Vec::new(); // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi10_1m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for symbol in filtered_2nd_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // if opclo_1m_option.is_some() && rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // if opclo_1m_vec.len() >= 1 && rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { // let result = rsi3_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_1m_vec[T].rsi_value < 10.0 { // let result = rsi10_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_1m_vec[T].rsi_value < 25.0 { // filtered_3rd_symbols.push(symbol); // } // } // Err(e) => {} // } // } // } // Err(e) => {} // } // } // } // } // // 4th filtering: check the latest and previous 30m candles are UPs // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_1m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_3rd_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && opclo_1m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 2 && opclo_1m_vec.len() >= 1 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(2); // opclo_30m_vec.reverse(); // if opclo_30m_vec.first().unwrap().candle_type == "UP" // && opclo_30m_vec.last().unwrap().candle_type == "UP" // { // filtered_4th_symbols // .push((symbol, opclo_1m_vec.last().unwrap().close_time)); // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(5, &filtered_4th_symbols, alldata).await; // } // // println!("strategist_005 완료"); // Ok(()) // } // pub async fn strategist_006( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_006 procedure] // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 3, the latest opclo_30m < SMA3_30m // // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 // // 4th filtering: the latest 30m quote vol > 2X the previous quote vol // // 1st filtering symbols: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // let mut opclo_1d_vec: Vec = Vec::new(); // let mut bb30_1d_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // let mut current_price: Option; // for symbol in &alldata.valid_symbol_vec { // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && bb30_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.truncate(2); // opclo_1d_vec.reverse(); // bb30_1d_vec.reverse(); // bb30_1d_vec.truncate(2); // bb30_1d_vec.reverse(); // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.first().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // current_price = get_current_price(&symbol, &alldata.price_vec).await; // if current_price.is_some() { // if current_price.unwrap().is_normal() { // if (bb30_1d_vec[T].upperband // > opclo_1d_vec.first().unwrap().opclo_price) // && (opclo_1d_vec.first().unwrap().opclo_price // > current_price.unwrap()) // { // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1d_vec[T].upperband // > opclo_1d_vec.last().unwrap().opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // } // } // Err(E) => {} // } // } // } // } // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 3, the latest opclo_30m < SMA3_30m // let mut opclo_30m_vec: Vec = Vec::new(); // let mut sma3_30m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // let mut cnt = 0; // for symbol in filtered_1st_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && sma3_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // sma3_30m_vec = alldata.sma3_30m_data[sma3_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 && sma3_30m_vec.len() >= 1 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // opclo_30m_vec.reverse(); // cnt = 0; // for element in &opclo_30m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 3 { // let result = sma3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma3_30m_vec[T].sma_value > opclo_30m_vec.last().unwrap().opclo_price // { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // } // } // // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 // let mut rsi3_30m_vec: Vec = Vec::new(); // let mut rsi10_30m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for symbol in filtered_2nd_symbols { // let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { // rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); // rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // let result = rsi3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_30m_vec[T].rsi_value < 15.0 { // let result = rsi10_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_30m_vec[T].rsi_value < 35.0 { // filtered_3rd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 4th filtering: the latest 30m quote vol > 2X the previous quote vol // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_3rd_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if opclo_30m_vec.len() >= 2 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(2); // opclo_30m_vec.reverse(); // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume // < opclo_30m_vec.last().unwrap().quote_asset_volume // && opclo_30m_vec.last().unwrap().candle_type == "DOWN" // { // filtered_4th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); // } // } // } // } // // 7. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(6, &filtered_4th_symbols, alldata).await; // Ok(()) // } // pub async fn strategist_006 () -> Result<(), Box> { // // [strategist_006 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (low_price_1m price avg < low_price_30m price avg) // // 3. 2nd filtering symbols (low_price_30m price at the previous candle < bb_sma30_30m lowerband) // // 4. insert [pre_suggested_coin_list] // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut low_price_1m_vec: Vec = Vec::new(); // let mut low_price_1m_avg = 0.0; // let mut low_price_30m_vec: Vec = Vec::new(); // let mut low_price_30m_avg = 0.0; // // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // low_price_1m_avg = 0.0; // low_price_30m_avg = 0.0; // // read 1m csv file // low_price_1m_vec = read_low_price_into_vector("1m", &element.symbol).await?; // // calculate opclo 1m price average // for element in &low_price_1m_vec { // low_price_1m_avg += element.price; // } // low_price_1m_avg /= low_price_1m_vec.len() as f64; // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element.symbol).await?; // // calculate opclo 30m price average // for element in &low_price_30m_vec { // low_price_30m_avg += element.price; // } // low_price_30m_avg /= low_price_30m_vec.len() as f64; // // campare both prices // if low_price_1m_avg < low_price_30m_avg { // filtered_1st_symbols.push(element.symbol); // } // } // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price // for element in filtered_1st_symbols { // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element).await?; // // read bollingerband sma30 csv file // read_bb_vec = read_bb_into_vector("sma30", "30m", &element).await?; // // 2nd filtering symbols // low_price_30m_vec.pop(); // let result = read_bb_vec.binary_search_by_key(&low_price_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband > low_price_30m_vec.last().unwrap().price { // filtered_2nd_symbols.push((element, read_bb_vec[T].server_epoch)); // } // }, // Err(E) => {} // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(6, &filtered_2nd_symbols).await; // println!("strategist_006 완료"); // Ok(()) // } // pub async fn strategist_007 () -> Result<(), Box> { // // [strategist_007 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (low_price_1m avg < low_price_30m price avg) // // 3. 2nd filtering symbols (sma30 price > low_price_30m, check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample) // // 4. insert [pre_suggested_coin_list] // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut low_price_1m_vec: Vec = Vec::new(); // let mut low_price_1m_avg = 0.0; // let mut low_price_30m_vec: Vec = Vec::new(); // let mut low_price_30m_avg = 0.0; // // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // low_price_1m_avg = 0.0; // low_price_30m_avg = 0.0; // // read 1m csv file // low_price_1m_vec = read_low_price_into_vector("1m", &element.symbol).await?; // // calculate opclo 1m price average // for element in &low_price_1m_vec { // low_price_1m_avg += element.price; // } // low_price_1m_avg /= low_price_1m_vec.len() as f64; // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element.symbol).await?; // // calculate opclo 30m price average // for element in &low_price_30m_vec { // low_price_30m_avg += element.price; // } // low_price_30m_avg /= low_price_30m_vec.len() as f64; // // campare both prices // if low_price_1m_avg < low_price_30m_avg { // filtered_1st_symbols.push(element.symbol); // } // } // let mut sma30_30m_vec: Vec = Vec::new(); // let mut rsi30_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 2nd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample // for element in filtered_1st_symbols { // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element).await?; // low_price_30m_vec.pop(); // low_price_30m_vec.reverse(); // low_price_30m_vec.truncate(5); // // read SMA30 csv file // sma30_30m_vec = read_ma_into_vector(&MA::Sma, 30, "30m", &element).await?; // // read rsi30 csv file // rsi30_vec = read_rsi_into_vector(30, "30m", &element).await?; // if low_price_30m_vec.len() == 5 { // // 2nd filtering symbols // let result = sma30_30m_vec.binary_search_by_key(&low_price_30m_vec.first().unwrap().server_epoch, |MaData{price, server_epoch}| *server_epoch); // match result { // Ok(T) => { // if sma30_30m_vec[T].price > low_price_30m_vec[0].price { // let index_of_min: Option = low_price_30m_vec // .iter() // .enumerate() // .min_by(|(_, a), (_, b)| a.price.partial_cmp(&b.price).expect("Nan was forbidden.")) // .map(|(index, _)| index); // // index 1 means the middle index of 5 element in a vec, assuming the latest price is included but removed in the vec. // if index_of_min == Some(1) { // let result = rsi30_vec.binary_search_by_key(&low_price_30m_vec[1].server_epoch, |&RsiData{rsi_value, server_epoch}|server_epoch); // match result { // Ok(T) => { // if rsi30_vec[T].rsi_value < 0.3 { // filtered_2nd_symbols.push((element, low_price_30m_vec.first().unwrap().server_epoch)); // } // }, // Err(e) => {} // } // } // } // }, // Err(E) => {} // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(7, &filtered_2nd_symbols).await; // println!("strategist_007 완료"); // Ok(()) // } // pub async fn strategist_008 () -> Result<(), Box> { // // [strategist_008 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (low_price_1m avg < low_price_30m avg) // // 3. 2nd filtering symbols (low_price_30m at the previous candle < bb_sma30_30m lowerband) // // 4. insert [pre_suggested_coin_list] // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut low_price_1m_vec: Vec = Vec::new(); // let mut low_price_1m_avg = 0.0; // let mut low_price_30m_vec: Vec = Vec::new(); // let mut low_price_30m_avg = 0.0; // // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // low_price_1m_avg = 0.0; // low_price_30m_avg = 0.0; // // read 1m csv file // low_price_1m_vec = read_low_price_into_vector("1m", &element.symbol).await?; // // calculate opclo 1m price average // for element in &low_price_1m_vec { // low_price_1m_avg += element.price; // } // low_price_1m_avg /= low_price_1m_vec.len() as f64; // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element.symbol).await?; // // calculate opclo 30m price average // for element in &low_price_30m_vec { // low_price_30m_avg += element.price; // } // low_price_30m_avg /= low_price_30m_vec.len() as f64; // // campare both prices // if low_price_1m_avg < low_price_30m_avg { // filtered_1st_symbols.push(element.symbol); // } // } // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price // for element in filtered_1st_symbols { // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element).await?; // // read bollingerband sma30 csv file // read_bb_vec = read_bb_into_vector("sma30", "30m", &element).await?; // // 2nd filtering symbols // low_price_30m_vec.pop(); // let result = read_bb_vec.binary_search_by_key(&low_price_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband > low_price_30m_vec.last().unwrap().price { // filtered_2nd_symbols.push((element, read_bb_vec[T].server_epoch)); // } // }, // Err(E) => {} // } // } // let mut sma30_30m_vec: Vec = Vec::new(); // let mut rsi30_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 4. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample // for element in filtered_2nd_symbols { // // read 30m csv file // low_price_30m_vec = read_low_price_into_vector("30m", &element.0).await?; // low_price_30m_vec.pop(); // low_price_30m_vec.reverse(); // low_price_30m_vec.truncate(5); // // read SMA30 csv file // sma30_30m_vec = read_ma_into_vector(&MA::Sma, 30, "30m", &element.0).await?; // // read rsi30 csv file // rsi30_vec = read_rsi_into_vector(30, "30m", &element.0).await?; // if low_price_30m_vec.len() == 5 { // // 2nd filtering symbols // let result = sma30_30m_vec.binary_search_by_key(&low_price_30m_vec.first().unwrap().server_epoch, |MaData{price, server_epoch}| *server_epoch); // match result { // Ok(T) => { // if sma30_30m_vec[T].price > low_price_30m_vec[0].price { // let index_of_min: Option = low_price_30m_vec // .iter() // .enumerate() // .min_by(|(_, a), (_, b)| a.price.partial_cmp(&b.price).expect("Nan was forbidden.")) // .map(|(index, _)| index); // // index 1 means the middle index of 5 element in a vec, assuming the latest price is included but removed in the vec. // if index_of_min == Some(1) { // let result = rsi30_vec.binary_search_by_key(&low_price_30m_vec[1].server_epoch, |&RsiData{rsi_value, server_epoch}|server_epoch); // match result { // Ok(T) => { // if rsi30_vec[T].rsi_value < 0.25 { // filtered_3rd_symbols.push((element.0, low_price_30m_vec.first().unwrap().server_epoch)); // } // }, // Err(e) => {} // } // } // } // }, // Err(E) => {} // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(8, &filtered_3rd_symbols).await; // println!("strategist_008 완료"); // Ok(()) // } // pub async fn strategist_009 () -> Result<(), Box> { // // [strategist_009 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) // // 3. 2nd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) // // 4. insert or update record into [strategist_001_table] // // 5. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_30m_price_avg = 0.0; // let mut opclo_1d_vec: Vec = Vec::new(); // let mut opclo_1d_price_avg = 0.0; // // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // opclo_30m_price_avg = 0.0; // opclo_1d_price_avg = 0.0; // // read 1m csv file // opclo_30m_vec = read_opclo_into_vector("30m", &element.symbol).await?; // // calculate opclo 1m price average // for element in &opclo_30m_vec { // opclo_30m_price_avg += element.price; // } // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // read 30m csv file // opclo_1d_vec = read_opclo_into_vector("1d", &element.symbol).await?; // // calculate opclo 30m price average // for element in &opclo_1d_vec { // opclo_1d_price_avg += element.price; // } // opclo_1d_price_avg /= opclo_1d_vec.len() as f64; // // campare both prices // if opclo_30m_price_avg < opclo_1d_price_avg { // filtered_1st_symbols.push(element.symbol); // } // } // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 2nd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample // for element in filtered_1st_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // // read rsi3 csv file // rsi3_vec = read_rsi_into_vector(3, "30m", &element).await?; // // read rsi10 csv file // rsi10_vec = read_rsi_into_vector(10, "30m", &element).await?; // if rsi3_vec.len() >= 2 && rsi10_vec.len() >= 2 { // if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.30 { // filtered_2nd_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(9, &filtered_2nd_symbols).await; // println!("strategist_009 완료"); // Ok(()) // } // pub async fn strategist_010 () -> Result<(), Box> { // // [strategist_010 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) // // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) // // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) // // 5. insert or update record into [strategist_001_table] // // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] // let instant = Instant::now(); // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_30m_price_avg = 0.0; // let mut opclo_1d_vec: Vec = Vec::new(); // let mut opclo_1d_price_avg = 0.0; // // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // opclo_30m_price_avg = 0.0; // opclo_1d_price_avg = 0.0; // // // let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; // let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; // // read opclo_30m and 1d csv file // if opclo_30m_result.is_ok() && opclo_1d_result.is_ok() { // opclo_30m_vec = opclo_30m_result.unwrap(); // opclo_1d_vec = opclo_1d_result.unwrap(); // if opclo_30m_vec.len() > 4 && opclo_1d_vec.len() > 7 { // opclo_1d_vec.reverse(); // opclo_1d_vec.split_off(7); // opclo_30m_vec.reverse(); // opclo_1d_vec.split_off(4); // // calculate opclo 1m price average // for element in &opclo_30m_vec { // opclo_30m_price_avg += element.price; // } // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // calculate opclo 30m price average // for element in &opclo_1d_vec { // opclo_1d_price_avg += element.price; // } // opclo_1d_price_avg /= opclo_1d_vec.len() as f64; // // campare both prices // if opclo_30m_price_avg < opclo_1d_price_avg { // filtered_1st_symbols.push(element.symbol); // } // } // } // } // // 4. 3rd filtering symbols: yesterday 1d RSI 3 < 10, 1d RSI 10 < 15 // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for element in filtered_1st_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "1d", &element).await; // let rsi10_result = read_rsi_into_vector(10, "1d", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() & rsi10_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // rsi3_vec.pop(); // rsi10_vec.pop(); // if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.15 { // filtered_2nd_symbols.push(element); // } // } // } // } // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for element in filtered_2nd_symbols { // let opclo_30m_result = read_low_price_into_vector("30m", &element).await; // let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; // // read 30m csv file && bollingerband sma30 csv file // if opclo_30m_result.is_ok() && read_bb_result.is_ok() { // opclo_30m_vec = opclo_30m_result.unwrap(); // read_bb_vec = read_bb_result.unwrap(); // if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { // // 2nd filtering symbols // opclo_30m_vec.pop(); // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().price { // filtered_3rd_symbols.push(element); // } // }, // Err(E) => {} // } // } // } // } // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample // for element in filtered_3rd_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let opclo_30m_result = read_low_price_into_vector("30m", &element).await; // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() && rsi10_result.is_ok() && opclo_30m_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // opclo_30m_vec = opclo_30m_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.20 { // filtered_4th_symbols.push((element, opclo_30m_vec.last().unwrap().server_epoch)); // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(10, &filtered_4th_symbols).await; // if instant.elapsed().as_millis() < 50 { // sleep(Duration::from_millis(50)).await; // } // // println!("strategist_010 완료"); // Ok(()) // } // pub async fn strategist_011 () -> Result<(), Box> { // // [strategist_011 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) // // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) // // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) // // 5. insert or update record into [strategist_001_table] // // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] // let instant = Instant::now(); // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut opclo_1m_vec: Vec = Vec::new(); // let mut opclo_1m_price_avg = 0.0; // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_30m_price_avg = 0.0; // // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // opclo_1m_price_avg = 0.0; // opclo_30m_price_avg = 0.0; // let opclo_1m_result = read_opclo_into_vector("1m", &element.symbol).await; // let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; // if opclo_1m_result.is_ok() && opclo_30m_result.is_ok() { // opclo_1m_vec = opclo_1m_result.unwrap(); // opclo_30m_vec = opclo_30m_result.unwrap(); // if opclo_1m_vec.len() > 1 && opclo_30m_vec.len() > 1 { // // calculate opclo 1m price average // for element in &opclo_1m_vec { // opclo_1m_price_avg += element.price; // } // opclo_1m_price_avg /= opclo_1m_vec.len() as f64; // // calculate opclo 30m price average // for element in &opclo_30m_vec { // opclo_30m_price_avg += element.price; // } // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // campare both prices // if opclo_1m_price_avg < opclo_30m_price_avg { // filtered_1st_symbols.push(element.symbol); // } // } // } // } // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for element in filtered_1st_symbols { // let opclo_30m_result = read_low_price_into_vector("30m", &element).await; // let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; // // read 30m csv file & bollingerband sma30 csv file // if opclo_30m_result.is_ok() && read_bb_result.is_ok() { // opclo_30m_vec = opclo_30m_result.unwrap(); // read_bb_vec = read_bb_result.unwrap(); // if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 // { // // 2nd filtering symbols // opclo_30m_vec.pop(); // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().price { // filtered_2nd_symbols.push(element); // } // }, // Err(E) => {} // } // } // } // } // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample // for element in filtered_2nd_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; // if rsi3_result.is_ok() && rsi10_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.20 { // filtered_3rd_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(11, &filtered_3rd_symbols).await; // if instant.elapsed().as_millis() < 50 { // sleep(Duration::from_millis(50)).await; // } // // println!("strategist_011 완료"); // Ok(()) // } // pub async fn strategist_012 () -> Result<(), Box> { // // [strategist_010 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) // // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) // // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) // // 5. insert or update record into [strategist_001_table] // // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] // let instant = Instant::now(); // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_30m_price_avg = 0.0; // let mut opclo_1d_vec: Vec = Vec::new(); // let mut opclo_1d_price_avg = 0.0; // // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // opclo_30m_price_avg = 0.0; // opclo_1d_price_avg = 0.0; // let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; // let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; // // read 30m csv file & read 1d csv file // if opclo_30m_result.is_ok() && opclo_1d_result.is_ok() { // opclo_30m_vec = opclo_30m_result.unwrap(); // opclo_1d_vec = opclo_1d_result.unwrap(); // if opclo_30m_vec.len() > 1 && opclo_1d_vec.len() > 1 { // // calculate opclo 1m price average // for element in &opclo_30m_vec { // opclo_30m_price_avg += element.price; // } // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // calculate opclo 30m price average // for element in &opclo_1d_vec { // opclo_1d_price_avg += element.price; // } // opclo_1d_price_avg /= opclo_1d_vec.len() as f64; // // campare both prices // if opclo_30m_price_avg < (opclo_1d_price_avg/4.0) { // filtered_1st_symbols.push(element.symbol); // } // } // } // } // let mut opclo_30m_vec: Vec = Vec::new(); // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for element in filtered_1st_symbols { // let opclo_30m_result = read_low_price_into_vector("30m", &element).await; // let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; // // read 1m csv file & bollingerband sma30 csv file // if opclo_30m_result.is_ok() & read_bb_result.is_ok() { // opclo_30m_vec = opclo_30m_result.unwrap(); // read_bb_vec = read_bb_result.unwrap(); // if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { // // 2nd filtering symbols // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().price { // filtered_2nd_symbols.push(element); // } // }, // Err(E) => {} // } // } // } // } // let mut opclo_1m_vec: Vec = Vec::new(); // let mut opclo_1m_price_avg = 0.0; // let mut opclo_30m_vec: Vec = Vec::new(); // let mut opclo_30m_price_avg = 0.0; // let mut filtered_3rd_symbols: Vec = Vec::new(); // for element in filtered_2nd_symbols { // // initialize avgs // opclo_1m_price_avg = 0.0; // opclo_30m_price_avg = 0.0; // let opclo_1m_result = read_opclo_into_vector("1m", &element).await; // let opclo_30m_result = read_opclo_into_vector("30m", &element).await; // if opclo_1m_result.is_ok() && opclo_30m_result.is_ok() { // opclo_1m_vec = opclo_1m_result.unwrap(); // opclo_30m_vec = opclo_30m_result.unwrap(); // if opclo_1m_vec.len() > 10 && opclo_30m_vec.len() > 4 { // opclo_1m_vec.reverse(); // opclo_1m_vec.split_off(10); // opclo_30m_vec.reverse(); // opclo_30m_vec.split_off(4); // // calculate opclo 1m price average // for element in &opclo_1m_vec { // opclo_1m_price_avg += element.price; // } // opclo_1m_price_avg /= opclo_1m_vec.len() as f64; // // calculate opclo 30m price average // for element in &opclo_30m_vec { // opclo_30m_price_avg += element.price; // } // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // campare both prices // if opclo_1m_price_avg < (opclo_30m_price_avg*0.99) { // filtered_3rd_symbols.push(element); // } // } // } // } // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample // for element in filtered_3rd_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() & rsi10_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { // filtered_4th_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(12, &filtered_4th_symbols).await; // if instant.elapsed().as_millis() < 50 { // sleep(Duration::from_millis(50)).await; // } // // println!("strategist_012 완료"); // Ok(()) // } // // original strategist 012 // // pub async fn strategist_012 () -> Result<(), Box> { // // // [strategist_010 procedure] // // // 1. retrieve all usdttrade symbols // // // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) // // // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) // // // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) // // // 5. insert or update record into [strategist_001_table] // // // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] // // let instant = Instant::now(); // // // 1. retrieve all usdttrade symbols // // #[derive(Debug, FromRow)] // // struct UsdtTrades { // // symbol: String, // // } // // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // // let table_name = String::from("valid_usdt_trades"); // // let column_name = String::from("symbol"); // // let table_condition = None; // // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut opclo_30m_price_avg = 0.0; // // let mut opclo_1d_vec: Vec = Vec::new(); // // let mut opclo_1d_price_avg = 0.0; // // // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg // // let mut filtered_1st_symbols: Vec = Vec::new(); // // for element in usdt_trade_symbols { // // // initialize avgs // // opclo_30m_price_avg = 0.0; // // opclo_1d_price_avg = 0.0; // // let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; // // let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; // // // read 30m csv file & read 1d csv file // // if opclo_30m_result.is_ok() && opclo_1d_result.is_ok() { // // opclo_30m_vec = opclo_30m_result.unwrap(); // // opclo_1d_vec = opclo_1d_result.unwrap(); // // if opclo_30m_vec.len() > 1 && opclo_1d_vec.len() > 1 { // // // calculate opclo 1m price average // // for element in &opclo_30m_vec { // // opclo_30m_price_avg += element.price; // // } // // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; // // // calculate opclo 30m price average // // for element in &opclo_1d_vec { // // opclo_1d_price_avg += element.price; // // } // // opclo_1d_price_avg /= opclo_1d_vec.len() as f64; // // // campare both prices // // if opclo_30m_price_avg < (opclo_1d_price_avg/3.0) { // // filtered_1st_symbols.push(element.symbol); // // } // // } // // } // // } // // let mut opclo_1m_vec: Vec = Vec::new(); // // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price // // let mut read_bb_vec: Vec = Vec::new(); // // let mut filtered_2nd_symbols: Vec = Vec::new(); // // for element in filtered_1st_symbols { // // let opclo_1m_result = read_low_price_into_vector("1m", &element).await; // // let read_bb_result = read_bb_into_vector("sma30", "1m", &element).await; // // // read 1m csv file & bollingerband sma30 csv file // // if opclo_1m_result.is_ok() & read_bb_result.is_ok() { // // opclo_1m_vec = opclo_1m_result.unwrap(); // // read_bb_vec = read_bb_result.unwrap(); // // if opclo_1m_vec.len() > 1 && read_bb_vec.len() > 1 { // // // 2nd filtering symbols // // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // // match result { // // Ok(T) => { // // if read_bb_vec[T].lowerband > opclo_1m_vec.last().unwrap().price { // // filtered_2nd_symbols.push(element); // // } // // }, // // Err(E) => {} // // } // // } // // } // // } // // let mut rsi3_vec: Vec = Vec::new(); // // let mut rsi10_vec: Vec = Vec::new(); // // let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample // // for element in filtered_2nd_symbols { // // rsi3_vec.clear(); // // rsi10_vec.clear(); // // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; // // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; // // // read rsi3 csv file & rsi10 csv file // // if rsi3_result.is_ok() & rsi10_result.is_ok() { // // rsi3_vec = rsi3_result.unwrap(); // // rsi10_vec = rsi10_result.unwrap(); // // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // // if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.20 { // // filtered_3rd_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); // // } // // } // // } // // } // // // 4. insert record into [pre_suggested_coin_list] // // insert_pre_suggested_coins(12, &filtered_3rd_symbols).await; // // if instant.elapsed().as_millis() < 50 { // // sleep(Duration::from_millis(50)).await; // // } // // // println!("strategist_012 완료"); // // Ok(()) // // } // pub async fn strategist_013 () -> Result<(), Box> { // // [strategist_013 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols (the latest opclo_1d price avg < 20% of opclo_1d price avg two days before, the latest opclo_1d price avg < opclo_1d price avg a day before) // // 3. 2nd filtering symbols (1d RSI3 and RSI10 are lower than 0.10) // // 4. 3rd filtering symbols (candle 1d low price < 90% of bb_sma30_1d lowerband) // // 5. 4th filtering symbols (30m RSI3 and RSI10 are lower than 0.10 abd 0.10 respectively) // // 6. 5th filtering symbols (candle 30m low price < 99.5% of bb_sma30_30m lowerband) // let instant = Instant::now(); // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // // 2. 1st filtering symbols (the latest opclo_1d price avg < 90% of opclo_1d price avg two days before) // let mut opclo_1d_vec: Vec = Vec::new(); // let mut opclo_1d_latest_price = 0.0; // let mut opclo_1d_1before_price = 0.0; // let mut opclo_1d_2before_price = 0.0; // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // opclo_1d_latest_price = 0.0; // opclo_1d_1before_price = 0.0; // opclo_1d_2before_price = 0.0; // let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; // // read 30m csv file & read 1d csv file // if opclo_1d_result.is_ok() { // opclo_1d_vec = opclo_1d_result.unwrap(); // if opclo_1d_vec.len() > 3 { // // compare the lastest price and 20% of 2 days before price // opclo_1d_vec.reverse(); // let mut iter = opclo_1d_vec.iter(); // opclo_1d_latest_price = iter.next().unwrap().price; // opclo_1d_1before_price = iter.next().unwrap().price; // opclo_1d_2before_price = iter.next().unwrap().price; // // campare both prices // if (opclo_1d_latest_price < opclo_1d_2before_price * 0.9) && (opclo_1d_latest_price < opclo_1d_1before_price * 0.95) { // filtered_1st_symbols.push(element.symbol); // } // } // } // } // // 3. 2nd filtering symbols (1d RSI3 and RSI10 are lower than 0.10) // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for element in filtered_1st_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "1d", &element).await; // let rsi10_result = read_rsi_into_vector(10, "1d", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() & rsi10_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { // filtered_2nd_symbols.push(element); // } // } // } // } // // 4. 3rd filtering symbols (candle 1d low price < 90% of bb_sma30_1d lowerband) // let mut opclo_30m_vec: Vec = Vec::new(); // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for element in filtered_2nd_symbols { // let opclo_1d_result = read_low_price_into_vector("1d", &element).await; // let read_bb_result = read_bb_into_vector("sma30", "1d", &element).await; // // read 1d csv file & bollingerband sma30 csv file // if opclo_1d_result.is_ok() & read_bb_result.is_ok() { // opclo_30m_vec = opclo_1d_result.unwrap(); // read_bb_vec = read_bb_result.unwrap(); // if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { // // 3rd filtering symbols // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband * 0.9 > opclo_30m_vec.last().unwrap().price { // filtered_3rd_symbols.push(element); // } // }, // Err(E) => {} // } // } // } // } // // 5. 4th filtering symbols (30m RSI3 and RSI10 are lower than 0.10 abd 0.10 respectively) // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec = Vec::new(); // for element in filtered_3rd_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() & rsi10_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { // filtered_4th_symbols.push(element); // } // } // } // } // // 6. 5th filtering symbols (candle 30m low price < 99.5% of bb_sma30_30m lowerband) // let mut opclo_30m_vec: Vec = Vec::new(); // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_5th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // for element in filtered_4th_symbols { // let opclo_30m_result = read_low_price_into_vector("30m", &element).await; // let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; // // read 1d csv file & bollingerband sma30 csv file // if opclo_30m_result.is_ok() & read_bb_result.is_ok() { // opclo_30m_vec = opclo_30m_result.unwrap(); // read_bb_vec = read_bb_result.unwrap(); // if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { // // 3rd filtering symbols // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].lowerband * 0.995 > opclo_30m_vec.last().unwrap().price { // filtered_5th_symbols.push((element, opclo_30m_vec.last().unwrap().server_epoch)); // } // }, // Err(E) => {} // } // } // } // } // // 4. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(13, &filtered_5th_symbols).await; // if instant.elapsed().as_millis() < 50 { // sleep(Duration::from_millis(50)).await; // } // // println!("strategist_013 완료"); // Ok(()) // } // pub async fn strategist_014 () -> Result<(), Box> { // // [strategist_014 procedure] // // 1. retrieve all usdttrade symbols // // 2. 1st filtering symbols: candle 1d price yesterday avg < 80% of candle 1d opclo price latest 7 days avg // // 3. 2nd filtering symbols: 85% of BB SMA10 MA price > candle 1d price yesterday avg // // 4. 3rd filtering symbols: yesterday 1d RSI 3 < 10, 1d RSI 10 < 15 // // 5. 4th filtering symbols: avg between yesterday 1d opclo price and yesterday low price> latest 30m opclo price // // 6. 5th filtering symbols: 30m RSI 3 < 10, 30m RSI 10 < 15 // // 7. insert record into [pre_suggested_coin_list] // let instant = Instant::now(); // // 1. retrieve all usdttrade symbols // #[derive(Debug, FromRow)] // struct UsdtTrades { // symbol: String, // } // let mut usdt_trades = UsdtTrades { symbol: String::new() }; // let table_name = String::from("valid_usdt_trades"); // let column_name = String::from("symbol"); // let table_condition = None; // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); // // 2. 1st filtering symbols: candle 1d price yesterday avg < 80% of candle 1d opclo price latest 7 days avg // let mut opclo_1d_vec: Vec = Vec::new(); // let mut opclo_1d_price_7days_avg = 0.0; // let mut filtered_1st_symbols: Vec = Vec::new(); // for element in usdt_trade_symbols { // // initialize avgs // opclo_1d_price_7days_avg = 0.0; // let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; // // read 1d csv file // if opclo_1d_result.is_ok() { // opclo_1d_vec = opclo_1d_result.unwrap(); // if opclo_1d_vec.len() >= 8 { // opclo_1d_vec.pop(); // opclo_1d_vec.reverse(); // opclo_1d_vec.split_off(7); // // calculate opclo 1d price average // for element in &opclo_1d_vec { // opclo_1d_price_7days_avg += element.price; // } // opclo_1d_price_7days_avg /= opclo_1d_vec.len() as f64; // // campare the yesterday opclo price with 30days avg // if opclo_1d_vec[0].price < (opclo_1d_price_7days_avg * 0.8) { // filtered_1st_symbols.push(element.symbol); // } // } // } // } // // 3. 2nd filtering symbols: 85% of BB SMA10 MA price > candle 1d price yesterday avg // let mut read_bb_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // for element in filtered_1st_symbols { // let opclo_1d_result = read_opclo_into_vector("1d", &element).await; // let read_bb_result = read_bb_into_vector("sma10", "1d", &element).await; // // read 1d csv file & bollingerband sma30 csv file // if opclo_1d_result.is_ok() & read_bb_result.is_ok() { // opclo_1d_vec = opclo_1d_result.unwrap(); // read_bb_vec = read_bb_result.unwrap(); // if opclo_1d_vec.len() > 1 && read_bb_vec.len() > 1 { // opclo_1d_vec.pop(); // read_bb_vec.pop(); // let result = read_bb_vec.binary_search_by_key(&opclo_1d_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); // match result { // Ok(T) => { // if read_bb_vec[T].ma_price * 0.85 > opclo_1d_vec.last().unwrap().price { // filtered_2nd_symbols.push(element); // } // }, // Err(E) => {} // } // } // } // } // // 4. 3rd filtering symbols: yesterday 1d RSI 3 < 10, 1d RSI 10 < 15 // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for element in filtered_2nd_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "1d", &element).await; // let rsi10_result = read_rsi_into_vector(10, "1d", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() & rsi10_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { // rsi3_vec.pop(); // rsi10_vec.pop(); // if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.15 { // filtered_3rd_symbols.push(element); // } // } // } // } // // 5. 4th filtering symbols: avg between yesterday 1d opclo price and yesterday low price> latest 30m opclo price // let mut opclo_1d_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut low_1d_vec: Vec = Vec::new(); // let mut avg = 0.0; // let mut price_same_closetime = 0.0; // let mut filtered_4th_symbols: Vec = Vec::new(); // for element in filtered_3rd_symbols { // // initialize avgs // avg = 0.0; // price_same_closetime = 0.0; // let opclo_1d_result = read_opclo_into_vector("1d", &element).await; // let opclo_30m_result = read_opclo_into_vector("30m", &element).await; // let low_1d_result = read_low_price_into_vector("1d", &element).await; // // read 1d csv file // if opclo_1d_result.is_ok() && low_1d_result.is_ok() && opclo_30m_result.is_ok() { // opclo_1d_vec = opclo_1d_result.unwrap(); // opclo_30m_vec = opclo_30m_result.unwrap(); // low_1d_vec = low_1d_result.unwrap(); // if opclo_1d_vec.len() > 1 && low_1d_vec.len() > 1 && opclo_30m_vec.len() > 1 { // opclo_1d_vec.pop(); // let result = low_1d_vec.binary_search_by_key(&opclo_1d_vec.last().unwrap().server_epoch, |OpcloData{price, server_epoch, usdt_volume, up_down}| *server_epoch); // match result { // Ok(T) => { // avg = (opclo_1d_vec.last().unwrap().price + low_1d_vec[T].price) / 2.0; // if opclo_30m_vec.last().unwrap().price < avg { // filtered_4th_symbols.push(element); // } // }, // Err(E) => {} // } // } // } // } // // 6. 5th filtering symbols: 30m RSI 3 < 10, 30m RSI 10 < 15 // let mut rsi3_vec: Vec = Vec::new(); // let mut rsi10_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_5th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // for element in filtered_4th_symbols { // rsi3_vec.clear(); // rsi10_vec.clear(); // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; // let opclo_30m_result = read_opclo_into_vector("30m", &element).await; // // read rsi3 csv file & rsi10 csv file // if rsi3_result.is_ok() & rsi10_result.is_ok() && opclo_30m_result.is_ok() { // rsi3_vec = rsi3_result.unwrap(); // rsi10_vec = rsi10_result.unwrap(); // opclo_30m_vec = opclo_30m_result.unwrap(); // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 && opclo_30m_vec.len() > 1 { // if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { // filtered_5th_symbols.push((element, opclo_30m_vec.last().unwrap().server_epoch)); // } // } // } // } // // 7. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(14, &filtered_5th_symbols).await; // if instant.elapsed().as_millis() < 50 { // sleep(Duration::from_millis(50)).await; // } // Ok(()) // } // pub async fn strategist_013( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_013 procedure] // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // // 3rd filtering: low price 30m < BB30_30m lowerband // // 4th filtering: RSI3_30m < 15, RSI10_30m < 35 // // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 // // 6th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // let mut opclo_1d_vec: Vec = Vec::new(); // let mut bb30_1d_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // let mut current_price: Option; // for symbol in &alldata.valid_symbol_vec { // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && bb30_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.truncate(2); // opclo_1d_vec.reverse(); // bb30_1d_vec.reverse(); // bb30_1d_vec.truncate(2); // bb30_1d_vec.reverse(); // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.first().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // current_price = get_current_price(&symbol, &alldata.price_vec).await; // if current_price.is_some() { // if current_price.unwrap().is_normal() { // if (bb30_1d_vec[T].upperband // > opclo_1d_vec.first().unwrap().opclo_price) // && (opclo_1d_vec.first().unwrap().opclo_price // > current_price.unwrap()) // { // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1d_vec[T].upperband // > opclo_1d_vec.last().unwrap().opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // } // } // Err(E) => {} // } // } // } // } // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_30m_vec: Vec = Vec::new(); // let mut sma30_30m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // let mut cnt = 0; // for symbol in filtered_1st_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); // let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && ema3_30m_option.is_some() && sma30_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); // sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 && ema3_30m_vec.len() >= 1 && sma30_30m_vec.len() >= 1 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // opclo_30m_vec.reverse(); // cnt = 0; // for element in &opclo_30m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 4 { // let result = ema3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema3_30m_vec[T].ema_value > opclo_30m_vec.last().unwrap().opclo_price // { // let result = sma30_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma30_30m_vec[T].sma_value // > opclo_30m_vec.last().unwrap().opclo_price // { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // } // // 3rd filtering: low price 30m < BB30_30m lowerband // let mut low_30m_vec: Vec = Vec::new(); // let mut bb30_30m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for symbol in filtered_2nd_symbols { // let low_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); // if low_30m_option.is_some() && bb30_30m_option.is_some() { // low_30m_vec = alldata.rt_price_30m_vec[low_30m_option.unwrap()].1.clone(); // bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); // if low_30m_vec.len() >= 1 && bb30_30m_vec.len() >= 1 { // let result = bb30_30m_vec.binary_search_by_key( // &low_30m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_30m_vec[T].lowerband > low_30m_vec.last().unwrap().low_price { // filtered_3rd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // } // // 4th filtering: 30m RSI 3 < 15, 30m RSI 10 < 35 // let mut rsi3_30m_vec: Vec = Vec::new(); // let mut rsi10_30m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec = Vec::new(); // for symbol in filtered_3rd_symbols { // let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { // rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); // rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // let result = rsi3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_30m_vec[T].rsi_value < 15.0 { // let result = rsi10_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_30m_vec[T].rsi_value < 35.0 { // filtered_4th_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi10_1m_vec: Vec = Vec::new(); // let mut filtered_5th_symbols: Vec = Vec::new(); // (symbol, closetime) // for symbol in filtered_4th_symbols { // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { // if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 // && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 // { // filtered_5th_symbols.push(symbol); // } // } // } // } // // 6th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m, clo_1m < BB30_1m lowerband // let mut opclo_1m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_1m_vec: Vec = Vec::new(); // let mut ema10_1m_vec: Vec = Vec::new(); // let mut bb30_1m_vec: Vec = Vec::new(); // let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_5th_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); // if opclo_1m_option.is_some() // && opclo_30m_option.is_some() // && ema3_1m_option.is_some() // && ema10_1m_option.is_some() // && bb30_1m_option.is_some() // { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // ema10_1m_vec = alldata.ema10_1m_data[ema10_1m_option.unwrap()].1.clone(); // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); // if opclo_1m_vec.len() >= 1 // && opclo_30m_vec.len() >= 1 // && ema3_1m_vec.len() >= 1 // && ema10_1m_vec.len() >= 1 // && bb30_1m_vec.len() >= 1 // { // let result = ema3_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema3_1m_vec[T].ema_value > opclo_1m_vec.last().unwrap().opclo_price { // let result = ema10_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema10_1m_vec[T].ema_value // > opclo_1m_vec.last().unwrap().opclo_price // { // let result = bb30_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| { // close_time // }, // ); // match result { // Ok(T) => { // if bb30_1m_vec[T].lowerband // > opclo_1d_vec.last().unwrap().close_price // { // filtered_6th_symbols.push(( // symbol, // opclo_30m_vec.last().unwrap().close_time, // )); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // insert_pre_suggested_coins(13, &filtered_6th_symbols, alldata).await; // Ok(()) // } // pub async fn strategist_014( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_014 procedure] // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d, // // 2nd filtering: the latest 2 opclo_1d < SMA3_1d (apply this filtering if 5days angle of marketcap is negative and marketcap opinion is DOWN or KEEP) // // 3rd filtering: RSI3_1d < 20, RSI10_1d < 35, RSI30_1d < 45 (if 5days angle of marketcap is negative and marketcap opinion is UP, this filtering will be passed) // // 4th filtering: // // 1) check the latest candle is DOWN (common) // // 2) DOWN candles having 0.3% below change is not counted // // 3) check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // // 4) OR, check 5 samples of candle 30m has DOWN candles at least 3, the latest clo_30m < BB30_30m lowerband // // 5th filtering: RSI3_30m < 20, RSI10_30m < 35 // // 6th filtering: RSI3_1m < 10, RSI10_1m < 25 // // 7th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m, clo_1m < BB30_1m lowerband // // 8th filtering: check the latest candle is DOWN and check 5 samples of candle 1m has DOWN candles at least 3 // let signal_opinions = select_signal_association_opinion().await; // let market_cap_index = select_marketcap().await; // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band and SMA3_1d, current price < previous opclo_1d, // let mut opclo_1d_vec: Vec = Vec::new(); // let mut bb30_1d_vec: Vec = Vec::new(); // let mut sma3_1d_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // let mut current_price: Option; // for symbol in &alldata.valid_symbol_vec { // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); // let sma3_1d_option = alldata.sma3_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && bb30_1d_option.is_some() && sma3_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); // sma3_1d_vec = alldata.sma3_1d_data[sma3_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 && sma3_1d_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.truncate(2); // opclo_1d_vec.reverse(); // bb30_1d_vec.reverse(); // bb30_1d_vec.truncate(2); // bb30_1d_vec.reverse(); // sma3_1d_vec.reverse(); // sma3_1d_vec.truncate(2); // sma3_1d_vec.reverse(); // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.first().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // current_price = get_current_price(&symbol, &alldata.price_vec).await; // if current_price.is_some() { // if current_price.unwrap().is_normal() { // if (bb30_1d_vec[T].upperband // > opclo_1d_vec.first().unwrap().opclo_price) // && (opclo_1d_vec.first().unwrap().opclo_price // > current_price.unwrap()) // { // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1d_vec[T].upperband // > opclo_1d_vec.last().unwrap().opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // } // } // Err(E) => {} // } // } // } // } // // 2nd filtering: the latest 2 opclo_1d < SMA3_1d (apply this filtering if 5days angle of marketcap is negative and marketcap opinion is DOWN or KEEP) // let mut opclo_1d_vec: Vec = Vec::new(); // let mut sma3_1d_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // if (signal_opinions[0].opinion.contains("DOWN") || signal_opinions[0].opinion.contains("KEEP")) // && market_cap_index[1].market_cap_index.is_sign_negative() // { // for symbol in &alldata.valid_symbol_vec { // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let sma3_1d_option = alldata.sma3_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && sma3_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // sma3_1d_vec = alldata.sma3_1d_data[sma3_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && sma3_1d_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.truncate(2); // opclo_1d_vec.reverse(); // sma3_1d_vec.reverse(); // sma3_1d_vec.truncate(2); // sma3_1d_vec.reverse(); // let result = sma3_1d_vec.binary_search_by_key( // &opclo_1d_vec.first().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma3_1d_vec[T].sma_value > opclo_1d_vec.first().unwrap().opclo_price // { // let result = sma3_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma3_1d_vec[T].sma_value // > opclo_1d_vec.last().unwrap().opclo_price // { // filtered_2nd_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // } else { // filtered_2nd_symbols = filtered_1st_symbols; // } // // 3rd filtering: RSI3_1d < 20, RSI10_1d < 35, RSI30_1d < 45 (if 5days angle of marketcap is negative and marketcap opinion is UP, this filtering will be passed) // let mut rsi3_1d_vec: Vec = Vec::new(); // let mut rsi10_1d_vec: Vec = Vec::new(); // let mut rsi30_1d_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // if signal_opinions[0].opinion.contains("UP") // && market_cap_index[1].market_cap_index.is_sign_negative() // { // filtered_3rd_symbols = filtered_2nd_symbols; // } else { // for symbol in filtered_2nd_symbols { // let rsi3_1d_option = alldata.rsi3_1d_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1d_option = alldata.rsi10_1d_data.iter().position(|x| *x.0 == *symbol); // let rsi30_1d_option = alldata.rsi30_1d_data.iter().position(|x| *x.0 == *symbol); // if rsi3_1d_option.is_some() && rsi10_1d_option.is_some() && rsi30_1d_option.is_some() { // rsi3_1d_vec = alldata.rsi3_1d_data[rsi3_1d_option.unwrap()].1.clone(); // rsi10_1d_vec = alldata.rsi10_1d_data[rsi10_1d_option.unwrap()].1.clone(); // rsi30_1d_vec = alldata.rsi30_1d_data[rsi30_1d_option.unwrap()].1.clone(); // if rsi3_1d_vec.len() >= 1 && rsi10_1d_vec.len() >= 1 && rsi30_1d_vec.len() >= 1 { // if rsi3_1d_vec.last().unwrap().rsi_value < 20.0 // && rsi10_1d_vec.last().unwrap().rsi_value < 35.0 // && rsi30_1d_vec.last().unwrap().rsi_value < 45.0 // { // filtered_3rd_symbols.push(symbol); // } // } // } // } // } // // 4th filtering: // // 1) check the latest candle is DOWN (common) // // 2) DOWN candles having 0.3% below change is not counted // // 3) check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // // 4) OR, check 5 samples of candle 30m has DOWN candles at least 3, the latest clo_30m < BB30_30m lowerband // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_30m_vec: Vec = Vec::new(); // let mut sma30_30m_vec: Vec = Vec::new(); // let mut bb30_30m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec = Vec::new(); // let mut cnt = 0; // for symbol in filtered_3rd_symbols { // let mut is_filtering_passed: bool = false; // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); // let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); // let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() // && ema3_30m_option.is_some() // && sma30_30m_option.is_some() // && bb30_30m_option.is_some() // { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); // sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); // bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 // && ema3_30m_vec.len() >= 1 // && sma30_30m_vec.len() >= 1 // && bb30_30m_vec.len() >= 1 // { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // opclo_30m_vec.reverse(); // if opclo_30m_vec.last().unwrap().candle_type == "DOWN" { // cnt = 0; // for element in &opclo_30m_vec { // if element.candle_type == "DOWN" { // if (element.open_price / element.close_price) - 1.0 > 0.003 { // cnt += 1; // } // } // } // if cnt >= 4 { // let result = ema3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema3_30m_vec[T].ema_value // > opclo_30m_vec.last().unwrap().opclo_price // { // let result = sma30_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma30_30m_vec[T].sma_value // > opclo_30m_vec.last().unwrap().opclo_price // { // is_filtering_passed = true; // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } else if cnt == 3 { // let result = bb30_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_30m_vec[T].lowerband // > opclo_30m_vec.last().unwrap().close_price // { // is_filtering_passed = true; // } // } // Err(E) => {} // } // } // } // } // } // if is_filtering_passed == true { // filtered_4th_symbols.push(symbol); // } // } // // 5th filtering: RSI3_30m < 20, RSI10_30m < 35 // let mut rsi3_30m_vec: Vec = Vec::new(); // let mut rsi10_30m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_5th_symbols: Vec = Vec::new(); // for symbol in filtered_4th_symbols { // let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { // rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); // rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // let result = rsi3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_30m_vec[T].rsi_value < 20.0 { // let result = rsi10_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_30m_vec[T].rsi_value < 35.0 { // filtered_5th_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 6th filtering: RSI3_1m < 10, RSI10_1m < 25 // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi10_1m_vec: Vec = Vec::new(); // let mut filtered_6th_symbols: Vec = Vec::new(); // for symbol in filtered_5th_symbols { // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { // if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 // && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 // { // filtered_6th_symbols.push(symbol); // } // } // } // } // // // 6. 5th filtering symbols: 30m current vol > 30m previous vol * 2 // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // for element in filtered_3rd_symbols { // // let opclo_30m_result = read_price_into_vector("30m", &element).await; // // if opclo_30m_result.is_ok() { // // let opclo_30m_option = opclo_30m_result?; // // if opclo_30m_option.is_some() { // // opclo_30m_vec = opclo_30m_option.unwrap(); // // if opclo_30m_vec.len() >= 2 { // // opclo_30m_vec.reverse(); // // opclo_30m_vec.truncate(2); // // opclo_30m_vec.reverse(); // // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume < opclo_30m_vec.last().unwrap().quote_asset_volume && opclo_30m_vec.last().unwrap().candle_type == "DOWN" { // // filtered_4th_symbols.push((element, opclo_30m_vec.last().unwrap().close_time)); // // } // // } // // } // // } // // } // // 7th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m, clo_1m < BB30_1m lowerband // let mut opclo_1m_vec: Vec = Vec::new(); // let mut ema3_1m_vec: Vec = Vec::new(); // let mut ema10_1m_vec: Vec = Vec::new(); // let mut bb30_1m_vec: Vec = Vec::new(); // let mut filtered_7th_symbols: Vec = Vec::new(); // for symbol in filtered_6th_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); // let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); // if opclo_1m_option.is_some() // && ema3_1m_option.is_some() // && ema10_1m_option.is_some() // && bb30_1m_option.is_some() // { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); // ema10_1m_vec = alldata.ema10_1m_data[ema10_1m_option.unwrap()].1.clone(); // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); // if opclo_1m_vec.len() >= 1 // && ema3_1m_vec.len() >= 1 // && ema10_1m_vec.len() >= 1 // && bb30_1m_vec.len() >= 1 // { // let result = ema3_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema3_1m_vec[T].ema_value > opclo_1m_vec.last().unwrap().opclo_price { // let result = ema10_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema10_1m_vec[T].ema_value // > opclo_1m_vec.last().unwrap().opclo_price // { // let result = bb30_1m_vec.binary_search_by_key( // &opclo_1m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| { // close_time // }, // ); // match result { // Ok(T) => { // if bb30_1m_vec[T].lowerband // > opclo_1d_vec.last().unwrap().close_price // { // filtered_7th_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 8th filtering: // // check the latest candle is DOWN and check 5 samples of candle 30m has DOWN candles at least 3 // let mut opclo_1m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_8th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // let mut cnt = 0; // for symbol in filtered_7th_symbols { // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && opclo_1m_option.is_some() { // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if opclo_1m_vec.len() >= 5 && opclo_30m_vec.len() >= 5 { // opclo_1m_vec.reverse(); // opclo_1m_vec.truncate(5); // opclo_1m_vec.reverse(); // if opclo_1m_vec.last().unwrap().candle_type == "DOWN" { // cnt = 0; // for element in &opclo_1m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 3 { // filtered_8th_symbols // .push((symbol, opclo_30m_vec.last().unwrap().close_time)); // } // } // } // } // } // insert_pre_suggested_coins(14, &filtered_8th_symbols, alldata).await; // Ok(()) // } // pub async fn strategist_015( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_015 procedure] // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // // 3rd filtering: low price 30m < BB30_30m lowerband // // 4th filtering: RSI3_30m < 15, RSI10_30m < 35 // // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // let mut opclo_1d_vec: Vec = Vec::new(); // let mut bb30_1d_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // let mut current_price: Option; // for symbol in &alldata.valid_symbol_vec { // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && bb30_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.truncate(2); // opclo_1d_vec.reverse(); // bb30_1d_vec.reverse(); // bb30_1d_vec.truncate(2); // bb30_1d_vec.reverse(); // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.first().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // current_price = get_current_price(&symbol, &alldata.price_vec).await; // if current_price.is_some() { // if current_price.unwrap().is_normal() { // if (bb30_1d_vec[T].upperband // > opclo_1d_vec.first().unwrap().opclo_price) // && (opclo_1d_vec.first().unwrap().opclo_price // > current_price.unwrap()) // { // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1d_vec[T].upperband // > opclo_1d_vec.last().unwrap().opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // } // } // Err(E) => {} // } // } // } // } // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_30m_vec: Vec = Vec::new(); // let mut sma30_30m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // let mut cnt = 0; // for symbol in filtered_1st_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); // let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && ema3_30m_option.is_some() && sma30_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); // sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 && ema3_30m_vec.len() >= 1 && sma30_30m_vec.len() >= 1 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // opclo_30m_vec.reverse(); // cnt = 0; // for element in &opclo_30m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 4 { // let result = ema3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema3_30m_vec[T].ema_value > opclo_30m_vec.last().unwrap().opclo_price // { // let result = sma30_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma30_30m_vec[T].sma_value // > opclo_30m_vec.last().unwrap().opclo_price // { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // } // // 3rd filtering: low price 30m < BB30_30m lowerband // let mut low_30m_vec: Vec = Vec::new(); // let mut bb30_30m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for symbol in filtered_2nd_symbols { // let low_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); // if low_30m_option.is_some() && bb30_30m_option.is_some() { // low_30m_vec = alldata.rt_price_30m_vec[low_30m_option.unwrap()].1.clone(); // bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); // if low_30m_vec.len() >= 1 && bb30_30m_vec.len() >= 1 { // let result = bb30_30m_vec.binary_search_by_key( // &low_30m_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_30m_vec[T].lowerband > low_30m_vec.last().unwrap().low_price { // filtered_3rd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // } // // 4th filtering: 30m RSI 3 < 15, 30m RSI 10 < 35 // let mut rsi3_30m_vec: Vec = Vec::new(); // let mut rsi10_30m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec = Vec::new(); // for symbol in filtered_3rd_symbols { // let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { // rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); // rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // let result = rsi3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_30m_vec[T].rsi_value < 15.0 { // let result = rsi10_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_30m_vec[T].rsi_value < 35.0 { // filtered_4th_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi10_1m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_4th_symbols { // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && opclo_30m_option.is_some() { // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 // && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 // { // filtered_5th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); // } // } // // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi3_1m_vec[T].rsi_value < 10.0 { // // let result = rsi10_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi10_1m_vec[T].rsi_value < 25.0 { // // filtered_5th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // } // } // // // 6. 5th filtering symbols: 30m current vol > 30m previous vol * 2 // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut filtered_5th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // for element in filtered_4th_symbols { // // let opclo_30m_result = read_price_into_vector("30m", &element).await; // // if opclo_30m_result.is_ok() { // // let opclo_30m_option = opclo_30m_result?; // // if opclo_30m_option.is_some() { // // opclo_30m_vec = opclo_30m_option.unwrap(); // // if opclo_30m_vec.len() >= 2 { // // opclo_30m_vec.reverse(); // // opclo_30m_vec.truncate(2); // // opclo_30m_vec.reverse(); // // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume < opclo_30m_vec.last().unwrap().quote_asset_volume && opclo_30m_vec.last().unwrap().candle_type == "DOWN" { // // filtered_5th_symbols.push((element, opclo_30m_vec.last().unwrap().close_time)); // // } // // } // // } // // } // // } // // println!("5: {:?}", filtered_5th_symbols); // // 7. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(15, &filtered_5th_symbols, alldata).await; // Ok(()) // } // pub async fn strategist_016( // alldata: &AllData, // ) -> Result<(), Box> { // // [strategist_016 procedure] // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 // // 4th filtering: RSI3_1m < 10, RSI10_1m < 25 // // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d // let mut opclo_1d_vec: Vec = Vec::new(); // let mut bb30_1d_vec: Vec = Vec::new(); // let mut filtered_1st_symbols: Vec = Vec::new(); // let mut current_price: Option; // for symbol in &alldata.valid_symbol_vec { // let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); // let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); // if opclo_1d_option.is_some() && bb30_1d_option.is_some() { // opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); // bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); // if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { // opclo_1d_vec.reverse(); // opclo_1d_vec.truncate(2); // opclo_1d_vec.reverse(); // bb30_1d_vec.reverse(); // bb30_1d_vec.truncate(2); // bb30_1d_vec.reverse(); // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.first().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // current_price = get_current_price(&symbol, &alldata.price_vec).await; // if current_price.is_some() { // if current_price.unwrap().is_normal() { // if (bb30_1d_vec[T].upperband // > opclo_1d_vec.first().unwrap().opclo_price) // && (opclo_1d_vec.first().unwrap().opclo_price // > current_price.unwrap()) // { // let result = bb30_1d_vec.binary_search_by_key( // &opclo_1d_vec.last().unwrap().close_time, // |&BollingerBandData { // sma, // upperband, // lowerband, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if bb30_1d_vec[T].upperband // > opclo_1d_vec.last().unwrap().opclo_price // { // filtered_1st_symbols.push(symbol.clone()); // } // } // Err(E) => {} // } // } // } // } // } // Err(E) => {} // } // } // } // } // // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_30m_vec: Vec = Vec::new(); // let mut sma30_30m_vec: Vec = Vec::new(); // let mut filtered_2nd_symbols: Vec = Vec::new(); // let mut cnt = 0; // for symbol in filtered_1st_symbols { // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); // let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); // if opclo_30m_option.is_some() && ema3_30m_option.is_some() && sma30_30m_option.is_some() { // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); // sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); // if opclo_30m_vec.len() >= 5 && ema3_30m_vec.len() >= 1 && sma30_30m_vec.len() >= 1 { // opclo_30m_vec.reverse(); // opclo_30m_vec.truncate(5); // opclo_30m_vec.reverse(); // cnt = 0; // for element in &opclo_30m_vec { // if element.candle_type == "DOWN" { // cnt += 1; // } // } // if cnt >= 4 { // let result = ema3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&EmaData { // ema_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if ema3_30m_vec[T].ema_value > opclo_30m_vec.last().unwrap().opclo_price // { // let result = sma30_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&SmaData { // sma_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if sma30_30m_vec[T].sma_value // > opclo_30m_vec.last().unwrap().opclo_price // { // filtered_2nd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // } // // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 // let mut rsi3_30m_vec: Vec = Vec::new(); // let mut rsi10_30m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_3rd_symbols: Vec = Vec::new(); // for symbol in filtered_2nd_symbols { // let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { // rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); // rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // let result = rsi3_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi3_30m_vec[T].rsi_value < 15.0 { // let result = rsi10_30m_vec.binary_search_by_key( // &opclo_30m_vec.last().unwrap().close_time, // |&RsiData { // rsi_value, // close_time, // }| close_time, // ); // match result { // Ok(T) => { // if rsi10_30m_vec[T].rsi_value < 35.0 { // filtered_3rd_symbols.push(symbol); // } // } // Err(E) => {} // } // } // } // Err(E) => {} // } // } // } // } // // 4th filtering: RSI3_1m < 10, RSI10_1m < 25 // let mut rsi3_1m_vec: Vec = Vec::new(); // let mut rsi10_1m_vec: Vec = Vec::new(); // let mut opclo_30m_vec: Vec = Vec::new(); // let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for symbol in filtered_3rd_symbols { // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); // let opclo_30m_option = alldata // .rt_price_30m_vec // .iter() // .position(|x| *x.0 == *symbol); // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && opclo_30m_option.is_some() { // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); // opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] // .1 // .clone(); // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 // && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 // { // filtered_4th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); // } // } // // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi3_1m_vec[T].rsi_value < 10.0 { // // let result = rsi10_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); // // match result { // // Ok(T) => { // // if rsi10_1m_vec[T].rsi_value < 25.0 { // // filtered_5th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); // // } // // }, // // Err(E) => {} // // } // // } // // }, // // Err(E) => {} // // } // // } // } // } // // // 6. 5th filtering symbols: 30m current vol > 30m previous vol * 2 // // let mut opclo_30m_vec: Vec = Vec::new(); // // let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) // // for element in filtered_3rd_symbols { // // let opclo_30m_result = read_price_into_vector("30m", &element).await; // // if opclo_30m_result.is_ok() { // // let opclo_30m_option = opclo_30m_result?; // // if opclo_30m_option.is_some() { // // opclo_30m_vec = opclo_30m_option.unwrap(); // // if opclo_30m_vec.len() >= 2 { // // opclo_30m_vec.reverse(); // // opclo_30m_vec.truncate(2); // // opclo_30m_vec.reverse(); // // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume < opclo_30m_vec.last().unwrap().quote_asset_volume && opclo_30m_vec.last().unwrap().candle_type == "DOWN" { // // filtered_4th_symbols.push((element, opclo_30m_vec.last().unwrap().close_time)); // // } // // } // // } // // } // // } // // println!("4: {:?}", filtered_4th_symbols); // // 7. insert record into [pre_suggested_coin_list] // insert_pre_suggested_coins(16, &filtered_4th_symbols, alldata).await; // Ok(()) // } // useful functions for strategists pub async fn get_current_price(symbol: &String, rt_price_vec: &Vec<(String, Vec)>) -> Option { let index_result = rt_price_vec.iter().position(|x| *x.0 == *symbol); match index_result { Some(T) => { if rt_price_vec[T].1.last().is_some() { Some(rt_price_vec[T].1.last().unwrap().close_price) } else { None } }, None => None, } } async fn insert_pre_suggested_coins( registerer: i32, filtered_symbols: &Vec<(String, i64, f64)>, alldata: &AllData, ) -> Result<(), Box> { // Check the existance of record that is registered by this strategist let mut dest_table_name = String::from("suggested_coin_list"); let mut dest2_table_name = String::from("buy_ordered_coin_list"); let mut dest3_table_name = String::from("pre_suggested_coin_list"); let mut insert_table_name = String::from("pre_suggested_coin_list"); let mut exists_condition_build = String::from("registerer="); exists_condition_build.push_str(registerer.to_string().as_str()); let mut exists_condition = Some(exists_condition_build); let exists_result1 = exists_record(&dest_table_name, &exists_condition).await; let exists_result2 = exists_record(&dest2_table_name, &exists_condition).await; let exists_result3 = exists_record(&dest3_table_name, &exists_condition).await; let insert_columns = vec![ "symbol", "close_time", "suggested_price", "current_price", "registered_server_epoch", "profit_percent", "minimum_profit_percent", "maximum_profit_percent", "registerer", ]; if exists_result1 == true && exists_result2 == true && exists_result3 == true { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } #[derive(FromRow)] struct SelectData2 { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let mut select_columns2 = String::from("symbol, close_time"); let select_data_structure2 = SelectData2 { symbol: String::new(), close_time: 0, }; let suggested_coin_list = try_select_record( &dest_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; let ordered_coin_list = try_select_record( &dest2_table_name, &select_columns2, &select_condition, &select_data_structure2, ) .await?; let pre_suggested_coin_list = try_select_record( &dest3_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } for list_element in &ordered_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } for list_element in &pre_suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else if exists_result1 == true && exists_result2 == true && exists_result3 == false { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } #[derive(FromRow)] struct SelectData2 { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let mut select_columns2 = String::from("symbol, close_time"); let select_data_structure2 = SelectData2 { symbol: String::new(), close_time: 0, }; let suggested_coin_list = try_select_record( &dest_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; let ordered_coin_list = try_select_record( &dest2_table_name, &select_columns2, &select_condition, &select_data_structure2, ) .await?; // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } for list_element in &ordered_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else if exists_result1 == true && exists_result2 == false && exists_result3 == true { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let suggested_coin_list = try_select_record( &dest_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; let pre_suggested_coin_list = try_select_record( &dest3_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } for list_element in &pre_suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else if exists_result1 == true && exists_result2 == false && exists_result3 == false { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let suggested_coin_list = try_select_record( &dest_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else if exists_result1 == false && exists_result2 == true && exists_result3 == true { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } #[derive(FromRow)] struct SelectData2 { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let mut select_columns2 = String::from("symbol, close_time"); let select_data_structure2 = SelectData2 { symbol: String::new(), close_time: 0, }; let ordered_coin_list = try_select_record( &dest2_table_name, &select_columns2, &select_condition, &select_data_structure2, ) .await?; let pre_suggested_coin_list = try_select_record( &dest3_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; // insert record without duplicate(registerer, close_time, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &ordered_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } for list_element in &pre_suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else if exists_result1 == false && exists_result2 == true && exists_result3 == false { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } #[derive(FromRow)] struct SelectData2 { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let mut select_columns2 = String::from("symbol, close_time"); let select_data_structure2 = SelectData2 { symbol: String::new(), close_time: 0, }; let ordered_coin_list = try_select_record( &dest2_table_name, &select_columns2, &select_condition, &select_data_structure2, ) .await?; // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &ordered_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else if exists_result1 == false && exists_result2 == false && exists_result3 == true { // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] #[derive(FromRow)] struct SelectData { symbol: String, close_time: i64, } let mut select_columns = String::from("symbol, close_time"); let mut condition_build = String::from("WHERE registerer="); condition_build.push_str(registerer.to_string().as_str()); let select_condition = Some(condition_build); let select_data_structure = SelectData { symbol: String::new(), close_time: 0, }; let pre_suggested_coin_list = try_select_record( &dest3_table_name, &select_columns, &select_condition, &select_data_structure, ) .await?; // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] for filtered_element in filtered_symbols { let mut is_dupe = false; // initialize for list_element in &pre_suggested_coin_list { if (filtered_element.0 == list_element.symbol) && (filtered_element.1 == list_element.close_time) { is_dupe = true; break; } } if is_dupe == false { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } } else { for filtered_element in filtered_symbols { let insert_values = vec![ filtered_element.0.clone(), // symbol filtered_element.1.to_string(), // close_time filtered_element.2.to_string(), // suggested_price filtered_element.2.to_string(), // current_price server_epoch().await.to_string(), // registered_server_epoch 0.0.to_string(), // profit_percent 0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; } } Ok(()) }