Explorar o código

bitget开发完成(提测)

JiahengHe %!s(int64=2) %!d(string=hai) anos
pai
achega
e4878c465f
Modificáronse 2 ficheiros con 94 adicións e 40 borrados
  1. 17 30
      strategy/src/exchange_disguise.rs
  2. 77 10
      strategy/src/quant.rs

+ 17 - 30
strategy/src/exchange_disguise.rs

@@ -1,5 +1,4 @@
 use std::collections::BTreeMap;
-use std::str::FromStr;
 use std::sync::Arc;
 use std::sync::atomic::AtomicBool;
 use std::time::Duration;
@@ -12,7 +11,7 @@ use tokio::time::sleep;
 use tracing::{error, info};
 use exchanges::binance_spot_ws::{BinanceSpotSubscribeType, BinanceSpotWs, BinanceSpotWsType};
 use exchanges::binance_swap_ws::{BinanceSubscribeType, BinanceSwapWs, BinanceWsType};
-use exchanges::bitget_spot_ws::{BitgetSpotWs, BitgetSubscribeType};
+use exchanges::bitget_spot_ws::{BitgetSpotWs, BitgetSubscribeType, BitgetWsType};
 use exchanges::gate_swap_rest::GateSwapRest;
 use exchanges::gate_swap_ws::{GateSubscribeType, GateSwapWs, GateWsType};
 use exchanges::kucoin_swap_ws::{KucoinSubscribeType, KucoinSwapWs, KucoinWsType};
@@ -68,7 +67,10 @@ pub async fn run_reference_exchange(bool_v1 :Arc<AtomicBool>, exchange_name: Str
 async fn gate_swap_run(bool_v1 :Arc<AtomicBool>, type_num: i8, quant_arc: Arc<Mutex<Quant>>, name: String, symbols: Vec<String>, exchange_params: BTreeMap<String, String>){
     let (tx, mut rx) = channel(100);
     let mut gate_exc = GateSwapRest::new(false, exchange_params.clone());
-    let user_id;
+    let mut user_id= "".to_string();
+    let symbols_one = symbols.clone();
+
+    // 交易
     if type_num == 1{
         // 获取user_id
         let res_data = gate_exc.wallet_fee().await;
@@ -79,21 +81,6 @@ async fn gate_swap_run(bool_v1 :Arc<AtomicBool>, type_num: i8, quant_arc: Arc<Mu
         user_id = wallet_obj["user_id"].to_string();
     }
 
-    let symbols_one = symbols.clone();
-    // 获取乘数(计价货币兑换为结算货币的乘数)
-    let response = gate_exc.get_market_details("usdt".to_string()).await;
-    assert_eq!(response.code, "200", "获取gate交易所参数 multiplier 失败, 启动失败!");
-
-    let contract_obj :Vec<Value> = parse_json_array(&response.data).unwrap();
-    let mut multiplier =  Decimal::ZERO;
-    for val in contract_obj {
-        if symbols[0].to_uppercase() == val["name"].as_str().unwrap(){
-            let num = val["quanto_multiplier"].as_str().unwrap();
-            multiplier = Decimal::from_str(num).unwrap();
-        }
-    }
-    assert_ne!(multiplier, Decimal::ZERO, "获取gate交易所参数 multiplier 为0!");
-
     spawn( async move {
         let mut gate_exc = GateSwapWs::new_label(name, false, exchange_params,
                                                  GateWsType::PublicAndPrivate("usdt".to_string()), tx);
@@ -116,6 +103,7 @@ async fn gate_swap_run(bool_v1 :Arc<AtomicBool>, type_num: i8, quant_arc: Arc<Mu
     });
     spawn(async move {
         let bot_arc_clone = Arc::clone(&quant_arc);
+        let multiplier = bot_arc_clone.lock().await.platform_rest.get_self_market().amount_size;
         let run_symbol = symbols.clone()[0].clone();
         // trade
         let mut max_buy = Decimal::ZERO;
@@ -548,23 +536,28 @@ async fn reference_binance_swap_run(bool_v1 :Arc<AtomicBool>, quant_arc: Arc<Mut
 
 async fn bitget_spot_run(bool_v1 :Arc<AtomicBool>, type_num: i8, quant_arc: Arc<Mutex<Quant>>, name: String, symbols: Vec<String>, exchange_params: BTreeMap<String, String>) {
     let (tx, mut rx) = channel(100);
+    let symbols_1 = symbols.clone();
     spawn( async move {
-        let mut bit_exc = BitgetSpotWs::new_label(name, false, exchange_params, BitgetSpot::PublicAndPrivate, tx);
+        let mut bit_exc_public = BitgetSpotWs::new_label(name.clone(), false, exchange_params.clone(), BitgetWsType::Public, tx.clone());
+        let mut bit_exc_private = BitgetSpotWs::new_label(name, false, exchange_params, BitgetWsType::Private, tx);
         // 交易
         if type_num == 1 {
-            bit_exc.set_subscribe(vec![
-                BitgetSubscribeType::PuTrade,
-                BitgetSubscribeType::PuBooks5,
+            bit_exc_private.set_subscribe(vec![
                 BitgetSubscribeType::PrAccount,
                 BitgetSubscribeType::PrOrders
             ]);
+            bit_exc_public.set_subscribe(vec![
+                BitgetSubscribeType::PuTrade,
+                BitgetSubscribeType::PuBooks5
+            ]);
         } else { // 参考
-            bit_exc.set_subscribe(vec![
+            bit_exc_public.set_subscribe(vec![
                 BitgetSubscribeType::PuTrade,
                 BitgetSubscribeType::PuBooks5
             ]);
         }
-        bit_exc.custom_subscribe(bool_v1, symbols.clone()).await;
+        bit_exc_public.custom_subscribe(bool_v1.clone(), symbols_1.clone()).await;
+        bit_exc_private.custom_subscribe(bool_v1, symbols_1).await;
     });
     spawn(async move {
         let bot_arc_clone = Arc::clone(&quant_arc);
@@ -660,10 +653,4 @@ async fn bitget_spot_run(bool_v1 :Arc<AtomicBool>, type_num: i8, quant_arc: Arc<
             }
         }
     });
-}
-
-
-
-fn parse_json_array(json: &str) -> serde_json::Result<Vec<Value>> {
-    serde_json::from_str(json)
 }

+ 77 - 10
strategy/src/quant.rs

@@ -25,6 +25,7 @@ use standard::exchange::ExchangeEnum::{BinanceSpot, BinanceSwap, GateSpot, GateS
 use crate::model::{LocalPosition, OrderInfo, TraderMsg};
 use crate::predictor::Predictor;
 use crate::strategy::Strategy;
+use crate::utils::clip;
 
 
 pub struct Quant {
@@ -99,6 +100,7 @@ pub struct Quant {
     pub local_depths: HashMap<String, Vec<Decimal>>,
     pub is_update: HashMap<String, bool>,
     pub running: Arc<AtomicBool>,
+    pub hold_coin: Decimal,
 }
 
 impl Quant {
@@ -111,6 +113,8 @@ impl Quant {
             symbol: symbol.clone(),
             base: pairs[0].to_string(),
             quote: pairs[1].to_string(),
+            // 现货底仓
+            hold_coin: clip(params.hold_coin, Decimal::ZERO, Decimal::ONE_HUNDRED*Decimal::ONE_HUNDRED),
             strategy: Strategy::new(&params, true),
             local_orders: Default::default(),
             local_orders_backup: Default::default(),
@@ -975,7 +979,7 @@ impl Quant {
             },
             Err(err)=>{
                 error!("取消所有订单异常: {}",err);
-                match self.platform_rest.cancel_orders() {
+                match self.platform_rest.cancel_orders().await {
                     Ok(val) => {
                         info!("清空当前币对挂单,{:?}", val);
                     },
@@ -990,6 +994,7 @@ impl Quant {
         } else { // 合约
             self.check_position_swap().await;
         }
+        info!("遗留仓位检测完毕");
     }
 
     pub async fn check_position_spot(&mut self){
@@ -997,11 +1002,62 @@ impl Quant {
         match self.platform_rest.get_spot_account().await {
             Ok(val) => {
                 for account in val {
-
+                    let coin_name = account.coin.to_uppercase();
+                    if check_coin(&self.exchange, &coin_name){
+                        continue;
+                    }
+                    let symbol = format!("{}_USDT", coin_name);
+                    let mut _hold_coin = Decimal::ZERO;
+                    if coin_name.eq(self.base.as_str()){
+                        _hold_coin = self.hold_coin;
+                    }
+                    let ap;
+                    let bp;
+                    let mp;
+                    match self.platform_rest.get_ticker().await {
+                        Ok(ticker)=>{
+                            ap = ticker.sell;
+                            bp = ticker.buy;
+                            mp = (ap + bp)/Decimal::TWO;
+                        },
+                        Err(_e)=>{
+                            error!("清仓中- 获取 {} 币对行情错误,该币对无法调整仓位。", symbol);
+                            continue;
+                        }
+                    }
+                    let coin_value = account.balance * mp;
+                    let diff = (_hold_coin - coin_value)* Decimal::from_str("0.99").unwrap();
+                    info!("需要调整现货仓位 {} usdt", diff);
+                    let side;
+                    let price= Decimal::ZERO;
+                    let amount;
+                    if diff > Decimal::from(20) {
+                        side = "kd";
+                        // price = mp*1.001;
+                        amount = diff/mp;
+                    } else if diff < Decimal::from(-20) {
+                        side = "kk";
+                        // price = mp*0.999;
+                        amount = -diff/mp;
+                    } else {
+                        continue;
+                    }
+                    // 价格0,市价单
+                    match self.platform_rest.take_order_symbol(symbol.clone(), Decimal::ONE, "t-123", side, price, amount).await{
+                        Ok(v)=>{
+                            info!("{} 清仓下单,{:?}", symbol, v);
+                            // 执行完当前币对  结束循环
+                            continue;
+                        },Err(ex)=>{
+                            error!("{} 清仓下单异常:{}", symbol, ex);
+                            // 执行完当前币对  结束循环
+                            continue;
+                        }
+                    }
                 }
             },
             Err(err) => {
-                error!("获取仓位信息异常: {}", error);
+                error!("获取仓位信息异常: {}", err);
             }
         }
     }
@@ -1029,7 +1085,7 @@ impl Quant {
                                 },
                                 Err(err) => {
                                     error!("获取当前market异常: {}", err);
-                                    break;
+                                    continue;
                                 }
                             }
                             info!(?position);
@@ -1047,20 +1103,20 @@ impl Quant {
                                 _ => {
                                     info!("仓位匹配失败,不做操作!");
                                     // 执行完当前币对  结束循环
-                                    break;
+                                    continue;
                                 }
                             }
                             // 发起清仓订单
-                            match self.platform_rest.take_order_symbol(position.symbol, "t-123", side, price, position.amount.abs()).await {
+                            match self.platform_rest.take_order_symbol(position.symbol.clone(), Decimal::ONE,"t-123", side, price, position.amount.abs()).await {
                                 Ok(order)=>{
-                                    info!("清仓下单,{:?}", order);
+                                    info!("{} 清仓下单,{:?}", position.symbol, order);
                                     // 执行完当前币对  结束循环
-                                    break;
+                                    continue;
                                 },
                                 Err(error)=>{
-                                    error!("清仓下单异常:{}", error);
+                                    error!("{} 清仓下单异常:{}", position.symbol, error);
                                     // 执行完当前币对  结束循环
-                                    break;
+                                    continue;
                                 }
                             };
                         },
@@ -1317,4 +1373,15 @@ pub fn on_timer(quant_arc: Arc<Mutex<Quant>>) -> JoinHandle<()> {
             }
         }
     });
+}
+
+pub fn check_coin(exchanges :&String, coin_name: &String) -> bool{
+    let mut result = false;
+    match exchanges.as_str() {
+        "bitget_usdt_spot" => {
+            result = ["GT", "USDT", "POINT"].contains(&coin_name.as_str());
+        }
+        _ => {}
+    }
+    result
 }