449 lines
16 KiB
Rust
449 lines
16 KiB
Rust
// assets_managing_team manages [asset_manage_announcement] and [wallet] ([wallet_testnet] as well)
|
|
|
|
use crate::coex::exchange_team::*;
|
|
use crate::database_control::*;
|
|
use crate::decimal_funcs::*;
|
|
use crate::RunningMode::*;
|
|
use crate::RUNNING_MODE;
|
|
use reqwest::Client;
|
|
use rust_decimal::{prelude::ToPrimitive, Decimal, RoundingStrategy};
|
|
use rust_decimal_macros::dec;
|
|
use serde_json::{Result, Value};
|
|
use sqlx::FromRow;
|
|
use crate::coex::order_team::DBlist;
|
|
|
|
#[derive(Debug, FromRow)]
|
|
pub struct AssetInfo {
|
|
pub initial_usdt: Decimal,
|
|
pub current_total_usdt: Decimal,
|
|
pub profit: Decimal,
|
|
pub realtime_expected_total_usdt: f64,
|
|
pub realtime_profit: f64,
|
|
pub available_usdt: Decimal,
|
|
pub is_tradable: u8,
|
|
pub unit_trade_usdt: Decimal,
|
|
}
|
|
|
|
impl DBlist for AssetInfo {
|
|
fn new() -> AssetInfo {
|
|
let a = AssetInfo {
|
|
initial_usdt: Decimal::new(0, 8),
|
|
current_total_usdt: Decimal::new(0, 8),
|
|
profit: Decimal::new(0, 8),
|
|
realtime_expected_total_usdt: 0.0,
|
|
realtime_profit: 0.0,
|
|
available_usdt: Decimal::new(0, 8),
|
|
is_tradable: 0,
|
|
unit_trade_usdt: Decimal::new(0, 8),
|
|
};
|
|
a
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, FromRow)]
|
|
pub struct WalletInfo {
|
|
pub asset: String,
|
|
pub free: Decimal,
|
|
pub locked: Decimal,
|
|
}
|
|
|
|
impl DBlist for WalletInfo {
|
|
fn new() -> WalletInfo {
|
|
let a = WalletInfo {
|
|
asset: String::new(),
|
|
free: Decimal::new(0, 8),
|
|
locked: Decimal::new(0, 8),
|
|
};
|
|
a
|
|
}
|
|
}
|
|
|
|
// set unit_trade_usdt
|
|
pub async fn set_unit_usdt() {
|
|
let asset_info = select_asset_manage_announcement().await;
|
|
let mut set_unit_trade_usdt = Decimal::new(0, 8);
|
|
|
|
if RUNNING_MODE == SIMUL {
|
|
set_unit_trade_usdt = dec!(100.0); // $100 for each trade
|
|
} else if RUNNING_MODE == REAL {
|
|
// define protect_rate and unit_trade_usdt as high as total_usdt_amount
|
|
if dec!(0.0) <= asset_info.current_total_usdt && asset_info.current_total_usdt < dec!(1000.0) {
|
|
set_unit_trade_usdt = dec!(50.0); // $100 for each trade
|
|
// set_unit_trade_usdt = decimal_mul(asset_info.current_total_usdt, dec!(0.8)); // 80% of total usdt
|
|
} else if dec!(1000.0) <= asset_info.current_total_usdt
|
|
{
|
|
// set_unit_trade_usdt = dec!(150.0); // $150 for each trade
|
|
set_unit_trade_usdt = decimal_mul(asset_info.current_total_usdt, dec!(0.05));
|
|
|
|
if set_unit_trade_usdt <= dec!(20) {
|
|
set_unit_trade_usdt = dec!(0);
|
|
} else {
|
|
let truncated = decimal_mul(decimal_mul(set_unit_trade_usdt, dec!(0.1)).trunc(), dec!(10));
|
|
let difference = decimal_sub(set_unit_trade_usdt, truncated);
|
|
|
|
if difference >= dec!(5) {
|
|
set_unit_trade_usdt = decimal_add(truncated, dec!(5));
|
|
} else {
|
|
set_unit_trade_usdt = truncated;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update fields in [asset_manage_announcement] table
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let update_values = vec![(
|
|
String::from("unit_trade_usdt"),
|
|
set_unit_trade_usdt.to_string(),
|
|
)];
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
// add extra usdt to initial usdt
|
|
pub async fn add_extra_usdt(extra_usdt: Decimal) {
|
|
// update fields in [asset_manage_announcement] table
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let mut value_build = String::from("initial_usdt + ");
|
|
value_build.push_str(
|
|
extra_usdt
|
|
.round_dp_with_strategy(8, RoundingStrategy::ToZero)
|
|
.to_string()
|
|
.as_str(),
|
|
);
|
|
|
|
let update_values = vec![(String::from("initial_usdt"), value_build)];
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
|
|
let mut value_build = String::from("current_total_usdt + ");
|
|
value_build.push_str(
|
|
extra_usdt
|
|
.round_dp_with_strategy(8, RoundingStrategy::ToZero)
|
|
.to_string()
|
|
.as_str(),
|
|
);
|
|
|
|
let update_values = vec![(String::from("current_total_usdt"), value_build)];
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
|
|
add_available_usdt(extra_usdt.round_dp_with_strategy(8, RoundingStrategy::ToZero)).await;
|
|
|
|
// add additional_usdt into [wallet_simul]
|
|
let mut update_table_name = String::new();
|
|
if RUNNING_MODE == SIMUL {
|
|
let update_table_name = String::from("wallet");
|
|
let mut value_build = String::from("free + ");
|
|
value_build.push_str(extra_usdt.to_string().as_str());
|
|
let update_values = vec![(String::from("free"), value_build)];
|
|
let update_condition = vec![(String::from("asset"), String::from("USDT"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
println!("add_extra_usdt 완료");
|
|
}
|
|
|
|
// update current_total_usdt and profit of asset
|
|
pub async fn update_current_total_usdt() {
|
|
let mut update_values: Vec<(String, String)> = Vec::new();
|
|
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
|
|
let free_usdt = fetch_free_usdt().await;
|
|
let initial_usdt = select_asset_manage_announcement().await.initial_usdt;
|
|
// println!("update_current_total_usdt실행 free_usdt: {}, initial_usdt: {}", free_usdt, initial_usdt);
|
|
let mut profit: Decimal;
|
|
if initial_usdt.is_zero() {
|
|
profit = dec!(0.0);
|
|
} else {
|
|
profit = decimal_sub(decimal_div(free_usdt, initial_usdt), dec!(1));
|
|
}
|
|
|
|
update_values = vec![
|
|
(String::from("current_total_usdt"), free_usdt.to_string()),
|
|
(String::from("profit"), profit.to_string()),
|
|
(
|
|
String::from("realtime_expected_total_usdt"),
|
|
0.0.to_string(),
|
|
),
|
|
(String::from("realtime_profit"), 0.0.to_string()),
|
|
];
|
|
} else {
|
|
let asset_info = select_asset_manage_announcement().await;
|
|
let mut profit: Decimal;
|
|
if asset_info.initial_usdt.is_zero() {
|
|
profit = dec!(0.0);
|
|
} else {
|
|
profit = decimal_sub(
|
|
decimal_div(asset_info.current_total_usdt, asset_info.initial_usdt),
|
|
dec!(1),
|
|
);
|
|
}
|
|
|
|
update_values = vec![
|
|
(
|
|
String::from("current_total_usdt"),
|
|
asset_info.available_usdt.to_string(),
|
|
),
|
|
(String::from("profit"), profit.to_string()),
|
|
(
|
|
String::from("realtime_expected_total_usdt"),
|
|
0.0.to_string(),
|
|
),
|
|
(String::from("realtime_profit"), 0.0.to_string()),
|
|
];
|
|
}
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
set_unit_usdt().await;
|
|
}
|
|
|
|
// monitor whether [buy_ordered_coin_list] is empty to update current_total_usdt and available_usdt in [asset_manage_announcement]
|
|
pub async fn monitoring_asset_usdt(previous_result: &mut bool, client: &Client) -> Result<()> {
|
|
let table_name = String::from("buy_ordered_coin_list");
|
|
let condition = None;
|
|
let buy_list_result = exists_record(&table_name, &condition).await;
|
|
|
|
let table_name = String::from("sell_ordered_coin_list");
|
|
let condition = None;
|
|
let sell_list_result = exists_record(&table_name, &condition).await;
|
|
|
|
if buy_list_result == false && sell_list_result == false {
|
|
if buy_list_result == false
|
|
&& sell_list_result == false
|
|
&& *previous_result == true
|
|
&& (RUNNING_MODE == TEST || RUNNING_MODE == REAL)
|
|
{
|
|
let mut result = crate::coex::order_team::account_information(&client).await; // (/api, Weight(IP) 10)
|
|
loop {
|
|
if result.is_ok() {
|
|
break;
|
|
} else {
|
|
println!("retry account_information()");
|
|
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
|
result = crate::coex::order_team::account_information(&client).await;
|
|
// (/api, Weight(IP) 10)
|
|
}
|
|
}
|
|
update_current_total_usdt().await;
|
|
set_available_usdt().await;
|
|
} else if buy_list_result == false
|
|
&& sell_list_result == false
|
|
&& *previous_result == true
|
|
&& (RUNNING_MODE == SIMUL)
|
|
{
|
|
update_current_total_usdt().await;
|
|
set_is_tradable().await;
|
|
}
|
|
*previous_result = false;
|
|
} else {
|
|
update_realtime_asset().await;
|
|
*previous_result = true;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
// update realtime_expected_total_usdt and realtime_profit
|
|
pub async fn update_realtime_asset() {
|
|
let asset_info = select_asset_manage_announcement().await;
|
|
let scoreboard_list = select_scoreboard().await;
|
|
let scoreboard_short = scoreboard_list.first().unwrap();
|
|
let scoreboard_long = scoreboard_list.last().unwrap();
|
|
|
|
if scoreboard_short.total_number_of_coin != 0 || scoreboard_long.total_number_of_coin != 0 {
|
|
// calculate expect_realtime_asset
|
|
let available_usdt = asset_info.available_usdt.to_f64().unwrap();
|
|
let total_used_usdt = scoreboard_short.total_used_usdt + scoreboard_long.total_used_usdt;
|
|
let current_pos_profit_usdt =
|
|
scoreboard_short.total_pos_profit_usdt + scoreboard_long.total_pos_profit_usdt;
|
|
let current_neg_profit_usdt =
|
|
scoreboard_short.total_neg_profit_usdt + scoreboard_long.total_neg_profit_usdt;
|
|
let expect_realtime_expected_total_usdt =
|
|
available_usdt + total_used_usdt + current_pos_profit_usdt + current_neg_profit_usdt;
|
|
|
|
// calculate realtime_profit
|
|
let mut realtime_profit = 0.0;
|
|
let current_total_usdt = asset_info.current_total_usdt;
|
|
if current_total_usdt.is_zero() {
|
|
realtime_profit = 0.0;
|
|
} else {
|
|
realtime_profit = ((expect_realtime_expected_total_usdt
|
|
/ current_total_usdt.to_f64().unwrap())
|
|
- 1.0)
|
|
* 100.0;
|
|
}
|
|
|
|
// update record
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let update_values = vec![
|
|
(
|
|
String::from("realtime_expected_total_usdt"),
|
|
expect_realtime_expected_total_usdt.to_string(),
|
|
),
|
|
(String::from("realtime_profit"), realtime_profit.to_string()),
|
|
];
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
}
|
|
|
|
// set available_usdt
|
|
pub async fn set_available_usdt() {
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
// fetch current_total_usdt
|
|
let mut asset_info = select_asset_manage_announcement().await;
|
|
|
|
let available_usdt = asset_info.current_total_usdt;
|
|
let unit_trade_usdt = asset_info.unit_trade_usdt;
|
|
|
|
// set available_usdt with current_total_usdt and update is_tradable
|
|
let update_value = {
|
|
if available_usdt > unit_trade_usdt {
|
|
vec![
|
|
(String::from("available_usdt"), available_usdt.to_string()),
|
|
(String::from("is_tradable"), (String::from("1"))),
|
|
]
|
|
} else {
|
|
vec![
|
|
(String::from("available_usdt"), available_usdt.to_string()),
|
|
(String::from("is_tradable"), (String::from("0"))),
|
|
]
|
|
}
|
|
};
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_value, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
// get available_usdt
|
|
pub async fn get_available_usdt() -> Decimal {
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let mut asset_info = select_asset_manage_announcement().await;
|
|
asset_info.available_usdt
|
|
}
|
|
|
|
// add available_usdt
|
|
pub async fn add_available_usdt(add_usdt: Decimal) {
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let mut value_build = String::from("available_usdt + ");
|
|
value_build.push_str(add_usdt.to_string().as_str());
|
|
|
|
let update_values = vec![(String::from("available_usdt"), value_build)];
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
// subtract available_usdt
|
|
pub async fn sub_available_usdt(sub_usdt: Decimal) {
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let mut value_build = String::from("available_usdt - ");
|
|
value_build.push_str(sub_usdt.to_string().as_str());
|
|
|
|
let update_values = vec![(String::from("available_usdt"), value_build)];
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_values, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
// set is_tradable as available_usdt
|
|
pub async fn set_is_tradable() {
|
|
let update_table_name = String::from("asset_manage_announcement");
|
|
let mut asset_info = select_asset_manage_announcement().await;
|
|
let unit_trade_usdt = asset_info.unit_trade_usdt;
|
|
let available_usdt = asset_info.available_usdt;
|
|
|
|
let update_value = {
|
|
if available_usdt > unit_trade_usdt {
|
|
vec![(String::from("is_tradable"), (String::from("1")))]
|
|
} else {
|
|
vec![(String::from("is_tradable"), (String::from("0")))]
|
|
}
|
|
};
|
|
let update_condition = vec![(String::from("id"), String::from("1"))];
|
|
update_record3(&update_table_name, &update_value, &update_condition)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
// get is_tradable
|
|
pub async fn get_is_tradable() -> bool {
|
|
let asset_info = select_asset_manage_announcement().await;
|
|
let is_tradable = asset_info.is_tradable;
|
|
|
|
if asset_info.is_tradable == 1 {
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
pub async fn get_unit_trade_usdt() -> Decimal {
|
|
let asset_info = select_asset_manage_announcement().await;
|
|
asset_info.unit_trade_usdt
|
|
}
|
|
|
|
pub async fn select_asset_manage_announcement() -> AssetInfo {
|
|
let mut asset_info = AssetInfo::new();
|
|
|
|
let table_name = String::from("asset_manage_announcement");
|
|
let columns = String::from("*");
|
|
let condition = None;
|
|
|
|
let select_result = select_record(&table_name, &columns, &condition, &asset_info)
|
|
.await
|
|
.unwrap();
|
|
let result_vec = select_result.first().unwrap();
|
|
|
|
asset_info.initial_usdt = result_vec.initial_usdt;
|
|
asset_info.current_total_usdt = result_vec.current_total_usdt;
|
|
asset_info.profit = result_vec.profit;
|
|
asset_info.realtime_expected_total_usdt = result_vec.realtime_expected_total_usdt;
|
|
asset_info.realtime_profit = result_vec.realtime_profit;
|
|
asset_info.available_usdt = result_vec.available_usdt;
|
|
asset_info.is_tradable = result_vec.is_tradable;
|
|
asset_info.unit_trade_usdt = result_vec.unit_trade_usdt;
|
|
|
|
asset_info
|
|
}
|
|
|
|
// fetch free usdt from wallet
|
|
pub async fn fetch_free_usdt() -> Decimal {
|
|
let wallet_info = WalletInfo::new();
|
|
let select_table_name = {
|
|
if RUNNING_MODE == SIMUL || RUNNING_MODE == REAL {
|
|
String::from("wallet")
|
|
} else {
|
|
String::from("wallet_testnet")
|
|
}
|
|
};
|
|
|
|
let select_columns_name = String::from("*");
|
|
let condition = Some(String::from("WHERE asset = 'USDT'"));
|
|
|
|
let mut select_result = select_record(
|
|
&select_table_name,
|
|
&select_columns_name,
|
|
&condition,
|
|
&wallet_info,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
select_result.first().unwrap().free
|
|
}
|