|
|
@@ -1,5 +1,5 @@
|
|
|
use std::cmp::{max, min};
|
|
|
-use std::collections::{BTreeMap, VecDeque};
|
|
|
+use std::collections::{BTreeMap, HashMap, VecDeque};
|
|
|
use std::sync::Arc;
|
|
|
use chrono::{Utc};
|
|
|
use futures_channel::mpsc::UnboundedSender;
|
|
|
@@ -75,7 +75,11 @@ pub struct Predictor {
|
|
|
|
|
|
pub params: Params,
|
|
|
|
|
|
- pub debug_sender: UnboundedSender<Vec<Decimal>>
|
|
|
+ pub debug_sender: UnboundedSender<Vec<Decimal>>,
|
|
|
+
|
|
|
+ pub trade_time_vec: VecDeque<Decimal>, // 交易时间队列
|
|
|
+ pub trade_side_map: HashMap<Decimal, String>, // 交易时间,对应的是kk,kd两个方向
|
|
|
+ pub trade_amount_map: HashMap<Decimal, Decimal>, // 交易数量
|
|
|
}
|
|
|
|
|
|
impl Predictor {
|
|
|
@@ -191,6 +195,10 @@ impl Predictor {
|
|
|
params,
|
|
|
|
|
|
debug_sender: tx,
|
|
|
+
|
|
|
+ trade_time_vec: VecDeque::new(),
|
|
|
+ trade_side_map: HashMap::new(),
|
|
|
+ trade_amount_map: HashMap::new(),
|
|
|
};
|
|
|
|
|
|
predictor
|
|
|
@@ -253,6 +261,22 @@ impl Predictor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // side, pk,pd从HashMap移除,kd,kk添加到HashMap
|
|
|
+ pub async fn on_order(&mut self, side: String, amount: Decimal) {
|
|
|
+ if side == "kk" || side == "kd" {
|
|
|
+ let now = Decimal::from(Utc::now().timestamp_millis());
|
|
|
+
|
|
|
+ self.trade_time_vec.push_back(now);
|
|
|
+ self.trade_side_map.insert(now, side);
|
|
|
+ self.trade_amount_map.insert(now, amount);
|
|
|
+ } else if side == "pd" || side == "pk" {
|
|
|
+ let pop_time = self.trade_time_vec.pop_front().unwrap();
|
|
|
+
|
|
|
+ self.trade_side_map.remove(&pop_time);
|
|
|
+ self.trade_amount_map.remove(&pop_time);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
pub async fn update_level(&mut self) {
|
|
|
self.level = (Decimal::NEGATIVE_ONE + (Decimal::ONE + dec!(8) * self.inventory.abs()).sqrt().unwrap()) / Decimal::TWO;
|
|
|
self.level = min(self.level, dec!(6));
|
|
|
@@ -384,49 +408,36 @@ impl Predictor {
|
|
|
}
|
|
|
|
|
|
// 可能是接针
|
|
|
- let is_open_long = self.force_order_value < -self.params.open
|
|
|
- && self.inventory < self.params.grid
|
|
|
- && self.inventory >= Decimal::ZERO
|
|
|
- && (self.mid_price < self.prev_trade_price * dec!(0.99) || self.prev_trade_price.is_zero())
|
|
|
- && self.force_order_value < self.prev_trade_force_order_value;
|
|
|
- let is_open_short = self.force_order_value > self.params.open
|
|
|
- && self.inventory > -self.params.grid
|
|
|
- && self.inventory <= Decimal::ZERO
|
|
|
- && (self.mid_price > self.prev_trade_price * dec!(1.01) || self.prev_trade_price.is_zero())
|
|
|
- && self.force_order_value > self.prev_trade_force_order_value;
|
|
|
-
|
|
|
- let (is_close_long, is_close_short) = match self.params.close_difficulty.as_str() {
|
|
|
- "easy" => {
|
|
|
- let is_close_long = self.inventory > Decimal::ZERO && self.force_order_value > Decimal::ZERO;
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO && self.force_order_value < Decimal::ZERO;
|
|
|
-
|
|
|
- (is_close_long, is_close_short)
|
|
|
- },
|
|
|
- "normal" => {
|
|
|
- let is_close_long = self.inventory > Decimal::ZERO && self.force_order_value > self.params.open * dec!(0.5);
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO && self.force_order_value < -self.params.open * dec!(0.5);
|
|
|
-
|
|
|
- (is_close_long, is_close_short)
|
|
|
- },
|
|
|
- "hard" => {
|
|
|
- let is_close_long = self.inventory > Decimal::ZERO && self.force_order_value > self.params.open;
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO && self.force_order_value < -self.params.open;
|
|
|
-
|
|
|
- (is_close_long, is_close_short)
|
|
|
- }
|
|
|
- _ => {
|
|
|
- panic!("错误的平仓条件:{}", self.params.close_difficulty)
|
|
|
- }
|
|
|
- };
|
|
|
+ let is_open_long = self.force_order_value < -self.params.open && self.inventory < self.params.grid;
|
|
|
+ let is_open_short = self.force_order_value > self.params.open && self.inventory > -self.params.grid;
|
|
|
|
|
|
self.bid_delta = dec!(-2);
|
|
|
self.ask_delta = dec!(-2);
|
|
|
|
|
|
- if is_close_long {
|
|
|
- self.ask_delta = self.mid_price * self.params.close;
|
|
|
- } else if is_close_short {
|
|
|
- self.bid_delta = self.mid_price * self.params.close;
|
|
|
- } else if is_open_long {
|
|
|
+ // 平仓优先级高一些
|
|
|
+ if self.trade_time_vec.len() > 0 {
|
|
|
+ let first = self.trade_time_vec.front().unwrap();
|
|
|
+ let now = Decimal::from(Utc::now().timestamp_millis());
|
|
|
+
|
|
|
+ if now - self.params.holding_time * Decimal::ONE_THOUSAND > *first {
|
|
|
+ let side = self.trade_side_map.get(first).unwrap();
|
|
|
+ let _ = self.trade_amount_map.get(first).unwrap();
|
|
|
+
|
|
|
+ match side.as_str() {
|
|
|
+ "kd" => {
|
|
|
+ self.ask_delta = Decimal::ZERO;
|
|
|
+ }
|
|
|
+ "kk" => {
|
|
|
+ self.bid_delta = Decimal::ZERO;
|
|
|
+ }
|
|
|
+ &_ => {
|
|
|
+ panic!("什么方向放进来了?side={}", side);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if is_open_long {
|
|
|
self.bid_delta = Decimal::ZERO;
|
|
|
} else if is_open_short {
|
|
|
self.ask_delta = Decimal::ZERO;
|