|
|
@@ -5,7 +5,7 @@ use tokio::sync::mpsc::Sender;
|
|
|
use async_trait::async_trait;
|
|
|
use rust_decimal::Decimal;
|
|
|
use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
|
|
|
-use serde_json::json;
|
|
|
+use serde_json::{json};
|
|
|
use futures::stream::FuturesUnordered;
|
|
|
use futures::{TryStreamExt};
|
|
|
use tracing::{error, debug, trace};
|
|
|
@@ -483,12 +483,83 @@ impl Platform for GateSwap {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async fn take_stop_loss_order(&mut self, _stop_price: Decimal, _price: Decimal, _side: &str) -> Result<String, Error> {
|
|
|
- todo!()
|
|
|
+ async fn take_stop_loss_order(&mut self, stop_price: Decimal, price: Decimal, side: &str) -> Result<String, Error>
|
|
|
+ {
|
|
|
+ let mut params = json!({});
|
|
|
+ let mut initial = json!({
|
|
|
+ "contract": "XRP_USDT",
|
|
|
+
|
|
|
+ "price": price.to_string(),
|
|
|
+
|
|
|
+ "tif": "ioc",
|
|
|
+
|
|
|
+ // 是否只减仓
|
|
|
+ "reduce_only": true,
|
|
|
+
|
|
|
+ // [平多:close_long, 平空:close_short]
|
|
|
+ // "auto_size": "close_long"
|
|
|
+ });
|
|
|
+ let mut trigger = json!({
|
|
|
+ // [平多:close-long-position, 平空:close-short-position]
|
|
|
+ // "order_type": "close-long-position",
|
|
|
+
|
|
|
+ // 一般都默认用0
|
|
|
+ "strategy_type": 0,
|
|
|
+
|
|
|
+ // [0 - 最新成交价,1 - 标记价格,2 - 指数价格]
|
|
|
+ "price_type": 0,
|
|
|
+
|
|
|
+ // [1: 引用价格大于等于我们传的价格,2:引用价格小于等于我们传的价格]
|
|
|
+ // 在止损的情况下:
|
|
|
+ // 1 可以理解为向上突破触发价(一般是给空单用)
|
|
|
+ // 2 可以理解为向下突破触发价(一般是给多单用)
|
|
|
+ // "rule": 2,
|
|
|
+
|
|
|
+ // 订单触发价格
|
|
|
+ "price": stop_price.to_string(),
|
|
|
+ });
|
|
|
+
|
|
|
+ match side {
|
|
|
+ "kd" => {
|
|
|
+ initial["auto_size"] = json!("close_long");
|
|
|
+ trigger["order_type"] = json!("close-long-position");
|
|
|
+ trigger["rule"] = json!(2);
|
|
|
+ },
|
|
|
+ "kk" => {
|
|
|
+ initial["auto_size"] = json!("close_short");
|
|
|
+ trigger["order_type"] = json!("close-short-position");
|
|
|
+ trigger["rule"] = json!(1);
|
|
|
+ },
|
|
|
+ _ => {
|
|
|
+ error!("gate swap 止损单side错误: {}", side);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ params["initial"] = initial;
|
|
|
+ params["trigger"] = trigger;
|
|
|
+
|
|
|
+ let binding = self.symbol.clone().to_lowercase();
|
|
|
+ let symbol_split: Vec<&str> = binding.split("_").collect();
|
|
|
+ let base_coin = symbol_split[1].to_string();
|
|
|
+ let response_data = self.request.place_price_order(base_coin, params).await;
|
|
|
+ if response_data.code == "200" {
|
|
|
+ Ok(response_data.data)
|
|
|
+ } else {
|
|
|
+ Err(Error::new(ErrorKind::Other, response_data.to_string()))
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- async fn cancel_stop_loss_order(&mut self, _order_id: &str) -> Result<String, Error> {
|
|
|
- todo!()
|
|
|
+ async fn cancel_stop_loss_order(&mut self, order_id: &str) -> Result<String, Error> {
|
|
|
+ let binding = self.symbol.clone().to_lowercase();
|
|
|
+ let symbol_split: Vec<&str> = binding.split("_").collect();
|
|
|
+ let base_coin = symbol_split[1].to_string();
|
|
|
+
|
|
|
+ let response_data = self.request.cancel_price_order(base_coin, order_id.to_string()).await;
|
|
|
+ if response_data.code == "200" {
|
|
|
+ Ok(response_data.data)
|
|
|
+ } else {
|
|
|
+ Err(Error::new(ErrorKind::Other, response_data.to_string()))
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 设置持仓模式
|