From f45d5da3c381fd11f8d22ed64e7fc52c3389c739 Mon Sep 17 00:00:00 2001 From: Sik Yoon Date: Mon, 20 Nov 2023 20:25:56 +0900 Subject: [PATCH] Change find() with position() --- src/coex/order_team.rs | 803 +++++++++++++++--------------- src/strategy_team/strategy_004.rs | 16 +- 2 files changed, 401 insertions(+), 418 deletions(-) diff --git a/src/coex/order_team.rs b/src/coex/order_team.rs index c51126c..1cf9b5a 100644 --- a/src/coex/order_team.rs +++ b/src/coex/order_team.rs @@ -439,11 +439,11 @@ pub async fn limit_order_buy( T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), ) .unwrap(); - let base_asset_precision = exchange_info_vec - .iter() - .find(|exchange_info| exchange_info.symbol == element.symbol) - .unwrap() - .base_asset_precision; + // let base_asset_precision = exchange_info_vec + // .iter() + // .find(|exchange_info| exchange_info.symbol == element.symbol) + // .unwrap() + // .base_asset_precision; let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered) .round_dp_with_strategy(8, RoundingStrategy::ToZero); @@ -718,58 +718,57 @@ pub async fn limit_order_sell( let mut insert_value_container: Vec = Vec::new(); let server_epoch = server_epoch().await; if RUNNING_MODE == SIMUL && buy_ordered_coin.status == "SIMUL" { - let quote_asset_precision = exchange_info_vec + let quote_asset_precision_option = exchange_info_vec .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == buy_ordered_coin.symbol) - .unwrap() - .quote_asset_precision; - let trade_fee = trade_fee_vec + .position(|exchange_info| exchange_info.symbol == buy_ordered_coin.symbol); + let trade_fee_option = trade_fee_vec .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == buy_ordered_coin.symbol) - .unwrap() - .takercommission; - let get_usdt = decimal_mul(sell_base_quantity, sell_base_price) - .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); - let get_usdt_fee_adjusted = decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + .position(|trade_fee| trade_fee.symbol == buy_ordered_coin.symbol); + if quote_asset_precision_option.is_some() && trade_fee_option.is_some() { + let quote_asset_precision = exchange_info_vec[quote_asset_precision_option.unwrap()].quote_asset_precision; + let trade_fee = trade_fee_vec[trade_fee_option.unwrap()].takercommission; + + let get_usdt = decimal_mul(sell_base_quantity, sell_base_price) .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); + let get_usdt_fee_adjusted = decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); - insert_value_container.push(buy_ordered_coin.symbol.to_string()); // symbol - insert_value_container.push(0.to_string()); // buy_order_id - insert_value_container.push(0.to_string()); // sell_order_id - insert_value_container.push(server_epoch.to_string()); // transact_time - insert_value_container.push(buy_ordered_coin.close_time.to_string()); // close_time - insert_value_container.push(String::from("SIMUL")); // status - insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt - insert_value_container.push(get_usdt.to_string()); // get_usdt - insert_value_container.push(get_usdt_fee_adjusted.to_string()); // get_usdt_fee_adjusted - insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price - insert_value_container.push(sell_base_price.to_string()); // sell_price - insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss - insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price - insert_value_container.push(sell_base_quantity.to_string()); // base_qty_ordered + insert_value_container.push(buy_ordered_coin.symbol.to_string()); // symbol + insert_value_container.push(0.to_string()); // buy_order_id + insert_value_container.push(0.to_string()); // sell_order_id + insert_value_container.push(server_epoch.to_string()); // transact_time + insert_value_container.push(buy_ordered_coin.close_time.to_string()); // close_time + insert_value_container.push(String::from("SIMUL")); // status + insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt + insert_value_container.push(get_usdt.to_string()); // get_usdt + insert_value_container.push(get_usdt_fee_adjusted.to_string()); // get_usdt_fee_adjusted + insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price + insert_value_container.push(sell_base_price.to_string()); // sell_price + insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss + insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price + insert_value_container.push(sell_base_quantity.to_string()); // base_qty_ordered - let pure_profit_percent = decimal_mul( - decimal_sub( - decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt), - dec!(1), - ), - dec!(100), - ); - insert_value_container.push(pure_profit_percent.to_string()); // pure_profit_percent - insert_value_container.push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent - insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer - insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long + let pure_profit_percent = decimal_mul( + decimal_sub( + decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt), + dec!(1), + ), + dec!(100), + ); + insert_value_container.push(pure_profit_percent.to_string()); // pure_profit_percent + insert_value_container.push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent + insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer + insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long - insert_values.push(insert_value_container.clone()); - insert_records(&insert_table_name, &insert_columns, &insert_values).await; + insert_values.push(insert_value_container.clone()); + insert_records(&insert_table_name, &insert_columns, &insert_values).await; - // delete record in buy_ordered_coin_list - let delete_table_name = String::from("buy_ordered_coin_list"); - let mut delete_condition = String::from("WHERE id = "); - delete_condition.push_str(buy_ordered_coin.id.to_string().as_str()); - delete_record(&delete_table_name, &delete_condition).await; + // delete record in buy_ordered_coin_list + let delete_table_name = String::from("buy_ordered_coin_list"); + let mut delete_condition = String::from("WHERE id = "); + delete_condition.push_str(buy_ordered_coin.id.to_string().as_str()); + delete_record(&delete_table_name, &delete_condition).await; + } } else if RUNNING_MODE == REAL || RUNNING_MODE == TEST { // building URL and API-keys let mut url = String::new(); @@ -831,86 +830,84 @@ pub async fn limit_order_sell( .push(T.get("status").unwrap().as_str().unwrap().to_string()); // status insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt - let quote_asset_precision = exchange_info_vec + let quote_asset_precision_option = exchange_info_vec .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == buy_ordered_coin.symbol) - .unwrap() - .quote_asset_precision; - let trade_fee = trade_fee_vec + .position(|exchange_info| exchange_info.symbol == buy_ordered_coin.symbol); + let trade_fee_option = trade_fee_vec .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == buy_ordered_coin.symbol) - .unwrap() - .takercommission; - let get_usdt = rust_decimal::prelude::FromStr::from_str( - T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let get_usdt_fee_adjusted = - decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) - .round_dp_with_strategy( - quote_asset_precision, - RoundingStrategy::ToZero, + .position(|trade_fee| trade_fee.symbol == buy_ordered_coin.symbol); + if quote_asset_precision_option.is_some() && trade_fee_option.is_some() { + let quote_asset_precision = exchange_info_vec[quote_asset_precision_option.unwrap()].quote_asset_precision; + let trade_fee = trade_fee_vec[trade_fee_option.unwrap()].takercommission; + let get_usdt = rust_decimal::prelude::FromStr::from_str( + T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), + ) + .unwrap(); + let get_usdt_fee_adjusted = + decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + .round_dp_with_strategy( + quote_asset_precision, + RoundingStrategy::ToZero, + ); + let ordered_base_qty = rust_decimal::prelude::FromStr::from_str( + T.get("origQty").unwrap().as_str().unwrap(), + ) + .unwrap(); + + if T.get("status").unwrap().as_str().unwrap() == "FILLED" { + insert_value_container.push(get_usdt.to_string()); // get_usdt + insert_value_container.push(get_usdt_fee_adjusted.to_string()); + // get_usdt_fee_adjusted + } else { + insert_value_container.push(0.0.to_string()); // get_usdt + insert_value_container.push(0.0.to_string()); // get_usdt_fee_adjusted + } + + insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price + + if T.get("status").unwrap().as_str().unwrap() == "FILLED" { + let sell_price = decimal_div(get_usdt, ordered_base_qty) + .round_dp_with_strategy( + quote_asset_precision, + RoundingStrategy::ToZero, + ); + insert_value_container.push(sell_price.to_string()); // sell_price + } else { + insert_value_container.push(0.0.to_string()); // sell_price + } + + insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss + insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price + insert_value_container.push(ordered_base_qty.to_string()); // base_qty_ordered + + if T.get("status").unwrap().as_str().unwrap() == "FILLED" { + let pure_profit_percent = decimal_mul( + decimal_sub( + decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt), + dec!(1), + ), + dec!(100), ); - let ordered_base_qty = rust_decimal::prelude::FromStr::from_str( - T.get("origQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - - if T.get("status").unwrap().as_str().unwrap() == "FILLED" { - insert_value_container.push(get_usdt.to_string()); // get_usdt - insert_value_container.push(get_usdt_fee_adjusted.to_string()); - // get_usdt_fee_adjusted - } else { - insert_value_container.push(0.0.to_string()); // get_usdt - insert_value_container.push(0.0.to_string()); // get_usdt_fee_adjusted - } - - insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price - - if T.get("status").unwrap().as_str().unwrap() == "FILLED" { - let sell_price = decimal_div(get_usdt, ordered_base_qty) - .round_dp_with_strategy( - quote_asset_precision, - RoundingStrategy::ToZero, - ); - insert_value_container.push(sell_price.to_string()); // sell_price - } else { - insert_value_container.push(0.0.to_string()); // sell_price - } - - insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss - insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price - insert_value_container.push(ordered_base_qty.to_string()); // base_qty_ordered - - if T.get("status").unwrap().as_str().unwrap() == "FILLED" { - let pure_profit_percent = decimal_mul( - decimal_sub( - decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt), - dec!(1), - ), - dec!(100), - ); + insert_value_container + .push(buy_ordered_coin.pure_profit_percent.to_string()); + // pure_profit_percent + } else { + insert_value_container.push(0.0.to_string()); // pure_profit_percent + } insert_value_container - .push(buy_ordered_coin.pure_profit_percent.to_string()); - // pure_profit_percent - } else { - insert_value_container.push(0.0.to_string()); // pure_profit_percent + .push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent + insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer + insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long + + insert_values.push(insert_value_container.clone()); + insert_records(&insert_table_name, &insert_columns, &insert_values).await; + + // delete record in buy_ordered_coin_list + let delete_table_name = String::from("buy_ordered_coin_list"); + let mut delete_condition = String::from("WHERE id = "); + delete_condition.push_str(buy_ordered_coin.id.to_string().as_str()); + delete_record(&delete_table_name, &delete_condition).await; } - insert_value_container - .push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent - insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer - insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long - - insert_values.push(insert_value_container.clone()); - insert_records(&insert_table_name, &insert_columns, &insert_values).await; - - // delete record in buy_ordered_coin_list - let delete_table_name = String::from("buy_ordered_coin_list"); - let mut delete_condition = String::from("WHERE id = "); - delete_condition.push_str(buy_ordered_coin.id.to_string().as_str()); - delete_record(&delete_table_name, &delete_condition).await; } } Err(e) => { @@ -1188,57 +1185,58 @@ pub async fn cancel_buy_order( status_value_build.push('\''); // calculate values to be updated - let trade_fee = trade_fee_vec + let trade_fee_option = trade_fee_vec .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == order.symbol) - .unwrap() - .takercommission; - - let base_qty_ordered = rust_decimal::prelude::FromStr::from_str( - T.get("executedQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let base_qty_fee_adjusted = - decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee)); - - let base_asset_precision = exchange_info_vec + .position(|trade_fee| trade_fee.symbol == order.symbol); + + let base_asset_precision_option = exchange_info_vec .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == order.symbol) - .unwrap() - .base_asset_precision; - let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered) - .round_dp_with_strategy(8, RoundingStrategy::ToZero); + .position(|exchange_info| exchange_info.symbol == order.symbol); - let update_values = vec![ - (String::from("status"), status_value_build), // status - (String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt - (String::from("buy_price"), buy_price.to_string()), // buy_price - ( - String::from("base_qty_ordered"), - base_qty_ordered.to_string(), - ), // base_qty_ordered - ( - String::from("base_qty_fee_adjusted"), - base_qty_fee_adjusted.to_string(), - ), // base_qty_fee_adjusted - ]; - let update_condition = vec![ - (String::from("order_id"), order.order_id.to_string()), - (String::from("symbol"), order.symbol.clone()), - ]; - update_record3(&table_name, &update_values, &update_condition) - .await + if trade_fee_option.is_some() && base_asset_precision_option.is_some() { + let trade_fee = trade_fee_vec[trade_fee_option.unwrap()].takercommission; + + let base_qty_ordered = rust_decimal::prelude::FromStr::from_str( + T.get("executedQty").unwrap().as_str().unwrap(), + ) .unwrap(); - // update available_usdt - if order.used_usdt > cummulative_quote_qty { - add_available_usdt(decimal_sub(order.used_usdt, cummulative_quote_qty)); - } else { - sub_available_usdt(decimal_sub(cummulative_quote_qty, order.used_usdt)); + let base_qty_fee_adjusted = + decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee)); + + let base_asset_precision = exchange_info_vec[base_asset_precision_option.unwrap()].base_asset_precision; + let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered) + .round_dp_with_strategy(8, RoundingStrategy::ToZero); + + let update_values = vec![ + (String::from("status"), status_value_build), // status + (String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt + (String::from("buy_price"), buy_price.to_string()), // buy_price + ( + String::from("base_qty_ordered"), + base_qty_ordered.to_string(), + ), // base_qty_ordered + ( + String::from("base_qty_fee_adjusted"), + base_qty_fee_adjusted.to_string(), + ), // base_qty_fee_adjusted + ]; + let update_condition = vec![ + (String::from("order_id"), order.order_id.to_string()), + (String::from("symbol"), order.symbol.clone()), + ]; + update_record3(&table_name, &update_values, &update_condition) + .await + .unwrap(); + + // update available_usdt + if order.used_usdt > cummulative_quote_qty { + add_available_usdt(decimal_sub(order.used_usdt, cummulative_quote_qty)); + } else { + sub_available_usdt(decimal_sub(cummulative_quote_qty, order.used_usdt)); + } + println!("partially buy {}", order.symbol); } - println!("partially buy {}", order.symbol); } } } else if T.get("code").is_some() { @@ -1371,162 +1369,148 @@ pub async fn cancel_sell_order( insert_values.push(insert_value_container.clone()); insert_records(&insert_table_name, &insert_columns, &insert_values).await; } else { - if base_qty_executed == base_qty_ordered { - // FILLED case - // update status FILLED - let quote_asset_precision = exchange_info_vec + let quote_asset_precision_option = exchange_info_vec .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == order.symbol) - .unwrap() - .quote_asset_precision; - let trade_fee = trade_fee_vec + .position(|exchange_info| exchange_info.symbol == order.symbol); + let trade_fee_option = trade_fee_vec .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == order.symbol) - .unwrap() - .takercommission; + .position(|trade_fee| trade_fee.symbol == order.symbol); - let get_usdt = rust_decimal::prelude::FromStr::from_str( - T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let get_usdt_fee_adjusted = - decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + if quote_asset_precision_option.is_some() && trade_fee_option.is_some() { + let quote_asset_precision = exchange_info_vec[quote_asset_precision_option.unwrap()].quote_asset_precision; + let trade_fee = trade_fee_vec[trade_fee_option.unwrap()].takercommission; + if base_qty_executed == base_qty_ordered { + // FILLED case + // update status FILLED + let get_usdt = rust_decimal::prelude::FromStr::from_str( + T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), + ) + .unwrap(); + let get_usdt_fee_adjusted = + decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + .round_dp_with_strategy( + quote_asset_precision, + RoundingStrategy::ToZero, + ); + let sell_price = decimal_div(get_usdt, base_qty_executed) .round_dp_with_strategy( quote_asset_precision, RoundingStrategy::ToZero, ); - let sell_price = decimal_div(get_usdt, base_qty_executed) - .round_dp_with_strategy( - quote_asset_precision, - RoundingStrategy::ToZero, + let pure_profit_percent = decimal_mul( + decimal_sub( + decimal_div(get_usdt_fee_adjusted, order.used_usdt), + dec!(1), + ), + dec!(100), ); - let pure_profit_percent = decimal_mul( - decimal_sub( - decimal_div(get_usdt_fee_adjusted, order.used_usdt), - dec!(1), - ), - dec!(100), - ); - - let table_name = String::from("sell_ordered_coin_list"); - let mut value_build = String::from("\'"); - value_build.push_str("FILLED"); - value_build.push('\''); - - let update_values = vec![ - (String::from("status"), value_build), - (String::from("get_usdt"), get_usdt.to_string()), - ( - String::from("get_usdt_fee_adjusted"), - get_usdt_fee_adjusted.to_string(), - ), - (String::from("sell_price"), sell_price.to_string()), - ( - String::from("pure_profit_percent"), - pure_profit_percent.to_string(), - ), - ]; - let update_condition = vec![(String::from("id"), order.id.to_string())]; - update_record3(&table_name, &update_values, &update_condition) - .await + + let table_name = String::from("sell_ordered_coin_list"); + let mut value_build = String::from("\'"); + value_build.push_str("FILLED"); + value_build.push('\''); + + let update_values = vec![ + (String::from("status"), value_build), + (String::from("get_usdt"), get_usdt.to_string()), + ( + String::from("get_usdt_fee_adjusted"), + get_usdt_fee_adjusted.to_string(), + ), + (String::from("sell_price"), sell_price.to_string()), + ( + String::from("pure_profit_percent"), + pure_profit_percent.to_string(), + ), + ]; + let update_condition = vec![(String::from("id"), order.id.to_string())]; + update_record3(&table_name, &update_values, &update_condition) + .await + .unwrap(); + } else { + // PARTIALLY FILLED case + // reflect partially filled information and update status with FILLED + let used_usdt = decimal_mul(base_qty_executed, order.buy_price); + let get_usdt = rust_decimal::prelude::FromStr::from_str( + T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), + ) .unwrap(); - } else { - // PARTIALLY FILLED case - // reflect partially filled information and update status with FILLED - let quote_asset_precision = exchange_info_vec - .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == order.symbol) - .unwrap() - .quote_asset_precision; - let trade_fee = trade_fee_vec - .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == order.symbol) - .unwrap() - .takercommission; - let used_usdt = decimal_mul(base_qty_executed, order.buy_price); - let get_usdt = rust_decimal::prelude::FromStr::from_str( - T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let get_usdt_fee_adjusted = - decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + let get_usdt_fee_adjusted = + decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + .round_dp_with_strategy( + quote_asset_precision, + RoundingStrategy::ToZero, + ); + let rest_used_usdt = decimal_sub(order.used_usdt, used_usdt); + let sell_price = decimal_div(get_usdt, base_qty_executed) .round_dp_with_strategy( quote_asset_precision, RoundingStrategy::ToZero, ); - let rest_used_usdt = decimal_sub(order.used_usdt, used_usdt); - let sell_price = decimal_div(get_usdt, base_qty_executed) - .round_dp_with_strategy( - quote_asset_precision, - RoundingStrategy::ToZero, + let pure_profit_percent = decimal_mul( + decimal_sub(decimal_div(get_usdt_fee_adjusted, get_usdt), dec!(1)), + dec!(100), ); - let pure_profit_percent = decimal_mul( - decimal_sub(decimal_div(get_usdt_fee_adjusted, get_usdt), dec!(1)), - dec!(100), - ); - - let table_name = String::from("sell_ordered_coin_list"); - let mut value_build = String::from("\'"); - value_build.push_str("FILLED"); - value_build.push('\''); - - let update_values = vec![ - (String::from("status"), value_build), - (String::from("used_usdt"), used_usdt.to_string()), - (String::from("get_usdt"), get_usdt.to_string()), - ( - String::from("get_usdt_fee_adjusted"), - get_usdt_fee_adjusted.to_string(), - ), - ( - String::from("base_qty_ordered"), - base_qty_executed.to_string(), - ), - (String::from("sell_price"), sell_price.to_string()), - ( - String::from("pure_profit_percent"), - pure_profit_percent.to_string(), - ), - ]; - let update_condition = vec![(String::from("id"), order.id.to_string())]; - update_record3(&table_name, &update_values, &update_condition) - .await - .unwrap(); - - // insert record in [buy_ordered_coin_list] - let rest_base_qty = decimal_sub(base_qty_ordered, base_qty_executed); - let rest_base_qty_fee_adjusted = - decimal_mul(rest_base_qty, decimal_sub(dec!(1), trade_fee)); - let mut insert_values: Vec> = Vec::new(); - let mut insert_value_container: Vec = Vec::new(); - let server_epoch = server_epoch().await; - insert_value_container.push(order.symbol.clone()); // symbol - insert_value_container.push(order.buy_order_id.to_string()); // order_id - insert_value_container.push(server_epoch.to_string()); // transact_time - insert_value_container.push(order.close_time.to_string()); // close_time - insert_value_container.push(String::from("FILLED")); // status - insert_value_container.push(rest_used_usdt.to_string()); // used_usdt - insert_value_container.push(0.0.to_string()); // expected_get_usdt - insert_value_container.push(0.0.to_string()); // expected_usdt_profit - insert_value_container.push(order.buy_price.to_string()); // buy_price - insert_value_container.push(0.0.to_string()); // current_price - insert_value_container.push(order.stoploss.to_string()); // stoploss - insert_value_container.push(order.target_price.to_string()); // target_price - insert_value_container.push(rest_base_qty.to_string()); // base_qty_ordered - insert_value_container.push(rest_base_qty_fee_adjusted.to_string()); // base_qty_fee_adjusted - insert_value_container.push(0.0.to_string()); // pure_profit_percent - insert_value_container.push(0.0.to_string()); // minimum_profit_percent - insert_value_container.push(0.0.to_string()); // maximum_profit_percent - insert_value_container.push(order.registerer.to_string()); // registerer - insert_value_container.push(order.is_long.to_string()); // is_long - - insert_values.push(insert_value_container.clone()); - insert_records(&insert_table_name, &insert_columns, &insert_values) - .await; + + let table_name = String::from("sell_ordered_coin_list"); + let mut value_build = String::from("\'"); + value_build.push_str("FILLED"); + value_build.push('\''); + + let update_values = vec![ + (String::from("status"), value_build), + (String::from("used_usdt"), used_usdt.to_string()), + (String::from("get_usdt"), get_usdt.to_string()), + ( + String::from("get_usdt_fee_adjusted"), + get_usdt_fee_adjusted.to_string(), + ), + ( + String::from("base_qty_ordered"), + base_qty_executed.to_string(), + ), + (String::from("sell_price"), sell_price.to_string()), + ( + String::from("pure_profit_percent"), + pure_profit_percent.to_string(), + ), + ]; + let update_condition = vec![(String::from("id"), order.id.to_string())]; + update_record3(&table_name, &update_values, &update_condition) + .await + .unwrap(); + + // insert record in [buy_ordered_coin_list] + let rest_base_qty = decimal_sub(base_qty_ordered, base_qty_executed); + let rest_base_qty_fee_adjusted = + decimal_mul(rest_base_qty, decimal_sub(dec!(1), trade_fee)); + let mut insert_values: Vec> = Vec::new(); + let mut insert_value_container: Vec = Vec::new(); + let server_epoch = server_epoch().await; + insert_value_container.push(order.symbol.clone()); // symbol + insert_value_container.push(order.buy_order_id.to_string()); // order_id + insert_value_container.push(server_epoch.to_string()); // transact_time + insert_value_container.push(order.close_time.to_string()); // close_time + insert_value_container.push(String::from("FILLED")); // status + insert_value_container.push(rest_used_usdt.to_string()); // used_usdt + insert_value_container.push(0.0.to_string()); // expected_get_usdt + insert_value_container.push(0.0.to_string()); // expected_usdt_profit + insert_value_container.push(order.buy_price.to_string()); // buy_price + insert_value_container.push(0.0.to_string()); // current_price + insert_value_container.push(order.stoploss.to_string()); // stoploss + insert_value_container.push(order.target_price.to_string()); // target_price + insert_value_container.push(rest_base_qty.to_string()); // base_qty_ordered + insert_value_container.push(rest_base_qty_fee_adjusted.to_string()); // base_qty_fee_adjusted + insert_value_container.push(0.0.to_string()); // pure_profit_percent + insert_value_container.push(0.0.to_string()); // minimum_profit_percent + insert_value_container.push(0.0.to_string()); // maximum_profit_percent + insert_value_container.push(order.registerer.to_string()); // registerer + insert_value_container.push(order.is_long.to_string()); // is_long + + insert_values.push(insert_value_container.clone()); + insert_records(&insert_table_name, &insert_columns, &insert_values) + .await; + } } } } else { @@ -1675,63 +1659,63 @@ pub async fn query_buy_order( value_build.push('\''); // calculate values to be updated - let trade_fee = trade_fee_vec + let trade_fee_option = trade_fee_vec .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == order.symbol) - .unwrap() - .takercommission; - - let base_qty_ordered = rust_decimal::prelude::FromStr::from_str( - T.get("executedQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let base_qty_fee_adjusted = - decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee)); - - let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str( - T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let base_asset_precision = exchange_info_vec + .position(|trade_fee| trade_fee.symbol == order.symbol); + let base_asset_precision_option = exchange_info_vec .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == order.symbol) - .unwrap() - .base_asset_precision; - let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered) - .round_dp_with_strategy(8, RoundingStrategy::ToZero); + .position(|exchange_info| exchange_info.symbol == order.symbol); - let update_values = vec![ - (String::from("status"), value_build), // status - (String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt - (String::from("buy_price"), buy_price.to_string()), // buy_price - ( - String::from("base_qty_ordered"), - base_qty_ordered.to_string(), - ), // base_qty_ordered - ( - String::from("base_qty_fee_adjusted"), - base_qty_fee_adjusted.to_string(), - ), // base_qty_fee_adjusted - ]; - let update_condition = vec![ - (String::from("order_id"), order.order_id.to_string()), - (String::from("symbol"), order.symbol.clone()), - ]; - update_record3(&table_name, &update_values, &update_condition) - .await + if trade_fee_option.is_some() && base_asset_precision_option.is_some() { + let trade_fee = trade_fee_vec[trade_fee_option.unwrap()].takercommission; + let base_asset_precision = exchange_info_vec[base_asset_precision_option.unwrap()].base_asset_precision; + let base_qty_ordered = rust_decimal::prelude::FromStr::from_str( + T.get("executedQty").unwrap().as_str().unwrap(), + ) .unwrap(); - - if T.get("status").unwrap().as_str().unwrap() == "FILLED" { - println!("buy {}", order.symbol); - // update available_usdt - if order.used_usdt > cummulative_quote_qty { - add_available_usdt(decimal_sub(order.used_usdt, cummulative_quote_qty)); - } else { - sub_available_usdt(decimal_sub(cummulative_quote_qty, order.used_usdt)); + let base_qty_fee_adjusted = + decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee)); + + let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str( + T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), + ) + .unwrap(); + + let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered) + .round_dp_with_strategy(8, RoundingStrategy::ToZero); + + let update_values = vec![ + (String::from("status"), value_build), // status + (String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt + (String::from("buy_price"), buy_price.to_string()), // buy_price + ( + String::from("base_qty_ordered"), + base_qty_ordered.to_string(), + ), // base_qty_ordered + ( + String::from("base_qty_fee_adjusted"), + base_qty_fee_adjusted.to_string(), + ), // base_qty_fee_adjusted + ]; + let update_condition = vec![ + (String::from("order_id"), order.order_id.to_string()), + (String::from("symbol"), order.symbol.clone()), + ]; + update_record3(&table_name, &update_values, &update_condition) + .await + .unwrap(); + + if T.get("status").unwrap().as_str().unwrap() == "FILLED" { + println!("buy {}", order.symbol); + // update available_usdt + if order.used_usdt > cummulative_quote_qty { + add_available_usdt(decimal_sub(order.used_usdt, cummulative_quote_qty)); + } else { + sub_available_usdt(decimal_sub(cummulative_quote_qty, order.used_usdt)); + } } } + } else if T.get("status").unwrap().as_str().unwrap() == "CANCELED" { let update_table_name = String::from("suggested_coin_list"); let update_condition = vec![ @@ -1798,57 +1782,56 @@ pub async fn query_sell_order( if T.get("status").unwrap().as_str().unwrap() == "FILLED" || T.get("status").unwrap().as_str().unwrap() == "PARTIALLY_FILLED" { - let quote_asset_precision = exchange_info_vec + let quote_asset_precision_option = exchange_info_vec .iter() - // FIXME: find() should be position() - .find(|exchange_info| exchange_info.symbol == order.symbol) - .unwrap() - .quote_asset_precision; - let trade_fee = trade_fee_vec + .position(|exchange_info| exchange_info.symbol == order.symbol); + let trade_fee_option = trade_fee_vec .iter() - // FIXME: find() should be position() - .find(|trade_fee| trade_fee.symbol == order.symbol) - .unwrap() - .takercommission; - let get_usdt = rust_decimal::prelude::FromStr::from_str( - T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let get_usdt_fee_adjusted = decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) - .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); - let ordered_base_qty = rust_decimal::prelude::FromStr::from_str( - T.get("executedQty").unwrap().as_str().unwrap(), - ) - .unwrap(); - let sell_price = decimal_div(get_usdt, ordered_base_qty) - .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); - let pure_profit_percent = decimal_mul( - decimal_sub(decimal_div(get_usdt_fee_adjusted, order.used_usdt), dec!(1)), - dec!(100), - ); + .position(|trade_fee| trade_fee.symbol == order.symbol); - let table_name = String::from("sell_ordered_coin_list"); - let mut value_build = String::from("\'"); - value_build.push_str(T.get("status").unwrap().as_str().unwrap()); - value_build.push('\''); - - let update_values = vec![ - (String::from("status"), value_build), - (String::from("get_usdt"), get_usdt.to_string()), - ( - String::from("get_usdt_fee_adjusted"), - get_usdt_fee_adjusted.to_string(), - ), - (String::from("sell_price"), sell_price.to_string()), - ( - String::from("pure_profit_percent"), - pure_profit_percent.to_string(), - ), - ]; - let update_condition = vec![(String::from("id"), order.id.to_string())]; - update_record3(&table_name, &update_values, &update_condition) - .await + if quote_asset_precision_option.is_some() && trade_fee_option.is_some() { + let quote_asset_precision = exchange_info_vec[quote_asset_precision_option.unwrap()].quote_asset_precision; + let trade_fee = trade_fee_vec[trade_fee_option.unwrap()].takercommission; + let get_usdt = rust_decimal::prelude::FromStr::from_str( + T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(), + ) .unwrap(); + let get_usdt_fee_adjusted = decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee)) + .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); + let ordered_base_qty = rust_decimal::prelude::FromStr::from_str( + T.get("executedQty").unwrap().as_str().unwrap(), + ) + .unwrap(); + let sell_price = decimal_div(get_usdt, ordered_base_qty) + .round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero); + let pure_profit_percent = decimal_mul( + decimal_sub(decimal_div(get_usdt_fee_adjusted, order.used_usdt), dec!(1)), + dec!(100), + ); + + let table_name = String::from("sell_ordered_coin_list"); + let mut value_build = String::from("\'"); + value_build.push_str(T.get("status").unwrap().as_str().unwrap()); + value_build.push('\''); + + let update_values = vec![ + (String::from("status"), value_build), + (String::from("get_usdt"), get_usdt.to_string()), + ( + String::from("get_usdt_fee_adjusted"), + get_usdt_fee_adjusted.to_string(), + ), + (String::from("sell_price"), sell_price.to_string()), + ( + String::from("pure_profit_percent"), + pure_profit_percent.to_string(), + ), + ]; + let update_condition = vec![(String::from("id"), order.id.to_string())]; + update_record3(&table_name, &update_values, &update_condition) + .await + .unwrap(); + } } } Err(e) => { diff --git a/src/strategy_team/strategy_004.rs b/src/strategy_team/strategy_004.rs index 9820270..d41dc8f 100644 --- a/src/strategy_team/strategy_004.rs +++ b/src/strategy_team/strategy_004.rs @@ -252,10 +252,10 @@ pub async fn list_up_for_sell( let lot_step_size_option = exchange_info_vec .iter() - .find(|exchange_info| exchange_info.symbol == element.symbol); + .position(|exchange_info| exchange_info.symbol == element.symbol); let quote_commission_precision_option = exchange_info_vec .iter() - .find(|exchange_info| exchange_info.symbol == element.symbol); + .position(|exchange_info| exchange_info.symbol == element.symbol); let opclo_30m_option = all_data .rt_price_30m_vec @@ -266,9 +266,9 @@ pub async fn list_up_for_sell( && 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() + let lot_step_size = exchange_info_vec[lot_step_size_option.unwrap()].stepsize; + let quote_commission_precision = exchange_info_vec[quote_commission_precision_option + .unwrap()] .quote_commission_precision; let base_qty_to_be_ordered = element.base_qty_fee_adjusted.round_dp_with_strategy( @@ -277,8 +277,8 @@ pub async fn list_up_for_sell( ); if (element.is_long == 0 || element.is_long == 1) && !element.current_price.is_zero() { - if element.current_price >= element.target_price { - println!("target selling {} {}", element.symbol, element.pure_profit_percent); + if element.current_price >= element.target_price && element.pure_profit_percent >= 0.1 { + println!("target selling {} {:.2}", element.symbol, element.pure_profit_percent); limit_order_sell( &element, element.current_price, @@ -289,7 +289,7 @@ pub async fn list_up_for_sell( ) .await; } else if element.current_price <= element.stoploss { - println!("stoploss selling {} {}", element.symbol, element.pure_profit_percent); + println!("stoploss selling {} {:.2}", element.symbol, element.pure_profit_percent); limit_order_sell( &element, element.current_price,