浏览代码

Merge remote-tracking branch 'origin/master'

gepangpang 2 年之前
父节点
当前提交
37dde93b41
共有 12 个文件被更改,包括 203 次插入127 次删除
  1. 2 1
      .gitignore
  2. 7 1
      Cargo.toml
  3. 25 0
      config.toml.sample
  4. 0 2
      main/.gitignore
  5. 0 11
      main/Cargo.toml
  6. 0 15
      main/README.md
  7. 0 24
      main/src/main.rs
  8. 5 5
      strategy/src/lib.rs
  9. 3 1
      strategy/src/params.rs
  10. 67 67
      strategy/src/strategy.rs
  11. 94 0
      tests/order_command_test.rs
  12. 0 0
      tests/sub_task_test.rs

+ 2 - 1
.gitignore

@@ -1,4 +1,5 @@
 /target
 /.idea
 
-Cargo.lock
+Cargo.lock
+config.toml

+ 7 - 1
Cargo.toml

@@ -6,10 +6,16 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+strategy = {path="./strategy"}
+standard = { path="./standard" }
+exchanges = { path="./exchanges" }
+global = { path="./global" }
+tokio = { version = "1.31.0", features = ["full"] }
+tracing = "0.1"
+tracing-subscriber = "0.3.17"
 
 [workspace]
 members=[
-    "main",
     "exchanges",
     "standard",
     "strategy",

+ 25 - 0
config.toml.sample

@@ -0,0 +1,25 @@
+broker_id = "gate"
+account_name = "gate_account"
+access_key = ""
+secret_key = ""
+pass_key = "21314123"
+exchange = "gate_usdt_swap"
+pair = "eth_usdt"
+open = 0.001
+close = 0.0002
+lever_rate = 1.0
+interval = 0.1
+ref_exchange = ["binance_usdt_swap"]
+ref_pair = ["eth_usdt"]
+used_pct = 0.9
+index = 0
+save = 0
+hold_coin = 0.0
+log = 1
+stop_loss = 0.02
+gamma = 0.999
+grid = 1
+place_order_limit = 0
+colo = 0
+# 日志级别,从低到高依次是:[trace, debug, info, warn, error]
+log_level = "debug"

+ 0 - 2
main/.gitignore

@@ -1,2 +0,0 @@
-/target
-/.idea

+ 0 - 11
main/Cargo.toml

@@ -1,11 +0,0 @@
-[package]
-name = "as-rust-main"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-tokio = { version = "1.31.0", features = ["full"] }
-standard = { path="../standard" }
-exchanges = { path="../exchanges" }

+ 0 - 15
main/README.md

@@ -1,15 +0,0 @@
-## 声明
-
-
-## 项目结构解析
-
-```
-|
-├─ main                                 // 系统入口
-│
-├─ exchanges                            // 交易所层(网络层)
-│
-├─ standard                             // 标准化层(中间件)
-│
-└─ strategy                             // 策略层(主逻辑、风控等)
-```

+ 0 - 24
main/src/main.rs

@@ -1,24 +0,0 @@
-use std::collections::BTreeMap;
-use std::io;
-use exchanges::binance_usdt_swap_ws;
-use exchanges::binance_usdt_swap_ws::BinanceUsdtSwapWs;
-use exchanges::response_base::ResponseData;
-use std::io::{Read, Write};
-
-#[tokio::main]
-async fn main() {
-    let get_res_data = move |res_data: ResponseData| {
-        async move {
-            // println!("?????{:?}", res_data);
-            let mut stdout = io::stdout();
-            writeln!(stdout, "?????-响应--{:?}", res_data).unwrap();
-        }
-    };
-
-
-    let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-    // btree_map.insert("lable".parse().unwrap(), "binance".parse().unwrap());//交易行名称
-
-    let ba_exc = BinanceUsdtSwapWs::new(false, true, btree_map);
-    ba_exc.kline(vec![&"BTCUSDT"], get_res_data);
-}

+ 5 - 5
strategy/src/lib.rs

@@ -1,6 +1,6 @@
-pub mod predictor;
-pub mod utils;
-mod params;
-mod quant;
+pub mod params;
+pub mod quant;
 mod model;
-mod strategy;
+mod strategy;
+mod predictor;
+mod utils;

+ 3 - 1
strategy/src/params.rs

@@ -47,7 +47,9 @@ pub struct Params {
     // 允许的每秒下单次数
     pub place_order_limit: i64,
     // 是否启用colocation技术, 1开启,0关闭 默认0
-    pub colo: i8
+    pub colo: i8,
+    // 日志级别,从低到高依次是:[trace, debug, info, warn, error]
+    pub log_level: String,
 }
 
 impl Params {

+ 67 - 67
strategy/src/strategy.rs

@@ -8,7 +8,7 @@ use rust_decimal_macros::dec;
 use crate::model::{OrderCommand, OrderInfo, Position, TraderMsg};
 use crate::params::Params;
 use crate::utils;
-use tracing::{info, trace, instrument, subscriber, error};
+use tracing::{info, instrument, subscriber, error, debug};
 use tracing_subscriber;
 
 #[derive(Debug)]
@@ -243,8 +243,8 @@ impl Strategy {
     // 更新当前strategy的各类信息
     #[instrument(skip(self, trader_msg), level="TRACE")]
     pub fn _update_data(&mut self, trader_msg: &TraderMsg) -> bool {
-        trace!(?self);
-        trace!(?trader_msg);
+        debug!(?self);
+        debug!(?trader_msg);
 
         self.local_orders.clear();
         self.local_orders = trader_msg.orders.clone();
@@ -258,7 +258,7 @@ impl Strategy {
             self.pos.short_pos = trader_msg.position.short_pos;
             self.pos.short_avg = trader_msg.position.short_avg;
         }
-        trace!(?self.pos);
+        debug!(?self.pos);
 
         // 价格值处理
         self.bp = trader_msg.market[global::public_params::BID_PRICE_INDEX];
@@ -270,7 +270,7 @@ impl Strategy {
         } else {
             self.mp_ema = self.mp_ema * dec!(0.999) + self.mp * dec!(0.001);
         }
-        trace!(?self.bp, ?self.ap, ?self.mp, ?self.mp_ema);
+        debug!(?self.bp, ?self.ap, ?self.mp, ?self.mp_ema);
 
         // 动态杠杆调节
         if self.mp > self.mp_ema {
@@ -278,12 +278,12 @@ impl Strategy {
         } else {
             self.adjust_lever_rate = dec!(0.8);
         }
-        trace!(?self.adjust_lever_rate);
+        debug!(?self.adjust_lever_rate);
 
         // 当前持仓价值处理
         self.long_hold_value = self.pos.long_pos * self.mp;
         self.short_hold_value = self.pos.short_pos * self.mp;
-        trace!(?self.long_hold_value, ?self.short_hold_value);
+        debug!(?self.long_hold_value, ?self.short_hold_value);
 
         // 分现货或合约计算最大开仓价值
         if self.exchange.contains("spot") {
@@ -293,7 +293,7 @@ impl Strategy {
             self.max_long_value = self.equity * self.lever_rate * self.adjust_lever_rate;
             self.max_short_value = self.max_long_value;
         }
-        trace!(?self.max_long_value, ?self.max_short_value, ?self.equity, ?self.lever_rate, ?self.adjust_lever_rate);
+        debug!(?self.max_long_value, ?self.max_short_value, ?self.equity, ?self.lever_rate, ?self.adjust_lever_rate);
 
         // 做市模式识别
         if self.ref_name[self.ref_index].eq(&self.trade_name) {
@@ -301,7 +301,7 @@ impl Strategy {
         } else {
             self.maker_mode = "follow".to_string();
         }
-        trace!(?self.maker_mode);
+        debug!(?self.maker_mode);
 
         // 参考价格
         if trader_msg.ref_price.len() == 0 {
@@ -313,12 +313,12 @@ impl Strategy {
             self.ref_ap = trader_msg.ref_price[self.ref_index][1];
             self.ref_price = (self.ref_bp + self.ref_ap) * dec!(0.5);
         }
-        trace!(?self.ref_bp, ?self.ref_ap, %self.ref_price);
+        debug!(?self.ref_bp, ?self.ref_ap, %self.ref_price);
 
         // spread
         let temp_predict = trader_msg.predict * self.predict_alpha;
         self.predict = utils::clip(temp_predict, -self.trade_open_dist, self.trade_open_dist);
-        trace!(?self.predict);
+        debug!(?self.predict);
 
         // 计算当前账户cash和coin
         self.coin = trader_msg.coin;
@@ -327,12 +327,12 @@ impl Strategy {
         if self.equity > self.max_equity {
             self.max_equity = self.equity;
         }
-        trace!(?self.coin, ?self.cash, ?self.equity, ?self.max_equity);
+        debug!(?self.coin, ?self.cash, ?self.equity, ?self.max_equity);
 
         // 总可开数量
         self.total_amount = self.equity * self.lever_rate * self.adjust_lever_rate / self.mp;
         self.total_amount = utils::fix_amount(self.total_amount, self.step_size);
-        trace!(?self.total_amount);
+        debug!(?self.total_amount);
         if self.total_amount.eq(&Decimal::ZERO) {
             error!("总可开数量太少!equity={}, lever_rate={}, adjust_lever_rate={}", self.equity, self.lever_rate, self.adjust_lever_rate);
             return false;
@@ -344,7 +344,7 @@ impl Strategy {
             if max_pos_rate > self.max_pos_rate {
                 self.max_pos_rate = max_pos_rate;
             }
-            trace!(?max_pos_rate, ?self.max_pos_rate);
+            debug!(?max_pos_rate, ?self.max_pos_rate);
         }
 
         return true;
@@ -366,7 +366,7 @@ impl Strategy {
             "pk".to_string()
         ];
 
-        trace!(?self.local_orders);
+        debug!(?self.local_orders);
         for client_id in self.local_orders.keys() {
             let order = self.local_orders.get(client_id).unwrap();
 
@@ -380,7 +380,7 @@ impl Strategy {
             let value = vec![order.client_id.clone(), order.order_id.clone()];
             command.cancel.insert(key, value);
         }
-        trace!(?command);
+        debug!(?command);
     }
 
     // 生成各类挂单价格,原文是gen_dist
@@ -406,7 +406,7 @@ impl Strategy {
             sell_start * (Decimal::ONE + predict + close - avoid),                   // sell lower
             sell_start * (Decimal::ONE + predict + close + avoid),                   // sell upper
         ];
-        trace!(?mp, ?buy_start, ?sell_start, ?avoid, ?close_dist);
+        debug!(?mp, ?buy_start, ?sell_start, ?avoid, ?close_dist);
 
         // 自由做市模式
         if mode == "free".to_string() {
@@ -421,7 +421,7 @@ impl Strategy {
         } else {
             panic!("未知做市类型:mode={}", mode)
         }
-        trace!(?mode, ?buy_start, ?sell_start, ?mp);
+        debug!(?mode, ?buy_start, ?sell_start, ?mp);
 
         // 开仓相关
         avoid = min(dec!(0.001), open * dec!(0.05));
@@ -434,7 +434,7 @@ impl Strategy {
             sell_start * (Decimal::ONE + predict + open * sell_shift - avoid),            // sell lower
             sell_start * (Decimal::ONE + predict + open * sell_shift + avoid),            // sell upper
         ];
-        trace!(?avoid, ?buy_shift, ?sell_shift, ?avoid, ?open_dist);
+        debug!(?avoid, ?buy_shift, ?sell_shift, ?avoid, ?open_dist);
 
         // 修复价格
         for open_price in &mut open_dist {
@@ -445,15 +445,15 @@ impl Strategy {
         }
         self.open_dist = open_dist.clone();
         self.close_dist = close_dist.clone();
-        trace!(?open_dist);
-        trace!(?close_dist);
+        debug!(?open_dist);
+        debug!(?close_dist);
     }
 
     // 统计请求次数
     #[instrument(skip(self, command), level="TRACE")]
     pub fn _update_request_num(&mut self, command: &OrderCommand) {
-        trace!(?command);
-        trace!(?self.request_order_count, ?self.request_count);
+        debug!(?command);
+        debug!(?self.request_order_count, ?self.request_count);
 
         let order_count = (command.limits_open.len() + command.limits_close.len()).to_i64().unwrap();
         let request_count = order_count + (command.cancel.len() + command.check.len()).to_i64().unwrap();
@@ -461,13 +461,13 @@ impl Strategy {
         self.request_order_count += order_count;
         self.request_count += request_count;
 
-        trace!(?self.request_order_count, ?self.request_count);
+        debug!(?self.request_order_count, ?self.request_count);
     }
 
     // 根据平均请求次数限制开仓下单
     #[instrument(skip(self, command), level="TRACE")]
     pub fn _check_request_limit(&mut self, command: &mut OrderCommand) {
-        trace!(?command);
+        debug!(?command);
         // 如果当前请求数超过限制
         if self.request_count > self.limit_requests_num {
             command.cancel.clear();
@@ -476,7 +476,7 @@ impl Strategy {
             command.limits_open.clear();
             command.limits_close.clear();
             error!("请求频率溢出,程序禁止任何操作!");
-            trace!(?command);
+            debug!(?command);
 
             return;
         }
@@ -490,15 +490,15 @@ impl Strategy {
 
         // 超过80%,直接取消limits_open的下单指令
         error!("80%+下单频率,程序禁止开仓!");
-        trace!(?self.request_order_count, ?self.limit_order_requests_num);
+        debug!(?self.request_order_count, ?self.limit_order_requests_num);
         command.limits_open.clear();
         // 100%超过下单频率,则不再进行平仓挂单
         if self.request_order_count >= self.limit_order_requests_num {
             command.limits_close.clear();
             error!("100%下单频率!程序禁止平仓!");
-            trace!(?self.request_order_count, ?self.limit_order_requests_num)
+            debug!(?self.request_order_count, ?self.limit_order_requests_num)
         }
-        trace!(?command);
+        debug!(?command);
     }
 
     // 新增正在撤单、检查撤单队列,释放过时限制
@@ -529,9 +529,9 @@ impl Strategy {
             }
         }
 
-        trace!(?command);
+        debug!(?command);
         command.cancel = new_cancel;
-        trace!(?command);
+        debug!(?command);
 
         // 释放撤单限制
         self._release_in_cancel();
@@ -540,7 +540,7 @@ impl Strategy {
     // 维护查单队列,检查是否在撤单
     #[instrument(skip(self), level="TRACE")]
     pub fn _release_in_check(&mut self) {
-        trace!(?self.in_check);
+        debug!(?self.in_check);
         // 为什么要移出来:Rust不允许边循环边修改map
         let mut to_remove = Vec::new();
 
@@ -560,13 +560,13 @@ impl Strategy {
         for client_id in to_remove {
             self.in_check.remove(&client_id);
         }
-        trace!(?self.in_check);
+        debug!(?self.in_check);
     }
 
     // 检查是否正在撤单
     #[instrument(skip(self), level="TRACE")]
     pub fn _release_in_cancel(&mut self) {
-        trace!(?self.in_cancel);
+        debug!(?self.in_cancel);
         // 为什么要移出来:Rust不允许边循环边修改map
         let mut to_remove = Vec::new();
 
@@ -586,7 +586,7 @@ impl Strategy {
         for client_id in to_remove {
             self.in_cancel.remove(&client_id);
         }
-        trace!(?self.in_cancel);
+        debug!(?self.in_cancel);
     }
 
     // 刷新请求限制
@@ -604,16 +604,16 @@ impl Strategy {
     // 刷新持仓比例
     #[instrument(skip(self), level="TRACE")]
     pub fn _pos_rate(&mut self) {
-        trace!(?self);
+        debug!(?self);
 
         if self.max_long_value > Decimal::ZERO {
             self.long_hold_rate = self.long_hold_value / self.max_long_value;
-            trace!(?self.long_hold_rate);
+            debug!(?self.long_hold_rate);
         }
 
         if self.max_short_value > Decimal::ZERO {
             self.short_hold_rate = self.short_hold_value / self.max_short_value;
-            trace!(?self.short_hold_rate);
+            debug!(?self.short_hold_rate);
         }
     }
 
@@ -635,7 +635,7 @@ impl Strategy {
             // 统计请求频率
             self._update_request_num(&mut command);
         }
-        trace!(?command);
+        debug!(?command);
 
         return command;
     }
@@ -658,7 +658,7 @@ impl Strategy {
             // 统计请求频率
             self._update_request_num(&mut command);
         }
-        trace!(?command);
+        debug!(?command);
 
         return command;
     }
@@ -669,7 +669,7 @@ impl Strategy {
         // 撤掉全部挂单
         let mut pd_amount = Decimal::ZERO;
         let mut pk_amount = Decimal::ZERO;
-        trace!(?self.local_orders);
+        debug!(?self.local_orders);
         for client_id in self.local_orders.keys() {
             let order = self.local_orders.get(client_id).unwrap();
 
@@ -685,12 +685,12 @@ impl Strategy {
                 pd_amount += order.amount;
             }
         }
-        trace!(?pd_amount, ?pk_amount);
+        debug!(?pd_amount, ?pk_amount);
 
         // 批量挂单
         let need_close_long = self.pos.long_pos - pd_amount;
         let need_close_short = self.pos.short_pos - pk_amount;
-        trace!(?need_close_long, ?need_close_short);
+        debug!(?need_close_long, ?need_close_short);
 
         // 做多仓位平仓
         if need_close_long * self.mp > self._min_amount_value {
@@ -710,7 +710,7 @@ impl Strategy {
             ];
             command.limits_close.insert(client_id.clone(), value);
 
-            trace!(?self.pos.long_pos, ?self.mp, ?need_close_long, ?command)
+            debug!(?self.pos.long_pos, ?self.mp, ?need_close_long, ?command)
         }
 
         // 做空仓位平仓
@@ -730,7 +730,7 @@ impl Strategy {
             ];
             command.limits_close.insert(client_id.clone(), value);
 
-            trace!(?self.pos.short_pos, ?self.mp, ?need_close_short, ?command)
+            debug!(?self.pos.short_pos, ?self.mp, ?need_close_short, ?command)
         }
     }
 
@@ -743,7 +743,7 @@ impl Strategy {
         let pre_hot:i64 = 10 * 1000;
         if !self.mp.eq(&Decimal::ZERO) && self.local_time - self.local_start_time > pre_hot {
             self.is_ready = true;
-            trace!(?self.mp, ?self.local_time, ?self.local_start_time, ?pre_hot);
+            debug!(?self.mp, ?self.local_time, ?self.local_start_time, ?pre_hot);
             info!("策略预热完毕,可以执行后续逻辑!")
         }
 
@@ -761,7 +761,7 @@ impl Strategy {
     // 平仓订单处理命令
     #[instrument(skip(self, command), level="TRACE")]
     pub fn _post_close(&self, command: &mut OrderCommand) {
-        trace!(?command);
+        debug!(?command);
 
         let mut pd_amount = Decimal::ZERO;
         let mut pd_order_num = 0;
@@ -797,7 +797,7 @@ impl Strategy {
                 pd_order_num += 1;
             }
         }
-        trace!(?command);
+        debug!(?command);
 
         // 判断是否需要全平
         let is_need_cancel_all_close =
@@ -815,7 +815,7 @@ impl Strategy {
                 }
             }
         }
-        trace!(?command);
+        debug!(?command);
 
         // 区分现货和期货
         if self.exchange.contains("spot") {
@@ -838,7 +838,7 @@ impl Strategy {
                         ];
                         command.limits_open.insert(order_client_id, order.clone());
 
-                        trace!(?command);
+                        debug!(?command);
                     }
                 }
             }
@@ -862,7 +862,7 @@ impl Strategy {
                         ];
                         command.limits_open.insert(order_client_id, order.clone());
 
-                        trace!(?command);
+                        debug!(?command);
                     }
                 }
             }
@@ -882,7 +882,7 @@ impl Strategy {
 
                 command.limits_open.insert(order_client_id, order.clone());
 
-                trace!(?command);
+                debug!(?command);
             }
 
             if self.pos.short_pos > Decimal::ZERO {
@@ -898,7 +898,7 @@ impl Strategy {
                     order_client_id.clone()
                 ];
 
-                trace!(?command);
+                debug!(?command);
             }
         }
     }
@@ -906,7 +906,7 @@ impl Strategy {
     // 生成取消订单的指令
     #[instrument(skip(self, command), level="TRACE")]
     pub fn _cancel_open(&self, command: &mut OrderCommand) {
-        trace!(?command);
+        debug!(?command);
         // 挂单范围
         let long_upper = self.open_dist[0];
         let long_lower = self.open_dist[1];
@@ -924,7 +924,7 @@ impl Strategy {
                 if order.price < long_upper && order.price > long_lower {
                     continue
                 }
-                trace!(?key, ?order.price, ?long_upper, ?long_lower);
+                debug!(?key, ?order.price, ?long_upper, ?long_lower);
                 command.cancel.insert(key.clone(), value.clone());
             }
 
@@ -934,7 +934,7 @@ impl Strategy {
                 if order.price > short_lower && order.price < short_upper {
                     continue
                 }
-                trace!(?key, ?order.price, ?short_lower, ?short_upper);
+                debug!(?key, ?order.price, ?short_lower, ?short_upper);
                 command.cancel.insert(key.clone(), value.clone());
             }
         }
@@ -943,7 +943,7 @@ impl Strategy {
     // 超时触发查单信号
     #[instrument(skip(self, command), level="TRACE")]
     pub fn _check_local_orders(&mut self, command: &mut OrderCommand) {
-        trace!(?command);
+        debug!(?command);
         // 超时检测
         if self.local_time - self._check_local_orders_time < self._check_local_orders_interval {
             return;
@@ -973,7 +973,7 @@ impl Strategy {
             self.in_check.insert(client_id.clone(), self.local_time);
             info!("查询订单:{:?}", client_id.clone());
 
-            trace!(?command);
+            debug!(?command);
         }
 
         // 维护查单队列
@@ -985,7 +985,7 @@ impl Strategy {
     // 开单指令生成逻辑
     #[instrument(skip(self, command), level="TRACE")]
     pub fn _post_open(&mut self, command: &mut OrderCommand) {
-        trace!(?command);
+        debug!(?command);
         // 开仓逻辑检测,主要是检测整点开仓逻辑
         if !self.check_allow_post_open() {
             return;
@@ -1023,7 +1023,7 @@ impl Strategy {
         // 计算可开价值
         let mut long_free_value = self.max_long_value - self.long_hold_value - buy_value;
         let mut short_free_value = self.max_short_value - self.short_hold_value - sell_value;
-        trace!(?long_free_value, ?short_free_value);
+        debug!(?long_free_value, ?short_free_value);
         // 现货要特殊处理
         if self.exchange.contains("spot") {
             let coin_value = self.coin * self.mp * self.lever_rate * self.adjust_lever_rate;
@@ -1036,10 +1036,10 @@ impl Strategy {
         let one_hand_long_value = dec!(0.99) * (self.max_long_value / self.grid);
         let one_hand_short_value = dec!(0.99) * (self.max_short_value / self.grid);
 
-        trace!(?self.post_side);
+        debug!(?self.post_side);
         // 挂多单
         if self.post_side >= 0 {
-            trace!(?buy_price_list);
+            debug!(?buy_price_list);
             if buy_price_list.len() == 0 {
                 let mut target_buy_price = (long_upper + long_lower) * dec!(0.5);
                 target_buy_price = utils::clip(target_buy_price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
@@ -1058,7 +1058,7 @@ impl Strategy {
                         client_id.clone(),
                     ];
 
-                    trace!(?order);
+                    debug!(?order);
                     command.limits_open.insert(client_id.clone(), order);
 
                     // 报单时间更新
@@ -1068,7 +1068,7 @@ impl Strategy {
         }
         // 挂空单
         if self.post_side <= 0 {
-            trace!(?sell_price_list);
+            debug!(?sell_price_list);
             if sell_price_list.len() == 0 {
                 let mut target_sell_price = (short_lower + short_upper) * dec!(0.5);
                 target_sell_price = utils::clip(target_sell_price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
@@ -1087,7 +1087,7 @@ impl Strategy {
                         client_id.clone(),
                     ];
 
-                    trace!(?order);
+                    debug!(?order);
                     command.limits_open.insert(client_id.clone(), order);
 
                     // 报单时间更新
@@ -1156,7 +1156,7 @@ impl Strategy {
 mod tests {
     use rust_decimal::Decimal;
     use rust_decimal_macros::dec;
-    use tracing::{trace};
+    use tracing::debug;
     use crate::model::{OrderInfo, TraderMsg};
     use crate::params::Params;
     use crate::strategy::Strategy;
@@ -1190,6 +1190,6 @@ mod tests {
         strategy.equity = dec!(1000);
         strategy.lever_rate = Decimal::ONE;
 
-        trace!("{:?}", strategy.on_time(&trader_msg));
+        debug!("{:?}", strategy.on_time(&trader_msg));
     }
 }

+ 94 - 0
tests/order_command_test.rs

@@ -0,0 +1,94 @@
+use std::collections::{BTreeMap};
+use std::{env};
+use tokio::sync::mpsc;
+use std::io::Error;
+use std::time::Duration;
+use tracing::{error, info, subscriber, trace};
+use exchanges::proxy;
+use standard::exchange::{Exchange, ExchangeEnum};
+use standard::{Order, OrderCommand};
+
+#[tokio::test]
+async fn main() {
+    if proxy::ParsingDetail::http_enable_proxy() {
+        println!("检测有代理配置,配置走代理")
+    }
+    let mut params: BTreeMap<String, String> = BTreeMap::new();
+    let access_key = env::var("gate_access_key").unwrap_or("".to_string());
+    let secret_key = env::var("gate_secret_key").unwrap_or("".to_string());
+    params.insert("access_key".to_string(), access_key);
+    params.insert("secret_key".to_string(), secret_key);
+    let exchange = Exchange::new(ExchangeEnum::GateSwap, "BTC_USDT".to_string(), false, params);
+
+    let sub = tracing_subscriber::fmt()
+        .with_max_level(tracing::Level::INFO)
+        .with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
+        .finish();
+    subscriber::set_global_default(sub).expect("策略模块日志初始化错误");
+
+    let (order_sender, mut order_receiver) = mpsc::channel::<Order>(100);
+    let (error_sender, mut error_receiver) = mpsc::channel::<Error>(100);
+
+    let main_thread = tokio::spawn(async move {
+        let client_id_0 = "123425678".to_string();
+        let client_id_1 = "123452679".to_string();
+
+        loop {
+            // 下单
+            info!("下单");
+            let mut command = OrderCommand::new();
+            command.limits_open.insert("BTC_USDT1".to_string(), vec!["0.001".to_string(), "kd".to_string(), "25000".to_string(), client_id_0.clone()]);
+            command.limits_open.insert("BTC_USDT2".to_string(), vec!["0.001".to_string(), "kk".to_string(), "28000".to_string(), client_id_1.clone()]);
+            exchange.command_order(command.clone(), order_sender.clone(), error_sender.clone()).await;
+            tokio::time::sleep(Duration::from_secs(5)).await;
+
+            // 查单
+            info!("查单");
+            let mut command = OrderCommand::new();
+            command.check.insert("BTC_USDT1".to_string(), vec![client_id_0.clone(), "".to_string()]);
+            command.check.insert("BTC_USDT2".to_string(), vec![client_id_1.clone(), "".to_string()]);
+            exchange.command_order(command.clone(), order_sender.clone(), error_sender.clone()).await;
+            tokio::time::sleep(Duration::from_secs(5)).await;
+
+            // 撤单
+            info!("撤单");
+            let mut command = OrderCommand::new();
+            command.cancel.insert("BTC_USDT1".to_string(), vec![client_id_0.clone(), "".to_string()]);
+            command.cancel.insert("BTC_USDT2".to_string(), vec![client_id_1.clone(), "".to_string()]);
+            exchange.command_order(command.clone(), order_sender.clone(), error_sender.clone()).await;
+            tokio::time::sleep(Duration::from_secs(10)).await;
+        }
+    });
+
+    let handler_thread = tokio::spawn(async move {
+        info!("handler_thread被创建");
+
+        loop {
+            match order_receiver.recv().await {
+                Some(order) => {
+                    info!(?order)
+                },
+                None => {
+                    error!("Channel has been closed!");
+                    break;
+                }
+            }
+        }
+    });
+
+    let error_handler_thread = tokio::spawn(async move {
+        info!("error_handler_thread被创建");
+
+        loop {
+            match error_receiver.recv().await {
+                Some(error) => error!(?error),
+                None => {
+                    error!("Channel has been closed!");
+                    break;
+                }
+            }
+        }
+    });
+
+    tokio::try_join!(main_thread, handler_thread, error_handler_thread).unwrap();
+}

+ 0 - 0
main/tests/sub_task_test.rs → tests/sub_task_test.rs