ソースを参照

完成指定的深度信息处理
添加撤销订单
添加撤销所有订单

gepangpang 2 年 前
コミット
c4efe00022

+ 83 - 1
standard/src/binance_handle.rs

@@ -1,9 +1,14 @@
+use std::cmp::Ordering;
 use std::io::{Error, ErrorKind};
+use rust_decimal::Decimal;
+use rust_decimal::prelude::FromPrimitive;
 use rust_decimal_macros::dec;
 use serde_json::json;
 use exchanges::response_base::ResponseData;
-use crate::Account;
+use global::public_params;
+use crate::{Account, MarketOrder, SpecialDepth, SpecialTicker};
 
+// 处理账号信息
 pub fn handle_account_info(res_data: ResponseData, symbol: &str) -> Result<Account, Error> {
     if res_data.code == "200" {
         let res_data_str = &res_data.data;
@@ -31,4 +36,81 @@ pub fn handle_account_info(res_data: ResponseData, symbol: &str) -> Result<Accou
     } else {
         Err(Error::new(ErrorKind::Other, res_data.message))
     }
+}
+
+// 处理特殊深度数据
+pub fn handle_special_depth(res_data: ResponseData) -> SpecialDepth {
+    let res_data_str = res_data.data;
+    let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
+    let mut depth_asks: Vec<MarketOrder> = parse_depth_items(&res_data_json["asks"]);
+    let mut depth_bids: Vec<MarketOrder> = parse_depth_items(&res_data_json["bids"]);
+    depth_asks.sort_by(|a, b| a.price.partial_cmp(&b.price).unwrap_or(Ordering::Equal));
+    depth_bids.sort_by(|a, b| b.price.partial_cmp(&a.price).unwrap_or(Ordering::Equal));
+    let mp = (depth_asks[0].price + depth_bids[0].price) * dec!(0.5);
+    let step = (public_params::EFF_RANGE * mp / Decimal::from_usize(public_params::LEVEL).unwrap()).round_dp(mp.scale());
+    let mut ap = Vec::new();
+    let mut bp = Vec::new();
+    let mut av: Vec<Decimal> = Vec::new();
+    let mut bv: Vec<Decimal> = Vec::new();
+    for i in 0..public_params::LEVEL {
+        let price = (depth_asks[0].price + step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_asks[0].price.scale());
+        ap.push(price);
+    }
+    for i in 0..public_params::LEVEL {
+        let price = (depth_bids[0].price - step * Decimal::from_f64(i as f64).unwrap()).round_dp(depth_bids[0].price.scale());
+        bp.push(price);
+    }
+    let mut ap_price_tag = depth_asks[0].price + step;
+    let mut ap_index = 0;
+    for item in depth_asks.iter() {
+        let price = item.price;
+        let amount = item.amount;
+        if av.get(ap_index).is_none() { av.push(dec!(0)) };
+        if price < ap_price_tag {
+            av[ap_index] += amount;
+        } else {
+            ap_price_tag += step;
+            ap_index += 1;
+            if ap_index == public_params::LEVEL {
+                break;
+            }
+            av[ap_index] += amount
+        }
+    }
+
+    let mut bp_price_tag = depth_bids[0].price - step;
+    let mut bp_index = 0;
+    for item in depth_bids.iter() {
+        let price = item.price;
+        let amount = item.amount;
+        if bv.get(bp_index).is_none() { bv.push(dec!(0)) };
+        if price > bp_price_tag {
+            bv[bp_index] += amount;
+        } else {
+            bp_price_tag -= step;
+            bp_index += 1;
+            if bp_index == public_params::LEVEL {
+                break;
+            }
+            bv[bp_index] += amount
+        }
+    }
+    let ticker_info = SpecialTicker{ sell: depth_asks[0].price, buy: depth_bids[0].price};
+    let depth_info = bp.iter().cloned().chain(bv.iter().cloned()).chain(ap.iter().cloned()).chain(av.iter().cloned()).collect();
+    let result = SpecialDepth{
+        depth: depth_info,
+        ticker: ticker_info,
+    };
+    return result;
+}
+
+fn parse_depth_items(value: &serde_json::Value) -> Vec<MarketOrder> {
+    let mut depth_items: Vec<MarketOrder> = vec![];
+    for value in value.as_array().unwrap() {
+        depth_items.push(MarketOrder {
+            price: value[0].as_str().unwrap_or("0").parse().unwrap_or(dec!(0)),
+            amount: value[1].as_str().unwrap_or("0").parse().unwrap_or(dec!(0)),
+        })
+    }
+    return depth_items;
 }

+ 8 - 0
standard/src/binance_spot.rs

@@ -92,4 +92,12 @@ impl Platform for BinanceSpot {
     async fn take_order(&self, _custom_id: &str, _origin_side: &str, _coin: &str, _symbol: &str, _amount: Decimal) -> Result<Order, Error> {
         todo!()
     }
+
+    async fn cancel_order(&self, _symbol: &str, _order_id: &str) -> Result<Order, Error> {
+        todo!()
+    }
+
+    async fn cancel_orders(&self, _symbol: &str) -> Result<Vec<Order>, Error> {
+        todo!()
+    }
 }

+ 8 - 74
standard/src/binance_swap.rs

@@ -110,6 +110,14 @@ impl Platform for BinanceSwap {
         todo!()
     }
 
+    async fn cancel_order(&self, _symbol: &str, _order_id: &str) -> Result<Order, Error> {
+        todo!()
+    }
+
+    async fn cancel_orders(&self, _symbol: &str) -> Result<Vec<Order>, Error> {
+        todo!()
+    }
+
     // 订阅深度信息
     // fn subscribe_depth(&self, symbol: &str) {
     //     let symbol_format = &utils::format_symbol(symbol, "");
@@ -134,80 +142,6 @@ impl Platform for BinanceSwap {
     //     self.wss.custom_subscribe(vec![symbol_format], 0, 0, get_res_data)
     // }
 
-    // 订阅深度信息
-    // fn subscribe_special_depth(&self, symbol: &str) {
-    //     let symbol_format = &utils::format_symbol(symbol, "");
-    //     let get_res_data = move |res_data: ResponseData| {
-    //         async move {
-    //             if res_data.code == "200" && res_data.channel == "depth" {
-    //                 let res_data_str = res_data.data;
-    //                 let res_data_json: serde_json::Value = serde_json::from_str(&*res_data_str).unwrap();
-    //                 let mut depth_asks: Vec<MarketOrder> = parse_depth_items(&res_data_json["asks"]);
-    //                 let mut depth_bids: Vec<MarketOrder> = parse_depth_items(&res_data_json["bids"]);
-    //                 depth_asks.sort_by(|a, b| a.price.partial_cmp(&b.price).unwrap_or(Ordering::Equal));
-    //                 depth_bids.sort_by(|a, b| b.price.partial_cmp(&a.price).unwrap_or(Ordering::Equal));
-    //                 let mp = (depth_asks[0].price + depth_bids[0].price) * dec!(0.5);
-    //                 let step = (public_params::EFF_RANGE * mp / Decimal::from_usize(public_params::LEVEL).unwrap()).round();
-    //                 let mut ap = Vec::new();
-    //                 let mut bp = Vec::new();
-    //                 let mut av: Vec<Decimal> = Vec::new();
-    //                 let mut bv: Vec<Decimal> = Vec::new();
-    //                 for i in 0..public_params::LEVEL {
-    //                     let price = (depth_asks[0].price + step * Decimal::from_f64(i as f64).unwrap()).round();
-    //                     ap.push(price);
-    //                 }
-    //                 for i in 0..public_params::LEVEL {
-    //                     let price = (depth_asks[0].price - step * Decimal::from_f64(i as f64).unwrap()).round();
-    //                     bp.push(price);
-    //                 }
-    //                 let mut ap_price_tag = depth_asks[0].price + step;
-    //                 let mut ap_index = 0;
-    //                 for item in depth_asks.iter() {
-    //                     let price = item.price;
-    //                     let amount = item.amount;
-    //                     println!("{} {}", price, amount);
-    //                     if price > ap_price_tag {
-    //                         av[ap_index] += amount;
-    //                     } else {
-    //                         ap_price_tag += step;
-    //                         ap_index += 1;
-    //                         if ap_index == public_params::LEVEL {
-    //                             break;
-    //                         }
-    //                         av[ap_index] += amount
-    //                     }
-    //                 }
-    //
-    //                 let mut bp_price_tag = depth_bids[0].price - step;
-    //                 let mut bp_index = 0;
-    //                 for item in depth_bids.iter() {
-    //                     let price = item.price;
-    //                     let amount = item.amount;
-    //                     if price > bp_price_tag {
-    //                         bv[bp_index] += amount;
-    //                     } else {
-    //                         bp_price_tag -= step;
-    //                         bp_index += 1;
-    //                         if bp_index == public_params::LEVEL {
-    //                             break;
-    //                         }
-    //                         bv[bp_index] += amount
-    //                     }
-    //                 }
-    //
-    //                 let aa: Vec<&Decimal> = bp.iter().clone().chain(bv.iter().clone()).chain(ap.iter().clone()).chain(av.iter().clone()).collect::<Vec<_>>();
-    //                 println!("{:?}", aa);
-    //                 let result = Depth {
-    //                     time: 123456,
-    //                     asks: depth_asks,
-    //                     bids: depth_bids,
-    //                 };
-    //                 println!("subscribe_special_depth: {:?}", result)
-    //             }
-    //         }
-    //     };
-    //     self.wss.custom_subscribe(vec![symbol_format], 0, 0, get_res_data)
-    // }
 }
 
 // fn parse_depth_items(value: &serde_json::Value) -> Vec<MarketOrder> {

+ 8 - 0
standard/src/gate_spot.rs

@@ -93,4 +93,12 @@ impl Platform for GateSpot {
     async fn take_order(&self, _custom_id: &str, _origin_side: &str, _coin: &str, _symbol: &str, _amount: Decimal) -> Result<Order, Error> {
         todo!()
     }
+
+    async fn cancel_order(&self, _symbol: &str, _order_id: &str) -> Result<Order, Error> {
+        todo!()
+    }
+
+    async fn cancel_orders(&self, _symbol: &str) -> Result<Vec<Order>, Error> {
+        todo!()
+    }
 }

+ 28 - 2
standard/src/gate_swap.rs

@@ -222,7 +222,7 @@ impl Platform for GateSwap {
         }
     }
     // 下单接口
-    async fn take_order(&self, custom_id: &str, origin_side: &str, coin: &str, symbol: &str, amount: Decimal) -> Result<Order, Error>{
+    async fn take_order(&self, custom_id: &str, origin_side: &str, coin: &str, symbol: &str, amount: Decimal) -> Result<Order, Error> {
         let symbol_format = utils::format_symbol(symbol.clone(), "_");
         let coin_format = coin.to_string().to_lowercase();
         let res_data = self.request.swap_bazaar_order(custom_id.to_string(), origin_side.to_string(), coin_format.clone(), symbol_format, amount.to_i64().unwrap()).await;
@@ -235,8 +235,34 @@ impl Platform for GateSwap {
             Err(Error::new(ErrorKind::Other, res_data.message))
         }
     }
-
+    // 撤销订单
+    async fn cancel_order(&self, symbol: &str, order_id: &str) -> Result<Order, Error> {
+        let symbol_array: Vec<&str> = symbol.split("_").collect();
+        let res_data = self.request.cancel_order(symbol_array[1].to_string().to_lowercase(), order_id.to_string()).await;
+        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 = parse_order_item(&res_data_json);
+            Ok(result)
+        } else {
+            Err(Error::new(ErrorKind::Other, res_data.message))
+        }
+    }
+    // 批量撤销订单
+    async fn cancel_orders(&self, symbol: &str) -> Result<Vec<Order>, Error> {
+        let symbol_array: Vec<&str> = symbol.split("_").collect();
+        let res_data = self.request.cancel_orders(symbol_array[1].to_string().to_lowercase(), symbol.to_string()).await;
+        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 result = res_data_json.iter().map(|item| parse_order_item(item)).collect();
+            Ok(result)
+        } else {
+            Err(Error::new(ErrorKind::Other, res_data.message))
+        }
+    }
 }
+
 fn parse_order_item(order: &serde_json::Value) -> Order {
     Order {
         id: order["id"].to_string(),

+ 24 - 2
standard/src/lib.rs

@@ -9,11 +9,11 @@ pub mod exchange;
 // 引入binance模块
 mod binance_swap;
 mod binance_spot;
-mod binance_handle;
+pub mod binance_handle;
 // 引入gate模块
 mod gate_swap;
 mod gate_spot;
-mod gate_handle;
+pub mod gate_handle;
 // 引入工具模块
 pub mod utils;
 
@@ -53,6 +53,24 @@ pub struct Depth {
     pub bids: Vec<MarketOrder>,
 }
 
+/// 特殊Depth结构体(市场深度)
+/// - `depth(Vec<Decimal>)`: 深度信息;
+/// - `ticker(SpecialTicker)`: 市场行情;
+#[derive(Debug)]
+pub struct SpecialDepth {
+    pub depth: Vec<Decimal>,
+    pub ticker: SpecialTicker,
+}
+/// 特殊Ticker结构体(市场行情)
+/// - `sell(Decimal)`: 卖一价
+/// - `buy(Decimal)`: 买一价
+#[derive(Debug)]
+pub struct SpecialTicker {
+    pub sell: Decimal,
+    pub buy: Decimal,
+}
+
+
 /// MarketOrder结构体(市场深度单)
 /// - `price(Decimal)`: 价格
 /// - `amount(Decimal)`: 数量
@@ -280,5 +298,9 @@ pub trait Platform {
     async fn wallet_transfers(&self, coin: &str, from: &str, to: &str, amount: Decimal) -> Result<String, Error>;
     // 下单接口
     async fn take_order(&self, custom_id: &str, origin_side: &str, coin: &str, symbol: &str, amount: Decimal) -> Result<Order, Error>;
+    // 撤销订单
+    async fn cancel_order(&self, symbol: &str, order_id: &str) -> Result<Order,Error>;
+    // 批量撤销订单
+    async fn cancel_orders(&self, symbol: &str) -> Result<Vec<Order>, Error>;
 }