Эх сурвалжийг харах

bitmart逻辑接入 待测试

JiahengHe 1 жил өмнө
parent
commit
ab2f26c752

+ 5 - 8
exchanges/src/bitmart_swap_rest.rs

@@ -251,14 +251,14 @@ impl BitMartSwapRest {
         }
 
         //请求头配置-如果需要登录则存在额外配置
-        let mut body = "".to_string();
+        let body;
         let mut headers = HeaderMap::new();
         headers.insert("Content-Type", "application/json".parse().unwrap());
 
         let timestamp = Utc::now().timestamp_millis().to_string();
         // let timestamp = "1589793796145".to_string();
 
-        let mut params_str = params.to_string();
+        let params_str = params.to_string();
         // let mut params_str =  json!({
         //     "count":"100","price":"8600","symbol":"BTC_USDT"
         // }).to_string();
@@ -268,14 +268,13 @@ impl BitMartSwapRest {
             body = params_str.clone();
         }
         //是否需要登录-- 组装sing
-        let mut sing = "".to_string();
         if is_login {
             if !is_login_param {
                 let e = ResponseData::error(self.label.clone(), "登录参数错误!".to_string());
                 return e;
             } else {//需要登录-且登录参数齐全
                 //组装sing
-                sing = Self::sign(secret_key.clone(),
+                let sing = Self::sign(secret_key.clone(),
                                   api_memo.clone(),
                                   params_str.clone(),
                                   timestamp.clone(),
@@ -370,8 +369,6 @@ impl BitMartSwapRest {
         // return  ResponseData::new(self.label.clone(), 200, "success".to_string(), json_value);
 
         let code = json_value["code"].as_i64();
-        let message = json_value["message"].as_str();
-        let trace = json_value["trace"].as_str();
         match code {
             Some(c) => {
                 if c == 1000 {
@@ -392,10 +389,10 @@ impl BitMartSwapRest {
         let json_value = serde_json::from_str::<Value>(&text);
         match json_value {
             Ok(d) => {
-                ResponseData::new(self.label.clone(), 400, format!("错误:{}", d["message"].as_str().unwrap()), d)
+                ResponseData::new(self.label.clone(), 400, format!("base_url {} params {} 错误:{} ", base_url, params, d["message"].as_str().unwrap()), d)
             }
             Err(_) => {
-                ResponseData::new(self.label.clone(), 400, format!("未知错误"), text.parse().unwrap())
+                ResponseData::new(self.label.clone(), 400, "未知错误".to_string(), text.parse().unwrap())
             }
         }
     }

+ 5 - 7
standard/src/bitmart_swap.rs

@@ -187,7 +187,6 @@ impl Platform for BitmartSwap {
 
     async fn get_market_symbol(&mut self, symbol: String) -> Result<Market, Error> {
         let symbol_format = utils::format_symbol(symbol.clone(), "");
-        let symbol_array: Vec<&str> = self.symbol.split("_").collect();
 
         let params = json!({
             "symbol": symbol_format,
@@ -231,7 +230,7 @@ impl Platform for BitmartSwap {
         Ok(result)
     }
 
-    async fn get_order_detail(&mut self, order_id: &str, custom_id: &str) -> Result<Order, Error> {
+    async fn get_order_detail(&mut self, order_id: &str, _custom_id: &str) -> Result<Order, Error> {
         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
         let ct_val = self.market.ct_val;
 
@@ -250,7 +249,7 @@ impl Platform for BitmartSwap {
         Ok(result)
     }
 
-    async fn get_orders_list(&mut self, status: &str) -> Result<Vec<Order>, Error> {
+    async fn get_orders_list(&mut self, _status: &str) -> Result<Vec<Order>, Error> {
         let symbol_format = utils::format_symbol(self.symbol.clone(), "");
         let ct_val = self.market.ct_val;
 
@@ -278,7 +277,7 @@ impl Platform for BitmartSwap {
         let final_size = (amount / ct_val).floor();
         let mut params = json!({
             "symbol": symbol_format,
-            "client_order_id": custom_id.clone(),
+            "client_order_id": custom_id,
             "open_type": "cross",
             "size": Decimal::to_i64(&final_size).unwrap(),
             "leverage": "10"
@@ -340,9 +339,8 @@ impl Platform for BitmartSwap {
             return Err(Error::new(ErrorKind::NotFound, format!("bitmart_swap 取消订单异常{:?}", response).to_string()));
         }
 
-        let res_data_json = response.data;
-        let mut id = order_id.to_string();
-        let mut custom_id = custom_id.to_string();
+        let id = order_id.to_string();
+        let custom_id = custom_id.to_string();
         let result = Order {
             id,
             custom_id,

+ 0 - 1
standard/src/bitmart_swap_handle.rs

@@ -4,7 +4,6 @@ use rust_decimal::Decimal;
 use rust_decimal::prelude::FromPrimitive;
 use rust_decimal_macros::dec;
 use tokio::time::Instant;
-use tracing::trace;
 use exchanges::response_base::ResponseData;
 use global::trace_stack::TraceStack;
 use crate::{Account, MarketOrder, Order, Position, PositionModeEnum, SpecialDepth, SpecialOrder, SpecialTicker};

+ 1 - 1
standard/src/handle_info.rs

@@ -4,7 +4,7 @@ use rust_decimal::{Decimal};
 use rust_decimal::prelude::FromPrimitive;
 use rust_decimal_macros::dec;
 use serde_json::json;
-use tracing::{error, info, trace};
+use tracing::{error, info};
 use exchanges::response_base::ResponseData;
 use global::public_params;
 use crate::exchange::ExchangeEnum;

+ 187 - 0
strategy/src/bitmart_usdt_swap.rs

@@ -0,0 +1,187 @@
+use std::collections::BTreeMap;
+use std::sync::Arc;
+use std::sync::atomic::AtomicBool;
+use rust_decimal::Decimal;
+use tokio::spawn;
+use tokio::sync::Mutex;
+use tracing::{error, info};
+use exchanges::bitmart_swap_ws::{BitMartSwapLogin, BitMartSwapSubscribeType, BitMartSwapWs, BitMartSwapWsType};
+use exchanges::response_base::ResponseData;
+use global::trace_stack::TraceStack;
+use standard::exchange::ExchangeEnum::{BitmartSwap};
+use standard::{Position, PositionModeEnum};
+use crate::core::Core;
+use crate::exchange_disguise::on_special_depth;
+use crate::model::OrderInfo;
+
+pub async fn bitmart_usdt_swap_run(is_shutdown_arc :Arc<AtomicBool>,
+                                  is_trade: bool,
+                                  core_arc: Arc<Mutex<Core>>,
+                                  name: String,
+                                  symbols: Vec<String>,
+                                  _is_colo: bool,
+                                  exchange_params: BTreeMap<String, String>) {
+    // 开启公共频道
+    let (write_tx_public, write_rx_public) = futures_channel::mpsc::unbounded();
+
+    // 开启公共连接
+    let is_shutdown_arc_c1 = is_shutdown_arc.clone();
+    let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
+    let name_clone = name.clone();
+    let core_arc_clone = core_arc.clone();
+    let symbols_clone = symbols.clone();
+    spawn(async move {
+        // 构建链接ws
+        let mut bg_public = BitMartSwapWs::new_label(name_clone.clone(),
+                                                    None,
+                                                    BitMartSwapWsType::Public);
+
+        // 消费数据的函数
+        let mut update_flag_u = Decimal::ZERO;
+        let fun = move |data: ResponseData| {
+            let core_arc_cc = core_arc_clone.clone();
+
+            async move {
+                on_public_data(core_arc_cc, &mut update_flag_u, data).await
+            }
+        };
+
+        // 准备链接
+        bg_public.set_subscribe(vec![BitMartSwapSubscribeType::PuFuturesTicker]); // 只用订阅ticker数据
+        bg_public.set_symbols(symbols_clone);
+        bg_public.ws_connect_async(is_shutdown_arc_c1, fun, &write_tx_am_public, write_rx_public).await.expect("bitmart_usdt_swap 链接有异常")
+    });
+
+    // 不需要交易就不用开启私有频道了
+    if !is_trade {
+        return;
+    }
+
+    // 开启私有频道
+    let (write_tx_private, write_rx_private) = futures_channel::mpsc::unbounded();
+
+    // 开启公共连接
+    let is_shutdown_arc_c1 = is_shutdown_arc.clone();
+    let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
+    spawn(async move {
+        // 构建链接ws
+        let mut bg_private = BitMartSwapWs::new_label(name.clone(),
+                                                     Some(parse_btree_map_to_bitmart_swap_login(exchange_params)),
+                                                     BitMartSwapWsType::Private);
+
+        // 消费数据的函数
+        let core_arc_clone = core_arc.clone();
+        let run_symbol = symbols[0].clone();
+        let ct_val = core_arc_clone.lock().await.platform_rest.get_self_market().ct_val;
+        let fun = move |data: ResponseData| {
+            let core_arc_cc = core_arc_clone.clone();
+            let run_symbol_c = run_symbol.clone();
+
+            async move {
+                on_private_data(core_arc_cc, ct_val, data, &run_symbol_c).await
+            }
+        };
+
+        // 准备链接
+        bg_private.set_subscribe(vec![
+            BitMartSwapSubscribeType::PrFuturesOrders,
+            BitMartSwapSubscribeType::PrFuturesBalances,
+            BitMartSwapSubscribeType::PrFuturesPositions
+        ]);
+        bg_private.set_symbols(symbols.clone());
+        bg_private.ws_connect_async(is_shutdown_arc_c1, fun, &write_tx_am_private, write_rx_private).await.expect("bitmart_usdt_swap 链接有异常")
+    });
+}
+
+async fn on_private_data(core_arc_clone: Arc<Mutex<Core>>,
+                         ct_val: Decimal,
+                         response: ResponseData,
+                         run_symbol: &String) {
+    let mut trace_stack = TraceStack::new(response.time, response.ins);
+    trace_stack.on_after_span_line();
+
+    // public类型,目前只考虑订单流数据
+    match response.channel.as_str() {
+        "account" => {
+            let account = standard::handle_info::HandleSwapInfo::handle_account_info(BitmartSwap, &response, run_symbol);
+            let mut core = core_arc_clone.lock().await;
+            core.update_equity(account).await;
+        },
+        "positions" => {
+            let mut positions = standard::handle_info::HandleSwapInfo::handle_position(BitmartSwap, &response, &ct_val);
+
+            // bitmart如果没有仓位不会给0,会给个空数组
+            if positions.is_empty() {
+                positions.push(Position {
+                    symbol: run_symbol.replace("_", "").to_uppercase(),
+                    margin_level: Default::default(),
+                    amount: Default::default(),
+                    frozen_amount: Default::default(),
+                    price: Default::default(),
+                    profit: Default::default(),
+                    position_mode: PositionModeEnum::Both,
+                    margin: Default::default(),
+                });
+            }
+
+            let mut core = core_arc_clone.lock().await;
+            core.update_position(positions).await;
+        },
+        "orders" => {
+            trace_stack.set_source("gate_swap.orders".to_string());
+            let orders = standard::handle_info::HandleSwapInfo::handle_order(BitmartSwap, response.clone(), ct_val.clone());
+
+            let mut order_infos:Vec<OrderInfo> = Vec::new();
+            for mut order in orders.order {
+                if order.status == "NULL" {
+                    error!("bitmart_usdt_swap 未识别的订单状态:{:?}", response);
+
+                    continue;
+                }
+
+                let order_info = OrderInfo::parse_order_to_order_info(&mut order);
+                order_infos.push(order_info);
+            }
+
+            {
+                let mut core = core_arc_clone.lock().await;
+                core.update_order(order_infos, trace_stack).await;
+            }
+        },
+        "pong" => {}
+        _ => {
+            info!("bitmart_usdt_swap 113 未知的订阅数据: {:?}", response);
+        }
+    }
+}
+
+async fn on_public_data(core_arc_clone: Arc<Mutex<Core>>,
+                        update_flag_u: &mut Decimal,
+                        response: ResponseData) {
+    let mut trace_stack = TraceStack::new(response.time, response.ins);
+    trace_stack.on_after_span_line();
+
+    // public类型,目前只考虑订单流数据
+    match response.channel.as_str() {
+        "books1" => {
+            trace_stack.set_source("bitmart_usdt_swap.books1".to_string());
+            let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BitmartSwap, &response);
+            trace_stack.on_after_format();
+
+            on_special_depth(core_arc_clone, update_flag_u, &response.label, &mut trace_stack, &special_depth).await;
+        },
+        "pong" => {},
+        _ => {
+            info!("bitmart_usdt_swap 125 未知的订阅数据");
+            info!(?response)
+        }
+    }
+}
+
+fn parse_btree_map_to_bitmart_swap_login(exchange_params: BTreeMap<String, String>) -> BitMartSwapLogin {
+    BitMartSwapLogin {
+        api_key: exchange_params.get("access_key").unwrap().clone(),
+        secret: exchange_params.get("secret_key").unwrap().clone(),
+        api_memo: exchange_params.get("pass_key").unwrap().clone(),
+    }
+}

+ 1 - 1
strategy/src/coinex_usdt_swap.rs

@@ -1,4 +1,4 @@
-use tracing::{error, info};
+use tracing::{error};
 use std::collections::BTreeMap;
 use std::sync::Arc;
 use std::sync::atomic::AtomicBool;

+ 7 - 0
strategy/src/exchange_disguise.rs

@@ -9,6 +9,7 @@ use standard::SpecialDepth;
 
 use crate::binance_usdt_swap::reference_binance_swap_run;
 use crate::bitget_usdt_swap::bitget_usdt_swap_run;
+use crate::bitmart_usdt_swap::bitmart_usdt_swap_run;
 use crate::gate_swap::gate_swap_run;
 // use crate::binance_spot::reference_binance_spot_run;
 // use crate::bitget_spot::bitget_spot_run;
@@ -50,6 +51,9 @@ pub async fn run_transactional_exchange(is_shutdown_arc :Arc<AtomicBool>,
             tokio::time::sleep(Duration::from_secs(1)).await;
             coinex_swap_run(is_shutdown_arc,true, core_arc, name, symbols, is_colo, exchange_params).await;
         }
+        "bitmart_usdt_sawp" => {
+            bitmart_usdt_swap_run(is_shutdown_arc, true, core_arc, name, symbols, is_colo, exchange_params).await;
+        }
         _ => {
             let msg = format!("不支持的交易交易所:{}", exchange_name);
             panic!("{}", msg);
@@ -96,6 +100,9 @@ pub async fn run_reference_exchange(is_shutdown_arc: Arc<AtomicBool>,
         "coinex_usdt_swap" => {
             coinex_swap_run(is_shutdown_arc,false, core_arc, name, symbols, is_colo, exchange_params).await;
         }
+        "bitmart_usdt_sawp" => {
+            bitmart_usdt_swap_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        }
         _ => {
             let msg = format!("不支持的参考交易所:{}", exchange_name);
             panic!("{}", msg);

+ 2 - 1
strategy/src/lib.rs

@@ -13,4 +13,5 @@ mod bitget_spot;
 mod okx_usdt_swap;
 mod bybit_usdt_swap;
 mod bitget_usdt_swap;
-mod coinex_usdt_swap;
+mod coinex_usdt_swap;
+mod bitmart_usdt_swap;