diff --git a/src/coex/order_team.rs b/src/coex/order_team.rs index fe0b6de..8a57dc6 100644 --- a/src/coex/order_team.rs +++ b/src/coex/order_team.rs @@ -90,6 +90,21 @@ pub struct SellOrderedCoinList { pub is_long: u8, } +#[derive(Debug, FromRow, Clone)] +pub struct SellHistoryList { + pub id: u64, + pub symbol: String, + pub soldtime: i64, + pub used_usdt: Decimal, + pub get_usdt: Decimal, + pub buy_price: Decimal, + pub sell_price: Decimal, + pub base_qty: Decimal, + pub pure_profit_percent: f64, + pub pure_profit_usdt: Decimal, + pub registerer: u16, +} + pub trait DBlist { fn new() -> Self; } @@ -145,6 +160,25 @@ impl DBlist for BuyOrderedCoinList { } } +impl DBlist for SellHistoryList { + fn new() -> SellHistoryList { + let a = SellHistoryList { + id: 0, + symbol: String::new(), + soldtime: 0, + used_usdt: Decimal::new(0, 8), + get_usdt: Decimal::new(0, 8), + buy_price: Decimal::new(0, 8), + sell_price: Decimal::new(0, 8), + base_qty: Decimal::new(0, 8), + pure_profit_percent: 0.0, + pure_profit_usdt: Decimal::new(0, 8), + registerer: 0, + }; + a + } +} + #[derive(Debug, FromRow)] pub struct SignalDecisionInfo { pub decision: String, @@ -489,7 +523,7 @@ pub async fn monitoring_filled_buy_order( exchange_info_vec: &Vec, trade_fee_vec: &Vec, ) -> Result<(), Box> { - // let index_list = select_marketcap().await; + let index_list = select_marketcap().await; // let scoreboard_list = select_scoreboard().await; // let signal_decision = select_signal_decision().await; @@ -603,37 +637,28 @@ pub async fn monitoring_filled_buy_order( ((average_amplitude) * multiplier) + (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy)) } }; - - if server_epoch - element.close_time >= (1_800_000 * 2) * 12 // (30min * 2) * 12 - { - println!( - "selling {} due to time up {:.3}", - element.symbol, - element.pure_profit_percent - ); - limit_order_sell( - &element, - element.current_price, - base_qty_to_be_ordered, - &client, - &exchange_info_vec, - &trade_fee_vec, - ) - .await; - } else { + + 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(2.0) + 0.2 - && element.pure_profit_percent >= target_profit_percent(2.0) + 0.2 + 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 {} 200% target_profit_percent: {:.3}", + "Selling {} 500% target_profit_percent: {:.3}", element.symbol, element.pure_profit_percent ); is_sell = true; - } else if server_epoch - element.close_time >= (1_800_000 * 2) * 6 // (30min * 2) * 6 + } 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}", @@ -641,13 +666,7 @@ pub async fn monitoring_filled_buy_order( element.pure_profit_percent ); is_sell = true; - } else if element.pure_profit_percent >= 1.5 { - println!( - "selling {} 1.5% profit", - element.symbol - ); - is_sell = true; - } + } if is_sell == true { // let mut sell_price_ahead: Decimal = Decimal::new(14, 8); @@ -664,25 +683,25 @@ pub async fn monitoring_filled_buy_order( } } else { let mut is_sell = false; - if element.pure_profit_percent <= target_profit_percent(-1.5) - 0.2 // -0.2 means about total trade fees. + if element.pure_profit_percent <= target_profit_percent(-2.5) - 0.2 // -0.2 means about total trade fees. { println!( - "Selling {} -150% target_profit_percent: {:.3}", + "Selling {} -250% target_profit_percent: {:.3}", element.symbol, element.pure_profit_percent ); is_sell = true; - } else if element.pure_profit_percent <= -1.0 && server_epoch - element.close_time >= (1_800_000 * 2) * 2 // (30min * 2) * 2 + } else if element.pure_profit_percent <= -5.0 { println!( - "selling {} -1.0% profit", + "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, @@ -694,7 +713,6 @@ pub async fn monitoring_filled_buy_order( } } } - } } @@ -743,72 +761,79 @@ async fn update_repeat_task( .position(|x| *x.symbol == element.symbol); let lot_step_size_result = exchange_info_vec .iter() - .find(|ExchangeInfo| ExchangeInfo.symbol == element.symbol); + .position(|ExchangeInfo| ExchangeInfo.symbol == element.symbol); let quote_commission_precision_result = exchange_info_vec .iter() - .find(|ExchangeInfo| ExchangeInfo.symbol == element.symbol); - let trade_fee = trade_fee_vec + .position(|ExchangeInfo| ExchangeInfo.symbol == element.symbol); + let trade_fee_result = trade_fee_vec .iter() - .find(|TradeFee| TradeFee.symbol == element.symbol) - .unwrap() - .takercommission; + .position(|TradeFee| TradeFee.symbol == element.symbol); + if price_index_option.is_some() && lot_step_size_result.is_some() && quote_commission_precision_result.is_some() + && trade_fee_result.is_some() { - price = rust_decimal::prelude::FromPrimitive::from_f64( + let price_result: Option = rust_decimal::prelude::FromPrimitive::from_f64( coin_price_vec[price_index_option.unwrap()].current_price, - ) - .unwrap(); - // to get quote_commission_precision - let lot_step_size = lot_step_size_result.unwrap().stepsize; - let quote_commission_precision = 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_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; - 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(pure_profit_percent.to_string()); // pure_profit_percent + if price_result.is_some() { + price = price_result.unwrap(); + if !price.is_zero() { + // 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 expected_get_usdt = decimal_mul( + 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; - if element.minimum_profit_percent > pure_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 { - update_record_build.push(element.minimum_profit_percent.to_string()); - // minimum_profit_percent + 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(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 + } else if pure_profit_percent >= 0.0 { + update_record_build.push(0.0.to_string()); // minimum_profit_percent + } else { + update_record_build.push(element.minimum_profit_percent.to_string()); + // minimum_profit_percent + } + + if element.maximum_profit_percent < pure_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 { + update_record_build.push(element.maximum_profit_percent.to_string()); + // maximum_profit_percent + } + + if server_epoch - element.transact_time >= 86_400_000 { + // turn is_long from 0 to 1 for orders whose transact time is over than a day (86,400,000 millis = a day) + update_record_build.push(1.to_string()); + } else { + update_record_build.push(0.to_string()); + } + update_record.push(update_record_build.clone()); + } } - - if element.maximum_profit_percent < pure_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 { - update_record_build.push(element.maximum_profit_percent.to_string()); - // maximum_profit_percent - } - - if server_epoch - element.transact_time >= 86_400_000 { - // turn is_long from 0 to 1 for orders whose transact time is over than a day (86,400,000 millis = a day) - update_record_build.push(1.to_string()); - } else { - update_record_build.push(0.to_string()); - } - update_record.push(update_record_build.clone()); + } }