diff --git a/src/coex/assets_managing_team.rs b/src/coex/assets_managing_team.rs index b072a48..8f95d40 100644 --- a/src/coex/assets_managing_team.rs +++ b/src/coex/assets_managing_team.rs @@ -1,6 +1,7 @@ // assets_managing_team manages [asset_manage_announcement], [kelly_criterion], and[wallet] ([wallet_testnet] as well) use crate::coex::exchange_team::*; +use crate::coex::order_team::{DBlist, SellHistoryList}; use crate::database_control::*; use crate::decimal_funcs::*; use crate::RunningMode::*; @@ -10,7 +11,6 @@ use rust_decimal::{prelude::ToPrimitive, Decimal, RoundingStrategy}; use rust_decimal_macros::dec; use serde_json::{Result, Value}; use sqlx::FromRow; -use crate::coex::order_team::{DBlist, SellHistoryList}; #[derive(Debug, FromRow)] pub struct AchievementEvaluationInfo { @@ -106,7 +106,7 @@ pub async fn set_unit_usdt() { let mut set_unit_trade_usdt = Decimal::new(0, 8); set_unit_trade_usdt = dec!(30.0); // $30 for each trade - + // update fields in [asset_manage_announcement] table let update_table_name = String::from("asset_manage_announcement"); let update_values = vec![( @@ -196,12 +196,16 @@ pub async fn update_current_total_usdt() { let asset_info = select_asset_manage_announcement().await; let achievement_evaluation = select_achievement_evaluation().await; - let balance = decimal_sub(achievement_evaluation.usdt_profit, achievement_evaluation.invested_usdt); + let balance = decimal_sub( + achievement_evaluation.usdt_profit, + achievement_evaluation.invested_usdt, + ); let current_total_usdt = decimal_add(asset_info.initial_usdt, balance); let profit = decimal_sub( decimal_div(current_total_usdt, asset_info.initial_usdt), - dec!(1)); + dec!(1), + ); update_values = vec![ ( @@ -290,16 +294,27 @@ pub async fn update_kelly_criterion() -> Result<()> { .await .unwrap(); - let least_number = 50; // the least number of sell hostory to calculate kelly criterion - + // FIXME: let least_number = 50; + let least_number = 1000000000; // the least number of sell hostory to calculate kelly criterion + if sell_history_vec.len() >= least_number { - let lose_collection_vec = sell_history_vec.iter().filter(|&a| a.pure_profit_percent < 0.0).collect::>(); - let win_collection_vec = sell_history_vec.iter().filter(|&a| a.pure_profit_percent >= 0.0).collect::>(); - let win_rate: f64 = (win_collection_vec.len() as f64)/(sell_history_vec.len() as f64); + let lose_collection_vec = sell_history_vec + .iter() + .filter(|&a| a.pure_profit_percent < 0.0) + .collect::>(); + let win_collection_vec = sell_history_vec + .iter() + .filter(|&a| a.pure_profit_percent >= 0.0) + .collect::>(); + let win_rate: f64 = (win_collection_vec.len() as f64) / (sell_history_vec.len() as f64); let lose_rate: f64 = 1.0 - win_rate; - let loss_sum = lose_collection_vec.iter().fold(0.0, |acc, x| acc + x.pure_profit_percent); + let loss_sum = lose_collection_vec + .iter() + .fold(0.0, |acc, x| acc + x.pure_profit_percent); let loss_rate_avg = (loss_sum * 0.01) / (lose_collection_vec.len() as f64) * -1.0; - let profit_sum = win_collection_vec.iter().fold(0.0, |acc, x| acc + x.pure_profit_percent); + let profit_sum = win_collection_vec + .iter() + .fold(0.0, |acc, x| acc + x.pure_profit_percent); let profit_rate_avg = (profit_sum * 0.01) / (win_collection_vec.len() as f64); let betting_rate = (win_rate / loss_rate_avg) - (lose_rate / profit_rate_avg); @@ -307,19 +322,18 @@ pub async fn update_kelly_criterion() -> Result<()> { // update kelly_criterion let update_table_name = String::from("kelly_criterion"); let update_value = vec![ - (String::from("betting_rate"), betting_rate.to_string()), - (String::from("win_rate"), win_rate.to_string()), - (String::from("lose_rate"), lose_rate.to_string()), - (String::from("profit_rate"), profit_rate_avg.to_string()), - (String::from("loss_rate"), loss_rate_avg.to_string()), - ] - ; + (String::from("betting_rate"), betting_rate.to_string()), + (String::from("win_rate"), win_rate.to_string()), + (String::from("lose_rate"), lose_rate.to_string()), + (String::from("profit_rate"), profit_rate_avg.to_string()), + (String::from("loss_rate"), loss_rate_avg.to_string()), + ]; let update_condition = vec![(String::from("id"), String::from("1"))]; update_record3(&update_table_name, &update_value, &update_condition) .await .unwrap(); } - } + } Ok(()) } @@ -376,19 +390,24 @@ pub async fn set_available_usdt() { // fetch current_total_usdt let mut asset_info = select_asset_manage_announcement().await; let kelly_criterion_info = select_kelly_criterion().await; - + let mut available_usdt: Decimal; - if kelly_criterion_info.betting_rate >= 5.0 && kelly_criterion_info.betting_rate < 100.0 {; - available_usdt = decimal_mul(asset_info.current_total_usdt, rust_decimal::prelude::FromPrimitive::from_f64( - kelly_criterion_info.betting_rate * 0.01, - ) - .unwrap()); + if kelly_criterion_info.betting_rate >= 5.0 && kelly_criterion_info.betting_rate < 100.0 { + available_usdt = decimal_mul( + asset_info.current_total_usdt, + rust_decimal::prelude::FromPrimitive::from_f64( + kelly_criterion_info.betting_rate * 0.01, + ) + .unwrap(), + ); } else if kelly_criterion_info.betting_rate >= 100.0 { available_usdt = asset_info.current_total_usdt; - } else { // default: 5% of current_total_usdt - available_usdt = decimal_mul(asset_info.current_total_usdt, dec!(0.05)); + } else { + // default: 5% of current_total_usdt + // FIXME: dec!(0.05) + available_usdt = decimal_mul(asset_info.current_total_usdt, dec!(1)); } - + let unit_trade_usdt = asset_info.unit_trade_usdt; // set available_usdt with current_total_usdt and update is_tradable @@ -563,9 +582,14 @@ pub async fn select_achievement_evaluation() -> AchievementEvaluationInfo { let columns = String::from("*"); let condition = None; // FIXME: this code should be general - let select_result = select_record(&table_name, &columns, &condition, &achievement_evaluation_info) - .await - .unwrap(); + let select_result = select_record( + &table_name, + &columns, + &condition, + &achievement_evaluation_info, + ) + .await + .unwrap(); let result_vec = &select_result[2]; //strategist #3 achievement_evaluation_info.strategist = result_vec.strategist; diff --git a/src/coex/exchange_team.rs b/src/coex/exchange_team.rs index 3a426e1..94201fe 100644 --- a/src/coex/exchange_team.rs +++ b/src/coex/exchange_team.rs @@ -1,10 +1,10 @@ use crate::coex::assets_managing_team::*; use crate::coex::order_team::*; -use crate::strategy_team::AllData; use crate::coin_health_check_team::request_others::{CoinPriceData, ExchangeInfo, TradeFee}; use crate::database_control::*; use crate::decimal_funcs::{decimal, decimal_add, decimal_div, decimal_mul, decimal_sub}; use crate::signal_association::signal_decision::*; +use crate::strategy_team::AllData; use reqwest::{Client, ClientBuilder}; use rust_decimal::{prelude::FromPrimitive, prelude::ToPrimitive, Decimal, RoundingStrategy}; use rust_decimal_macros::dec; @@ -196,7 +196,7 @@ pub struct MarketCapIndex { impl DBlist for MarketCapIndex { fn new() -> MarketCapIndex { - let a = MarketCapIndex { + let a = MarketCapIndex { market_cap_index: 0.0, minimum: 0.0, maximum: 0.0, @@ -221,15 +221,15 @@ pub async fn buy_coin( let mut filtered_suggested_coin_vec: Vec<&SuggestedCoin> = Vec::new(); let mut is_exist_delete_symbol: bool = false; let mut delete_condition = String::from("WHERE "); - + // filtering symbols to buy for element in &suggested_coin { - if element.already_buy == 0 - && server_epoch - element.registered_server_epoch <= 300_000 + if element.already_buy == 0 && server_epoch - element.registered_server_epoch <= 300_000 // 300_000 (300 secs = 5 mins) { filtered_suggested_coin_vec.push(element); - } else if server_epoch - element.registered_server_epoch >= 5_400_000 { // 30mins * 3 + } else if server_epoch - element.registered_server_epoch >= 5_400_000 { + // 30mins * 3 delete_condition.push_str("id = "); delete_condition.push_str(element.id.to_string().as_str()); delete_condition.push_str(" OR "); @@ -255,14 +255,13 @@ pub async fn buy_coin( .iter() .position(|TradeFee| TradeFee.symbol == element.symbol); - if exchange_info_result.is_some() - && trade_fee_result.is_some() - { - let lot_step_size = exchange_info_vec[exchange_info_result.unwrap()].stepsize; + if exchange_info_result.is_some() && trade_fee_result.is_some() { + let lot_step_size = + exchange_info_vec[exchange_info_result.unwrap()].stepsize; let tick_size = exchange_info_vec[exchange_info_result.unwrap()].ticksize; - let base_commission_precision = exchange_info_vec[exchange_info_result - .unwrap()] - .base_commission_precision; + let base_commission_precision = exchange_info_vec + [exchange_info_result.unwrap()] + .base_commission_precision; let trade_fee = trade_fee_vec[trade_fee_result.unwrap()].takercommission; // buy the suggested coin and transfer it into [buy_ordered_coin_list] @@ -272,7 +271,7 @@ pub async fn buy_coin( lot_step_size.normalize().scale(), RoundingStrategy::ToZero, ); - + let mut base_qty_fee_adjusted = Decimal::new(0, 8); base_qty_fee_adjusted = decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee)) @@ -280,7 +279,7 @@ pub async fn buy_coin( base_commission_precision, RoundingStrategy::ToZero, ); - + let mut used_usdt = Decimal::new(0, 8); used_usdt = decimal_mul(base_qty_ordered, element.suggested_price) .round_dp_with_strategy( @@ -301,7 +300,7 @@ pub async fn buy_coin( .to_f64() .unwrap() * 100.0; - + // order the symbol based on base_qty_ordered and current_price limit_order_buy( element, @@ -343,7 +342,7 @@ pub async fn buy_coin( .unwrap(); println!("Delete suggested coin list"); } - } + } Ok(()) } diff --git a/src/coex/order_team.rs b/src/coex/order_team.rs index cee5091..cf5875e 100644 --- a/src/coex/order_team.rs +++ b/src/coex/order_team.rs @@ -11,11 +11,11 @@ use crate::URL_TEST; // use crates use crate::coex::assets_managing_team::*; use crate::coex::exchange_team::*; -use crate::strategy_team::{AllData, TimeData}; use crate::coin_health_check_team::request_others::{CoinPriceData, ExchangeInfo, TradeFee}; use crate::database_control::*; use crate::decimal_funcs::*; use crate::signal_association::signal_decision::*; +use crate::strategy_team::{AllData, TimeData}; use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; use crate::value_estimation_team::indicators::ema::EmaData; use crate::value_estimation_team::indicators::sma::SmaData; @@ -589,7 +589,7 @@ async fn update_repeat_task( let trade_fee_result = trade_fee_vec .iter() .position(|TradeFee| TradeFee.symbol == element.symbol); - + if price_index_option.is_some() && lot_step_size_result.is_some() && quote_commission_precision_result.is_some() @@ -605,30 +605,36 @@ async fn update_repeat_task( // to get quote_commission_precision let trade_fee = trade_fee_vec[trade_fee_result.unwrap()].takercommission; let lot_step_size = exchange_info_vec[lot_step_size_result.unwrap()].stepsize; - let quote_commission_precision = exchange_info_vec[quote_commission_precision_result - .unwrap()] - .quote_commission_precision; - let base_qty_to_be_ordered = element.base_qty_fee_adjusted.round_dp_with_strategy( - lot_step_size.normalize().scale(), - RoundingStrategy::ToZero, - ); + let quote_commission_precision = exchange_info_vec + [quote_commission_precision_result.unwrap()] + .quote_commission_precision; + let base_qty_to_be_ordered = + element.base_qty_fee_adjusted.round_dp_with_strategy( + lot_step_size.normalize().scale(), + RoundingStrategy::ToZero, + ); let expected_get_usdt = decimal_mul( - decimal_mul(base_qty_to_be_ordered, price) - .round_dp_with_strategy(quote_commission_precision, RoundingStrategy::ToZero), + decimal_mul(base_qty_to_be_ordered, price).round_dp_with_strategy( + quote_commission_precision, + RoundingStrategy::ToZero, + ), decimal_sub(dec!(1), trade_fee), ); - let pure_profit_percent = - ((expected_get_usdt.to_f64().unwrap() / element.used_usdt.to_f64().unwrap()) - 1.0) - * 100.0; + let pure_profit_percent = ((expected_get_usdt.to_f64().unwrap() + / element.used_usdt.to_f64().unwrap()) + - 1.0) + * 100.0; update_record_build.push(element.id.to_string()); // id update_record_build.push(price.to_string()); // current_price update_record_build.push(expected_get_usdt.to_string()); //expected_get_usdt - update_record_build.push(decimal_sub(expected_get_usdt, element.used_usdt).to_string()); // expected_usdt_profit + update_record_build + .push(decimal_sub(expected_get_usdt, element.used_usdt).to_string()); // expected_usdt_profit update_record_build.push(pure_profit_percent.to_string()); // pure_profit_percent if element.minimum_profit_percent > pure_profit_percent { - update_record_build.push(pure_profit_percent.to_string()); // minimum_profit_percent + update_record_build.push(pure_profit_percent.to_string()); + // minimum_profit_percent } else if pure_profit_percent >= 0.0 { update_record_build.push(0.0.to_string()); // minimum_profit_percent } else { @@ -637,7 +643,8 @@ async fn update_repeat_task( } if element.maximum_profit_percent < pure_profit_percent { - update_record_build.push(pure_profit_percent.to_string()); // maximum_profit_percent + update_record_build.push(pure_profit_percent.to_string()); + // maximum_profit_percent } else if pure_profit_percent <= 0.0 { update_record_build.push(0.0.to_string()); // maximum_profit_percent } else { @@ -2089,7 +2096,9 @@ async fn get_timestamp() -> String { } // parameter 0: select all registerers -pub async fn select_filled_buy_orders(registerer: u32) -> Result, Box> { +pub async fn select_filled_buy_orders( + registerer: u32, +) -> Result, Box> { let select_table_name = String::from("buy_ordered_coin_list"); let select_columns = String::from("*"); let mut select_condition_build = String::from("WHERE (status = 'FILLED' or status = 'SIMUL')"); @@ -2115,7 +2124,6 @@ pub async fn select_filled_buy_orders(registerer: u32) -> Result Result<(), Box= 0 AND lastId >= 0"); condition_build.push_str(" AND bidPrice > 0"); condition_build.push_str(" AND bidQty > 0"); @@ -58,11 +61,12 @@ pub async fn initialize_valid_usde_trade() -> Result<(), Box= 0 AND lastId >= 0"); condition_build.push_str(" AND bidPrice > 0"); condition_build.push_str(" AND bidQty > 0"); @@ -122,11 +130,12 @@ pub async fn collect_valid_usde_trade( condition_build.push_str(" AND symbol NOT LIKE 'BTCSTUSDT'"); condition_build.push_str(" AND symbol NOT LIKE 'ACAUSDT'"); condition_build.push_str(" AND symbol NOT LIKE 'ANCUSDT'"); - + let condition = Some(condition_build); // get valid usdt trades - let usdt_trades = select_record(&fetch_table_name, &column_name, &condition, &usdt_trades).await?; + let usdt_trades = + select_record(&fetch_table_name, &column_name, &condition, &usdt_trades).await?; // filtering usdt trades let mut filtered_usdt_trades: Vec = Vec::new(); @@ -136,13 +145,15 @@ pub async fn collect_valid_usde_trade( let step_size_result = exchange_info_vec .iter() .position(|ExchangeInfo| ExchangeInfo.symbol == usdt_trade.symbol); - + if step_size_result.is_some() { - let avg_price: Decimal = rust_decimal::prelude::FromPrimitive::from_f64(usdt_trade.weightedavgprice).unwrap(); + let avg_price: Decimal = + rust_decimal::prelude::FromPrimitive::from_f64(usdt_trade.weightedavgprice) + .unwrap(); let step_size = exchange_info_vec[step_size_result.unwrap()].stepsize; let step_price = decimal_mul(step_size, avg_price); let unit_trade_usdt = crate::coex::assets_managing_team::get_unit_trade_usdt().await; - + // exclude USDT trades whose step_price is over than 1% of unit_trade_usdt if step_price > decimal_mul(unit_trade_usdt, dec!(0.01)) { excluded_usdt_trades.push(usdt_trade.symbol.clone()); @@ -151,7 +162,7 @@ pub async fn collect_valid_usde_trade( } } } - + // update valid usdt trades let table_name = String::from("valid_usdt_trades"); let columns = vec!["symbol"]; @@ -164,7 +175,7 @@ pub async fn collect_valid_usde_trade( *valid_usdt_trade_vec = filtered_usdt_trades; delete_all_rows(&table_name).await?; insert_records(&table_name, &columns, &value_wrapper).await?; - + // update stop usdt trades let table_name = String::from("stop_usdt_trades"); let columns = vec!["symbol"]; diff --git a/src/database_control.rs b/src/database_control.rs index 87c076b..ebc4d54 100644 --- a/src/database_control.rs +++ b/src/database_control.rs @@ -689,7 +689,7 @@ where } let mut conn_result = sqlx::mysql::MySqlConnection::connect(DB_URL).await; - + //retry connection until it will be done. while conn_result.is_err() { sleep(Duration::from_millis(200)).await; @@ -700,7 +700,7 @@ where // let mut query_result: Vec = sqlx::query_as::<_, T>(&query).fetch_all(&mut conn).await?; let mut query_result = sqlx::query_as::<_, T>(&query).fetch_all(&mut conn).await; let mut query_result_vec: Vec = Vec::new(); - + loop { match query_result { Ok(T) => { diff --git a/src/initialization.rs b/src/initialization.rs index fb569ed..c9be954 100644 --- a/src/initialization.rs +++ b/src/initialization.rs @@ -1,8 +1,8 @@ use crate::coex::assets_managing_team; use crate::coex::order_team; use crate::coex::order_team::{BuyOrderedCoinList, SellOrderedCoinList}; -use crate::coin_health_check_team::*; use crate::coin_health_check_team::request_others::ExchangeInfo; +use crate::coin_health_check_team::*; use crate::database_control::*; use crate::time_checking_team::{UserTime, *}; use crate::RunningMode::*; @@ -15,7 +15,6 @@ use sqlx::FromRow; use std::{io, io::Write, path::Path, process::Stdio}; use tokio::{fs::*, io::ErrorKind, process::Command, task::JoinHandle, time::*}; - const STRATEGIST_NUMBER: u32 = 16; pub async fn initialization() { @@ -240,8 +239,8 @@ async fn initialize_database() { } } delete_all_rows(&table_name) - .await - .expect("Failed to delete rows!"); + .await + .expect("Failed to delete rows!"); println!("Ok"); } @@ -270,8 +269,8 @@ async fn initialize_database() { } } delete_all_rows(&table_name) - .await - .expect("Failed to delete rows!"); + .await + .expect("Failed to delete rows!"); monitors::initialize_valid_usde_trade().await; println!("Ok"); @@ -983,7 +982,7 @@ async fn initialize_database() { } if RUNNING_MODE == SIMUL { - assets_managing_team::add_extra_usdt(dec!(2200.0)).await; + assets_managing_team::add_extra_usdt(dec!(10000000000.0)).await; assets_managing_team::update_current_total_usdt().await; } else { let mut table_name = String::new(); @@ -1428,7 +1427,7 @@ async fn initialize_database() { sleep(Duration::from_millis(10)).await; } } - } + } // else { // delete_all_rows(&table_name) // .await diff --git a/src/lib.rs b/src/lib.rs index ba95b49..8695f11 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,9 +28,9 @@ pub mod coex; pub mod coin_health_check_team; pub mod database_control; pub mod decimal_funcs; +pub mod initialization; pub mod server_health_check_team; pub mod signal_association; +pub mod strategy_team; pub mod time_checking_team; pub mod value_estimation_team; -pub mod strategy_team; -pub mod initialization; diff --git a/src/main.rs b/src/main.rs index c326124..1d4b5de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ #![allow(unused)] #![allow(warnings)] -use crate::strategy_team::AllData; use crate::coin_health_check_team::*; use crate::request_candles::CandleData; use crate::request_others::{CoinPriceData, ExchangeInfo, TradeFee}; use crate::server_health_check_team::ServerHealth; +use crate::strategy_team::AllData; use crate::time_checking_team::UserTime; use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; use reqwest::{Client, ClientBuilder}; @@ -204,7 +204,7 @@ async fn main() -> Result<(), Box> { println!("*** REAL MODE ***"); } else if RUNNING_MODE == RunningMode::TEST { println!("*** TEST MODE ***"); - } else if RUNNING_MODE == RunningMode::SIMUL { + } else if RUNNING_MODE == RunningMode::SIMUL { println!("*** SIMULATION MODE ***"); } @@ -238,7 +238,7 @@ async fn main() -> Result<(), Box> { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL { let mut elapsed_time = instant.elapsed().as_secs(); let mut remaining_time: u64 = 60 - elapsed_time; - + while remaining_time > 0 && 60 > remaining_time { print!("\rstart tradingbot in {} seconds", remaining_time); io::stdout().flush(); @@ -503,7 +503,7 @@ async fn main() -> Result<(), Box> { break; } } - + match result { Ok(T) => { tx_tradefee_vec.send_modify(|vec| *vec = tradefee_vec_temp); @@ -552,13 +552,11 @@ async fn main() -> Result<(), Box> { break; } } - + match result { Ok(T) => { tx_exchange_info_data.send_modify(|vec| *vec = exchange_info_data_temp); - tx_task3 - .send(3) - .expect("The mpsc channel has been closed."); + tx_task3.send(3).expect("The mpsc channel has been closed."); } Err(E) => {} } @@ -566,11 +564,11 @@ async fn main() -> Result<(), Box> { } }); - // Task#4: request 24h price changes, - // pick valid USDT Trades, - // filtering stop USDT Trades, - // monitor total_24h_change_profit_index, - // usdt_24h_change_profit_index, + // Task#4: request 24h price changes, + // pick valid USDT Trades, + // filtering stop USDT Trades, + // monitor total_24h_change_profit_index, + // usdt_24h_change_profit_index, // total_price_down_dist_index tokio::task::spawn(async move { sleep(Duration::from_secs(10)).await; @@ -586,8 +584,11 @@ async fn main() -> Result<(), Box> { Ok(T) => { let exchange_info_vec = rx5_exchange_info_data.borrow().clone(); let mut valid_usdt_trade_vec_temp: Vec = Vec::new(); - let result = - monitors::collect_valid_usde_trade(&mut valid_usdt_trade_vec_temp, &exchange_info_vec).await; + let result = monitors::collect_valid_usde_trade( + &mut valid_usdt_trade_vec_temp, + &exchange_info_vec, + ) + .await; match result { Ok(T) => { @@ -716,7 +717,8 @@ async fn main() -> Result<(), Box> { if tx_rt_price_30m_vec.is_closed() { eprintln!("tx_rt_price_30m_vec has been closed!"); } else { - tx_rt_price_30m_vec.send_modify(|vec| *vec = rt_price_30m_vec_write_temp); + tx_rt_price_30m_vec + .send_modify(|vec| *vec = rt_price_30m_vec_write_temp); } } Err(E) => {} @@ -813,7 +815,8 @@ async fn main() -> Result<(), Box> { // sleep as much as the loop recurs per 10 seconds, expecting child threads will have finished within 10 seconds. elapsed_time = instant.elapsed().as_millis(); - if 30_000 > elapsed_time { // 10_000 for major trade + if 30_000 > elapsed_time { + // 10_000 for major trade sleep(Duration::from_millis((30_000 - elapsed_time) as u64)).await; } } @@ -827,8 +830,7 @@ async fn main() -> Result<(), Box> { let instant = Instant::now(); let mut candle_30m_vec_temp: Vec<(String, Vec)> = Vec::new(); let result = - - request_candles::fetch_candle_delay(&interval, &mut candle_30m_vec_temp).await; + request_candles::fetch_candle_delay(&interval, &mut candle_30m_vec_temp).await; // request_candles::fetch_candle_parallel(&interval, &mut candle_30m_vec_temp).await; match result { @@ -840,7 +842,8 @@ async fn main() -> Result<(), Box> { } // sleep as much as the loop recurs per 60 seconds, expecting child threads will have finished within 60 seconds. elapsed_time = instant.elapsed().as_millis(); - if 60_000 > elapsed_time { //60_000 + if 60_000 > elapsed_time { + //60_000 sleep(Duration::from_millis((60_000 - elapsed_time) as u64)).await; } } @@ -1015,7 +1018,8 @@ async fn main() -> Result<(), Box> { all_data.rt_price_1w_vec = rx3_rt_price_1w_vec.borrow().clone(); all_data.rt_price_1mon_vec = rx3_rt_price_1mon_vec.borrow().clone(); - let result = strategy_team::strategy_manager::execute_list_up_for_buy(&all_data).await; + let result = + strategy_team::strategy_manager::execute_list_up_for_buy(&all_data).await; match result { Ok(T) => { @@ -1090,7 +1094,12 @@ async fn main() -> Result<(), Box> { all_data.rt_price_1w_vec = rx4_rt_price_1w_vec.borrow().clone(); all_data.rt_price_1mon_vec = rx4_rt_price_1mon_vec.borrow().clone(); - let result = strategy_team::strategy_manager::execute_list_up_for_sell(&all_data, &exchange_info_vec, &trade_fee_vec).await; + let result = strategy_team::strategy_manager::execute_list_up_for_sell( + &all_data, + &exchange_info_vec, + &trade_fee_vec, + ) + .await; match result { Ok(T) => { @@ -1110,7 +1119,7 @@ async fn main() -> Result<(), Box> { } } }); - } + } // Task#18: monitoring pre-suggested coins tokio::task::spawn(async move { @@ -1143,17 +1152,14 @@ async fn main() -> Result<(), Box> { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST { tokio::task::spawn(async move { sleep(Duration::from_secs(30)).await; - + let mut elapsed_time = 0; loop { let instant = Instant::now(); let exchange_info_vec = rx_exchange_info_data.borrow().clone(); let trade_fee_vec = rx_tradefee_vec.borrow().clone(); - let result = coex::exchange_team::buy_coin( - &exchange_info_vec, - &trade_fee_vec, - ) - .await; + let result = + coex::exchange_team::buy_coin(&exchange_info_vec, &trade_fee_vec).await; // send Task#0 a message to notify running on match result { @@ -1183,11 +1189,7 @@ async fn main() -> Result<(), Box> { let exchange_info_vec = rx_exchange_info_data.borrow().clone(); let trade_fee_vec = rx_tradefee_vec.borrow().clone(); // let result = coex::exchange_team::buy_coin_for_test(&client, &coin_price_vec, &exchange_info_vec, &trade_fee_vec).await; - let result = coex::exchange_team::buy_coin( - &exchange_info_vec, - &trade_fee_vec, - ) - .await; + let result = coex::exchange_team::buy_coin(&exchange_info_vec, &trade_fee_vec).await; // send Task#0 a message to notify running on match result { @@ -1431,8 +1433,7 @@ async fn main() -> Result<(), Box> { let mut elapsed_time = 0; loop { let instant = Instant::now(); - let result = - coex::assets_managing_team::update_kelly_criterion().await; + let result = coex::assets_managing_team::update_kelly_criterion().await; // send Task#0 a message to notify running on match result { diff --git a/src/signal_association/coinmarketcap.rs b/src/signal_association/coinmarketcap.rs index f9e632f..2eee88b 100644 --- a/src/signal_association/coinmarketcap.rs +++ b/src/signal_association/coinmarketcap.rs @@ -40,14 +40,11 @@ pub async fn market_cap_index() -> Result<(), Box = 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 { @@ -200,13 +200,13 @@ // let rt_price_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == element.0); // let element_c = element.clone(); // let filtered_5th_symbols_arc_c = Arc::clone(&filtered_5th_symbols_arc); - + // if rt_price_30m_option.is_some() { // let mut rt_price_30m_vec_c = alldata.rt_price_30m_vec[rt_price_30m_option.unwrap()].1.clone(); // let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec) // .await // .unwrap(); - + // task_vec.push(tokio::spawn(async move { // if rt_price_30m_vec_c.len() >= 21 { // rt_price_30m_vec_c.pop(); @@ -314,7 +314,7 @@ // } // } // } - + // // 7th 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_8th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) // for element in filtered_7th_symbols { @@ -340,7 +340,7 @@ // 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 @@ -421,4 +421,4 @@ // insert_pre_suggested_coins(1, false, &a, alldata).await; // Ok(()) -// } \ No newline at end of file +// } diff --git a/src/strategy_team/strategy_002.rs b/src/strategy_team/strategy_002.rs index 1d0c2d4..692f4ca 100644 --- a/src/strategy_team/strategy_002.rs +++ b/src/strategy_team/strategy_002.rs @@ -13,7 +13,7 @@ // 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 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 { @@ -139,7 +139,7 @@ // if ema30_search_result.is_ok() && ema150_search_result.is_ok() { // if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && -// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && @@ -183,7 +183,7 @@ // }| close_time, // ); // if stoch_rsi_search_result.is_ok() { -// if stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k <= 5.0 && +// if stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k <= 5.0 && // stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].d <= 5.0 && // stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= 5.0 { // filtered_5th_symbols.push(element); @@ -192,7 +192,7 @@ // } // } // } - + // // 7th 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 { @@ -216,10 +216,10 @@ // }| *close_time, // ); // if heatmap_search_result.is_ok() { -// if +// 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 diff --git a/src/strategy_team/strategy_003.rs b/src/strategy_team/strategy_003.rs index fa6fa71..87d2904 100644 --- a/src/strategy_team/strategy_003.rs +++ b/src/strategy_team/strategy_003.rs @@ -1,4 +1,8 @@ -use super::{limit_order_sell, AllData, RealtimePriceData, Mutex, Arc, try_join_all, exists_record, StochRsiData, EmaData, SupertrendData, RsiData, stoch_rsi, ema, rsi, supertrend, select_filled_buy_orders, ExchangeInfo, TradeFee, Client, ClientBuilder, dec, RoundingStrategy}; +use super::{ + dec, ema, exists_record, limit_order_sell, rsi, select_filled_buy_orders, stoch_rsi, + supertrend, try_join_all, AllData, Arc, Client, ClientBuilder, EmaData, ExchangeInfo, Mutex, + RealtimePriceData, RoundingStrategy, RsiData, StochRsiData, SupertrendData, TradeFee, +}; pub async fn list_up_for_buy( alldata: &AllData, @@ -105,18 +109,10 @@ pub async fn list_up_for_buy( // 3rd filtering: EMA30 > EMA 150 let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); - let ema30_30m_data: Vec<(String, Vec)> = ema( - 30, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - let ema150_30m_data: Vec<(String, Vec)> = ema( - 150, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; + let ema30_30m_data: Vec<(String, Vec)> = + ema(30, &alldata.rt_price_30m_vec, &filtered_3rd_symbols_c).await?; + let ema150_30m_data: Vec<(String, Vec)> = + ema(150, &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(); @@ -144,26 +140,33 @@ pub async fn list_up_for_buy( let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( &element_c.1, |&EmaData { - ema_value, - close_time, + ema_value, + close_time, }| close_time, ); let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( &element_c.1, |&EmaData { - ema_value, - close_time, + ema_value, + close_time, }| close_time, ); if ema30_search_result.is_ok() && ema150_search_result.is_ok() { - if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value + if ema30_30m_vec_c[ema30_search_result.unwrap() - 3].ema_value + > ema150_30m_vec_c[ema150_search_result.unwrap() - 3].ema_value + && ema30_30m_vec_c[ema30_search_result.unwrap() - 2].ema_value + > ema150_30m_vec_c[ema150_search_result.unwrap() - 2].ema_value + && ema30_30m_vec_c[ema30_search_result.unwrap() - 1].ema_value + > ema150_30m_vec_c[ema150_search_result.unwrap() - 1].ema_value + && ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value + > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value + && ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value + > ema30_30m_vec_c[ema30_search_result.unwrap() - 1].ema_value + && ema30_30m_vec_c[ema30_search_result.unwrap() - 1].ema_value + > ema30_30m_vec_c[ema30_search_result.unwrap() - 2].ema_value + && ema30_30m_vec_c[ema30_search_result.unwrap() - 2].ema_value + > ema30_30m_vec_c[ema30_search_result.unwrap() - 3].ema_value { let mut filtered_4th_symbols_lock = filtered_4th_symbols_arc_c.lock().await; @@ -176,14 +179,10 @@ pub async fn list_up_for_buy( } try_join_all(task_vec).await?; - // 4th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) 20 > k > kn-1 > kn-2 > kn-3, + // 4th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) 20 > k > kn-1 > kn-2 > kn-3, let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone(); - let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( - 10, - &alldata.rt_price_30m_vec, - &filtered_4th_symbol_c, - ) - .await?; + let mut rsi10_30m_data: Vec<(String, Vec)> = + rsi(10, &alldata.rt_price_30m_vec, &filtered_4th_symbol_c).await?; let stoch_rsi_data = stoch_rsi(&rsi10_30m_data, 10, 3, 3).await?; let mut stoch_rsi10_30m_vec: Vec = Vec::new(); let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) @@ -194,19 +193,19 @@ pub async fn list_up_for_buy( stoch_rsi10_30m_vec = stoch_rsi_data[stoch_rsi10_30m_option.unwrap()].1.clone(); if stoch_rsi10_30m_vec.len() >= 3 { - let stoch_rsi_search_result = stoch_rsi10_30m_vec.binary_search_by_key( - &element.1, - |&StochRsiData { - k, - d, - close_time, - }| close_time, - ); + let stoch_rsi_search_result = stoch_rsi10_30m_vec + .binary_search_by_key(&element.1, |&StochRsiData { k, d, close_time }| { + close_time + }); if stoch_rsi_search_result.is_ok() { - if 10.0 > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-2].k && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-2].k <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-3].k { + if 10.0 > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k + && stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k + > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap() - 1].k + && stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap() - 1].k + <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap() - 2].k + && stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap() - 2].k + <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap() - 3].k + { filtered_5th_symbols.push(element); } } @@ -252,7 +251,7 @@ pub async fn list_up_for_buy( try_join_all(task_vec).await?; // TODO: abnormal price filtering (too high current price) - + // 6th filtering condition: MACD // let mut opclo_30m_vec: Vec = Vec::new(); // let mut ema3_1d_vec: &Vec = &Vec::new(); @@ -333,13 +332,15 @@ pub async fn list_up_for_sell( let mut opclo_30m_vec = all_data.rt_price_30m_vec[opclo_30m_option.unwrap()] .1 .clone(); - + opclo_30m_vec.pop(); opclo_30m_vec.reverse(); let mut opclo_sample_length: usize = 50; // 50 candle samsples let nbr_of_exclusive: usize = 5; opclo_30m_vec.truncate(opclo_sample_length); - opclo_30m_vec.sort_by(|a, b| (a.high_price-a.low_price).total_cmp(&(b.high_price-b.low_price))); + opclo_30m_vec.sort_by(|a, b| { + (a.high_price - a.low_price).total_cmp(&(b.high_price - b.low_price)) + }); opclo_30m_vec.truncate(opclo_sample_length - nbr_of_exclusive); opclo_sample_length -= nbr_of_exclusive; @@ -367,13 +368,14 @@ pub async fn list_up_for_sell( // let target_profit_percent = average_amplitude + (standard_deviation_amplitude * (average_ratio_amp_body)); let target_profit_percent = |multiplier: f64| -> f64 { if multiplier < 0.0 { - ((average_amplitude) * multiplier) - (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy)) + ((average_amplitude) * multiplier) + - (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy)) } else { - ((average_amplitude) * multiplier) + (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy)) + ((average_amplitude) * multiplier) + + (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy)) } }; - if element.is_long == 0 || element.is_long == 1 { if element.pure_profit_percent >= 0.0 { let mut is_sell = false; @@ -382,19 +384,14 @@ pub async fn list_up_for_sell( { println!( "Selling {} 500% target_profit_percent: {:.3}", - element.symbol, - element.pure_profit_percent + element.symbol, element.pure_profit_percent ); is_sell = true; - } else if element.pure_profit_percent >= 7.0 - { - println!( - "Selling {} 7% profit_percent", - element.symbol - ); + } else if element.pure_profit_percent >= 7.0 { + println!("Selling {} 7% profit_percent", element.symbol); is_sell = true; } - + if is_sell == true { // let mut sell_price_ahead: Decimal = Decimal::new(14, 8); // sell_price_ahead = decimal_mul(decimal_add(decimal_mul(decimal_mul(rust_decimal::Decimal::from_f64(element.pure_profit_percent).unwrap(), dec!(0.01)), dec!(0.97)), dec!(1)), element.buy_price).round_dp_with_strategy(2, RoundingStrategy::ToZero); @@ -410,25 +407,21 @@ pub async fn list_up_for_sell( } } else { let mut is_sell = false; - if element.pure_profit_percent <= target_profit_percent(-2.5) - 0.2 // -0.2 means about total trade fees. - { - println!( - "Selling {} -250% target_profit_percent: {:.3}", - element.symbol, - element.pure_profit_percent - ); - is_sell = true; - } else if element.pure_profit_percent <= -5.0 + if element.pure_profit_percent <= target_profit_percent(-2.5) - 0.2 + // -0.2 means about total trade fees. { println!( - "selling {} -5.0% profit", - element.symbol + "Selling {} -250% target_profit_percent: {:.3}", + element.symbol, element.pure_profit_percent ); is_sell = true; + } else if element.pure_profit_percent <= -5.0 { + println!("selling {} -5.0% profit", element.symbol); + is_sell = true; } if is_sell == true { - limit_order_sell( + limit_order_sell( &element, element.current_price, base_qty_to_be_ordered, @@ -446,4 +439,4 @@ pub async fn list_up_for_sell( } Ok(()) -} \ No newline at end of file +} diff --git a/src/strategy_team/strategy_004.rs b/src/strategy_team/strategy_004.rs index 5a6f4fc..aee0bc3 100644 --- a/src/strategy_team/strategy_004.rs +++ b/src/strategy_team/strategy_004.rs @@ -163,7 +163,7 @@ // ema30_30m_vec_c[ema30_search_result.unwrap()-4].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-4].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && -// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value >= ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && // ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && @@ -206,15 +206,15 @@ // if heatmap_search_result.is_ok() { // if (heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::Low -// || +// || // heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::Normal) && // (heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level // == HeatMapLevel::Low -// || +// || // heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level // == HeatMapLevel::Normal -// ) +// ) // { // filtered_5th_symbols.push(element); // } @@ -265,4 +265,4 @@ // insert_pre_suggested_coins(4, false, &a, alldata).await; // Ok(()) -// } \ No newline at end of file +// } diff --git a/src/strategy_team/strategy_005.rs b/src/strategy_team/strategy_005.rs index 6422b44..ac25158 100644 --- a/src/strategy_team/strategy_005.rs +++ b/src/strategy_team/strategy_005.rs @@ -126,19 +126,19 @@ // if heatmap_search_result.is_ok() { // if (heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::Low -// || +// || // heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level // == HeatMapLevel::Normal) && // (heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level // == HeatMapLevel::Low -// || +// || // heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level // == HeatMapLevel::Normal) && // (heatmap_volume_vec[heatmap_search_result.unwrap()-2].heatmap_level // == HeatMapLevel::Low -// || +// || // heatmap_volume_vec[heatmap_search_result.unwrap()-2].heatmap_level -// == HeatMapLevel::Normal) +// == HeatMapLevel::Normal) // { // filtered_4th_symbols.push(element); // } diff --git a/src/strategy_team/strategy_006.rs b/src/strategy_team/strategy_006.rs index 2f14958..94546f8 100644 --- a/src/strategy_team/strategy_006.rs +++ b/src/strategy_team/strategy_006.rs @@ -13,7 +13,7 @@ // 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 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 { @@ -82,7 +82,7 @@ // } // try_join_all(task_vec).await?; -// // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth kn > kn-1 +// // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth kn > kn-1 // let filtered_3rd_symbol_c = filtered_3rd_symbols_arc.lock().await.clone(); // let mut rsi10_1d_data: Vec<(String, Vec)> = rsi( // 10, @@ -110,7 +110,7 @@ // ); // if stoch_rsi_search_result.is_ok() { // if stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k > stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()-1].k && -// stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k < 90.0 && +// stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k < 90.0 && // stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()-1].k > 10.0 { // filtered_4th_symbols.push(element); // } @@ -200,4 +200,4 @@ // insert_pre_suggested_coins(6, true, &a, alldata).await; // Ok(()) -// } \ No newline at end of file +// } diff --git a/src/strategy_team/strategy_manager.rs b/src/strategy_team/strategy_manager.rs index 1fb931b..cf788e4 100644 --- a/src/strategy_team/strategy_manager.rs +++ b/src/strategy_team/strategy_manager.rs @@ -6,9 +6,12 @@ use rust_decimal::prelude::ToPrimitive; use rust_decimal::Decimal; use serde::Deserialize; -use tokio::time::{sleep, Duration, Instant}; +use super::{ + exists_record, insert_one_record, try_select_record, AllData, ExchangeInfo, FromRow, + RealtimePriceData, TradeFee, +}; use crate::signal_association::signal_decision::*; -use super::{AllData, RealtimePriceData, exists_record, try_select_record, insert_one_record, FromRow, ExchangeInfo, TradeFee}; +use tokio::time::{sleep, Duration, Instant}; #[derive(Debug, FromRow)] struct ServerEpoch { @@ -41,10 +44,14 @@ pub async fn execute_list_up_for_buy( pub async fn execute_list_up_for_sell( all_data: &AllData, exchange_info_vec: &Vec, - trade_fee_vec: &Vec + trade_fee_vec: &Vec, ) -> Result<(), Box> { - - crate::strategy_team::strategy_003::list_up_for_sell(all_data, exchange_info_vec, trade_fee_vec).await?; + crate::strategy_team::strategy_003::list_up_for_sell( + all_data, + exchange_info_vec, + trade_fee_vec, + ) + .await?; Ok(()) } @@ -271,7 +278,7 @@ pub async fn insert_pre_suggested_coins( 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; - + if is_long == true { insert_values.push(1.to_string()); // is_long } else { @@ -555,7 +562,7 @@ pub async fn insert_pre_suggested_coins( 0.0.to_string(), // maximum_profit_percent registerer.to_string(), // registerer ]; - + if is_long == true { insert_values.push(1.to_string()); // is_long } else { @@ -649,4 +656,3 @@ pub async fn insert_pre_suggested_coins( Ok(()) } - diff --git a/src/value_estimation_team/datapoints/mod.rs b/src/value_estimation_team/datapoints/mod.rs index 23eec08..581004c 100644 --- a/src/value_estimation_team/datapoints/mod.rs +++ b/src/value_estimation_team/datapoints/mod.rs @@ -1 +1 @@ -pub mod price_data; \ No newline at end of file +pub mod price_data; diff --git a/src/value_estimation_team/indicators/rsi.rs b/src/value_estimation_team/indicators/rsi.rs index e84d85e..67d10c7 100644 --- a/src/value_estimation_team/indicators/rsi.rs +++ b/src/value_estimation_team/indicators/rsi.rs @@ -4,10 +4,10 @@ use crate::database_control::*; use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; use csv::{DeserializeRecordsIter, StringRecord}; +use futures::future::try_join_all; use serde::Deserialize; use sqlx::FromRow; use std::f64::NAN; -use futures::future::try_join_all; use std::sync::Arc; use tokio::{fs::*, io::AsyncWriteExt, sync::Mutex, time::*}; @@ -36,10 +36,9 @@ pub async fn rsi( let mut rsi_data_wrapper: Vec<(String, Vec)> = Vec::new(); let mut rsi_data_wrapper_arc = Arc::new(Mutex::new(rsi_data_wrapper)); - + let mut task_vec = Vec::new(); for element in filtered_symbols { - let element_c = element.clone(); let rsi_data_wrapper_arc_c = Arc::clone(&rsi_data_wrapper_arc); let symbol_search_result = input_rt_data.iter().position(|x| x.0 == *element_c.0); @@ -135,8 +134,8 @@ pub async fn rsi( prev_avg_ups = current_avg_ups; prev_avg_downs = current_avg_downs; - let rs = - current_avg_ups.unwrap() / (current_avg_downs.unwrap() + 0.00000001); // 0.00000001 is used to avoid division by 0 + let rs = current_avg_ups.unwrap() + / (current_avg_downs.unwrap() + 0.00000001); // 0.00000001 is used to avoid division by 0 let rsi = 100.0 - (100.0 / (1.0 + rs)); diff --git a/src/value_estimation_team/indicators/stoch_rsi.rs b/src/value_estimation_team/indicators/stoch_rsi.rs index 7a51cb6..bc13aa1 100644 --- a/src/value_estimation_team/indicators/stoch_rsi.rs +++ b/src/value_estimation_team/indicators/stoch_rsi.rs @@ -4,10 +4,10 @@ use crate::database_control::*; use crate::value_estimation_team::indicators::rsi::RsiData; use csv::{DeserializeRecordsIter, StringRecord}; +use futures::{future::try_join_all, lock::Mutex}; use serde::Deserialize; use sqlx::FromRow; use std::f64::NAN; -use futures::{future::try_join_all, lock::Mutex}; use std::sync::Arc; use tokio::{fs::*, io::AsyncWriteExt, time::*}; @@ -55,14 +55,17 @@ pub async fn stoch_rsi( let mut stoch_rsi_data_vec: Vec = Vec::new(); if stoch_rsi_length == 0 || smooth_k == 0 || smooth_d == 0 { - panic!("stoch_rsi_length or smooth_k or smooth_d can't be 0! stoch_rsi_length: {}, k:{}, d:{}", stoch_rsi_length, smooth_k, smooth_d); + panic!( + "stoch_rsi_length or smooth_k or smooth_d can't be 0! stoch_rsi_length: {}, k:{}, d:{}", + stoch_rsi_length, smooth_k, smooth_d + ); } let mut task_vec = Vec::new(); for element in input_rsi_data { let mut stoch_rsi_data = StochRsiData::new(); let mut stoch_rsi_k_data = StochRsiKData::new(); let stoch_rsi_data_wrapper_arc_c = Arc::clone(&stoch_rsi_data_wrapper_arc); - + let element_c = element.clone(); task_vec.push(tokio::spawn(async move { let mut stoch_rsi_data_vec: Vec = Vec::new(); @@ -70,9 +73,10 @@ pub async fn stoch_rsi( let mut stoch_rsi_vec: Vec = Vec::new(); let mut stoch_rsi = RsiData::new(); - if element_c.1.len() >= stoch_rsi_length && - element_c.1.len() >= smooth_k && - element_c.1.len() >= smooth_d { + if element_c.1.len() >= stoch_rsi_length + && element_c.1.len() >= smooth_k + && element_c.1.len() >= smooth_d + { let mut read_data_vec = element_c.1; let window_iter = read_data_vec.windows(stoch_rsi_length); diff --git a/src/value_estimation_team/mod.rs b/src/value_estimation_team/mod.rs index b684404..2ef7663 100644 --- a/src/value_estimation_team/mod.rs +++ b/src/value_estimation_team/mod.rs @@ -1,2 +1,2 @@ pub mod datapoints; -pub mod indicators; \ No newline at end of file +pub mod indicators;