Refactor codes
This commit is contained in:
parent
9d7e001860
commit
39b8c31e30
|
|
@ -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,35 +598,42 @@ 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 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
|
||||
);
|
||||
|
||||
if element.is_long == 0 || element.is_long == 1 {
|
||||
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)
|
||||
&& element.pure_profit_percent >= target_profit_percent(2.0)
|
||||
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,
|
||||
target_profit_percent(2.0)
|
||||
element.pure_profit_percent
|
||||
);
|
||||
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
|
||||
} else if server_epoch - element.close_time >= (1_800_000 * 2) * 6 // (30min * 2) * 6
|
||||
{
|
||||
println!(
|
||||
"selling {} due to time up {:.3}",
|
||||
|
|
@ -572,8 +641,14 @@ 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);
|
||||
// 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);
|
||||
|
|
@ -588,14 +663,26 @@ 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
|
||||
);
|
||||
limit_order_sell(
|
||||
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,
|
||||
base_qty_to_be_ordered,
|
||||
|
|
@ -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;
|
||||
|
||||
select_result
|
||||
if select_result.is_ok() {
|
||||
Ok(select_result.unwrap())
|
||||
} else {
|
||||
eprint!("select_filled_buy_order() error!");
|
||||
Err("error")?
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user