Implement closing position
This commit is contained in:
parent
1337a78d73
commit
5e5f0cbc05
|
|
@ -88,8 +88,6 @@ pub async fn entry_position(
|
|||
// order the symbol based on base_qty_ordered and current_price
|
||||
limit_order_entry(
|
||||
&element,
|
||||
futures_exchange_info_map,
|
||||
trade_fee,
|
||||
TimeInForce::Gtc,
|
||||
entry_price,
|
||||
base_qty_ordered,
|
||||
|
|
@ -108,8 +106,6 @@ pub async fn entry_position(
|
|||
|
||||
pub async fn limit_order_entry(
|
||||
entry_coin_info: &PositionCoinList,
|
||||
exchange_info_map: &HashMap<String, FuturesExchangeInfo>,
|
||||
trade_fee: Decimal,
|
||||
tif: TimeInForce,
|
||||
order_price: Decimal,
|
||||
order_quantity: Decimal,
|
||||
|
|
@ -136,7 +132,7 @@ pub async fn limit_order_entry(
|
|||
|
||||
sub_future_available_usdt(used_usdt).await;
|
||||
|
||||
println!("SIMUL {} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
println!("SIMUL positining {} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
} else {
|
||||
// building URL and API-keys
|
||||
let mut url = String::new();
|
||||
|
|
@ -209,10 +205,148 @@ pub async fn limit_order_entry(
|
|||
update_values.push((String::from("status"), String::from("NEW")));
|
||||
} else if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
|
||||
update_values.push((String::from("status"), String::from("FILLED")));
|
||||
println!("{} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
println!("positioning {} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
} else if T.get("status").unwrap().as_str().unwrap() == "PARTIALLY_FILLED" {
|
||||
update_values.push((String::from("status"), String::from("PARTIALLY_FILLED")));
|
||||
println!("Partially filled {} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
println!("positioning {} {} (Partially filled)", entry_coin_info.position, entry_coin_info.symbol);
|
||||
}
|
||||
|
||||
let base_qty_ordered = rust_decimal::prelude::FromStr::from_str(
|
||||
T.get("origQty").unwrap().as_str().unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str(
|
||||
T.get("cumQuote").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 entry_price = decimal_div(cummulative_quote_qty, base_qty_ordered)
|
||||
.round_dp_with_strategy(8, RoundingStrategy::ToZero);
|
||||
|
||||
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("base_qty_ordered"), base_qty_ordered.to_string()));
|
||||
|
||||
// reflect available_usdt in [asset_manage_announcement]
|
||||
// sub_available_usdt(cummulative_quote_qty).await;
|
||||
sub_future_available_usdt(cummulative_quote_qty).await;
|
||||
|
||||
let update_condition = vec![(String::from("id"), entry_coin_info.id.to_string())];
|
||||
update_record2(&update_table_name, &update_values, &update_condition)
|
||||
.await.unwrap();
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::warn!("order failed!: {}", body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn limit_order_close(
|
||||
entry_coin_info: &PositionCoinList,
|
||||
tif: TimeInForce,
|
||||
order_price: Decimal,
|
||||
order_quantity: Decimal,
|
||||
client: &Client,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let update_table_name = String::from("future_ordered_coin_list");
|
||||
let server_epoch = get_server_epoch().await;
|
||||
unsafe {
|
||||
if RUNNING_MODE == SIMUL {
|
||||
let mut update_values = vec![
|
||||
(String::from("order_type"), String::from("CLOSING")),
|
||||
(String::from("status"), String::from("FILLED")),
|
||||
];
|
||||
|
||||
let update_condition = vec![(String::from("id"), entry_coin_info.id.to_string())];
|
||||
update_record2(&update_table_name, &update_values, &update_condition)
|
||||
.await.unwrap();
|
||||
|
||||
println!("SIMUL closed {} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
|
||||
} else {
|
||||
// building URL and API-keys
|
||||
let mut url = String::new();
|
||||
let mut api_key = String::new();
|
||||
if RUNNING_MODE == TEST {
|
||||
url.push_str(FUTURES_URL_TEST);
|
||||
api_key = API_KEY_TESTNET.to_string();
|
||||
} else {
|
||||
url.push_str(FUTURES_URL);
|
||||
api_key = API_KEY.to_string();
|
||||
}
|
||||
|
||||
let endpoint_url = "/fapi/v1/order?";
|
||||
url.push_str(endpoint_url);
|
||||
|
||||
let mut url_build = String::new();
|
||||
|
||||
// add parameters into URL
|
||||
url_build.push_str("&symbol=");
|
||||
url_build.push_str(&entry_coin_info.symbol);
|
||||
if entry_coin_info.position.contains("Long") {
|
||||
url_build.push_str("&side=SELL");
|
||||
} else {
|
||||
url_build.push_str("&side=BUY");
|
||||
}
|
||||
url_build.push_str("&type=LIMIT");
|
||||
url_build.push_str("&quantity=");
|
||||
url_build.push_str(order_quantity.to_string().as_str());
|
||||
url_build.push_str("&price=");
|
||||
url_build.push_str(order_price.to_string().as_str());
|
||||
match tif {
|
||||
TimeInForce::Gtc => {
|
||||
url_build.push_str("&timeInForce=GTC");
|
||||
}
|
||||
TimeInForce::Ioc => {
|
||||
url_build.push_str("&timeInForce=IOC");
|
||||
}
|
||||
TimeInForce::Fok => {
|
||||
url_build.push_str("&timeInForce=FOK");
|
||||
}
|
||||
}
|
||||
|
||||
hmac_signature(&mut url_build).await;
|
||||
url.push_str(&url_build);
|
||||
|
||||
let res = client
|
||||
.post(&url)
|
||||
.header("X-MBX-APIKEY", api_key)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let body = res.text_with_charset("utf-8").await.unwrap();
|
||||
// deserialize JSON and then insert record into table
|
||||
let v = serde_json::from_str::<Value>(body.as_str());
|
||||
|
||||
match v {
|
||||
Ok(T) => {
|
||||
if T.get("code").is_some() { // when request failed
|
||||
} else {
|
||||
// when request succeed
|
||||
let mut update_values = vec![];
|
||||
update_values.push((String::from("order_type"), (String::from("CLOSING"))));
|
||||
update_values.push((String::from("order_id"), T.get("orderId").unwrap().as_u64().unwrap().to_string()));
|
||||
update_values.push((String::from("transact_time"), server_epoch.to_string()));
|
||||
|
||||
// status
|
||||
if T.get("status").unwrap().as_str().unwrap() == "NEW" {
|
||||
update_values.push((String::from("status"), String::from("NEW")));
|
||||
} else if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
|
||||
update_values.push((String::from("status"), String::from("FILLED")));
|
||||
println!("Closed {} {}", entry_coin_info.position, entry_coin_info.symbol);
|
||||
} else if T.get("status").unwrap().as_str().unwrap() == "PARTIALLY_FILLED" {
|
||||
update_values.push((String::from("status"), String::from("PARTIALLY_FILLED")));
|
||||
println!("Closing {} {} (Partially filled)", entry_coin_info.position, entry_coin_info.symbol);
|
||||
}
|
||||
|
||||
let base_qty_ordered = rust_decimal::prelude::FromStr::from_str(
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use super::{
|
|||
|
||||
use crate::future::{Position, FuturesExchangeInfo};
|
||||
use crate::future::table_mgmt::select_filled_positions;
|
||||
use crate::future::order::{limit_order_close, TimeInForce};
|
||||
|
||||
// BUY conditions
|
||||
pub async fn list_up_for_buy(
|
||||
|
|
@ -74,68 +75,48 @@ pub async fn list_up_for_buy(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// pub async fn list_up_for_sell(
|
||||
// all_data: &AllData,
|
||||
// exchange_info_map: &HashMap<String, ExchangeInfo>,
|
||||
// trade_fee_map: &HashMap<String, TradeFee>,
|
||||
// ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
// let filled_positions = select_filled_positions().await?;
|
||||
pub async fn list_up_for_sell() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let filled_positions = select_filled_positions().await?;
|
||||
|
||||
// let client = ClientBuilder::new()
|
||||
// .timeout(tokio::time::Duration::from_millis(5000))
|
||||
// .build()
|
||||
// .unwrap();
|
||||
// let server_epoch = get_server_epoch().await;
|
||||
let client = ClientBuilder::new()
|
||||
.timeout(tokio::time::Duration::from_millis(5000))
|
||||
.build()
|
||||
.unwrap();
|
||||
let server_epoch = get_server_epoch().await;
|
||||
|
||||
// for element in filled_positions {
|
||||
// let mut is_sell = false;
|
||||
for element in filled_positions {
|
||||
let mut is_sell = false;
|
||||
|
||||
// if element.used_usdt >= dec!(10.0) {
|
||||
// if let (Some(exchange_info), Some(tradefee)) = (
|
||||
// exchange_info_map.get(&element.symbol),
|
||||
// trade_fee_map.get(&element.symbol),
|
||||
// ) {
|
||||
// let lot_step_size = exchange_info.stepsize;
|
||||
// let quote_commission_precision = exchange_info.quote_commission_precision;
|
||||
// TODO: BNB 코인이 있으면
|
||||
// let base_qty_to_be_ordered =
|
||||
// element.base_qty_ordered.round_dp_with_strategy(
|
||||
// lot_step_size.normalize().scale(),
|
||||
// RoundingStrategy::ToZero,
|
||||
// );
|
||||
// TODO: BNB 코인이 없으면
|
||||
|
||||
// // TODO: BNB 코인이 있으면
|
||||
// // let base_qty_to_be_ordered =
|
||||
// // element.base_qty_ordered.round_dp_with_strategy(
|
||||
// // lot_step_size.normalize().scale(),
|
||||
// // RoundingStrategy::ToZero,
|
||||
// // );
|
||||
// // TODO: BNB 코인이 없으면
|
||||
// let base_qty_to_be_ordered =
|
||||
// element.base_qty_fee_adjusted.round_dp_with_strategy(
|
||||
// lot_step_size.normalize().scale(),
|
||||
// RoundingStrategy::ToZero,
|
||||
// );
|
||||
if !element.current_price.is_zero() {
|
||||
if element.pure_profit_percent >= 1.0 {
|
||||
is_sell = true;
|
||||
} else if element.pure_profit_percent <= -1.0 {
|
||||
is_sell = true;
|
||||
} else if server_epoch - element.transact_time >= (1_800_000) * 1 {
|
||||
// time up selling
|
||||
is_sell = true;
|
||||
}
|
||||
|
||||
// if !element.current_price.is_zero() {
|
||||
// if element.pure_profit_percent >= 1.0 {
|
||||
// is_sell = true;
|
||||
// } else if element.pure_profit_percent <= -0.8 {
|
||||
// is_sell = true;
|
||||
// } else if server_epoch - element.transact_time >= (1_800_000) * 1 {
|
||||
// // time up selling
|
||||
// is_sell = true;
|
||||
// }
|
||||
if is_sell == true {
|
||||
limit_order_close(
|
||||
&element,
|
||||
TimeInForce::Gtc,
|
||||
element.current_price,
|
||||
element.base_qty_ordered,
|
||||
&client
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if is_sell == true {
|
||||
// limit_order_sell(
|
||||
// &element,
|
||||
// element.current_price,
|
||||
// base_qty_to_be_ordered,
|
||||
// &client,
|
||||
// &exchange_info_map,
|
||||
// &trade_fee_map,
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ pub async fn execute_list_up_for_buy(
|
|||
// crate::strategy_team::strategy_005::list_up_for_buy(all_data).await;
|
||||
// crate::strategy_team::strategy_006::list_up_for_buy(all_data).await;
|
||||
// crate::strategy_team::strategy_007::list_up_for_buy(all_data).await;
|
||||
crate::strategy_team::strategy_008::list_up_for_buy(all_data).await;
|
||||
crate::strategy_team::strategy_009::list_up_for_buy(all_data).await;
|
||||
// crate::strategy_team::strategy_008::list_up_for_buy(all_data).await;
|
||||
// crate::strategy_team::strategy_009::list_up_for_buy(all_data).await;
|
||||
crate::strategy_team::future_strategy::list_up_for_buy(all_data, &future_exchange_info_map).await;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -70,20 +70,20 @@ pub async fn execute_list_up_for_sell(
|
|||
// &trade_fee_map,
|
||||
// )
|
||||
// .await;
|
||||
crate::strategy_team::strategy_008::list_up_for_sell(
|
||||
&all_data,
|
||||
&exchange_info_map,
|
||||
&trade_fee_map,
|
||||
)
|
||||
.await;
|
||||
|
||||
crate::strategy_team::strategy_009::list_up_for_sell(
|
||||
&all_data,
|
||||
&exchange_info_map,
|
||||
&trade_fee_map,
|
||||
)
|
||||
.await;
|
||||
// crate::strategy_team::strategy_008::list_up_for_sell(
|
||||
// &all_data,
|
||||
// &exchange_info_map,
|
||||
// &trade_fee_map,
|
||||
// )
|
||||
// .await;
|
||||
|
||||
// crate::strategy_team::strategy_009::list_up_for_sell(
|
||||
// &all_data,
|
||||
// &exchange_info_map,
|
||||
// &trade_fee_map,
|
||||
// )
|
||||
// .await;
|
||||
crate::strategy_team::future_strategy::list_up_for_sell().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user