|
|
@@ -88,8 +88,8 @@ impl Platform for KucoinSwap {
|
|
|
if res_data.code == "200" {
|
|
|
let res_data_str = &res_data.data;
|
|
|
let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
|
|
|
- let balance = res_data_json["accountEquity"].to_string().parse().unwrap_or(dec!(0));
|
|
|
- let available_balance = res_data_json["availableBalance"].to_string().parse().unwrap_or(dec!(0));
|
|
|
+ let balance = Decimal::from_str(&res_data_json["accountEquity"].to_string()).unwrap();
|
|
|
+ let available_balance = Decimal::from_str(&res_data_json["availableBalance"].to_string()).unwrap();
|
|
|
let frozen_balance = balance - available_balance;
|
|
|
let result = Account {
|
|
|
balance,
|
|
|
@@ -143,12 +143,12 @@ impl Platform for KucoinSwap {
|
|
|
let time = (Decimal::from_str(&*ticker_info["ts"].to_string()).unwrap() / dec!(1000000)).floor().to_i64().unwrap();
|
|
|
let result = Ticker {
|
|
|
time,
|
|
|
- high: ticker_info["bestAskPrice"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- low: ticker_info["bestBidPrice"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- sell: ticker_info["bestAskPrice"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- buy: ticker_info["bestBidPrice"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- last: ticker_info["price"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- volume: ticker_info["size"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
+ high: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
|
|
|
+ low: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
|
|
|
+ sell: Decimal::from_str(ticker_info["bestAskPrice"].as_str().unwrap()).unwrap(),
|
|
|
+ buy: Decimal::from_str(ticker_info["bestBidPrice"].as_str().unwrap()).unwrap(),
|
|
|
+ last: Decimal::from_str(ticker_info["price"].as_str().unwrap()).unwrap(),
|
|
|
+ volume: Decimal::from_str(&ticker_info["size"].to_string()).unwrap(),
|
|
|
};
|
|
|
Ok(result)
|
|
|
} else {
|
|
|
@@ -162,28 +162,36 @@ impl Platform for KucoinSwap {
|
|
|
if res_data.code == "200" {
|
|
|
let res_data_str = &res_data.data;
|
|
|
let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
|
|
|
- let default_info = json!({});
|
|
|
- let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format).unwrap_or(&default_info);
|
|
|
- let tick_size = market_info["tickSize"].to_string().parse().unwrap_or(dec!(0));
|
|
|
- let amount_size = market_info["multiplier"].to_string().parse().unwrap_or(dec!(0));
|
|
|
- let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
|
|
|
- let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
|
|
|
+ let market_info = res_data_json.iter().find(|item| item["symbol"].as_str().unwrap() == symbol_format);
|
|
|
+ match market_info {
|
|
|
+ None => {
|
|
|
+ panic!("Kucoin:获取Market信息错误!\nget_market:res_data={}", res_data_str)
|
|
|
+ }
|
|
|
+ Some(value) => {
|
|
|
+ let base_asset = value["baseCurrency"].as_str().unwrap_or("").to_string();
|
|
|
+ let quote_asset = value["quoteCurrency"].as_str().unwrap_or("").to_string();
|
|
|
+ let tick_size = Decimal::from_str(&value["tickSize"].to_string()).unwrap();
|
|
|
+ let amount_size = Decimal::from_str(&value["multiplier"].to_string()).unwrap();
|
|
|
+ let price_precision = Decimal::from_u32(tick_size.scale()).unwrap();
|
|
|
+ let amount_precision = Decimal::from_u32(amount_size.scale()).unwrap();
|
|
|
|
|
|
- let result = Market {
|
|
|
- symbol: self.symbol.clone(),
|
|
|
- base_asset: market_info["baseCurrency"].as_str().unwrap_or("").to_string(),
|
|
|
- quote_asset: market_info["quoteCurrency"].as_str().unwrap_or("").to_string(),
|
|
|
- tick_size: market_info["tickSize"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- amount_size: market_info["multiplier"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- price_precision,
|
|
|
- amount_precision,
|
|
|
- min_qty: market_info["lotSize"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- max_qty: market_info["maxOrderQty"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- min_notional: Default::default(),
|
|
|
- max_notional: market_info["maxPrice"].to_string().parse().unwrap_or(dec!(0)),
|
|
|
- ct_val: Default::default(),
|
|
|
- };
|
|
|
- Ok(result)
|
|
|
+ let result = Market {
|
|
|
+ symbol: format!("{}_{}", base_asset, quote_asset),
|
|
|
+ base_asset,
|
|
|
+ quote_asset,
|
|
|
+ tick_size,
|
|
|
+ amount_size,
|
|
|
+ price_precision,
|
|
|
+ amount_precision,
|
|
|
+ min_qty: Decimal::from_str(&value["lotSize"].to_string()).unwrap(),
|
|
|
+ max_qty: Decimal::from_str(&value["maxOrderQty"].to_string()).unwrap(),
|
|
|
+ min_notional: Default::default(),
|
|
|
+ max_notional: Decimal::from_str(&value["maxPrice"].to_string()).unwrap(),
|
|
|
+ ct_val: Default::default(),
|
|
|
+ };
|
|
|
+ Ok(result)
|
|
|
+ }
|
|
|
+ }
|
|
|
} else {
|
|
|
Err(Error::new(ErrorKind::Other, res_data.message))
|
|
|
}
|
|
|
@@ -195,7 +203,7 @@ impl Platform for KucoinSwap {
|
|
|
if res_data.code == "200" {
|
|
|
let res_data_str = &res_data.data;
|
|
|
let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
|
|
|
- let result = kucoin_handle::format_order_item(res_data_json, amount_size);
|
|
|
+ let result = format_order_item(res_data_json, amount_size);
|
|
|
Ok(result)
|
|
|
} else {
|
|
|
Err(Error::new(ErrorKind::Other, res_data.message))
|
|
|
@@ -210,25 +218,13 @@ impl Platform for KucoinSwap {
|
|
|
let res_data_str = &res_data.data;
|
|
|
let res_data_json: Vec<serde_json::Value> = serde_json::from_str(res_data_str).unwrap();
|
|
|
let order_info: Vec<&serde_json::Value> = res_data_json.iter().filter(|item| item["contract"].as_str().unwrap_or("") == self.symbol.clone()).collect();
|
|
|
- let result = order_info.iter().map(|&item| kucoin_handle::format_order_item(item.clone(), amount_size)).collect();
|
|
|
+ let result = order_info.iter().map(|&item| format_order_item(item.clone(), amount_size)).collect();
|
|
|
Ok(result)
|
|
|
} else {
|
|
|
Err(Error::new(ErrorKind::Other, res_data.message))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> {
|
|
|
- todo!()
|
|
|
- }
|
|
|
-
|
|
|
- async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> {
|
|
|
- todo!()
|
|
|
- }
|
|
|
-
|
|
|
- async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> {
|
|
|
- todo!()
|
|
|
- }
|
|
|
-
|
|
|
async fn take_order(&mut self, custom_id: &str, origin_side: &str, price: Decimal, amount: Decimal) -> Result<Order, Error> {
|
|
|
let symbol_format = format!("{}M", utils::format_symbol(self.symbol.clone(), ""));
|
|
|
let amount_size = self.market.amount_size;
|
|
|
@@ -260,7 +256,7 @@ impl Platform for KucoinSwap {
|
|
|
if res_data.code == "200" {
|
|
|
let res_data_str = &res_data.data;
|
|
|
let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
|
|
|
- let result = kucoin_handle::format_order_item(res_data_json, amount_size);
|
|
|
+ let result = format_order_item(res_data_json, amount_size);
|
|
|
Ok(result)
|
|
|
} else {
|
|
|
Err(Error::new(ErrorKind::Other, res_data.message))
|
|
|
@@ -273,16 +269,20 @@ impl Platform for KucoinSwap {
|
|
|
if res_data.code == "200" {
|
|
|
let res_data_str = &res_data.data;
|
|
|
let res_data_json: serde_json::Value = serde_json::from_str(res_data_str).unwrap();
|
|
|
- let result = kucoin_handle::format_order_item(res_data_json, amount_size);
|
|
|
+ let result = format_order_item(res_data_json, amount_size);
|
|
|
Ok(result)
|
|
|
} else {
|
|
|
Err(Error::new(ErrorKind::Other, res_data.message))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> {
|
|
|
- todo!()
|
|
|
- }
|
|
|
+ async fn cancel_orders(&mut self) -> Result<Vec<Order>, Error> { todo!() }
|
|
|
+
|
|
|
+ async fn set_dual_mode(&mut self, _coin: &str, _is_dual_mode: bool) -> Result<String, Error> { todo!() }
|
|
|
+
|
|
|
+ async fn set_dual_leverage(&mut self, _leverage: &str) -> Result<String, Error> { todo!() }
|
|
|
+
|
|
|
+ async fn wallet_transfers(&mut self, _coin: &str, _from: &str, _to: &str, _amount: Decimal) -> Result<String, Error> { todo!() }
|
|
|
|
|
|
// 指令下单
|
|
|
async fn command_order(&mut self, order_command: OrderCommand) {
|
|
|
@@ -368,3 +368,26 @@ impl Platform for KucoinSwap {
|
|
|
let _: Result<Vec<_>, _> = futures.try_collect().await;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+pub fn format_order_item(order: serde_json::Value, amount_size: Decimal) -> Order {
|
|
|
+ let price = Decimal::from_str(order["price"].as_str().unwrap()).unwrap();
|
|
|
+ let size = Decimal::from_str(&order["size"].to_string()).unwrap();
|
|
|
+ let status = order["status"].as_str().unwrap_or("");
|
|
|
+ let filled_size = Decimal::from_str(&order["filledSize"].to_string()).unwrap();
|
|
|
+ let filled_value = Decimal::from_str(&order["filledValue"].to_string()).unwrap();
|
|
|
+
|
|
|
+ let amount = size * amount_size;
|
|
|
+ let deal_amount = filled_size * amount_size;
|
|
|
+ let avg_price = if deal_amount.is_zero() { dec!(0) } else { filled_value / deal_amount };
|
|
|
+ let custom_status = if ["done", "match"].contains(&status) { "REMOVE".to_string() } else if status == "open" { "NEW".to_string() } else { panic!("Kucoin:格式化订单状态错误!\nformat_order_item:status={}", status); };
|
|
|
+ Order {
|
|
|
+ id: order["id"].as_str().unwrap().to_string(),
|
|
|
+ custom_id: order["clientOid"].as_str().unwrap().to_string(),
|
|
|
+ price,
|
|
|
+ amount,
|
|
|
+ deal_amount,
|
|
|
+ avg_price,
|
|
|
+ status: custom_status,
|
|
|
+ order_type: order["type"].as_str().unwrap().to_string(),
|
|
|
+ }
|
|
|
+}
|