strategy.rs 48 KB

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