Separate selling function

This commit is contained in:
Sik Yoon 2023-11-19 01:27:51 +09:00
parent de71293f0b
commit dc0cc8234a
6 changed files with 363 additions and 314 deletions

View File

@ -576,7 +576,7 @@ pub async fn monitoring_scoreboard(
let mut update_condition: Vec<(String, String)> = Vec::new(); let mut update_condition: Vec<(String, String)> = Vec::new();
let mut update_condition2: Vec<(String, String)> = Vec::new(); let mut update_condition2: Vec<(String, String)> = Vec::new();
let filled_buy_orders = select_filled_buy_orders().await?; let filled_buy_orders = select_filled_buy_orders(0).await?;
if filled_buy_orders.is_empty() { if filled_buy_orders.is_empty() {
// initialization of table // initialization of table

View File

@ -516,27 +516,21 @@ pub async fn monitoring_open_buy_order(
Ok(()) Ok(())
} }
pub async fn monitoring_filled_buy_order( pub async fn update_price_of_filled_buy_order(
all_data: &AllData,
coin_price_vec: &Vec<CoinPriceData>, coin_price_vec: &Vec<CoinPriceData>,
exchange_info_vec: &Vec<ExchangeInfo>, exchange_info_vec: &Vec<ExchangeInfo>,
trade_fee_vec: &Vec<TradeFee>, trade_fee_vec: &Vec<TradeFee>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let index_list = select_marketcap().await; let filled_buy_orders = select_filled_buy_orders(0).await?;
// let scoreboard_list = select_scoreboard().await;
// let signal_decision = select_signal_decision().await;
let filled_buy_orders = select_filled_buy_orders().await?;
if !filled_buy_orders.is_empty() { if !filled_buy_orders.is_empty() {
// 심볼들을 2개씩 청스로 나누어 테스크를 생성하고 각 태스크 별로 병렬로 처리한다. // 심볼들을 2개씩 청스로 나누어 테스크를 생성하고 각 태스크 별로 병렬로 처리한다.
// update real-time current price to each record through chunks // update real-time current price to each record through chunks
let chunks: std::slice::Chunks<'_, BuyOrderedCoinList> = filled_buy_orders.chunks(2); let chunks: std::slice::Chunks<'_, BuyOrderedCoinList> = filled_buy_orders.chunks(3);
let mut task_vec = Vec::new(); let mut task_vec = Vec::new();
for chunk in chunks { for chunk in chunks {
let chunk_vec = chunk.to_vec(); let chunk_vec = chunk.to_vec();
let interval_clone = interval.clone();
let coin_price_vec_c = coin_price_vec.clone(); let coin_price_vec_c = coin_price_vec.clone();
let exchange_info_vec_c = exchange_info_vec.clone(); let exchange_info_vec_c = exchange_info_vec.clone();
let trade_fee_vec_c = trade_fee_vec.clone(); let trade_fee_vec_c = trade_fee_vec.clone();
@ -550,179 +544,7 @@ pub async fn monitoring_filled_buy_order(
.await; .await;
})); }));
} }
let result = try_join_all(task_vec).await;
// sell coin if its sell condition is satisfied
let filled_buy_orders = select_filled_buy_orders().await?;
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(5000))
.build()
.unwrap();
let instant = Instant::now();
let server_epoch = server_epoch().await;
let mut sell_order_count = 0;
for element in filled_buy_orders {
if element.used_usdt >= dec!(10.0) {
// ignore coins having 10 usdt below because of not traded
let sell_percent_for_uptrend = |z: f64| 0.94 * z - 0.5;
let lot_step_size_option = exchange_info_vec
.iter()
.find(|ExchangeInfo| ExchangeInfo.symbol == element.symbol);
let quote_commission_precision_option = exchange_info_vec
.iter()
.find(|ExchangeInfo| ExchangeInfo.symbol == element.symbol);
let opclo_30m_option = all_data
.rt_price_30m_vec
.iter()
.position(|x| *x.0 == element.symbol);
if lot_step_size_option.is_some()
&& quote_commission_precision_option.is_some()
&& opclo_30m_option.is_some()
{
let lot_step_size = lot_step_size_option.unwrap().stepsize;
let quote_commission_precision = quote_commission_precision_option
.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 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.truncate(opclo_sample_length - nbr_of_exclusive);
opclo_sample_length -= nbr_of_exclusive;
let mut sum_amplitude_candles = 0.0;
let mut sum_ratio_amp_body = 0.0;
for element in &opclo_30m_vec {
sum_amplitude_candles +=
((element.high_price / element.low_price) - 1.0) * 100.0;
sum_ratio_amp_body += (element.close_price - element.open_price).abs()
/ (element.high_price - element.low_price);
} }
let average_amplitude = sum_amplitude_candles / opclo_sample_length as f64; // percent unit
let average_ratio_amp_body = sum_ratio_amp_body / opclo_sample_length as f64;
let mut amplitude_variance = 0.0;
for element in &opclo_30m_vec {
amplitude_variance += ((((element.high_price / element.low_price) - 1.0)
* 100.0)
- average_amplitude)
.powi(2);
}
amplitude_variance = amplitude_variance / (opclo_sample_length - 1) as f64;
let standard_deviation_amplitude = amplitude_variance.sqrt();
// 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))
} else {
((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;
if element.maximum_profit_percent >= target_profit_percent(5.0) + 0.2
&& element.pure_profit_percent >= target_profit_percent(5.0) + 0.2
{
println!(
"Selling {} 500% target_profit_percent: {:.3}",
element.symbol,
element.pure_profit_percent
);
is_sell = true;
} else if element.pure_profit_percent >= 7.0
{
println!(
"Selling {} 7% profit_percent",
element.symbol
);
is_sell = true;
} else if server_epoch - element.close_time >= (3_600_000 * 24) && element.pure_profit_percent >= 0.2 // (1hr * 24)
{
println!(
"selling {} due to time up {:.3}",
element.symbol,
element.pure_profit_percent
);
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);
limit_order_sell(
&element,
element.current_price,
base_qty_to_be_ordered,
&client,
&exchange_info_vec,
&trade_fee_vec,
)
.await;
}
} 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
{
println!(
"selling {} -5.0% profit",
element.symbol
);
is_sell = true;
}
if is_sell == true {
limit_order_sell(
&element,
element.current_price,
base_qty_to_be_ordered,
&client,
&exchange_info_vec,
&trade_fee_vec,
)
.await;
}
}
}
}
}
if sell_order_count == 25 {
// to avoid Limit of order: LIMIT 50 for 10 secs
sleep(Duration::from_secs(10)).await;
sell_order_count = 0;
}
}
}
Ok(()) Ok(())
} }
@ -832,7 +654,6 @@ async fn update_repeat_task(
update_record.push(update_record_build.clone()); update_record.push(update_record_build.clone());
} }
} }
} }
} }
@ -2267,10 +2088,17 @@ async fn get_timestamp() -> String {
timestamp timestamp
} }
pub async fn select_filled_buy_orders() -> Result<Vec<BuyOrderedCoinList>, Box<dyn std::error::Error + Send + Sync>> { // parameter 0: select all registerers
pub async fn select_filled_buy_orders(registerer: u32) -> Result<Vec<BuyOrderedCoinList>, Box<dyn std::error::Error + Send + Sync>> {
let select_table_name = String::from("buy_ordered_coin_list"); let select_table_name = String::from("buy_ordered_coin_list");
let select_columns = String::from("*"); let select_columns = String::from("*");
let select_condition = Some(String::from("WHERE status = 'FILLED' or status = 'SIMUL'")); let mut select_condition_build = String::from("WHERE (status = 'FILLED' or status = 'SIMUL')");
if registerer > 0 {
select_condition_build.push_str(" and registerer = ");
select_condition_build.push_str(registerer.to_string().as_str());
}
let select_condition = Some(select_condition_build);
let data_struct = BuyOrderedCoinList::new(); let data_struct = BuyOrderedCoinList::new();
let select_result = try_select_record( let select_result = try_select_record(

View File

@ -58,6 +58,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let tx_task7 = tx_task1.clone(); // for Task#7 let tx_task7 = tx_task1.clone(); // for Task#7
let tx_task8 = tx_task1.clone(); // for Task#8 let tx_task8 = tx_task1.clone(); // for Task#8
let tx_task9 = tx_task1.clone(); // for Task#9 let tx_task9 = tx_task1.clone(); // for Task#9
let tx_task10 = tx_task1.clone(); // for Task#10
let tx_task11 = tx_task1.clone(); // for Task#11
let tx_task12 = tx_task1.clone(); // for Task#12 let tx_task12 = tx_task1.clone(); // for Task#12
let tx_task13 = tx_task1.clone(); // for Task#13 let tx_task13 = tx_task1.clone(); // for Task#13
let tx_task14 = tx_task1.clone(); // for Task#14 let tx_task14 = tx_task1.clone(); // for Task#14
@ -73,7 +75,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let tx_task24 = tx_task1.clone(); // for Task#24 let tx_task24 = tx_task1.clone(); // for Task#24
let tx_task25 = tx_task1.clone(); // for Task#25 let tx_task25 = tx_task1.clone(); // for Task#25
let tx_task26 = tx_task1.clone(); // for Task#26 let tx_task26 = tx_task1.clone(); // for Task#26
let tx_task27 = tx_task1.clone(); // for Task#27
let (tx1, mut rx1_1) = watch::channel(0); // local_epoch let (tx1, mut rx1_1) = watch::channel(0); // local_epoch
let mut rx1_2 = rx1_1.clone(); let mut rx1_2 = rx1_1.clone();
@ -90,6 +91,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rx2_tradefee_vec = rx_tradefee_vec.clone(); let mut rx2_tradefee_vec = rx_tradefee_vec.clone();
let mut rx3_tradefee_vec = rx_tradefee_vec.clone(); let mut rx3_tradefee_vec = rx_tradefee_vec.clone();
let mut rx4_tradefee_vec = rx_tradefee_vec.clone(); let mut rx4_tradefee_vec = rx_tradefee_vec.clone();
let mut rx5_tradefee_vec = rx_tradefee_vec.clone();
// valid usdt trade data // valid usdt trade data
let mut valid_usdt_trade_vec: Vec<String> = Vec::new(); // symbol let mut valid_usdt_trade_vec: Vec<String> = Vec::new(); // symbol
@ -97,6 +99,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
watch::channel(valid_usdt_trade_vec); watch::channel(valid_usdt_trade_vec);
let mut rx2_valid_usdt_trade_vec = rx_valid_usdt_trade_vec.clone(); let mut rx2_valid_usdt_trade_vec = rx_valid_usdt_trade_vec.clone();
let mut rx3_valid_usdt_trade_vec = rx_valid_usdt_trade_vec.clone(); let mut rx3_valid_usdt_trade_vec = rx_valid_usdt_trade_vec.clone();
let mut rx4_valid_usdt_trade_vec = rx_valid_usdt_trade_vec.clone();
// price per second data and channels // price per second data and channels
let mut price_vec: Vec<CoinPriceData> = Vec::new(); // (symbol, price) let mut price_vec: Vec<CoinPriceData> = Vec::new(); // (symbol, price)
@ -126,27 +129,32 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rx2_rt_price_1m_vec = rx_rt_price_1m_vec.clone(); let mut rx2_rt_price_1m_vec = rx_rt_price_1m_vec.clone();
let mut rx3_rt_price_1m_vec = rx_rt_price_1m_vec.clone(); let mut rx3_rt_price_1m_vec = rx_rt_price_1m_vec.clone();
let mut rx4_rt_price_1m_vec = rx_rt_price_1m_vec.clone(); let mut rx4_rt_price_1m_vec = rx_rt_price_1m_vec.clone();
let mut rx5_rt_price_1m_vec = rx_rt_price_1m_vec.clone();
let mut rt_price_30m_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new(); let mut rt_price_30m_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new();
let (tx_rt_price_30m_vec, mut rx_rt_price_30m_vec) = watch::channel(rt_price_30m_vec); let (tx_rt_price_30m_vec, mut rx_rt_price_30m_vec) = watch::channel(rt_price_30m_vec);
let mut rx2_rt_price_30m_vec = rx_rt_price_30m_vec.clone(); let mut rx2_rt_price_30m_vec = rx_rt_price_30m_vec.clone();
let mut rx3_rt_price_30m_vec = rx_rt_price_30m_vec.clone(); let mut rx3_rt_price_30m_vec = rx_rt_price_30m_vec.clone();
let mut rx4_rt_price_30m_vec = rx_rt_price_30m_vec.clone(); let mut rx4_rt_price_30m_vec = rx_rt_price_30m_vec.clone();
let mut rx5_rt_price_30m_vec = rx_rt_price_30m_vec.clone();
let mut rt_price_1d_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new(); let mut rt_price_1d_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new();
let (tx_rt_price_1d_vec, mut rx_rt_price_1d_vec) = watch::channel(rt_price_1d_vec); let (tx_rt_price_1d_vec, mut rx_rt_price_1d_vec) = watch::channel(rt_price_1d_vec);
let mut rx2_rt_price_1d_vec = rx_rt_price_1d_vec.clone(); let mut rx2_rt_price_1d_vec = rx_rt_price_1d_vec.clone();
let mut rx3_rt_price_1d_vec = rx_rt_price_1d_vec.clone(); let mut rx3_rt_price_1d_vec = rx_rt_price_1d_vec.clone();
let mut rx4_rt_price_1d_vec = rx_rt_price_1d_vec.clone();
let mut rt_price_1w_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new(); let mut rt_price_1w_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new();
let (tx_rt_price_1w_vec, mut rx_rt_price_1w_vec) = watch::channel(rt_price_1w_vec); let (tx_rt_price_1w_vec, mut rx_rt_price_1w_vec) = watch::channel(rt_price_1w_vec);
let mut rx2_rt_price_1w_vec = rx_rt_price_1w_vec.clone(); let mut rx2_rt_price_1w_vec = rx_rt_price_1w_vec.clone();
let mut rx3_rt_price_1w_vec = rx_rt_price_1w_vec.clone(); let mut rx3_rt_price_1w_vec = rx_rt_price_1w_vec.clone();
let mut rx4_rt_price_1w_vec = rx_rt_price_1w_vec.clone();
let mut rt_price_1mon_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new(); let mut rt_price_1mon_vec: Vec<(String, Vec<RealtimePriceData>)> = Vec::new();
let (tx_rt_price_1mon_vec, mut rx_rt_price_1mon_vec) = watch::channel(rt_price_1mon_vec); let (tx_rt_price_1mon_vec, mut rx_rt_price_1mon_vec) = watch::channel(rt_price_1mon_vec);
let mut rx2_rt_price_1mon_vec = rx_rt_price_1mon_vec.clone(); let mut rx2_rt_price_1mon_vec = rx_rt_price_1mon_vec.clone();
let mut rx3_rt_price_1mon_vec = rx_rt_price_1mon_vec.clone(); let mut rx3_rt_price_1mon_vec = rx_rt_price_1mon_vec.clone();
let mut rx4_rt_price_1mon_vec = rx_rt_price_1mon_vec.clone();
// TEMA data // TEMA data
// let mut tema3_1m_data: Vec<(String, Vec<(f64, i64)>)> = Vec::new(); // Vec<(symbol, Vec<(price, closetime)>)> // let mut tema3_1m_data: Vec<(String, Vec<(f64, i64)>)> = Vec::new(); // Vec<(symbol, Vec<(price, closetime)>)>
@ -189,6 +197,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rx3_exchange_info_data = rx_exchange_info_data.clone(); let mut rx3_exchange_info_data = rx_exchange_info_data.clone();
let mut rx4_exchange_info_data = rx_exchange_info_data.clone(); let mut rx4_exchange_info_data = rx_exchange_info_data.clone();
let mut rx5_exchange_info_data = rx_exchange_info_data.clone(); let mut rx5_exchange_info_data = rx_exchange_info_data.clone();
let mut rx6_exchange_info_data = rx_exchange_info_data.clone();
{ {
if RUNNING_MODE == RunningMode::REAL { if RUNNING_MODE == RunningMode::REAL {
@ -259,103 +268,99 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match result { match result {
Some(1) => { Some(1) => {
print!("\r1[■] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[■] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(2) => { Some(2) => {
print!("\r1[ ] 2[■] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[■] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(3) => { Some(3) => {
print!("\r1[ ] 2[ ] 3[■] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[■] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(4) => { Some(4) => {
print!("\r1[ ] 2[ ] 3[ ] 4[■] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[■] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(5) => { Some(5) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[■] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[■] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(6) => { Some(6) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[■] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[■] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(7) => { Some(7) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[■] 8[] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[■] 8[] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(8) => { Some(8) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[■ 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[■ 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(9) => { Some(9) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[■] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[■] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(12) => { Some(12) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[■] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[■] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(13) => { Some(13) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[■] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[■] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(14) => { Some(14) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[■] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[■] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(15) => { Some(15) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[■] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[■] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(16) => { Some(16) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[■] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[■] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(17) => { Some(17) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[■] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[■] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(18) => { Some(18) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[■] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[■] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(19) => { Some(19) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[■] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[■] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(20) => { Some(20) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[■] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[■] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(21) => { Some(21) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[■] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[■] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(22) => { Some(22) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[■] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[■] 23[ ] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(23) => { Some(23) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[■] 24[ ] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[■] 24[ ] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(24) => { Some(24) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[■] 25[ ] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[■] 25[ ] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(25) => { Some(25) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[■] 26[ ] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[■] 26[ ]");
io::stdout().flush(); io::stdout().flush();
} }
Some(26) => { Some(26) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[■] 27[ ]"); print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[■]");
io::stdout().flush();
}
Some(27) => {
print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[■]");
io::stdout().flush(); io::stdout().flush();
} }
Some(_) => {} Some(_) => {}
@ -524,7 +529,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#13: request lot stepsize and ticksize // Task#3: request lot stepsize and ticksize
tokio::task::spawn(async move { tokio::task::spawn(async move {
let client = ClientBuilder::new() let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000)) .timeout(tokio::time::Duration::from_millis(3000))
@ -551,8 +556,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match result { match result {
Ok(T) => { Ok(T) => {
tx_exchange_info_data.send_modify(|vec| *vec = exchange_info_data_temp); tx_exchange_info_data.send_modify(|vec| *vec = exchange_info_data_temp);
tx_task13 tx_task3
.send(13) .send(3)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -561,7 +566,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#3: request 24h price changes, // Task#4: request 24h price changes,
// pick valid USDT Trades, // pick valid USDT Trades,
// filtering stop USDT Trades, // filtering stop USDT Trades,
// monitor total_24h_change_profit_index, // monitor total_24h_change_profit_index,
@ -588,7 +593,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(T) => { Ok(T) => {
tx_valid_usdt_trade_vec tx_valid_usdt_trade_vec
.send_modify(|vec| *vec = valid_usdt_trade_vec_temp); .send_modify(|vec| *vec = valid_usdt_trade_vec_temp);
tx_task3.send(3).expect("The mpsc channel has been closed."); tx_task4.send(4).expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
} }
@ -636,7 +641,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#4: price per second // Task#5: price per second
tokio::task::spawn(async move { tokio::task::spawn(async move {
sleep(Duration::from_secs(20)).await; sleep(Duration::from_secs(20)).await;
let client = ClientBuilder::new() let client = ClientBuilder::new()
@ -655,7 +660,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(T) => { Ok(T) => {
price_vec_temp_c = price_vec_temp.clone(); price_vec_temp_c = price_vec_temp.clone();
tx_price_vec.send_modify(|vec| *vec = price_vec_temp); tx_price_vec.send_modify(|vec| *vec = price_vec_temp);
tx_task4.send(4).expect("The mpsc channel has been closed."); tx_task5.send(5).expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
} }
@ -788,7 +793,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#5: fetch candle 1m // Task#6: fetch candle 1m
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut elapsed_time = 0; let mut elapsed_time = 0;
let interval = String::from("1m"); let interval = String::from("1m");
@ -801,7 +806,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match result { match result {
Ok(T) => { Ok(T) => {
tx_candle_1m_vec.send_modify(|vec| *vec = candle_1m_vec_temp); tx_candle_1m_vec.send_modify(|vec| *vec = candle_1m_vec_temp);
tx_task5.send(5).expect("The mpsc channel has been closed."); tx_task6.send(6).expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
} }
@ -814,7 +819,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#6: fetch candle 30m // Task#7: fetch candle 30m
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut elapsed_time = 0; let mut elapsed_time = 0;
let interval = String::from("30m"); let interval = String::from("30m");
@ -829,7 +834,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match result { match result {
Ok(T) => { Ok(T) => {
tx_candle_30m_vec.send_modify(|vec| *vec = candle_30m_vec_temp); tx_candle_30m_vec.send_modify(|vec| *vec = candle_30m_vec_temp);
tx_task6.send(6).expect("The mpsc channel has been closed."); tx_task7.send(7).expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
} }
@ -841,7 +846,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#7: fetch candle 1d // Task#8: fetch candle 1d
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut elapsed_time = 0; let mut elapsed_time = 0;
let interval = String::from("1d"); let interval = String::from("1d");
@ -855,7 +860,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match result { match result {
Ok(T) => { Ok(T) => {
tx_candle_1d_vec.send_modify(|vec| *vec = candle_1d_vec_temp); tx_candle_1d_vec.send_modify(|vec| *vec = candle_1d_vec_temp);
tx_task7.send(7).expect("The mpsc channel has been closed."); tx_task8.send(8).expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
} }
@ -867,7 +872,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// // Task#8: fetch candle 1w // // Task#9: fetch candle 1w
// tokio::task::spawn(async move{ // tokio::task::spawn(async move{
// let interval = String::from("1w"); // let interval = String::from("1w");
// sleep(Duration::from_secs(600)).await; // sleep(Duration::from_secs(600)).await;
@ -878,14 +883,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// match result { // match result {
// Ok(T) => { // Ok(T) => {
// tx_candle_1w_vec.send_modify(|vec| *vec = candle_1w_vec_temp); // tx_candle_1w_vec.send_modify(|vec| *vec = candle_1w_vec_temp);
// tx_task8.send(8).expect("The mpsc channel has been closed."); // tx_task9.send(9).expect("The mpsc channel has been closed.");
// } // }
// Err(E) => {} // Err(E) => {}
// } // }
// } // }
// }); // });
// // Task#9: fetch candle 1mon // // Task#10: fetch candle 1mon
// tokio::task::spawn(async move{ // tokio::task::spawn(async move{
// let interval = String::from("1mon"); // let interval = String::from("1mon");
// sleep(Duration::from_secs(600)).await; // sleep(Duration::from_secs(600)).await;
@ -896,22 +901,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// match result { // match result {
// Ok(T) => { // Ok(T) => {
// tx_candle_1mon_vec.send_modify(|vec| *vec = candle_1mon_vec_temp); // tx_candle_1mon_vec.send_modify(|vec| *vec = candle_1mon_vec_temp);
// tx_task9.send(9).expect("The mpsc channel has been closed."); // tx_task10.send(10).expect("The mpsc channel has been closed.");
// } // }
// Err(E) => {} // Err(E) => {}
// } // }
// } // }
// }); // });
// Task#12: monitoring total market cap // Task#11: monitoring total market cap
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST {
tokio::task::spawn(async move { tokio::task::spawn(async move {
loop { loop {
let result = signal_association::coinmarketcap::market_cap_index().await; let result = signal_association::coinmarketcap::market_cap_index().await;
match result { match result {
Ok(T) => { Ok(T) => {
tx_task12 tx_task11
.send(12) .send(11)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -920,15 +925,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// Task#14: monitoring foreign exchange rate // Task#12: monitoring foreign exchange rate
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move { tokio::task::spawn(async move {
loop { loop {
let result = signal_association::exchange_rate::monitoring_fx_rate_index().await; let result = signal_association::exchange_rate::monitoring_fx_rate_index().await;
match result { match result {
Ok(T) => { Ok(T) => {
tx_task14 tx_task12
.send(14) .send(12)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -938,14 +943,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// // // Task#15: monitoring dollar index // // // Task#13: monitoring dollar index
// // tokio::task::spawn(async move { // // tokio::task::spawn(async move {
// // loop // // loop
// // { // // {
// // let result = signal_association::dollar_index::monitoring_dollar_index().await; // // let result = signal_association::dollar_index::monitoring_dollar_index().await;
// // match result { // // match result {
// // Ok(T) => { // // Ok(T) => {
// // tx_task15.send(15).expect("The mpsc channel has been closed."); // // tx_task13.send(13).expect("The mpsc channel has been closed.");
// // } // // }
// // Err(E) => {} // // Err(E) => {}
// // } // // }
@ -953,7 +958,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// // } // // }
// // }); // // });
// Task#16: monitoring signal decision // Task#14: monitoring signal decision
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST {
tokio::task::spawn(async move { tokio::task::spawn(async move {
loop { loop {
@ -961,8 +966,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
signal_association::signal_decision::monitoring_signal_decision().await; signal_association::signal_decision::monitoring_signal_decision().await;
match result { match result {
Ok(T) => { Ok(T) => {
tx_task16 tx_task14
.send(16) .send(14)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -973,15 +978,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// Task#17: monitoring future ratio // Task#15: monitoring future ratio
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST {
tokio::task::spawn(async move { tokio::task::spawn(async move {
loop { loop {
let result = signal_association::future_ratio::monitoring_future_ratio().await; let result = signal_association::future_ratio::monitoring_future_ratio().await;
match result { match result {
Ok(T) => { Ok(T) => {
tx_task17 tx_task15
.send(17) .send(15)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -993,7 +998,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
// COEX part // COEX part
// Task#18: strategists // Task#16: execute strategis for buy
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move { tokio::task::spawn(async move {
sleep(Duration::from_secs(40)).await; sleep(Duration::from_secs(40)).await;
@ -1007,15 +1012,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
all_data.rt_price_1m_vec = rx3_rt_price_1m_vec.borrow().clone(); all_data.rt_price_1m_vec = rx3_rt_price_1m_vec.borrow().clone();
all_data.rt_price_30m_vec = rx3_rt_price_30m_vec.borrow().clone(); all_data.rt_price_30m_vec = rx3_rt_price_30m_vec.borrow().clone();
all_data.rt_price_1d_vec = rx3_rt_price_1d_vec.borrow().clone(); all_data.rt_price_1d_vec = rx3_rt_price_1d_vec.borrow().clone();
// all_data.rt_price_1w_vec = rx3_rt_price_1w_vec.borrow().clone(); 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(); 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 { match result {
Ok(T) => { Ok(T) => {
tx_task18 tx_task16
.send(18) .send(16)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => { Err(E) => {
@ -1049,8 +1054,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// match result { // match result {
// Ok(T) => { // Ok(T) => {
// tx_task18 // tx_task16
// .send(18) // .send(16)
// .expect("The mpsc channel has been closed."); // .expect("The mpsc channel has been closed.");
// } // }
// Err(E) => {} // Err(E) => {}
@ -1065,7 +1070,49 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// Task#19: monitoring pre-suggested coins // Task#17: execute strategis for sell
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move {
sleep(Duration::from_secs(40)).await;
let mut all_data = AllData::new();
let mut exchange_info_vec: Vec<ExchangeInfo> = Vec::new();
let mut trade_fee_vec: Vec<TradeFee> = Vec::new();
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
all_data.valid_symbol_vec = rx4_valid_usdt_trade_vec.borrow().clone();
exchange_info_vec = rx6_exchange_info_data.borrow().clone();
trade_fee_vec = rx5_tradefee_vec.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx5_rt_price_1m_vec.borrow().clone();
all_data.rt_price_30m_vec = rx5_rt_price_30m_vec.borrow().clone();
all_data.rt_price_1d_vec = rx4_rt_price_1d_vec.borrow().clone();
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;
match result {
Ok(T) => {
tx_task17
.send(17)
.expect("The mpsc channel has been closed.");
}
Err(E) => {
// eprintln!("Couldn't execute strategists.");
}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
});
}
// Task#18: monitoring pre-suggested coins
tokio::task::spawn(async move { tokio::task::spawn(async move {
sleep(Duration::from_secs(30)).await; sleep(Duration::from_secs(30)).await;
let mut elapsed_time = 0; let mut elapsed_time = 0;
@ -1077,8 +1124,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task19 tx_task18
.send(19) .send(18)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -1092,7 +1139,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#20: buy_coin // Task#19: buy_coin
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST { if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST {
tokio::task::spawn(async move { tokio::task::spawn(async move {
sleep(Duration::from_secs(30)).await; sleep(Duration::from_secs(30)).await;
@ -1111,8 +1158,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task20 tx_task19
.send(20) .send(19)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => { Err(E) => {
@ -1145,8 +1192,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task20 tx_task19
.send(20) .send(19)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -1160,7 +1207,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// Task#21: monitoring_open_buy_order // Task#20: monitoring_open_buy_order
if RUNNING_MODE == REAL || RUNNING_MODE == TEST { if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
tokio::task::spawn(async move { tokio::task::spawn(async move {
if RUNNING_MODE == REAL { if RUNNING_MODE == REAL {
@ -1187,8 +1234,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task21 tx_task20
.send(21) .send(20)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -1203,7 +1250,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// Task#22: monitoring_filled_buy_order // Task#21: update_price_of_filled_buy_order
tokio::task::spawn(async move { tokio::task::spawn(async move {
if RUNNING_MODE == TEST { if RUNNING_MODE == TEST {
sleep(Duration::from_secs(10)).await; sleep(Duration::from_secs(10)).await;
@ -1211,18 +1258,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
sleep(Duration::from_secs(30)).await; sleep(Duration::from_secs(30)).await;
} }
let mut elapsed_time = 0; let mut elapsed_time = 0;
let mut all_data = AllData::new();
loop { loop {
let instant = Instant::now(); let instant = Instant::now();
let coin_price_vec = rx5_price_vec.borrow().clone(); let coin_price_vec = rx5_price_vec.borrow().clone();
let exchange_info_vec = rx2_exchange_info_data.borrow().clone(); let exchange_info_vec = rx2_exchange_info_data.borrow().clone();
let trade_fee_vec = rx3_tradefee_vec.borrow().clone(); let trade_fee_vec = rx3_tradefee_vec.borrow().clone();
// realtime price data let result = coex::order_team::update_price_of_filled_buy_order(
all_data.rt_price_30m_vec = rx4_rt_price_30m_vec.borrow().clone();
let result = coex::order_team::monitoring_filled_buy_order(
&all_data,
&coin_price_vec, &coin_price_vec,
&exchange_info_vec, &exchange_info_vec,
&trade_fee_vec, &trade_fee_vec,
@ -1232,8 +1274,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task22 tx_task21
.send(22) .send(21)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -1248,7 +1290,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#23: monitoring_open_sell_order // Task#22: monitoring_open_sell_order
if RUNNING_MODE == REAL || RUNNING_MODE == TEST { if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
tokio::task::spawn(async move { tokio::task::spawn(async move {
if RUNNING_MODE == REAL { if RUNNING_MODE == REAL {
@ -1275,8 +1317,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task23 tx_task22
.send(23) .send(22)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => {} Err(E) => {}
@ -1291,7 +1333,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}); });
} }
// Task#24: monitoring_filled_sell_order // Task#23: monitoring_filled_sell_order
tokio::task::spawn(async move { tokio::task::spawn(async move {
let client = ClientBuilder::new() let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000)) .timeout(tokio::time::Duration::from_millis(3000))
@ -1302,6 +1344,36 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let instant = Instant::now(); let instant = Instant::now();
let result = coex::order_team::monitoring_filled_sell_order(&client).await; let result = coex::order_team::monitoring_filled_sell_order(&client).await;
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task23
.send(23)
.expect("The mpsc channel has been closed.");
}
Err(E) => {}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 200 > elapsed_time {
sleep(Duration::from_millis((200 - elapsed_time) as u64)).await;
}
}
});
// Task#24: monitoring_scoreboard
tokio::task::spawn(async move {
let mut elapsed_time = 0;
let mut all_data = AllData::new();
loop {
let instant = Instant::now();
// realtime price data
all_data.rt_price_1m_vec = rx4_rt_price_1m_vec.borrow().clone();
let result = coex::exchange_team::monitoring_scoreboard(&all_data).await;
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
@ -1320,37 +1392,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#25: monitoring_scoreboard // Task#25: update current_total_usdt and available_usdt
tokio::task::spawn(async move {
let mut elapsed_time = 0;
let mut all_data = AllData::new();
loop {
let instant = Instant::now();
// realtime price data
all_data.rt_price_1m_vec = rx4_rt_price_1m_vec.borrow().clone();
let result = coex::exchange_team::monitoring_scoreboard(&all_data).await;
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task25
.send(25)
.expect("The mpsc channel has been closed.");
}
Err(E) => {}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 200 > elapsed_time {
sleep(Duration::from_millis((200 - elapsed_time) as u64)).await;
}
}
});
// Task#26: update current_total_usdt and available_usdt
tokio::task::spawn(async move { tokio::task::spawn(async move {
let client = ClientBuilder::new() let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000)) .timeout(tokio::time::Duration::from_millis(3000))
@ -1367,8 +1409,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task26 tx_task25
.send(26) .send(25)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => { Err(E) => {
@ -1384,7 +1426,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
}); });
// Task#27: update kelly_criterion // Task#26: update kelly_criterion
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut elapsed_time = 0; let mut elapsed_time = 0;
loop { loop {
@ -1395,8 +1437,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send Task#0 a message to notify running on // send Task#0 a message to notify running on
match result { match result {
Ok(T) => { Ok(T) => {
tx_task27 tx_task26
.send(27) .send(26)
.expect("The mpsc channel has been closed."); .expect("The mpsc channel has been closed.");
} }
Err(E) => { Err(E) => {

View File

@ -19,7 +19,12 @@ use crate::value_estimation_team::indicators::supertrend::{supertrend, Supertren
use crate::value_estimation_team::indicators::heatmap_volume::{ use crate::value_estimation_team::indicators::heatmap_volume::{
heatmap_volume, HeatMapLevel, HeatmapVolumeData, heatmap_volume, HeatMapLevel, HeatmapVolumeData,
}; };
use crate::coex::order_team::{limit_order_sell, select_filled_buy_orders};
use crate::coin_health_check_team::request_others::{ExchangeInfo, TradeFee};
use futures::future::try_join_all; use futures::future::try_join_all;
use reqwest::{Client, ClientBuilder};
use rust_decimal::{prelude::FromPrimitive, prelude::ToPrimitive, Decimal, RoundingStrategy};
use rust_decimal_macros::dec;
use sqlx::FromRow; use sqlx::FromRow;
use tokio::sync::Mutex; use tokio::sync::Mutex;

View File

@ -1,4 +1,4 @@
use super::{AllData, RealtimePriceData, Mutex, Arc, try_join_all, exists_record, StochRsiData, EmaData, SupertrendData, RsiData, stoch_rsi, ema, rsi, supertrend}; 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};
pub async fn list_up_for_buy( pub async fn list_up_for_buy(
alldata: &AllData, alldata: &AllData,
@ -284,3 +284,166 @@ pub async fn list_up_for_buy(
Ok(()) Ok(())
} }
pub async fn list_up_for_sell(
all_data: &AllData,
exchange_info_vec: &Vec<ExchangeInfo>,
trade_fee_vec: &Vec<TradeFee>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let filled_buy_orders = select_filled_buy_orders(3).await?;
if !filled_buy_orders.is_empty() {
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(5000))
.build()
.unwrap();
let mut sell_order_count = 0;
for element in filled_buy_orders {
if element.used_usdt >= dec!(10.0) {
// ignore coins having 10 usdt below because of not traded
let sell_percent_for_uptrend = |z: f64| 0.94 * z - 0.5;
let lot_step_size_option = exchange_info_vec
.iter()
.find(|ExchangeInfo| ExchangeInfo.symbol == element.symbol);
let quote_commission_precision_option = exchange_info_vec
.iter()
.find(|ExchangeInfo| ExchangeInfo.symbol == element.symbol);
let opclo_30m_option = all_data
.rt_price_30m_vec
.iter()
.position(|x| *x.0 == element.symbol);
if lot_step_size_option.is_some()
&& quote_commission_precision_option.is_some()
&& opclo_30m_option.is_some()
{
let lot_step_size = lot_step_size_option.unwrap().stepsize;
let quote_commission_precision = quote_commission_precision_option
.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 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.truncate(opclo_sample_length - nbr_of_exclusive);
opclo_sample_length -= nbr_of_exclusive;
let mut sum_amplitude_candles = 0.0;
let mut sum_ratio_amp_body = 0.0;
for element in &opclo_30m_vec {
sum_amplitude_candles +=
((element.high_price / element.low_price) - 1.0) * 100.0;
sum_ratio_amp_body += (element.close_price - element.open_price).abs()
/ (element.high_price - element.low_price);
}
let average_amplitude = sum_amplitude_candles / opclo_sample_length as f64; // percent unit
let average_ratio_amp_body = sum_ratio_amp_body / opclo_sample_length as f64;
let mut amplitude_variance = 0.0;
for element in &opclo_30m_vec {
amplitude_variance += ((((element.high_price / element.low_price) - 1.0)
* 100.0)
- average_amplitude)
.powi(2);
}
amplitude_variance = amplitude_variance / (opclo_sample_length - 1) as f64;
let standard_deviation_amplitude = amplitude_variance.sqrt();
// 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))
} else {
((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;
if element.maximum_profit_percent >= target_profit_percent(5.0) + 0.2
&& element.pure_profit_percent >= target_profit_percent(5.0) + 0.2
{
println!(
"Selling {} 500% target_profit_percent: {:.3}",
element.symbol,
element.pure_profit_percent
);
is_sell = true;
} 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);
limit_order_sell(
&element,
element.current_price,
base_qty_to_be_ordered,
&client,
&exchange_info_vec,
&trade_fee_vec,
)
.await;
}
} 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
{
println!(
"selling {} -5.0% profit",
element.symbol
);
is_sell = true;
}
if is_sell == true {
limit_order_sell(
&element,
element.current_price,
base_qty_to_be_ordered,
&client,
&exchange_info_vec,
&trade_fee_vec,
)
.await;
}
}
}
}
}
}
}
Ok(())
}

View File

@ -8,7 +8,7 @@ use serde::Deserialize;
use tokio::time::{sleep, Duration, Instant}; use tokio::time::{sleep, Duration, Instant};
use crate::signal_association::signal_decision::*; use crate::signal_association::signal_decision::*;
use super::{AllData, RealtimePriceData, exists_record, try_select_record, insert_one_record, FromRow}; use super::{AllData, RealtimePriceData, exists_record, try_select_record, insert_one_record, FromRow, ExchangeInfo, TradeFee};
#[derive(Debug, FromRow)] #[derive(Debug, FromRow)]
struct ServerEpoch { struct ServerEpoch {
@ -38,6 +38,17 @@ pub async fn execute_list_up_for_buy(
Ok(()) Ok(())
} }
pub async fn execute_list_up_for_sell(
all_data: &AllData,
exchange_info_vec: &Vec<ExchangeInfo>,
trade_fee_vec: &Vec<TradeFee>
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
crate::strategy_team::strategy_003::list_up_for_sell(all_data, exchange_info_vec, trade_fee_vec).await?;
Ok(())
}
// useful functions for strategists // useful functions for strategists
pub async fn get_current_price( pub async fn get_current_price(
symbol: &String, symbol: &String,