Parcourir la source

完成bitget部分

gepangpang il y a 2 ans
Parent
commit
858aa2fa14

+ 45 - 50
exchange_data_formatter/src/bitget_handle.rs

@@ -199,35 +199,29 @@ pub(crate) fn handle_swap_market(data: String, symbol: String) -> Market {
 }
 
 /// Bitget交易所行情信息请求数据结构
-/// - 接口`"/api/v2/spot/trade/orderInfo"`
+/// - 接口`"/api/v2/spot/trade/orderInfo`
 ///
-/// struct SwapOrder
-/// `id`: i128, 合约订单 ID
-/// `create_time`: i64, 订单创建时间
-/// `finish_time`: Option<i64>, 订单结束时间,未结束订单无此字段返回
-/// `finish_as`: String, 结束方式(filled: 完全成交、cancelled: 用户撤销、liquidated: 强制平仓撤销、ioc: 未立即完全成交,因为tif设置为ioc、auto_deleveraged: 自动减仓撤销、reduce_only: 增持仓位撤销,因为设置reduce_only或平仓、position_closed: 因为仓位平掉了,所以挂单被撤掉、reduce_out: 只减仓被排除的不容易成交的挂单、stp: 订单发生自成交限制而被撤销)
-/// `status`: String, 订单状态(open: 等待处理、finished: 已结束的订单)
-/// `contract`: String, 合约标识
-/// `size`: Decimal, 必选。交易数量,正数为买入,负数为卖出。平仓委托则设置为0
-/// `iceberg`: Decimal, 冰山委托显示数量。0为完全不隐藏。注意,隐藏部分成交按照taker收取手续费
-/// `price`:Decimal, 委托价。价格为0并且tif为ioc,代表市价委托
-/// `close`: bool, 	设置为 true 的时候执行平仓操作,并且size应设置为0
-/// `is_close`: bool, 是否为平仓委托。对应请求中的close
-/// `reduce_only`: bool, 设置为 true 的时候,为只减仓委托
-/// `is_reduce_only`: bool, 是否为只减仓委托。对应请求中的reduce_only
-/// `is_liq`: bool, 是否为强制平仓委托
-/// `tif`: String, Time in force 策略,市价单当前只支持 ioc 模式(gtc: GoodTillCancelled、ioc: ImmediateOrCancelled,立即成交或者取消,只吃单不挂单、poc: PendingOrCancelled,被动委托,只挂单不吃单、fok: FillOrKill, 完全成交,或者完全取消)
-/// `left`: Decimal, 未成交数量
-/// `fill_price`: Decimal, 成交价
-/// `text`: String, 订单自定义信息,用户可以用该字段设置自定义 ID,用户自定义字段必须满足以下条件:(1. 必须以 t- 开头、2. 不计算 t- ,长度不能超过 28 字节、3. 输入内容只能包含数字、字母、下划线(_)、中划线(-) 或者点(.))
-/// `tkfr`: Decimal, 吃单费率
-/// `mkfr`: Decimal, 做单费率
-/// `auto_size`: String,双仓模式下用于设置平仓的方向,close_long 平多头, close_short 平空头,需要同时设置 size 为 0
-/// `stp_id`: i64, 订单所属的STP用户组id,同一个STP用户组内用户之间的订单不允许发生自成交。
-/// `stp_act`: String, Self-Trading Prevention Action,用户可以用该字段设置自定义限制自成交策略。
-/// `amend_text`: String 用户修改订单时备注的信息
-#[derive(Debug, Deserialize, Serialize)]
-struct SwapOrder {
+/// struct SpotOrder
+/// - `user_id`: String, 账户id
+/// - `symbol`: String, 交易对名称
+/// - `order_id`: String, 订单ID
+/// - `client_oid`: String, 自定义ID
+/// - `price`: Decimal, 委托价格
+/// - `size`: Decimal, 委托数量
+/// - `order_type`: String, 订单类型
+/// - `side`: String, 交易方向
+/// - `status`: String, 订单状态
+/// - `price_avg`:  Decimal, 成交价格
+/// - `base_volume`:  Decimal, 成交数量,左币
+/// - `quote_volume`:  Decimal, 成交总额,右币
+/// - `enter_point_source`: String, 订单来源
+/// - `fee_detail`: String, 手续费明细
+/// - `order_source`: String, 订单来源
+/// - `c_time`: i64, 创建时间,Unix毫秒时间戳
+/// - `u_time`: i64, 更新时间,Unix毫秒时间戳
+#[derive(Debug, Deserialize, Serialize, Clone)]
+#[serde(rename_all = "camelCase")]
+struct SpotOrder {
     user_id: String,
     symbol: String,
     order_id: String,
@@ -237,40 +231,41 @@ struct SwapOrder {
     order_type: String,
     side: String,
     status: String,
-    price_avg:  Decimal,
-    base_volume:  Decimal,
-    quote_volume:  Decimal,
+    price_avg: Decimal,
+    base_volume: Decimal,
+    quote_volume: Decimal,
     enter_point_source: String,
     fee_detail: String,
     order_source: String,
-    c_time: i64,
-    u_time: i64,
+    c_time: String,
+    u_time: String,
 }
 
 /// 处理合约订单信息
 ///
-/// pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order;
+/// pub(crate) fn handle_spot_order(data: String, ct_val: Decimal) -> Order;
 ///
 /// - `data`:String, 交易所返回账户信息,JsonString
-/// - `amount_size`:Decimal, 张数价值
-pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order {
-    let order_info: SwapOrder = serde_json::from_str(&data).unwrap();
-    let custom_status = match order_info.status.as_str() {
-        "finished" => { "REMOVE".to_string() }
-        "open" => { "NEW".to_string() }
-        _ => {
-            error!("Gate:格式化订单状态错误!\nhandle_swap_order:status={:?}", order_info.status);
-            panic!("Gate:格式化订单状态错误!\nhandle_swap_order:status={:?}", order_info.status)
-        }
+/// - `ct_val`:Decimal, 张数价值
+pub(crate) fn handle_spot_order(data: String, ct_val: Decimal) -> Order {
+    let order_info_list: Vec<SpotOrder> = serde_json::from_str(&data).unwrap();
+    let order_info = order_info_list[0].clone();
+
+    let custom_status = if ["filled", "cancelled"].contains(&order_info.status.as_str()) {
+        "REMOVE".to_string()
+    } else if ["init", "live", "new", "partially_filled"].contains(&order_info.status.as_str()) {
+        "NEW".to_string()
+    } else {
+        "NULL".to_string()
     };
     Order {
-        id: order_info.id.to_string(),
-        custom_id: order_info.text.replace("t-my-custom-id_", ""),
+        id: order_info.order_id,
+        custom_id: order_info.client_oid,
         price: order_info.price,
-        amount: order_info.size * amount_size,
-        deal_amount: (order_info.size - order_info.left) * amount_size,
-        avg_price: order_info.fill_price,
+        amount: order_info.size * ct_val,
+        deal_amount: order_info.base_volume * ct_val,
+        avg_price: order_info.price_avg,
         status: custom_status,
-        order_type: "limit".to_string(),
+        order_type: order_info.order_type,
     }
 }

+ 9 - 9
exchange_data_formatter/src/gate_handle.rs

@@ -145,12 +145,12 @@ struct SwapPosition {
 
 /// 处理合约仓位信息
 ///
-/// pub(crate) fn handle_swap_position(data: String, symbol: String, amount_size: Decimal) -> Vec<Position>;
+/// pub(crate) fn handle_swap_position(data: String, symbol: String, ct_val: Decimal) -> Vec<Position>;
 ///
 /// - `data`:String, 交易所返回账户信息,JsonString
 /// - `symbol`:String, 交易币对
-/// - `amount_size`:Decimal, 张数价值
-pub(crate) fn handle_swap_position(data: String, _symbol: String, amount_size: Decimal) -> Vec<Position> {
+/// - `ct_val`:Decimal, 张数价值
+pub(crate) fn handle_swap_position(data: String, _symbol: String, ct_val: Decimal) -> Vec<Position> {
     let position_info_list: Vec<SwapPosition> = serde_json::from_str(&data).unwrap();
     position_info_list.iter().map(|item| {
         let position_mode = match item.mode.as_str() {
@@ -165,7 +165,7 @@ pub(crate) fn handle_swap_position(data: String, _symbol: String, amount_size: D
         Position {
             symbol: item.contract.clone(),
             margin_level: item.leverage,
-            amount: item.size * amount_size,
+            amount: item.size * ct_val,
             frozen_amount: dec!(0),
             price: item.entry_price,
             profit: item.unrealised_pnl,
@@ -428,11 +428,11 @@ struct SwapOrder {
 
 /// 处理合约订单信息
 ///
-/// pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order;
+/// pub(crate) fn handle_swap_order(data: String, ct_val: Decimal) -> Order;
 ///
 /// - `data`:String, 交易所返回账户信息,JsonString
-/// - `amount_size`:Decimal, 张数价值
-pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order {
+/// - `ct_val`:Decimal, 张数价值
+pub(crate) fn handle_swap_order(data: String, ct_val: Decimal) -> Order {
     let order_info: SwapOrder = serde_json::from_str(&data).unwrap();
     let custom_status = match order_info.status.as_str() {
         "finished" => { "REMOVE".to_string() }
@@ -446,8 +446,8 @@ pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order {
         id: order_info.id.to_string(),
         custom_id: order_info.text.replace("t-my-custom-id_", ""),
         price: order_info.price,
-        amount: order_info.size * amount_size,
-        deal_amount: (order_info.size - order_info.left) * amount_size,
+        amount: order_info.size * ct_val,
+        deal_amount: (order_info.size - order_info.left) * ct_val,
         avg_price: order_info.fill_price,
         status: custom_status,
         order_type: "limit".to_string(),

+ 10 - 10
exchange_data_formatter/src/kucoin_handle.rs

@@ -139,12 +139,12 @@ struct SwapPosition {
 
 /// 处理合约仓位信息
 ///
-/// pub(crate) fn handle_swap_position(data: String, symbol: String, amount_size: Decimal) -> Vec<Position>;
+/// pub(crate) fn handle_swap_position(data: String, symbol: String, ct_val: Decimal) -> Vec<Position>;
 ///
 /// - `data`:String, 交易所返回账户信息,JsonString
 /// - `symbol`:String, 交易币对
-/// - `amount_size`:Decimal, 张数价值
-pub(crate) fn handle_swap_position(data: String, symbol: String, amount_size: Decimal) -> Vec<Position> {
+/// - `ct_val`:Decimal, 张数价值
+pub(crate) fn handle_swap_position(data: String, symbol: String, ct_val: Decimal) -> Vec<Position> {
     let exchange_symbol = utils::symbol_mapper(KucoinSwapRest, &symbol);
     let position_info: SwapPosition = serde_json::from_str(&data).unwrap();
     let coin = position_info.symbol[..symbol.find(&position_info.settle_currency).unwrap() - 1].to_string();
@@ -152,11 +152,11 @@ pub(crate) fn handle_swap_position(data: String, symbol: String, amount_size: De
     vec![Position {
         symbol: format!("{}_{}", base_asset, position_info.settle_currency),
         margin_level: position_info.real_leverage,
-        amount: position_info.current_qty * amount_size,
+        amount: position_info.current_qty * ct_val,
         frozen_amount: dec!(0),
         price: position_info.avg_entry_price,
         profit: position_info.unrealised_pnl,
-        position_mode: if position_info.current_qty * amount_size > dec!(0) { PositionModeEnum::Long } else { PositionModeEnum::Short },
+        position_mode: if position_info.current_qty * ct_val > dec!(0) { PositionModeEnum::Long } else { PositionModeEnum::Short },
         margin: position_info.pos_margin,
     }]
 }
@@ -448,15 +448,15 @@ struct SwapOrder {
 
 /// 处理合约订单信息
 ///
-/// pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order;
+/// pub(crate) fn handle_swap_order(data: String, ct_val: Decimal) -> Order;
 ///
 /// - `data`:String, 交易所返回账户信息,JsonString
-/// - `amount_size`:Decimal, 张数价值
-pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order {
+/// - `ct_val`:Decimal, 张数价值
+pub(crate) fn handle_swap_order(data: String, ct_val: Decimal) -> Order {
     let order_info: SwapOrder = serde_json::from_str(&data).unwrap();
 
     let status = order_info.status;
-    let deal_amount = order_info.filled_size * amount_size;
+    let deal_amount = order_info.filled_size * ct_val;
     let avg_price = if deal_amount.is_zero() { dec!(0) } else { order_info.filled_value / deal_amount };
     let custom_status = match status.as_str() {
         "open" => { "NEW".to_string() }
@@ -473,7 +473,7 @@ pub(crate) fn handle_swap_order(data: String, amount_size: Decimal) -> Order {
         id: order_info.id,
         custom_id: order_info.client_oid,
         price: order_info.price,
-        amount: order_info.size * amount_size,
+        amount: order_info.size * ct_val,
         deal_amount,
         avg_price,
         status: custom_status,

+ 11 - 8
exchange_data_formatter/src/lib.rs

@@ -271,16 +271,16 @@ impl Exchange {
             }
         }
     }
-    pub fn handle_position(&self, data: String, amount_size: Decimal) -> Vec<Position> {
+    pub fn handle_position(&self, data: String, ct_val: Decimal) -> Vec<Position> {
         match self.exchange_enum {
             ExchangeEnum::BinanceSwapRest => {
-                binance_handle::handle_swap_position(data, self.symbol.clone(), amount_size)
+                binance_handle::handle_swap_position(data, self.symbol.clone(), ct_val)
             }
             ExchangeEnum::GateSwapRest => {
-                gate_handle::handle_swap_position(data, self.symbol.clone(), amount_size)
+                gate_handle::handle_swap_position(data, self.symbol.clone(), ct_val)
             }
             ExchangeEnum::KucoinSwapRest => {
-                kucoin_handle::handle_swap_position(data, self.symbol.clone(), amount_size)
+                kucoin_handle::handle_swap_position(data, self.symbol.clone(), ct_val)
             }
             _ => {
                 panic!()
@@ -325,16 +325,19 @@ impl Exchange {
             }
         }
     }
-    pub fn handle_order(&self, data: String, amount_size: Decimal) -> Order {
+    pub fn handle_order(&self, data: String, ct_val: Decimal) -> Order {
         match self.exchange_enum {
             ExchangeEnum::BinanceSwapRest => {
-                binance_handle::handle_swap_order(data, amount_size)
+                binance_handle::handle_swap_order(data, ct_val)
             }
             ExchangeEnum::GateSwapRest => {
-                gate_handle::handle_swap_order(data, amount_size)
+                gate_handle::handle_swap_order(data, ct_val)
             }
             ExchangeEnum::KucoinSwapRest => {
-                kucoin_handle::handle_swap_order(data, amount_size)
+                kucoin_handle::handle_swap_order(data, ct_val)
+            }
+            ExchangeEnum::BitgetSpotRest => {
+                bitget_handle::handle_swap_order(data, ct_val)
             }
             _ => {
                 panic!()

+ 13 - 0
exchange_data_formatter/tests/bitget_handle_test.rs

@@ -38,4 +38,17 @@ async fn test_handle_market() {
     let exchange = Exchange::new(ExchangeEnum::BitgetSpotRest, "BLZ_USDT".to_string());
     let result = exchange.handle_market(data.to_string());
     trace!(?result);
+}
+
+// 测试获取订单信息
+#[tokio::test]
+#[instrument(level = "TRACE")]
+async fn test_handle_order() {
+    global::log_utils::init_log_with_trace();
+
+    let data = "[{\"userId\":\"3198287736\",\"symbol\":\"BLZUSDT\",\"orderId\":\"1101704049840279552\",\"clientOid\":\"9999990\",\"price\":\"0.2100000000000000\",\"size\":\"30.0000000000000000\",\"orderType\":\"limit\",\"side\":\"buy\",\"status\":\"live\",\"priceAvg\":\"0\",\"baseVolume\":\"0.0000000000000000\",\"quoteVolume\":\"0.0000000000000000\",\"enterPointSource\":\"API\",\"feeDetail\":\"\",\"orderSource\":\"normal\",\"cTime\":\"1698392634830\",\"uTime\":\"1698392634830\"}]";
+
+    let exchange = Exchange::new(ExchangeEnum::BitgetSpotRest, "BLZ_USDT".to_string());
+    let result = exchange.handle_order(data.to_string(), dec!(1));
+    trace!(?result);
 }

+ 1 - 0
standard/src/bitget_spot.rs

@@ -257,6 +257,7 @@ impl Platform for BitgetSpot {
         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();
+            println!("{}", res_data_str);
             let order_info = res_data_json[0].clone();
             let result = bitget_spot_handle::format_order_item(order_info, ct_val);
             Ok(result)

+ 3 - 3
standard/tests/bitget_spot_test.rs

@@ -146,7 +146,7 @@ async fn test_get_order_detail() {
     global::log_utils::init_log_with_trace();
 
     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-    let bitget_get_order_detail = bitget_swap_exchange.get_order_detail("", "999998").await;
+    let bitget_get_order_detail = bitget_swap_exchange.get_order_detail("1101704049840279552", "").await;
     trace!(?bitget_get_order_detail);
 }
 
@@ -168,7 +168,7 @@ async fn test_take_order() {
     global::log_utils::init_log_with_trace();
 
     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-    let bitget_take_order = bitget_swap_exchange.take_order("999996", "kd", dec!(0.15), dec!(40)).await;
+    let bitget_take_order = bitget_swap_exchange.take_order("9999990", "kd", dec!(0.21), dec!(30)).await;
     trace!(?bitget_take_order);
 }
 
@@ -179,7 +179,7 @@ async fn test_cancel_order() {
     global::log_utils::init_log_with_trace();
 
     let mut bitget_swap_exchange: Box<dyn Platform> = test_new_exchange(ExchangeEnum::BitgetSpot, SYMBOL).await;
-    let bitget_cancel_order = bitget_swap_exchange.cancel_order("", "999997").await;
+    let bitget_cancel_order = bitget_swap_exchange.cancel_order("", "9999990").await;
     trace!(?bitget_cancel_order);
 }