strategy.rs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. use std::cmp::{max, min};
  2. use std::collections::HashMap;
  3. use std::ops::{Div, Mul};
  4. use chrono::Utc;
  5. use rust_decimal::Decimal;
  6. use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
  7. use rust_decimal_macros::dec;
  8. use crate::model::{LocalPosition, OrderInfo};
  9. use crate::utils;
  10. use tracing::{info, error, warn};
  11. use tokio::time::Instant;
  12. use global::params::Params;
  13. use standard::{OrderCommand};
  14. use crate::avellaneda_stoikov::AvellanedaStoikov;
  15. #[derive(Debug)]
  16. pub struct Strategy {
  17. // 各类时间戳和时延,我们都改成了毫秒级
  18. pub _print_time: i64, // 上次打印时间
  19. pub _print_interval: i64, // 打印时延
  20. pub _start_time: i64, // 开始时间
  21. pub local_time: i64, // 本地时间
  22. pub local_start_time: i64, // 本地开始时间
  23. pub post_open_time: i64, // 上次提交订单的时间戳
  24. pub post_open_interval: i64, // 提交订单时延
  25. pub _check_local_orders_time: i64, // 上次查单时间
  26. pub _check_local_orders_interval: i64, // 查单间距,原文是秒级,这里改成毫秒级
  27. pub in_cancel: HashMap<String, i64>, // 撤单队列
  28. pub cancel_wait_interval: i64, // 取消等待时延
  29. pub in_check: HashMap<String, i64>, // 查单队列
  30. pub check_wait_interval: i64, // 检测时延
  31. pub request_limit_check_time: i64, // 上次检查订单的时间
  32. pub request_limit_check_interval: i64, // 原文是秒级,这里改成毫秒级
  33. pub request_count: i64, // 记录请求次数,原文的request_num
  34. pub request_order_count: i64, // 记录下单次数,原文的request_order_num
  35. pub request_over_log_interval: i64, // 两次超时打印之间的间隔
  36. pub request_over_log_time: i64, // 上次打印时间
  37. pub limit_requests_num: i64, // 单位(时延)时间内请求次数上限
  38. pub limit_order_requests_num: i64, // 单位(时延)时间内下单次数上限
  39. pub _req_num_per_window: i64, // 单位(时延)时间内请求上限窗口
  40. pub params: Params, //
  41. pub exchange: String, //
  42. pub broker_id: String, //
  43. pub trade_name: String, //
  44. pub ref_exchange_length: usize, //
  45. pub ref_name: Vec<String>, //
  46. pub maker_mode: String, //
  47. pub local_orders: HashMap<String, OrderInfo>, // 本地订单
  48. pub pos: LocalPosition, //
  49. pub long_hold_value: Decimal, //
  50. pub short_hold_value: Decimal, //
  51. pub equity: Decimal, //
  52. pub coin: Decimal, //
  53. pub cash: Decimal, //
  54. pub start_equity: Decimal, //
  55. pub start_coin: Decimal, //
  56. pub start_cash: Decimal, //
  57. pub max_equity: Decimal, //
  58. pub local_profit: Decimal, //
  59. pub total_amount: Decimal, //
  60. pub is_ready: bool, // 程序是否已经准备好,ready
  61. pub _is_print: bool, //
  62. pub mp_ema: Decimal, // 原文的mp_ewma
  63. pub mp: Decimal, //
  64. pub bp: Decimal, //
  65. pub ap: Decimal, //
  66. pub ref_price: Decimal, //
  67. pub ref_bp: Decimal, //
  68. pub ref_ap: Decimal, //
  69. pub step_size: Decimal, // 原文的stepSize
  70. pub tick_size: Decimal, // 原文的tickSize
  71. pub min_amount_value: Decimal, // 最小下单价值
  72. pub max_amount_value: Decimal, // 最大下单价值
  73. pub max_pos_rate: Decimal, // 原文的maxPos,其实是最大持仓比例
  74. pub profit: Decimal, //
  75. pub daily_return: Decimal, //
  76. pub adjust_lever_rate: Decimal, // 原文的adjust_leverrate
  77. pub lever_rate: Decimal, // 原文的leverrate
  78. pub long_pos_bias: Decimal, // 做多浮盈
  79. pub short_pos_bias: Decimal, // 做空浮盈
  80. pub long_hold_rate: Decimal, //
  81. pub short_hold_rate: Decimal, //
  82. pub max_long_value: Decimal, // 最大做多持仓
  83. pub max_short_value: Decimal, // 最大做空持仓
  84. pub open_dist: Vec<Decimal>, // 开仓相关价格
  85. pub trade_close_dist: Decimal, //
  86. pub trade_open_dist: Decimal, //
  87. pub ref_index: usize, //
  88. pub predict: Decimal, //
  89. pub predict_alpha: Decimal, //
  90. pub post_side: i64, // 交易方向
  91. pub trade_vol_24h_w: Decimal, // 24小时成交额(单位:万)
  92. pub grid: Decimal, // 网格数量
  93. // pub open_num: i64,
  94. // pub no_open_num: i64
  95. }
  96. impl Strategy {
  97. pub fn new(params: &Params, is_print: bool) -> Self {
  98. if params.ref_exchange.len() != params.ref_pair.len(){
  99. error!("参考盘口数不等于参考品种数,退出,请检查配置!");
  100. panic!("参考盘口数不等于参考品种数,退出,请检查配置!");
  101. }
  102. // strategy的初始化,里面已经有一些参数初始化了
  103. let mut strategy = Self {
  104. _print_time: 0,
  105. _start_time: 0,
  106. local_time: 0,
  107. local_start_time: 0,
  108. request_count: 0,
  109. request_order_count: 0,
  110. request_over_log_interval: 60 * 1000,
  111. request_over_log_time: 0,
  112. _print_interval: 5 * 1000,
  113. in_cancel: Default::default(),
  114. cancel_wait_interval: (0.2 * 1000f64).to_i64().unwrap(),
  115. in_check: Default::default(),
  116. check_wait_interval: 10 * 1000,
  117. _check_local_orders_time: 0,
  118. _check_local_orders_interval: 0,
  119. request_limit_check_time: 0,
  120. request_limit_check_interval: 0,
  121. limit_requests_num: 0,
  122. limit_order_requests_num: 0,
  123. _req_num_per_window: 0,
  124. post_open_time: 0,
  125. post_open_interval: 0,
  126. params: params.clone(),
  127. exchange: params.exchange.clone(),
  128. broker_id: params.broker_id.clone(),
  129. trade_name: "".to_string(),
  130. ref_exchange_length: params.ref_exchange.len(),
  131. ref_name: vec![],
  132. maker_mode: "free".to_string(),
  133. local_orders: Default::default(),
  134. pos: LocalPosition {
  135. long_pos: Default::default(),
  136. short_pos: Default::default(),
  137. long_avg: Default::default(),
  138. short_avg: Default::default(),
  139. },
  140. long_hold_value: Default::default(),
  141. short_hold_value: Default::default(),
  142. equity: Default::default(),
  143. coin: Default::default(),
  144. cash: Default::default(),
  145. start_equity: Default::default(),
  146. start_coin: Default::default(),
  147. start_cash: Default::default(),
  148. max_equity: Default::default(),
  149. local_profit: Default::default(),
  150. total_amount: Default::default(),
  151. is_ready: false,
  152. _is_print: is_print,
  153. min_amount_value: dec!(0.01),
  154. max_amount_value: dec!(10000.0),
  155. mp_ema: Default::default(),
  156. mp: Default::default(),
  157. bp: Default::default(),
  158. ap: Default::default(),
  159. ref_price: Default::default(),
  160. ref_bp: Default::default(),
  161. ref_ap: Default::default(),
  162. step_size: dec!(1e-10),
  163. tick_size: dec!(1e-10),
  164. max_pos_rate: Default::default(),
  165. profit: Default::default(),
  166. daily_return: Default::default(),
  167. adjust_lever_rate: Decimal::ONE,
  168. lever_rate: Default::default(),
  169. long_pos_bias: Default::default(),
  170. short_pos_bias: Default::default(),
  171. long_hold_rate: Default::default(),
  172. short_hold_rate: Default::default(),
  173. max_long_value: Default::default(),
  174. max_short_value: Default::default(),
  175. open_dist: vec![],
  176. trade_close_dist: params.close,
  177. trade_open_dist: params.open,
  178. ref_index: 0,
  179. predict: Default::default(),
  180. predict_alpha: Default::default(),
  181. post_side: 0,
  182. trade_vol_24h_w: Default::default(),
  183. grid: Decimal::from(params.grid),
  184. // open_num: 0,
  185. // no_open_num: 0,
  186. };
  187. // 交易名字
  188. strategy.trade_name = format!("{}@{}", params.exchange.clone(), params.pair.clone());
  189. // 参考交易所的trade_name
  190. for index in 0..strategy.ref_exchange_length {
  191. strategy.ref_name.push(format!("{}@{}", params.ref_exchange[index], params.ref_pair[index]));
  192. }
  193. // 杠杆比例处理
  194. strategy.lever_rate = params.lever_rate;
  195. if strategy.exchange.contains("spot") {
  196. strategy.lever_rate = min(params.lever_rate, Decimal::ONE);
  197. }
  198. // 各类时间戳
  199. let now = Utc::now();
  200. strategy.local_time = now.timestamp_millis();
  201. strategy.local_start_time = now.timestamp_millis();
  202. strategy._print_time = now.timestamp_millis();
  203. strategy._start_time = now.timestamp_millis();
  204. // 检查订单的时间戳
  205. strategy._check_local_orders_time = now.timestamp_millis();
  206. strategy._check_local_orders_interval = 10 * 1000;
  207. // 下单的相关限制处理
  208. strategy.request_limit_check_time = now.timestamp_millis();
  209. strategy.request_limit_check_interval = 10 * 1000;
  210. // 求得正常请求数量和下单请求数量(interval时间内)
  211. let request_limit_check_interval_per_second = strategy.request_limit_check_interval / 1000;
  212. strategy.limit_requests_num = utils::get_limit_requests_num_per_second(params.exchange.clone()) * (request_limit_check_interval_per_second);
  213. strategy.limit_order_requests_num = utils::get_limit_order_requests_num_per_second(params.exchange.clone()) * (request_limit_check_interval_per_second);
  214. // 开仓下单间隔 均匀下单机会
  215. strategy.post_open_time = now.timestamp_millis();
  216. let post_open_interval_per_second = Decimal::ONE.div(Decimal::from_i64(utils::get_limit_order_requests_num_per_second(params.exchange.clone())).unwrap());
  217. strategy.post_open_interval = dec!(1000).mul(post_open_interval_per_second).to_i64().unwrap();
  218. info!("策略模块初始化完成!");
  219. return strategy;
  220. }
  221. // 更新当前strategy的各类信息
  222. // #[instrument(skip(self, trader_msg), level="TRACE")]
  223. pub fn _update_data(&mut self,
  224. local_position: &LocalPosition,
  225. agg_market: &Vec<Decimal>,
  226. local_cash: &Decimal,
  227. local_coin: &Decimal,
  228. ref_price: &Vec<Vec<Decimal>>,
  229. predict: &Decimal) -> bool {
  230. // position信息更新
  231. if self.pos.long_pos != local_position.long_pos {
  232. self.pos.long_pos = local_position.long_pos;
  233. self.pos.long_avg = local_position.long_avg;
  234. }
  235. if self.pos.short_pos != local_position.short_pos {
  236. self.pos.short_pos = local_position.short_pos;
  237. self.pos.short_avg = local_position.short_avg;
  238. }
  239. // debug!(?self.pos);
  240. // 价格值处理
  241. self.bp = agg_market[global::public_params::BID_PRICE_INDEX];
  242. self.ap = agg_market[global::public_params::ASK_PRICE_INDEX];
  243. self.mp = (self.bp + self.ap) * dec!(0.5);
  244. // 中间价的ema值处理
  245. if self.mp_ema.eq(&Decimal::ZERO) {
  246. self.mp_ema = self.mp;
  247. } else {
  248. self.mp_ema = self.mp_ema * dec!(0.999) + self.mp * dec!(0.001);
  249. }
  250. // debug!(?self.bp, ?self.ap, ?self.mp, ?self.mp_ema);
  251. // 动态杠杆调节
  252. if self.mp > self.mp_ema {
  253. self.adjust_lever_rate = Decimal::ONE;
  254. } else {
  255. self.adjust_lever_rate = dec!(0.8);
  256. }
  257. // debug!(?self.adjust_lever_rate);
  258. // 当前持仓价值处理
  259. self.long_hold_value = self.pos.long_pos * self.mp;
  260. self.short_hold_value = self.pos.short_pos * self.mp;
  261. // debug!(?self.long_hold_value, ?self.short_hold_value);
  262. // 分现货或合约计算最大开仓价值
  263. if self.exchange.contains("spot") {
  264. self.max_long_value = *local_cash * self.lever_rate * self.adjust_lever_rate;
  265. self.max_short_value = *local_coin * self.lever_rate * self.adjust_lever_rate * self.mp;
  266. } else {
  267. self.max_long_value = self.equity * self.lever_rate * self.adjust_lever_rate;
  268. self.max_short_value = self.max_long_value;
  269. }
  270. // debug!(?self.max_long_value, ?self.max_short_value, ?self.equity, ?self.lever_rate, ?self.adjust_lever_rate);
  271. // 做市模式识别
  272. if self.ref_name[self.ref_index].eq(&self.trade_name) {
  273. self.maker_mode = "free".to_string();
  274. } else {
  275. self.maker_mode = "follow".to_string();
  276. }
  277. // debug!(?self.maker_mode);
  278. // 参考价格
  279. if ref_price.len() == 0 {
  280. self.ref_bp = self.bp;
  281. self.ref_ap = self.ap;
  282. self.ref_price = self.mp;
  283. } else {
  284. self.ref_bp = ref_price[self.ref_index][0];
  285. self.ref_ap = ref_price[self.ref_index][1];
  286. self.ref_price = (self.ref_bp + self.ref_ap) * dec!(0.5);
  287. }
  288. // debug!(?self.ref_bp, ?self.ref_ap, %self.ref_price);
  289. // spread
  290. let temp_predict = predict * self.predict_alpha;
  291. self.predict = utils::clip(temp_predict, -self.trade_open_dist, self.trade_open_dist);
  292. // debug!(?self.predict);
  293. // 计算当前账户cash和coin
  294. self.coin = local_coin.clone();
  295. self.cash = local_cash.clone();
  296. self.equity = local_cash + local_coin * self.mp;
  297. if self.equity > self.max_equity {
  298. self.max_equity = self.equity;
  299. }
  300. // debug!(?self.coin, ?self.cash, ?self.equity, ?self.max_equity);
  301. // 总可开数量
  302. self.total_amount = self.equity * self.lever_rate * self.adjust_lever_rate / self.mp;
  303. self.total_amount = utils::fix_amount(self.total_amount, self.step_size);
  304. // debug!(?self.total_amount);
  305. if self.total_amount.eq(&Decimal::ZERO) {
  306. error!("总可开数量低于一张,请尝试加大杠杆倍数或资金!equity={}, lever_rate={}, adjust_lever_rate={}, mp={}, step_size={}",
  307. self.equity, self.lever_rate, self.adjust_lever_rate, self.mp, self.step_size);
  308. return false;
  309. }
  310. // 求最大pos
  311. if self.equity > Decimal::ZERO {
  312. let max_pos_rate = max(self.pos.long_pos, self.pos.short_pos) * self.mp / self.equity;
  313. if max_pos_rate > self.max_pos_rate {
  314. self.max_pos_rate = max_pos_rate;
  315. }
  316. // debug!(?max_pos_rate, ?self.max_pos_rate);
  317. }
  318. return true;
  319. }
  320. // 打印状态信息
  321. // 耗时700微秒
  322. // #[instrument(skip(self), level="TRACE")]
  323. pub fn _print_summary(&mut self) {
  324. self.mp.rescale(10);
  325. self.ref_price.rescale(10);
  326. self.equity.rescale(3);
  327. self.cash.rescale(3);
  328. let mut value = self.coin * self.mp;
  329. value.rescale(3);
  330. let mut price_bias = Decimal::ONE_HUNDRED * (self.ref_price - self.mp) / self.mp;
  331. price_bias.rescale(2);
  332. // 盈亏计算
  333. self.profit = if self.start_equity.gt(&Decimal::ZERO) {
  334. ((self.equity - self.start_equity) / self.start_equity) * Decimal::ONE_HUNDRED
  335. } else {
  336. Decimal::ZERO
  337. };
  338. self.profit.rescale(2);
  339. // 多仓杠杆计算
  340. let mut long_pos_leverage = if self.equity.gt(&Decimal::ZERO) {
  341. self.pos.long_pos * self.mp / self.equity
  342. } else {
  343. Decimal::ZERO
  344. };
  345. long_pos_leverage.rescale(3);
  346. // 多仓浮盈计算
  347. self.long_pos_bias = if self.pos.long_pos.gt(&Decimal::ZERO) {
  348. Decimal::ONE_HUNDRED - Decimal::ONE_HUNDRED * self.pos.long_avg / self.mp
  349. } else {
  350. Decimal::ZERO
  351. };
  352. self.long_pos_bias.rescale(2);
  353. // 空仓杠杆计算
  354. let mut short_pos_leverage = if self.equity.gt(&Decimal::ZERO) {
  355. self.pos.short_pos * self.mp / self.equity
  356. } else {
  357. Decimal::ZERO
  358. };
  359. short_pos_leverage.rescale(3);
  360. // 多仓浮盈计算
  361. self.short_pos_bias = if self.pos.short_pos.gt(&Decimal::ZERO) {
  362. Decimal::ONE_HUNDRED - Decimal::ONE_HUNDRED * self.pos.short_avg / self.mp
  363. } else {
  364. Decimal::ZERO
  365. };
  366. let run_time = Utc::now().timestamp_millis() - self._start_time;
  367. let run_time_day = Decimal::from(run_time) / (dec!(86400000));
  368. self.daily_return = self.profit / run_time_day;
  369. self.daily_return.rescale(2);
  370. self.short_pos_bias.rescale(2);
  371. self.trade_open_dist.rescale(6);
  372. self.trade_close_dist.rescale(6);
  373. self.predict.rescale(5);
  374. // 挂单列表长度
  375. let o_num = self.local_orders.len();
  376. let mut msg = String::new();
  377. msg.push_str("当前状态: ");
  378. msg.push_str(format!("[品种 {}, 现价 {:?}, 定价 {:?}, 偏差 {:?}%, 杠杆 {:?}, 动态{:?}, 最大{:?}, 预测 {:?}, 预估24H成交额 {:?}万], ",
  379. self.params.pair, self.mp, self.ref_price, price_bias, self.lever_rate,
  380. self.adjust_lever_rate, self.max_pos_rate, self.predict, self.trade_vol_24h_w).as_str());
  381. msg.push_str(format!("[净值 {:?}, Cash {:?}, Coin(价值) {:?}, 日化 {:?}%], ", self.equity, self.cash, value, self.daily_return).as_str());
  382. msg.push_str(format!("[推算利润 {:?}, 盈亏 {:?}%, 做多杠杆 {:?}%, 做多浮盈 {:?}%, 做空杠杆 {:?}%, 做空浮盈 {:?}%], ",
  383. self.local_profit, self.profit, long_pos_leverage, self.long_pos_bias, short_pos_leverage, self.short_pos_bias).as_str());
  384. msg.push_str(format!("[请求 {:?}, 上限{:?}次/10秒], ", self._req_num_per_window, self.limit_order_requests_num).as_str());
  385. msg.push_str(format!("[当前参数, 开仓 {:?}, 平仓 {:?}, 参考 {:?}, 模式 {:?}], ",
  386. self.trade_open_dist, self.trade_close_dist, self.ref_name[self.ref_index], self.maker_mode).as_str());
  387. msg.push_str(format!("[挂单列表,共{:?}单, ", o_num).as_str());
  388. for (_, order) in &self.local_orders {
  389. let mut order_value = order.amount * self.mp;
  390. let mut order_lever_rate = if self.equity.gt(&Decimal::ZERO) {
  391. order.amount * self.mp / self.equity
  392. } else {
  393. Decimal::ZERO
  394. };
  395. let mut order_bias = Decimal::ONE_HUNDRED * (order.price - self.mp) / self.mp;
  396. order_value.rescale(2);
  397. order_lever_rate.rescale(3);
  398. order_bias.rescale(3);
  399. msg.push_str(format!("[{:?} {:?} {:?}, 杠杆{:?}X 价值{:?}U 价格{:?} 偏离{:?}%]",
  400. order.symbol, order.client_id, order.side, order_lever_rate, order_value, order.price, order_bias).as_str());
  401. }
  402. msg.push_str("]");
  403. info!("{}", msg);
  404. }
  405. // 取消目标方向订单,原文是_cancel_targit_side_orders
  406. // #[instrument(skip(self, command), level="TRACE")]
  407. pub fn _cancel_target_side_orders(&self, command: &mut OrderCommand) {
  408. // 要取消的目标方向
  409. let target_side = vec![
  410. "kd".to_string(),
  411. "kk".to_string(),
  412. "pd".to_string(),
  413. "pk".to_string()
  414. ];
  415. // debug!(?self.local_orders);
  416. for client_id in self.local_orders.keys() {
  417. let order = self.local_orders.get(client_id).unwrap();
  418. // 如果不属于目标方向,则不需要取消
  419. if !target_side.contains(&order.side.clone()) {
  420. continue;
  421. }
  422. // 属于目标方向,则取消
  423. let key = format!("Cancel{}", client_id);
  424. let value = vec![order.client_id.clone(), order.order_id.clone()];
  425. command.cancel.insert(key, value);
  426. }
  427. // debug!(?command);
  428. }
  429. // 修复挂单价格,不然单子打不出去
  430. // #[instrument(skip(self), level="TRACE")]
  431. pub fn fix_price(&mut self, predictor: &mut AvellanedaStoikov) {
  432. predictor.optimal_ask_price = utils::fix_price(predictor.optimal_ask_price, self.tick_size);
  433. predictor.optimal_bid_price = utils::fix_price(predictor.optimal_bid_price, self.tick_size);
  434. let delta_ask = predictor.ask_delta.clone();
  435. let delta_bid = predictor.ask_delta.clone();
  436. // 开仓相关
  437. let avoid_ask = min(dec!(0.001), (delta_ask / predictor.mid_price) * dec!(0.1));
  438. let avoid_bid = min(dec!(0.001), (delta_bid / predictor.mid_price) * dec!(0.1));
  439. // 用于判断价格是否出界
  440. self.open_dist = vec![
  441. predictor.optimal_bid_price * (Decimal::ONE + avoid_bid), // buy upper
  442. predictor.optimal_bid_price * (Decimal::ONE - avoid_bid), // buy lower
  443. predictor.optimal_ask_price * (Decimal::ONE - avoid_ask), // sell lower
  444. predictor.optimal_ask_price * (Decimal::ONE + avoid_ask), // sell upper
  445. ];
  446. // 修复价格范围
  447. for open_price in &mut self.open_dist {
  448. *open_price = utils::fix_price(*open_price, self.tick_size);
  449. }
  450. }
  451. // 统计请求次数
  452. // #[instrument(skip(self, command), level="TRACE")]
  453. pub fn _update_request_num(&mut self, command: &OrderCommand) {
  454. // debug!(?command);
  455. // debug!(?self.request_order_count, ?self.request_count);
  456. let order_count = (command.limits_open.len() + command.limits_close.len()).to_i64().unwrap();
  457. let request_count = order_count + (command.cancel.len() + command.check.len()).to_i64().unwrap();
  458. self.request_order_count += order_count;
  459. self.request_count += request_count;
  460. // debug!(?self.request_order_count, ?self.request_count);
  461. }
  462. // 根据平均请求次数限制开仓下单
  463. // #[instrument(skip(self, command), level="TRACE")]
  464. pub fn _check_request_limit(&mut self, command: &mut OrderCommand) {
  465. let mut msg = String::new();
  466. // 如果当前请求数超过限制
  467. if self.request_count > self.limit_requests_num {
  468. command.cancel.clear();
  469. command.check.clear();
  470. command.limits_open.clear();
  471. command.limits_close.clear();
  472. msg = format!("请求频率溢出,程序禁止任何操作!({}/{})", self.request_count, self.limit_requests_num);
  473. } else if self.request_order_count >= self.limit_order_requests_num { // 100%超过下单频率,则不再进行平仓挂单
  474. command.limits_close.clear();
  475. command.limits_open.clear();
  476. msg = format!("超过100%下单频率!程序禁止开平仓!({}/{})", self.request_order_count, self.limit_order_requests_num);
  477. } else if self.request_count > self.limit_requests_num * 5 / 10
  478. && self.request_order_count > self.limit_order_requests_num * 8 / 10 { // 超过80%,直接取消limits_open的下单指令
  479. command.limits_open.clear();
  480. msg = format!("超过80%下单频率,程序禁止开仓!({}/{})", self.request_order_count, self.limit_order_requests_num);
  481. }
  482. // 检查是否需要打印msg
  483. if !msg.is_empty() && self.local_time - self.request_over_log_time > self.request_over_log_interval {
  484. warn!("{}", msg);
  485. self.request_over_log_time = self.local_time;
  486. }
  487. }
  488. // 新增正在撤单、检查撤单队列,释放过时限制
  489. // #[instrument(skip(self), level="TRACE")]
  490. pub fn _update_in_cancel(&mut self,
  491. command: &mut OrderCommand,
  492. local_orders: &HashMap<String, OrderInfo>) {
  493. let mut new_cancel: HashMap<String, Vec<String>> = HashMap::new();
  494. for cancel_name in command.cancel.keys() {
  495. let cancel = command.cancel.get(cancel_name).unwrap();
  496. let client_id = cancel[0].clone();
  497. let mut need_limit_cancel = true;
  498. let order_some = local_orders.get(&client_id);
  499. // 判断是否在本地挂单表中
  500. if let Some(order) = order_some {
  501. let is_side_error = (order.side == "kk") || (order.side == "kd");
  502. // 如果订单创建时间大于100ms,才能有撤单操作
  503. if self.local_time - order.create_time < 100 {
  504. need_limit_cancel = false;
  505. }
  506. // 如果方向有误,直接撤单
  507. if is_side_error {
  508. need_limit_cancel = true;
  509. }
  510. }
  511. if need_limit_cancel {
  512. // 如果已经不在撤销队列里,增加到撤销队列
  513. if self.in_cancel.get(&client_id).is_none() {
  514. self.in_cancel.insert(client_id, self.local_time);
  515. new_cancel.insert(cancel_name.clone(), cancel.clone());
  516. }
  517. }
  518. }
  519. // debug!(?command);
  520. command.cancel = new_cancel;
  521. // debug!(?command);
  522. // 释放撤单限制
  523. self._release_in_cancel();
  524. }
  525. // 维护查单队列,检查是否在撤单
  526. // #[instrument(skip(self), level="TRACE")]
  527. pub fn _release_in_check(&mut self) {
  528. // debug!(?self.in_check);
  529. // 为什么要移出来:Rust不允许边循环边修改map
  530. let mut to_remove = Vec::new();
  531. for client_id in self.in_check.keys() {
  532. let time = self.in_check.get(client_id).unwrap();
  533. // 等待不超时,就不移除
  534. if self.local_time - time <= self.check_wait_interval {
  535. continue;
  536. }
  537. // 等待超时,就移除正在撤单队列
  538. // debug!("移除查单队列:{}", client_id.clone());
  539. to_remove.push(client_id.clone());
  540. }
  541. // 在后面的循环中去单独处理map的更新
  542. for client_id in to_remove {
  543. self.in_check.remove(&client_id);
  544. }
  545. // debug!(?self.in_check);
  546. }
  547. // 检查是否正在撤单
  548. // #[instrument(skip(self), level="TRACE")]
  549. pub fn _release_in_cancel(&mut self) {
  550. // debug!(?self.in_cancel);
  551. // 为什么要移出来:Rust不允许边循环边修改map
  552. let mut to_remove = Vec::new();
  553. for client_id in self.in_cancel.keys() {
  554. let time = self.in_cancel.get(client_id).unwrap();
  555. // 等待不超时,就不移除
  556. if self.local_time - time <= self.cancel_wait_interval {
  557. continue;
  558. }
  559. // 等待超时,就移除正在撤单队列
  560. // debug!("等待超过后移除正在撤单队列:{}", client_id.clone());
  561. to_remove.push(client_id.clone());
  562. }
  563. // 在后面的循环中去单独处理map的更新
  564. for client_id in to_remove {
  565. self.in_cancel.remove(&client_id);
  566. }
  567. // debug!(?self.in_cancel);
  568. }
  569. // 刷新请求限制
  570. pub fn _refresh_request_limit(&mut self) {
  571. if self.local_time - self.request_limit_check_time < self.request_limit_check_interval {
  572. return;
  573. }
  574. self._req_num_per_window = self.request_count;
  575. self.request_count = 0;
  576. self.request_order_count = 0;
  577. self.request_limit_check_time = self.local_time;
  578. }
  579. // 刷新持仓比例
  580. // #[instrument(skip(self), level="TRACE")]
  581. pub fn _pos_rate(&mut self) {
  582. // debug!(?self);
  583. if self.max_long_value > Decimal::ZERO {
  584. self.long_hold_rate = self.long_hold_value / self.max_long_value;
  585. // debug!(?self.long_hold_rate);
  586. }
  587. if self.max_short_value > Decimal::ZERO {
  588. self.short_hold_rate = self.short_hold_value / self.max_short_value;
  589. // debug!(?self.short_hold_rate);
  590. }
  591. }
  592. // 当退出时调用,全撤全平 准备退出
  593. pub fn on_exit(&mut self,
  594. local_orders: &HashMap<String, OrderInfo>,
  595. local_position: &LocalPosition,
  596. agg_market: &Vec<Decimal>,
  597. local_cash: &Decimal,
  598. local_coin: &Decimal,
  599. ref_price: &Vec<Vec<Decimal>>,
  600. predict: &Decimal) -> OrderCommand {
  601. let mut command = OrderCommand::new();
  602. if self._update_data(local_position,
  603. agg_market,
  604. local_cash,
  605. local_coin,
  606. ref_price,
  607. predict) {
  608. if !self.check_ready() {
  609. return command;
  610. }
  611. // 取消、平掉所有
  612. self._close_all(&mut command);
  613. // 更新撤单队列
  614. self._update_in_cancel(&mut command, local_orders);
  615. // 检查限频
  616. self._check_request_limit(&mut command);
  617. // 统计请求频率
  618. self._update_request_num(&mut command);
  619. }
  620. // debug!(?command);
  621. return command;
  622. }
  623. // 休眠时调用,全撤 不再下新订单了 防止影响check_position执行
  624. pub fn on_sleep(&mut self,
  625. local_orders: &HashMap<String, OrderInfo>,
  626. local_position: &LocalPosition,
  627. agg_market: &Vec<Decimal>,
  628. local_cash: &Decimal,
  629. local_coin: &Decimal,
  630. ref_price: &Vec<Vec<Decimal>>,
  631. predict: &Decimal) -> OrderCommand {
  632. let mut command = OrderCommand::new();
  633. if self._update_data(local_position,
  634. agg_market,
  635. local_cash,
  636. local_coin,
  637. ref_price,
  638. predict) {
  639. if !self.check_ready() {
  640. return command;
  641. }
  642. // 只是取消掉目标侧订单
  643. self._cancel_target_side_orders(&mut command);
  644. // 更新撤单队列
  645. self._update_in_cancel(&mut command, local_orders);
  646. // 检查限频
  647. self._check_request_limit(&mut command);
  648. // 统计请求频率
  649. self._update_request_num(&mut command);
  650. }
  651. // debug!(?command);
  652. return command;
  653. }
  654. // 清空所有挂单和仓位保持休眠状态
  655. // #[instrument(skip(self, command), level="TRACE")]
  656. pub fn _close_all(&self, command: &mut OrderCommand) {
  657. // 撤掉全部挂单
  658. let mut pd_amount = Decimal::ZERO;
  659. let mut pk_amount = Decimal::ZERO;
  660. // debug!(?self.local_orders);
  661. for client_id in self.local_orders.keys() {
  662. let order = self.local_orders.get(client_id).unwrap();
  663. // 命令生成
  664. let key = format!("Cancel{}", client_id);
  665. let value = vec![order.client_id.clone(), order.order_id.clone()];
  666. command.cancel.insert(key, value);
  667. // 统计部分
  668. if order.side == "pk".to_string() {
  669. pk_amount += order.amount;
  670. } else if order.side == "pd".to_string() {
  671. pd_amount += order.amount;
  672. }
  673. }
  674. // debug!(?pd_amount, ?pk_amount);
  675. // 批量挂单
  676. let need_close_long = self.pos.long_pos - pd_amount;
  677. let need_close_short = self.pos.short_pos - pk_amount;
  678. // debug!(?need_close_long, ?need_close_short);
  679. // 做多仓位平仓
  680. if need_close_long * self.mp > self.min_amount_value {
  681. let mut amount = need_close_long;
  682. // 现货要对数量精度进行限定处理
  683. if self.exchange.contains("spot") {
  684. amount = utils::fix_amount(amount, self.step_size);
  685. }
  686. let price = utils::fix_price(self.mp, self.tick_size);
  687. let client_id = utils::generate_client_id(Some(self.broker_id.clone()));
  688. let value = vec![
  689. amount.to_string(),
  690. "pd".to_string(),
  691. price.to_string(),
  692. client_id.to_string()
  693. ];
  694. command.limits_close.insert(client_id.clone(), value);
  695. // debug!(?self.pos.long_pos, ?self.mp, ?need_close_long, ?command)
  696. }
  697. // 做空仓位平仓
  698. if need_close_short * self.mp > self.min_amount_value {
  699. let mut amount = need_close_short;
  700. if self.exchange.contains("spot") {
  701. amount = utils::fix_amount(amount, self.step_size);
  702. }
  703. let price = utils::fix_price(self.mp, self.tick_size);
  704. let client_id = utils::generate_client_id(Some(self.broker_id.clone()));
  705. let value = vec![
  706. amount.to_string(),
  707. "pk".to_string(),
  708. price.to_string(),
  709. client_id.to_string()
  710. ];
  711. command.limits_close.insert(client_id.clone(), value);
  712. // debug!(?self.pos.short_pos, ?self.mp, ?need_close_short, ?command)
  713. }
  714. }
  715. // 检查是否完成准备,注意:原文是未准备完成返回true!!!!!!!!!!!!!!!!!!!
  716. pub fn check_ready(&mut self) -> bool {
  717. if self.is_ready {
  718. return true;
  719. }
  720. let pre_hot:i64 = 10 * 1000;
  721. if !self.mp.eq(&Decimal::ZERO) && self.local_time - self.local_start_time > pre_hot {
  722. self.is_ready = true;
  723. // debug!(?self.mp, ?self.local_time, ?self.local_start_time, ?pre_hot);
  724. info!("策略预热完毕,可以执行后续逻辑!")
  725. }
  726. return false;
  727. }
  728. // 接近整点时刻 不允许报单 防止下单bug
  729. pub fn check_allow_post_open(&self) -> bool {
  730. let local_time_second = self.local_time / 1000;
  731. let diff_time = local_time_second % (60 * 60);
  732. return diff_time > 30 && diff_time < 3570;
  733. }
  734. // 生成取消订单的指令
  735. // #[instrument(skip(self, command), level="TRACE")]
  736. pub fn _cancel_open(&self, command: &mut OrderCommand, local_orders: &HashMap<String, OrderInfo>) {
  737. // debug!(?command);
  738. // 挂单范围
  739. let long_upper = self.open_dist[0];
  740. let long_lower = self.open_dist[1];
  741. let short_lower = self.open_dist[2];
  742. let short_upper = self.open_dist[3];
  743. for order_client_id in local_orders.keys() {
  744. let order = local_orders.get(order_client_id).unwrap();
  745. let key = format!("Cancel{}", *order_client_id);
  746. let value = vec![order.client_id.clone(), order.order_id.clone()];
  747. // 开多订单处理
  748. if order.side == "kd".to_string() {
  749. // 在价格范围内时不处理
  750. if order.price <= long_upper && order.price >= long_lower {
  751. // if self.local_time - order.local_time <= 200 {
  752. continue
  753. }
  754. // debug!(?key, ?order.price, ?long_upper, ?long_lower);
  755. command.cancel.insert(key, value);
  756. } else if order.side == "kk".to_string() { // 开空订单处理
  757. // 在价格范围内时不处理
  758. if order.price >= short_lower && order.price <= short_upper {
  759. // if self.local_time - order.local_time <= 200 {
  760. continue
  761. }
  762. // debug!(?key, ?order.price, ?short_lower, ?short_upper);
  763. command.cancel.insert(key, value);
  764. }
  765. }
  766. }
  767. // 超时触发查单信号
  768. // #[instrument(skip(self, command), level="TRACE")]
  769. pub fn _check_local_orders(&mut self,
  770. command: &mut OrderCommand,
  771. local_orders: &HashMap<String, OrderInfo>) {
  772. // debug!(?command);
  773. // 超时检测
  774. if self.local_time - self._check_local_orders_time < self._check_local_orders_interval {
  775. return;
  776. }
  777. // 查单指令生成主逻辑
  778. for client_id in local_orders.keys() {
  779. let check_some = self.in_check.get(client_id);
  780. // 如果在查单队列中,不需要再添加
  781. if let Some(_) = check_some {
  782. continue;
  783. }
  784. let order = local_orders.get(client_id).unwrap();
  785. // 没有超过10s的订单,不需要检查
  786. if self.local_time - order.local_time < self._check_local_orders_interval {
  787. continue;
  788. }
  789. let key = format!("Check{}", client_id);
  790. let value = vec![
  791. client_id.clone(),
  792. order.order_id.clone(),
  793. ];
  794. command.check.insert(key, value);
  795. self.in_check.insert(client_id.clone(), self.local_time);
  796. // debug!("查询订单:{:?}", client_id.clone());
  797. // debug!(?command);
  798. }
  799. // 维护查单队列
  800. self._release_in_check();
  801. // 更新查单时间
  802. self._check_local_orders_time = self.local_time;
  803. }
  804. // 开单指令生成逻辑
  805. // #[instrument(skip(self, command), level="TRACE")]
  806. pub fn _post_open(&mut self, command: &mut OrderCommand, local_orders: &HashMap<String, OrderInfo>, predictor: &mut AvellanedaStoikov) {
  807. // 开仓逻辑检测,主要是检测整点开仓逻辑
  808. if !self.check_allow_post_open() {
  809. return;
  810. }
  811. // 报单时延检测
  812. if self.local_time - self.post_open_time < self.post_open_interval {
  813. return;
  814. }
  815. // 报单时间更新
  816. self.post_open_time = self.local_time;
  817. // 获取当前挂单价值
  818. let mut buy_price_list: Vec<Decimal> = vec![];
  819. let mut sell_price_list: Vec<Decimal> = vec![];
  820. let mut buy_value = Decimal::ZERO;
  821. let mut sell_value = Decimal::ZERO;
  822. for client_id in local_orders.keys() {
  823. let order = local_orders.get(client_id).unwrap();
  824. if order.side == "kd".to_string() {
  825. buy_price_list.push(order.price);
  826. buy_value += order.amount * order.price;
  827. }
  828. if order.side == "kk".to_string() {
  829. sell_price_list.push(order.price);
  830. sell_value += order.amount * order.price;
  831. }
  832. }
  833. // // 计算可开价值
  834. // let mut long_free_value = self.max_long_value - self.long_hold_value - buy_value;
  835. // let mut short_free_value = self.max_short_value - self.short_hold_value - sell_value;
  836. // // debug!(?long_free_value, ?short_free_value);
  837. // // 现货要特殊处理
  838. // if self.exchange.contains("spot") {
  839. // let coin_value = self.coin * self.mp * self.lever_rate * self.adjust_lever_rate;
  840. // let cash_value = self.cash * self.lever_rate * self.adjust_lever_rate;
  841. //
  842. // long_free_value = min(cash_value, self.max_long_value) - buy_value;
  843. // short_free_value = min(coin_value, self.max_short_value) - sell_value;
  844. // }
  845. // // 一手开单价值计算
  846. // let one_hand_long_value = dec!(0.99) * (self.max_long_value / self.grid);
  847. // let one_hand_short_value = dec!(0.99) * (self.max_short_value / self.grid);
  848. // 挂多单
  849. if self.post_side >= 0 && buy_value == Decimal::ZERO && predictor.optimal_bid_price < predictor.mid_price {
  850. let mut target_buy_price = predictor.optimal_bid_price;
  851. // target_buy_price = utils::clip(target_buy_price, self.bp * dec!(0.97), self.ap * dec!(1.0005));
  852. target_buy_price = utils::fix_price(target_buy_price, self.tick_size);
  853. let amount = if predictor.inventory <= dec!(-3) {
  854. utils::get_amount_by_min_amount_value(self.min_amount_value * predictor.inventory.abs(), target_buy_price, self.step_size)
  855. } else {
  856. utils::get_amount_by_min_amount_value(self.min_amount_value, target_buy_price, self.step_size)
  857. };
  858. // let amount = if predictor.inventory < Decimal::ZERO {
  859. // // utils::fix_amount(self.step_size * predictor.inventory.abs(), self.step_size)
  860. // if predictor.level >= dec!(3) {
  861. // utils::get_amount_by_min_amount_value(self.min_amount_value * predictor.inventory.abs(), target_buy_price, self.step_size)
  862. // } else {
  863. // utils::get_amount_by_min_amount_value(self.min_amount_value * predictor.level, target_buy_price, self.step_size)
  864. // }
  865. // } else {
  866. // // utils::fix_amount(self.step_size * (predictor.level + Decimal::ONE), self.step_size)
  867. // utils::get_amount_by_min_amount_value(self.min_amount_value * (predictor.level + Decimal::ONE), target_buy_price, self.step_size)
  868. // };
  869. // 下单价值判定
  870. let amount_value = amount * target_buy_price;
  871. if amount_value >= self.min_amount_value {
  872. let client_id = utils::generate_client_id(Some(self.broker_id.clone()));
  873. let order = vec![
  874. amount.to_string(),
  875. "kd".to_string(),
  876. target_buy_price.to_string(),
  877. client_id.clone(),
  878. ];
  879. // debug!(?order);
  880. command.limits_open.insert(client_id, order);
  881. } else {
  882. info!("下单价值太小,要求:{},但是价格:{}, 数量:{}", self.min_amount_value, target_buy_price, amount);
  883. }
  884. }
  885. // 挂空单
  886. if self.post_side <= 0 && sell_value == Decimal::ZERO && predictor.optimal_ask_price > predictor.mid_price {
  887. let mut target_sell_price = predictor.optimal_ask_price;
  888. // target_sell_price = utils::clip(target_sell_price, self.bp * dec!(0.9995), self.ap * dec!(1.03));
  889. // 取消大小限制
  890. target_sell_price = utils::fix_price(target_sell_price, self.tick_size);
  891. let amount = if predictor.inventory >= dec!(3) {
  892. utils::get_amount_by_min_amount_value(self.min_amount_value * predictor.inventory.abs(), target_sell_price, self.step_size)
  893. } else {
  894. utils::get_amount_by_min_amount_value(self.min_amount_value, target_sell_price, self.step_size)
  895. };
  896. // let amount = if predictor.inventory > Decimal::ZERO {
  897. // if predictor.level >= dec!(3) {
  898. // utils::get_amount_by_min_amount_value(self.min_amount_value * predictor.inventory.abs(), target_sell_price, self.step_size)
  899. // } else {
  900. // utils::get_amount_by_min_amount_value(self.min_amount_value * predictor.level, target_sell_price, self.step_size)
  901. // }
  902. // // utils::fix_amount(self.step_size * predictor.inventory.abs(), self.step_size)
  903. // } else {
  904. // utils::get_amount_by_min_amount_value(self.min_amount_value * (predictor.level + Decimal::ONE), target_sell_price, self.step_size)
  905. // // utils::fix_amount(self.step_size * (predictor.level + Decimal::ONE), self.step_size)
  906. // };
  907. // 下单价值不能太大,也不能太小
  908. let amount_value = amount * target_sell_price;
  909. if amount_value >= self.min_amount_value {
  910. let client_id = utils::generate_client_id(Some(self.broker_id.clone()));
  911. let order = vec![
  912. amount.to_string(),
  913. "kk".to_string(),
  914. target_sell_price.to_string(),
  915. client_id.clone(),
  916. ];
  917. // debug!(?order);
  918. command.limits_open.insert(client_id, order);
  919. } else {
  920. info!("下单价值太小,要求:{},但是价格:{}, 数量:{}", self.min_amount_value, target_sell_price, amount);
  921. }
  922. }
  923. }
  924. // 定时打印
  925. pub fn on_time_print(&mut self) {
  926. if self.local_time - self._print_time < self._print_interval {
  927. return;
  928. }
  929. // 记录上次打印时间
  930. self._print_time = self.local_time;
  931. if !self._is_print {
  932. return;
  933. }
  934. // 准备好了的话就不打印预热中了
  935. if self.is_ready {
  936. return;
  937. }
  938. info!("预热中");
  939. }
  940. // 在满足条件后,返回非空command,否则返回一个空的command。
  941. pub fn on_tick(&mut self,
  942. _local_orders: &HashMap<String, OrderInfo>,
  943. local_position: &LocalPosition,
  944. agg_market: &Vec<Decimal>,
  945. local_cash: &Decimal,
  946. local_coin: &Decimal,
  947. ref_price: &Vec<Vec<Decimal>>,
  948. predict: &Decimal,
  949. _ins: &Instant) -> OrderCommand {
  950. self.on_time_print();
  951. let command = OrderCommand::new();
  952. // 更新逻辑数据出错时,不进行后面的逻辑处理
  953. if !self._update_data(local_position,
  954. agg_market,
  955. local_cash,
  956. local_coin,
  957. ref_price,
  958. predict) {
  959. return command;
  960. }
  961. // 检查是否准备充分
  962. if !self.check_ready() {
  963. return command;
  964. }
  965. return command;
  966. }
  967. pub fn do_strategy(&mut self, predictor: &mut AvellanedaStoikov, local_orders: &HashMap<String, OrderInfo>, local_coin: &Decimal, local_cash: &Decimal) -> OrderCommand {
  968. // 更新当前账户余额
  969. self.coin = local_coin.clone();
  970. self.cash = local_cash.clone();
  971. self.equity = local_cash + local_coin * self.mp;
  972. if self.equity > self.max_equity {
  973. self.max_equity = self.equity;
  974. }
  975. self.ref_ap = predictor.optimal_ask_price;
  976. self.ref_bp = predictor.optimal_bid_price;
  977. self.ref_price = predictor.ref_price;
  978. self.mp = predictor.mid_price;
  979. // 修复相关价格
  980. self.fix_price(predictor);
  981. let mut command = OrderCommand::new();
  982. // 检查是否准备充分
  983. if !predictor.is_ready {
  984. return command;
  985. }
  986. self._cancel_open(&mut command, local_orders); // 撤单命令处理
  987. // if predictor.vwpin_avg!=Decimal::ZERO && predictor.vwpin > predictor.vwpin_avg {
  988. // self.no_open_num += 1;
  989. // } else {
  990. // self.open_num += 1;
  991. // self._post_open(&mut command, local_orders, predictor); // 限价单命令处理
  992. // }
  993. // info!("允许开仓信号数: {}, 不允许开仓信号数: :{}", self.open_num, self.no_open_num);
  994. self._post_open(&mut command, local_orders, predictor); // 限价单命令处理
  995. self._check_local_orders(&mut command, local_orders); // 固定时间检查超时订单
  996. self._update_in_cancel(&mut command, local_orders); // 更新撤单队列,是一个filter
  997. self._check_request_limit(&mut command); // 限制频率,移除不合规则之订单,是一个filter
  998. self._refresh_request_limit(); // 刷新频率限制
  999. self._update_request_num(&mut command); // 统计刷新频率
  1000. return command;
  1001. }
  1002. }