Fix calculation of profit

This commit is contained in:
Sik Yoon 2024-05-21 00:43:11 +09:00
parent 26e32279eb
commit 970971e005
5 changed files with 17 additions and 79 deletions

View File

@ -132,7 +132,6 @@ pub struct PositionCoinList {
pub entry_price: Decimal, pub entry_price: Decimal,
pub current_price: Decimal, pub current_price: Decimal,
pub base_qty_ordered: Decimal, pub base_qty_ordered: Decimal,
pub base_qty_fee_adjusted: Decimal,
pub pure_profit_percent: f64, pub pure_profit_percent: f64,
pub minimum_profit_percent: f64, pub minimum_profit_percent: f64,
pub maximum_profit_percent: f64, pub maximum_profit_percent: f64,
@ -156,7 +155,6 @@ impl PositionCoinList {
entry_price: Decimal::new(0, 8), entry_price: Decimal::new(0, 8),
current_price: Decimal::new(0, 8), current_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8), base_qty_ordered: Decimal::new(0, 8),
base_qty_fee_adjusted: Decimal::new(0, 8),
pure_profit_percent: 0.0, pure_profit_percent: 0.0,
minimum_profit_percent: 0.0, minimum_profit_percent: 0.0,
maximum_profit_percent: 0.0, maximum_profit_percent: 0.0,

View File

@ -78,34 +78,12 @@ pub async fn entry_position(
RoundingStrategy::ToZero, RoundingStrategy::ToZero,
); );
let mut base_qty_fee_adjusted = Decimal::new(0, 8);
base_qty_fee_adjusted =
decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee))
.round_dp_with_strategy(
base_asset_precision,
RoundingStrategy::ToZero,
);
let mut used_usdt = Decimal::new(0, 8); let mut used_usdt = Decimal::new(0, 8);
used_usdt = decimal_mul(base_qty_ordered, entry_price) used_usdt = decimal_mul(base_qty_ordered, entry_price)
.round_dp_with_strategy( .round_dp_with_strategy(
tick_size.normalize().scale(), tick_size.normalize().scale(),
RoundingStrategy::ToZero, RoundingStrategy::ToZero,
); );
// let expected_pure_profit_percent: f64 = decimal_sub(
// decimal_div(
// decimal_mul(base_qty_fee_adjusted, entry_price)
// .round_dp_with_strategy(
// tick_size.normalize().scale(),
// RoundingStrategy::ToZero,
// ),
// used_usdt,
// ),
// dec!(1),
// )
// .to_f64()
// .unwrap()
// * 100.0;
// order the symbol based on base_qty_ordered and current_price // order the symbol based on base_qty_ordered and current_price
limit_order_entry( limit_order_entry(
@ -116,7 +94,6 @@ pub async fn entry_position(
entry_price, entry_price,
base_qty_ordered, base_qty_ordered,
used_usdt, used_usdt,
&base_qty_fee_adjusted.to_string(),
&client, &client,
) )
.await; .await;
@ -137,7 +114,6 @@ pub async fn limit_order_entry(
order_price: Decimal, order_price: Decimal,
order_quantity: Decimal, order_quantity: Decimal,
used_usdt: Decimal, used_usdt: Decimal,
simul_base_qty_fee_adjusted: &String,
client: &Client, client: &Client,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let update_table_name = String::from("future_ordered_coin_list"); let update_table_name = String::from("future_ordered_coin_list");
@ -152,7 +128,6 @@ pub async fn limit_order_entry(
(String::from("entry_price"), order_price.to_string()), (String::from("entry_price"), order_price.to_string()),
(String::from("current_price"), order_price.to_string()), (String::from("current_price"), order_price.to_string()),
(String::from("base_qty_ordered"), order_quantity.to_string()), (String::from("base_qty_ordered"), order_quantity.to_string()),
(String::from("base_qty_fee_adjusted"), simul_base_qty_fee_adjusted.to_string())
]; ];
let update_condition = vec![(String::from("id"), entry_coin_info.id.to_string())]; let update_condition = vec![(String::from("id"), entry_coin_info.id.to_string())];
@ -244,8 +219,6 @@ pub async fn limit_order_entry(
T.get("origQty").unwrap().as_str().unwrap(), T.get("origQty").unwrap().as_str().unwrap(),
) )
.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( let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str(
T.get("cumQuote").unwrap().as_str().unwrap(), T.get("cumQuote").unwrap().as_str().unwrap(),
@ -262,7 +235,6 @@ pub async fn limit_order_entry(
update_values.push((String::from("used_usdt"), cummulative_quote_qty.to_string())); update_values.push((String::from("used_usdt"), cummulative_quote_qty.to_string()));
update_values.push((String::from("entry_price"), entry_price.to_string())); update_values.push((String::from("entry_price"), entry_price.to_string()));
update_values.push((String::from("base_qty_ordered"), base_qty_ordered.to_string())); update_values.push((String::from("base_qty_ordered"), base_qty_ordered.to_string()));
update_values.push((String::from("base_qty_fee_adjusted"), base_qty_fee_adjusted.to_string()));
// reflect available_usdt in [asset_manage_announcement] // reflect available_usdt in [asset_manage_announcement]
// sub_available_usdt(cummulative_quote_qty).await; // sub_available_usdt(cummulative_quote_qty).await;
@ -407,8 +379,6 @@ pub async fn cancel_open_positioning_order(
) )
.unwrap(); .unwrap();
let base_qty_fee_adjusted =
decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee));
let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered) let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered)
.round_dp_with_strategy(8, RoundingStrategy::ToZero); .round_dp_with_strategy(8, RoundingStrategy::ToZero);
@ -416,14 +386,7 @@ pub async fn cancel_open_positioning_order(
(String::from("status"), String::from("FILLED")), // status (String::from("status"), String::from("FILLED")), // status
(String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt (String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt
(String::from("buy_price"), buy_price.to_string()), // buy_price (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_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![ let update_condition = vec![
(String::from("order_id"), order.order_id.to_string()), (String::from("order_id"), order.order_id.to_string()),
@ -515,8 +478,6 @@ pub async fn query_open_positioning_order(
T.get("executedQty").unwrap().as_str().unwrap(), T.get("executedQty").unwrap().as_str().unwrap(),
) )
.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( let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str(
T.get("cumQuote").unwrap().as_str().unwrap(), T.get("cumQuote").unwrap().as_str().unwrap(),
@ -530,14 +491,7 @@ pub async fn query_open_positioning_order(
(String::from("status"), value_build), // status (String::from("status"), value_build), // status
(String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt (String::from("used_usdt"), cummulative_quote_qty.to_string()), // used_usdt
(String::from("buy_price"), buy_price.to_string()), // buy_price (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_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![ let update_condition = vec![
(String::from("order_id"), order.order_id.to_string()), (String::from("order_id"), order.order_id.to_string()),

View File

@ -194,43 +194,32 @@ async fn update_repeat_task(
.get(&element.symbol) .get(&element.symbol)
.unwrap() .unwrap()
.quote_precision; .quote_precision;
let base_qty_to_be_ordered = element.base_qty_fee_adjusted.round_dp_with_strategy( let position_size = element.base_qty_ordered.round_dp_with_strategy(
lot_step_size.normalize().scale(), lot_step_size.normalize().scale(),
RoundingStrategy::ToZero, RoundingStrategy::ToZero,
); );
let expected_get_usdt = decimal_mul( let entry_trade_fee = decimal_mul(decimal_mul(position_size, element.entry_price), trade_fee);
decimal_mul(base_qty_to_be_ordered, price).round_dp_with_strategy( let exit_trade_fee = decimal_mul(decimal_mul(position_size, element.current_price), trade_fee);
quote_precision, let fee_total = decimal_add(entry_trade_fee, exit_trade_fee);
RoundingStrategy::ToZero, let initial_margin = decimal_add(decimal_mul(position_size, element.entry_price), entry_trade_fee);
),
decimal_sub(dec!(1), trade_fee),
);
// TODO: sell_count >=1 이면 expected_get_usdt 는 한번만 tradefee만 적용하여 업데이트 할 것. 현재는 수수료를 2번 (매수,매도)를 계산함. 아래 변수에 든 값으로 업데이트 하면 됨 let mut profit = Decimal::new(0, 8);
// let expected_get_usdt =
// decimal_mul(base_qty_to_be_ordered, price).round_dp_with_strategy(
// quote_commission_precision,
// RoundingStrategy::ToZero,
// );
let mut pure_profit_percent;
if element.position.contains("Long") { if element.position.contains("Long") {
pure_profit_percent = ((expected_get_usdt.to_f64().unwrap() profit = decimal_sub(decimal_sub(element.current_price, element.entry_price),fee_total);
/ element.used_usdt.to_f64().unwrap())
- 1.0)
* 100.0;
} else { } else {
pure_profit_percent = ((expected_get_usdt.to_f64().unwrap() profit = decimal_sub(decimal_sub(element.entry_price, element.current_price),fee_total);
/ element.used_usdt.to_f64().unwrap())
- 1.0)
* -100.0;
} }
let mut pure_profit_percent = (profit.to_f64().unwrap()
/ initial_margin.to_f64().unwrap())
* 100.0;
pure_profit_percent = (pure_profit_percent * 100.0).round() / 100.0; // Rounding pure_profit_percent = (pure_profit_percent * 100.0).round() / 100.0; // Rounding
update_record_build.push(element.id.to_string()); // id update_record_build.push(element.id.to_string()); // id
update_record_build.push(price.to_string()); // current_price 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_add(profit, element.used_usdt).to_string()); //expected_get_usdt
update_record_build update_record_build.push(profit.to_string()); // expected_usdt_profit
.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 update_record_build.push(pure_profit_percent.to_string()); // pure_profit_percent
if element.minimum_profit_percent > pure_profit_percent { if element.minimum_profit_percent > pure_profit_percent {

View File

@ -1317,7 +1317,6 @@ async fn initialize_database() {
("entry_price", "decimal(16,8)", None), ("entry_price", "decimal(16,8)", None),
("current_price", "decimal(16,8)", None), ("current_price", "decimal(16,8)", None),
("base_qty_ordered", "decimal(16,8)", None), ("base_qty_ordered", "decimal(16,8)", None),
("base_qty_fee_adjusted", "decimal(16,8)", None),
("pure_profit_percent", "double", None), ("pure_profit_percent", "double", None),
("minimum_profit_percent", "double", None), ("minimum_profit_percent", "double", None),
("maximum_profit_percent", "double", None), ("maximum_profit_percent", "double", None),

View File

@ -156,7 +156,6 @@ pub async fn insert_future_coins(
"entry_price", "entry_price",
"current_price", "current_price",
"base_qty_ordered", "base_qty_ordered",
"base_qty_fee_adjusted",
"pure_profit_percent", "pure_profit_percent",
"minimum_profit_percent", "minimum_profit_percent",
"maximum_profit_percent", "maximum_profit_percent",
@ -178,7 +177,6 @@ pub async fn insert_future_coins(
0.0.to_string(), // entry_price 0.0.to_string(), // entry_price
0.0.to_string(), // current_price 0.0.to_string(), // current_price
0.0.to_string(), // base_qty_ordered 0.0.to_string(), // base_qty_ordered
0.0.to_string(), // base_qty_fee_adjusted
0.0.to_string(), // pure_profit_percent 0.0.to_string(), // pure_profit_percent
0.0.to_string(), // minimum_profit_percent 0.0.to_string(), // minimum_profit_percent
0.0.to_string(), // maximum_profit_percent 0.0.to_string(), // maximum_profit_percent