Refactor codes

This commit is contained in:
Sik Yoon 2023-10-04 20:12:13 +09:00
parent 9d7e001860
commit 39b8c31e30

View File

@ -90,6 +90,61 @@ pub struct SellOrderedCoinList {
pub is_long: u8,
}
pub trait DBlist {
fn new() -> Self;
}
impl DBlist for SellOrderedCoinList {
fn new() -> SellOrderedCoinList {
let a = SellOrderedCoinList {
id: 0,
symbol: String::new(),
buy_order_id: 0,
sell_order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
get_usdt: Decimal::new(0, 8),
get_usdt_fee_adjusted: Decimal::new(0, 8),
buy_price: Decimal::new(0, 8),
sell_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
pure_profit_percent: Decimal::new(0, 8),
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
a
}
}
impl DBlist for BuyOrderedCoinList {
fn new() -> BuyOrderedCoinList {
let a = BuyOrderedCoinList {
id: 0,
symbol: String::new(),
order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
expected_get_usdt: 0.0,
expected_usdt_profit: 0.0,
buy_price: Decimal::new(0, 8),
current_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
base_qty_fee_adjusted: Decimal::new(0, 8),
pure_profit_percent: 0.0,
minimum_profit_percent: 0.0,
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
a
}
}
#[derive(Debug, FromRow)]
pub struct SignalDecisionInfo {
pub decision: String,
@ -258,6 +313,8 @@ pub async fn limit_order_buy(
// reflect available_usdt in [asset_manage_announcement]
sub_available_usdt(used_usdt).await;
println!("SIMUL buy coin: {}", element.symbol);
} else {
// building URL and API-keys
let mut url = String::new();
@ -436,7 +493,8 @@ pub async fn monitoring_filled_buy_order(
// let scoreboard_list = select_scoreboard().await;
// let signal_decision = select_signal_decision().await;
let filled_buy_orders = select_filled_buy_orders().await;
let filled_buy_orders = select_filled_buy_orders().await?;
if !filled_buy_orders.is_empty() {
// 심볼들을 2개씩 청스로 나누어 테스크를 생성하고 각 태스크 별로 병렬로 처리한다.
// update real-time current price to each record through chunks
@ -463,7 +521,7 @@ pub async fn monitoring_filled_buy_order(
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 filled_buy_orders = select_filled_buy_orders().await?;
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(5000))
.build()
@ -506,11 +564,15 @@ pub async fn monitoring_filled_buy_order(
let mut opclo_30m_vec = all_data.rt_price_30m_vec[opclo_30m_option.unwrap()]
.1
.clone();
let opclo_sample_length: usize = 50; // 50 candle samsples
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.reverse();
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;
@ -536,41 +598,54 @@ pub async fn monitoring_filled_buy_order(
// 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 / 2.0) * multiplier) - (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy))
((average_amplitude) * multiplier) - (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy))
} else {
((average_amplitude / 2.0) * multiplier) + (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy))
((average_amplitude) * multiplier) + (standard_deviation_amplitude * 2.0) // 2.0 sigma (recommand: 0.5 ~ 2.0(patient & greedy))
}
};
if element.is_long == 0 || element.is_long == 1 {
if element.pure_profit_percent >= 0.0 {
let mut is_sell = false;
if element.maximum_profit_percent >= target_profit_percent(2.0)
&& element.pure_profit_percent >= target_profit_percent(2.0)
{
println!(
"Selling {} 200% target_profit_percent: {:.3}",
element.symbol,
target_profit_percent(2.0)
);
is_sell = true;
} else if element.maximum_profit_percent < target_profit_percent(2.0)
&& element.maximum_profit_percent >= target_profit_percent(1.5)
&& element.pure_profit_percent < target_profit_percent(0.2)
{
println!(
"selling {} 20% target_profit_percent: {:.3}",
element.symbol,
target_profit_percent(0.2)
);
is_sell = true;
} else if server_epoch - element.close_time > (1_800_000) * 10 // 30min * 10
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.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
{
println!(
"Selling {} 200% 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
{
println!(
"selling {} due to time up {:.3}",
element.symbol,
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;
}
@ -588,13 +663,25 @@ pub async fn monitoring_filled_buy_order(
.await;
}
} else {
if element.pure_profit_percent < target_profit_percent(-1.333) - 0.2 // -0.2 means about total trade fees.
let mut is_sell = false;
if element.pure_profit_percent <= target_profit_percent(-1.5) - 0.2 // -0.2 means about total trade fees.
{
println!(
"selling {} due to lower limit {:.3}",
"Selling {} -150% 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
{
println!(
"selling {} -1.0% profit",
element.symbol
);
is_sell = true;
}
if is_sell == true {
limit_order_sell(
&element,
element.current_price,
@ -607,6 +694,7 @@ pub async fn monitoring_filled_buy_order(
}
}
}
}
}
@ -796,6 +884,7 @@ pub async fn limit_order_sell(
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
@ -2140,30 +2229,11 @@ async fn get_timestamp() -> String {
timestamp
}
pub async fn select_filled_buy_orders() -> Vec<BuyOrderedCoinList> {
pub async fn select_filled_buy_orders() -> Result<Vec<BuyOrderedCoinList>, Box<dyn std::error::Error + Send + Sync>> {
let select_table_name = String::from("buy_ordered_coin_list");
let select_columns = String::from("*");
let select_condition = Some(String::from("WHERE status = 'FILLED' or status = 'SIMUL'"));
let data_struct = BuyOrderedCoinList {
id: 0,
symbol: String::new(),
order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
expected_get_usdt: 0.0,
expected_usdt_profit: 0.0,
buy_price: Decimal::new(0, 8),
current_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
base_qty_fee_adjusted: Decimal::new(0, 8),
pure_profit_percent: 0.0,
minimum_profit_percent: 0.0,
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
let data_struct = BuyOrderedCoinList::new();
let select_result = try_select_record(
&select_table_name,
@ -2171,10 +2241,15 @@ pub async fn select_filled_buy_orders() -> Vec<BuyOrderedCoinList> {
&select_condition,
&data_struct,
)
.await
.unwrap();
.await;
if select_result.is_ok() {
Ok(select_result.unwrap())
} else {
eprint!("select_filled_buy_order() error!");
Err("error")?
}
select_result
}
// select open buy orders (NEW, Partially Filled)
@ -2184,26 +2259,7 @@ async fn select_open_buy_orders() -> Vec<BuyOrderedCoinList> {
let select_condition = Some(String::from(
"WHERE status = 'NEW' or status = 'PARTIALLY_FILLED'",
));
let data_struct = BuyOrderedCoinList {
id: 0,
symbol: String::new(),
order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
expected_get_usdt: 0.0,
expected_usdt_profit: 0.0,
buy_price: Decimal::new(0, 8),
current_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
base_qty_fee_adjusted: Decimal::new(0, 8),
pure_profit_percent: 0.0,
minimum_profit_percent: 0.0,
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
let data_struct = BuyOrderedCoinList::new();
let select_result = try_select_record(
&select_table_name,
&select_columns,
@ -2220,25 +2276,7 @@ pub async fn select_filled_sell_orders() -> Vec<SellOrderedCoinList> {
let select_table_name = String::from("sell_ordered_coin_list");
let select_columns = String::from("*");
let select_condition = Some(String::from("WHERE status = 'FILLED' or status = 'SIMUL'"));
let data_struct = SellOrderedCoinList {
id: 0,
symbol: String::new(),
buy_order_id: 0,
sell_order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
get_usdt: Decimal::new(0, 8),
get_usdt_fee_adjusted: Decimal::new(0, 8),
buy_price: Decimal::new(0, 8),
sell_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
pure_profit_percent: Decimal::new(0, 8),
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
let data_struct = SellOrderedCoinList::new();
let select_result = try_select_record(
&select_table_name,
@ -2259,25 +2297,7 @@ async fn select_open_sell_orders() -> Vec<SellOrderedCoinList> {
let select_condition = Some(String::from(
"WHERE status = 'NEW' or status = 'PARTIALLY_FILLED'",
));
let data_struct = SellOrderedCoinList {
id: 0,
symbol: String::new(),
buy_order_id: 0,
sell_order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
get_usdt: Decimal::new(0, 8),
get_usdt_fee_adjusted: Decimal::new(0, 8),
buy_price: Decimal::new(0, 8),
sell_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
pure_profit_percent: Decimal::new(0, 8),
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
let data_struct = SellOrderedCoinList::new();
let select_result = try_select_record(
&select_table_name,