|
|
@@ -1107,35 +1107,59 @@ impl Quant {
|
|
|
}
|
|
|
|
|
|
#[instrument(skip(self, target_hold_coin), level="TRACE")]
|
|
|
- pub async fn check_position(&mut self, target_hold_coin: Decimal) {
|
|
|
- info!("清空挂单!");
|
|
|
+ pub async fn check_position(&mut self, target_hold_coin: Decimal) -> bool {
|
|
|
+ let mut is_clear = false;
|
|
|
+
|
|
|
+ info!("------------------------------------------------------------------------------------------------------------");
|
|
|
+ info!("步骤一:检查挂单:");
|
|
|
match self.platform_rest.cancel_orders_all().await {
|
|
|
Ok(val) => {
|
|
|
- info!("清空所有挂单,{:?}", val);
|
|
|
+ let length = val.len();
|
|
|
+ is_clear = length == 0;
|
|
|
+
|
|
|
+ info!("已清空所有挂单({}条)", length);
|
|
|
+
|
|
|
+ for o in val {
|
|
|
+ info!(" {:?}", o);
|
|
|
+ }
|
|
|
}
|
|
|
Err(err) => {
|
|
|
- error!("取消所有订单异常: {}",err);
|
|
|
+ warn!("取消所有订单异常({}),启动备用方法。", err);
|
|
|
+
|
|
|
match self.platform_rest.cancel_orders().await {
|
|
|
Ok(val) => {
|
|
|
- info!("清空当前币对挂单,{:?}", val);
|
|
|
+ let length = val.len();
|
|
|
+ is_clear = length == 0;
|
|
|
+
|
|
|
+ info!("清空所有挂单({}条):{:?}", length, val);
|
|
|
}
|
|
|
Err(exc) => {
|
|
|
- error!("清空当前币对订单异常: {}",exc);
|
|
|
+ error!("清空当前币对订单异常: {}", exc);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ info!("挂单检查完毕。");
|
|
|
+ info!("");
|
|
|
+
|
|
|
+ info!("步骤二:检查仓位:");
|
|
|
if self.exchange.contains("spot") { // 现货
|
|
|
- self.check_position_spot(target_hold_coin).await;
|
|
|
+ is_clear = is_clear && (self.check_position_spot(target_hold_coin.clone()).await == 0);
|
|
|
+ info!("检查遗漏仓位(现货),目标持仓:{}USDT", target_hold_coin);
|
|
|
} else { // 合约
|
|
|
- self.check_position_swap().await;
|
|
|
+ is_clear = is_clear && (self.check_position_swap().await == 0);
|
|
|
+ info!("遗漏仓位检查完毕(合约)!");
|
|
|
}
|
|
|
- info!("遗留仓位检测完毕");
|
|
|
+ info!("------------------------------------------------------------------------------------------------------------");
|
|
|
+ info!("");
|
|
|
+
|
|
|
+ return is_clear;
|
|
|
}
|
|
|
|
|
|
#[instrument(skip(self, target_hold_coin), level="TRACE")]
|
|
|
- pub async fn check_position_spot(&mut self, target_hold_coin: Decimal) {
|
|
|
- info!("---------------------------检查遗漏仓位(现货),目标持仓:{}USDT---------------------------", target_hold_coin);
|
|
|
+ pub async fn check_position_spot(&mut self, target_hold_coin: Decimal) -> usize {
|
|
|
+ let mut length = 0;
|
|
|
+
|
|
|
match self.platform_rest.get_spot_account().await {
|
|
|
Ok(mut val) => {
|
|
|
// 如果返回的数组里没有交易货币,则补充交易货币
|
|
|
@@ -1180,8 +1204,13 @@ impl Quant {
|
|
|
// price = mp*0.999;
|
|
|
amount = -diff / mp;
|
|
|
} else {
|
|
|
+ // 不需要调整说明没有仓位了。
|
|
|
+
|
|
|
continue;
|
|
|
}
|
|
|
+ // 需要调整说明有仓位。
|
|
|
+ length = 1;
|
|
|
+
|
|
|
info!(?ticker);
|
|
|
info!("需要调整现货仓位 {}USDT(目标:{}USDT) 共计{}{}。", diff, _hold_coin, amount, coin_name);
|
|
|
let mut ts = TraceStack::default();
|
|
|
@@ -1217,18 +1246,23 @@ impl Quant {
|
|
|
}
|
|
|
}
|
|
|
info!("---------------------------遗漏仓位检查完毕(现货)!-----------------------------------");
|
|
|
+
|
|
|
+ return length;
|
|
|
}
|
|
|
|
|
|
#[instrument(skip(self), level="TRACE")]
|
|
|
- pub async fn check_position_swap(&mut self) {
|
|
|
- info!("---------------------------检查遗漏仓位(合约)!-----------------------------------");
|
|
|
+ pub async fn check_position_swap(&mut self) -> usize {
|
|
|
+ let mut length = 0;
|
|
|
match self.platform_rest.get_positions().await {
|
|
|
Ok(val) => {
|
|
|
+ info!("检查仓位信息({}条仓位信息,部分交易所会返回0持仓的):", length);
|
|
|
+
|
|
|
for position in val {
|
|
|
if position.amount.eq(&Decimal::ZERO) {
|
|
|
continue;
|
|
|
}
|
|
|
- info!("仓位获取到:{:?}", position);
|
|
|
+ length = length + 1;
|
|
|
+ info!(" 仓位:{:?}", position);
|
|
|
match self.platform_rest.get_ticker_symbol(position.symbol.clone()).await {
|
|
|
Ok(ticker) => {
|
|
|
let ap = ticker.sell;
|
|
|
@@ -1243,7 +1277,7 @@ impl Quant {
|
|
|
market_info = market;
|
|
|
}
|
|
|
Err(err) => {
|
|
|
- error!("{} 获取当前market异常: {}", position.symbol.clone(), err);
|
|
|
+ error!(" {} 获取当前market异常: {}", position.symbol.clone(), err);
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
@@ -1260,7 +1294,7 @@ impl Quant {
|
|
|
side = "pk";
|
|
|
}
|
|
|
_ => {
|
|
|
- info!("仓位position_mode匹配失败,不做操作!");
|
|
|
+ error!(" 仓位position_mode匹配失败,不做操作!");
|
|
|
// 执行完当前币对 结束循环
|
|
|
continue;
|
|
|
}
|
|
|
@@ -1272,29 +1306,32 @@ impl Quant {
|
|
|
match self.platform_rest.take_order_symbol(position.symbol.clone(), Decimal::ONE, utils::generate_client_id(None).as_str(), side, price, position.amount.abs()).await {
|
|
|
Ok(order) => {
|
|
|
ts.on_after_send();
|
|
|
- info!("{}仓位清除下单成功 {:?}, {}", position.symbol.clone(), order, ts.to_string());
|
|
|
+ info!(" {}仓位清除下单成功 {:?}, {}", position.symbol.clone(), order, ts.to_string());
|
|
|
// 执行完当前币对 结束循环
|
|
|
continue;
|
|
|
}
|
|
|
Err(error) => {
|
|
|
ts.on_after_send();
|
|
|
- error!("{}仓位清除下单异常 {}, {}", position.symbol.clone(), error, ts.to_string());
|
|
|
+ error!(" {}仓位清除下单异常 {}, {}", position.symbol.clone(), error, ts.to_string());
|
|
|
// 执行完当前币对 结束循环
|
|
|
continue;
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
Err(err) => {
|
|
|
- error!("{} 获取当前ticker异常: {}", position.symbol.clone(), err)
|
|
|
+ error!(" {} 获取当前ticker异常: {}", position.symbol.clone(), err)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Err(error) => {
|
|
|
+ length = 0;
|
|
|
+
|
|
|
error!("获取仓位信息异常: {}", error);
|
|
|
}
|
|
|
}
|
|
|
- info!("---------------------------遗漏仓位检查完毕(合约)!-----------------------------------");
|
|
|
+
|
|
|
+ return length
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1323,24 +1360,23 @@ impl Quant {
|
|
|
// info!("退出进程!");
|
|
|
}
|
|
|
|
|
|
- #[instrument(skip(self, delay), level="TRACE")]
|
|
|
- pub async fn exit(&mut self, delay: i8) {
|
|
|
- info!("--------------------------------------------------");
|
|
|
- info!("预约退出操作 delay:{}", delay);
|
|
|
- if delay > 0i8 {
|
|
|
- sleep(Duration::from_secs(delay as u64)).await;
|
|
|
+ #[instrument(skip(self), level="TRACE")]
|
|
|
+ pub async fn exit(&mut self) {
|
|
|
+ info!("-------------------------启动退出流程----------------------------");
|
|
|
+ info!("");
|
|
|
+
|
|
|
+ // 循环清空仓位,如若彻底清空,才进行退出。
|
|
|
+ let mut clear_count = 1;
|
|
|
+ while !self.check_position(Decimal::ZERO).await {
|
|
|
+ sleep(Duration::from_secs(1)).await;
|
|
|
+
|
|
|
+ clear_count += 1;
|
|
|
+ info!("清理指令发送完毕,启动第{}次检查。", clear_count);
|
|
|
+ info!("");
|
|
|
}
|
|
|
- info!("开始退出操作");
|
|
|
- info!("为避免api失效导致遗漏仓位 建议人工复查");
|
|
|
- self.check_position(Decimal::ZERO).await;
|
|
|
- sleep(Duration::from_secs(2)).await;
|
|
|
- info!("双重检查遗漏仓位");
|
|
|
- self.check_position(Decimal::ZERO).await;
|
|
|
- info!("停机退出 停机原因: {}", self.exit_msg);
|
|
|
- // 发送交易状态 await self._post_params()
|
|
|
- // TODO: 向中控发送信号
|
|
|
- self.running.store(false, Ordering::Relaxed);
|
|
|
- info!("退出进程!");
|
|
|
+
|
|
|
+ info!("订单、仓位清除完毕,为避免api失效导致遗漏仓位,建议人工复查。");
|
|
|
+ info!("停机原因:{}。", self.exit_msg);
|
|
|
}
|
|
|
|
|
|
#[instrument(skip(self), level="TRACE")]
|