|
|
@@ -57,6 +57,7 @@ pub struct Predictor {
|
|
|
pub mid_price_time_vec: FixedTimeRangeDeque<Decimal>, // 中间价格队列,
|
|
|
pub mid_price_long_time_vec: FixedTimeRangeDeque<Decimal>, // 中间价格队列,
|
|
|
pub mid_price_trend_time_vec: FixedTimeRangeDeque<Decimal>, // 中间价格队列,
|
|
|
+ pub mid_price_trend_rate: Decimal,
|
|
|
pub fair_price_time_vec: FixedTimeRangeDeque<Decimal>, // 公平价格队列,
|
|
|
pub fair_price_long_time_vec: FixedTimeRangeDeque<Decimal>, // 公平价格队列,
|
|
|
pub fair_price_vec: Vec<Decimal>, // 公平价格列表,0表示做市所,1表示参考所
|
|
|
@@ -180,6 +181,7 @@ impl Predictor {
|
|
|
mid_price_time_vec: FixedTimeRangeDeque::new((params.second_observation_time.to_f64().unwrap() * 1_000_000f64).to_i64().unwrap()),
|
|
|
mid_price_long_time_vec: FixedTimeRangeDeque::new((params.second_observation_time.to_f64().unwrap() * 1_000_000f64).to_i64().unwrap() * 2),
|
|
|
mid_price_trend_time_vec: FixedTimeRangeDeque::new(5 * 60 * 1_000_000),
|
|
|
+ mid_price_trend_rate: Default::default(),
|
|
|
fair_price: Default::default(),
|
|
|
fair_price_ema_short: Default::default(),
|
|
|
fair_price_ema_long: Default::default(),
|
|
|
@@ -227,23 +229,8 @@ impl Predictor {
|
|
|
self.mid_price_time_vec.push_back(self.mid_price);
|
|
|
self.mid_price_long_time_vec.push_back(self.mid_price);
|
|
|
self.mid_price_trend_time_vec.push_back(self.mid_price);
|
|
|
-
|
|
|
- if !self.inventory.is_zero() {
|
|
|
- let mut profit_now = if self.inventory > Decimal::ZERO {
|
|
|
- (self.mid_price - self.pos_avg_price) / self.pos_avg_price
|
|
|
- } else {
|
|
|
- (self.pos_avg_price - self.mid_price) / self.pos_avg_price
|
|
|
- };
|
|
|
-
|
|
|
- profit_now -= dec!(0.0006);
|
|
|
- profit_now.rescale(8);
|
|
|
-
|
|
|
- self.profit_point_vec.push(profit_now);
|
|
|
-
|
|
|
- // let total: Decimal = self.profit_fixed_vec.iter().sum();
|
|
|
- self.profit_point = profit_now;
|
|
|
- self.profit_point_ema = self.profit_point_ema * dec!(0.99) + self.profit_point * dec!(0.01);
|
|
|
- }
|
|
|
+ let (rate, _, _) = Self::get_real_rate(&self.mid_price_trend_time_vec);
|
|
|
+ self.mid_price_trend_rate = rate;
|
|
|
}
|
|
|
|
|
|
self.update_fair_price(depth, index).await;
|
|
|
@@ -327,6 +314,7 @@ impl Predictor {
|
|
|
|
|
|
if prev_inventory != self.inventory && prev_inventory.is_zero() {
|
|
|
self.prev_trade_time = Utc::now().timestamp_micros();
|
|
|
+ self.force_order_value = Decimal::ZERO;
|
|
|
}
|
|
|
|
|
|
// 重置fair数据,用于重新计算幅度
|
|
|
@@ -411,150 +399,6 @@ impl Predictor {
|
|
|
if self.fair_price_time_vec.len() < 2 {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- // let (mut fair_rate, fair_start) = Self::get_real_rate(&self.fair_price_time_vec);
|
|
|
- // fair_rate.rescale(8);
|
|
|
- // let (mut fair_long_rate, _) = Self::get_real_rate(&self.fair_price_long_time_vec);
|
|
|
- // fair_long_rate.rescale(8);
|
|
|
- let (mut mid_rate, _, _) = Self::get_real_rate(&self.mid_price_time_vec);
|
|
|
- mid_rate.rescale(8);
|
|
|
- let (mut mid_long_rate, _, _) = Self::get_real_rate(&self.mid_price_long_time_vec);
|
|
|
- mid_long_rate.rescale(8);
|
|
|
- let (_, max_price, min_price) = Self::get_real_rate(&self.mid_price_trend_time_vec);
|
|
|
-
|
|
|
- // 重置开仓焦点,条件1
|
|
|
- // if !self.fair_rate_focus_open.is_zero() {
|
|
|
- // if self.fair_rate_focus_open < Decimal::ZERO && self.spread_ema < Decimal::ZERO {
|
|
|
- // self.fair_rate_focus_open = Decimal::ZERO;
|
|
|
- // }
|
|
|
- //
|
|
|
- // if self.fair_rate_focus_open > Decimal::ZERO && self.spread_ema > Decimal::ZERO {
|
|
|
- // self.fair_rate_focus_open = Decimal::ZERO;
|
|
|
- // }
|
|
|
- // }
|
|
|
- // 重置开仓焦点,条件2
|
|
|
- if !self.mid_rate_focus_open.is_zero() && !self.inventory.is_zero() {
|
|
|
- self.mid_rate_focus_open = Decimal::ZERO;
|
|
|
- }
|
|
|
- // 重置开仓焦点,条件3
|
|
|
- if !self.mid_price_focus_open.is_zero() {
|
|
|
- let focus_rate = (self.mid_price - self.mid_price_focus_open) / self.mid_price_focus_open;
|
|
|
-
|
|
|
- if focus_rate.abs() > self.params.open_activate / dec!(4) {
|
|
|
- self.mid_rate_focus_open = Decimal::ZERO;
|
|
|
- }
|
|
|
- }
|
|
|
- // 更新程序关注的开仓焦点
|
|
|
- if self.mid_rate_focus_open.is_zero() && self.inventory.is_zero() {
|
|
|
- // 是同起点
|
|
|
- // let mut is_cross = fair_rate.abs() > self.params.open_activate;
|
|
|
- // is_cross = is_cross && mid_rate.abs() > self.params.open_activate;
|
|
|
- // is_cross = is_cross && ((mid_start - fair_start) / mid_start).abs() < dec!(0.0005);
|
|
|
-
|
|
|
- // 小于40%的波动发生在最后一段时间
|
|
|
- let is_high_speed = mid_rate.abs() < mid_long_rate.abs() * dec!(0.4) && mid_rate * mid_long_rate > Decimal::ZERO;
|
|
|
-
|
|
|
- if is_high_speed && mid_rate.abs() > self.params.open_activate {
|
|
|
- // 向上涨,并且fair下穿mid,视为观测阶段开始
|
|
|
- if mid_rate > Decimal::ZERO && mid_long_rate > Decimal::ZERO && self.mid_price < max_price {
|
|
|
- self.mid_rate_focus_open = dec!(-0.01);
|
|
|
- self.mid_price_focus_open = self.mid_price;
|
|
|
- }
|
|
|
-
|
|
|
- // 向下跌,并且fair上穿mid,视为观测阶段开始
|
|
|
- if mid_rate < Decimal::ZERO && mid_long_rate < Decimal::ZERO && self.mid_price > min_price {
|
|
|
- self.mid_rate_focus_open = dec!(0.01);
|
|
|
- self.mid_price_focus_open = self.mid_price;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // ============================ 平仓逻辑处理 =======================
|
|
|
- // close_rate:
|
|
|
- // 大于0:当前价格在均线之上
|
|
|
- // 小于0:当前价格在均线之下
|
|
|
- let close_rate = mid_rate.clone();
|
|
|
- // 重置平仓焦点,条件1
|
|
|
- if !self.mid_rate_focus_close.is_zero() && self.inventory.is_zero() {
|
|
|
- self.mid_rate_focus_close = Decimal::ZERO;
|
|
|
- }
|
|
|
- // 重置平仓焦点,条件2
|
|
|
- // if !self.fair_rate_focus_close.is_zero() && self.fair_rate_focus_close > dec!(-0.1) {
|
|
|
- // let focus_rate = (self.mid_price - self.fair_price_focus_close) / self.fair_price_focus_close;
|
|
|
- //
|
|
|
- // if self.fair_rate_focus_close > Decimal::ZERO && focus_rate < Decimal::NEGATIVE_ONE * self.params.close_activate / Decimal::TWO {
|
|
|
- // self.fair_rate_focus_close = Decimal::ZERO;
|
|
|
- // }
|
|
|
- //
|
|
|
- // if self.fair_rate_focus_close < Decimal::ZERO && focus_rate > self.params.close_activate / Decimal::TWO {
|
|
|
- // self.fair_rate_focus_close = Decimal::ZERO;
|
|
|
- // }
|
|
|
- // }
|
|
|
- // 更新程序关注的平仓焦点
|
|
|
- let close_activate = self.params.open_activate;
|
|
|
- if self.mid_rate_focus_close.is_zero() && !self.inventory.is_zero() && close_rate.abs() > close_activate {
|
|
|
- // 多单平仓逻辑
|
|
|
- if self.inventory > Decimal::ZERO && close_rate > Decimal::ZERO {
|
|
|
- if self.profit_point > Decimal::ZERO {
|
|
|
- self.mid_rate_focus_close = close_rate;
|
|
|
- self.fair_price_focus_close = self.mid_price;
|
|
|
- } else if self.t_diff.is_zero() {
|
|
|
- self.mid_rate_focus_close = close_rate;
|
|
|
- self.fair_price_focus_close = self.mid_price;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 空单平仓逻辑
|
|
|
- if self.inventory < Decimal::ZERO && close_rate < Decimal::ZERO {
|
|
|
- if self.profit_point > Decimal::ZERO {
|
|
|
- self.mid_rate_focus_close = close_rate;
|
|
|
- self.fair_price_focus_close = self.fair_price;
|
|
|
- } else if self.t_diff.is_zero() {
|
|
|
- self.mid_rate_focus_close = close_rate;
|
|
|
- self.fair_price_focus_close = self.fair_price;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // 15秒以后平仓
|
|
|
- // let is_time_over = Utc::now().timestamp_micros() - self.prev_trade_time > 20 * 1_000_000;
|
|
|
- // if self.mid_rate_focus_close.is_zero() && !self.inventory.is_zero() && is_time_over {
|
|
|
- // if self.inventory > Decimal::ZERO {
|
|
|
- // self.mid_rate_focus_close = dec!(0.01);
|
|
|
- // self.fair_price_focus_close = self.mid_price;
|
|
|
- // }
|
|
|
- // if self.inventory < Decimal::ZERO {
|
|
|
- // self.mid_rate_focus_close = dec!(-0.01);
|
|
|
- // self.fair_price_focus_close = self.mid_price;
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
- // ============================ 平仓特殊逻辑处理1 =======================
|
|
|
- // if self.mid_rate_focus_close.is_zero() && !self.inventory.is_zero() && self.profit_point < dec!(-0.002) {
|
|
|
- // self.mid_rate_focus_close = dec!(-0.11);
|
|
|
- // self.fair_price_focus_close = self.mid_price;
|
|
|
- //
|
|
|
- // // let prev_open_activate = self.params.open_activate;
|
|
|
- // // self.params.open_activate = self.params.open_activate * dec!(1.5);
|
|
|
- //
|
|
|
- // info!("----------------------------------------");
|
|
|
- // // info!("止损,参数调整:{} -> {}", prev_open_activate, self.params.open_activate);
|
|
|
- // info!("硬止损, 在价格{}处,成本价{},价值={}, p={}。", self.fair_price_focus_close, self.pos_avg_price, self.pos_avg_price*self.pos_amount, self.profit_point);
|
|
|
- // info!("----------------------------------------");
|
|
|
- // }
|
|
|
- // ============================ 平仓特殊逻辑处理2 =======================
|
|
|
- if self.mid_rate_focus_close.is_zero() && !self.inventory.is_zero() && self.profit_point_vec.len() > 1 {
|
|
|
- let prev_profit_point = self.profit_point_vec[self.profit_point_vec.len() - 2];
|
|
|
- let profit_point = self.profit_point_vec[self.profit_point_vec.len() - 1];
|
|
|
-
|
|
|
- if (prev_profit_point >= Decimal::ZERO && profit_point < Decimal::ZERO) || (prev_profit_point > Decimal::ZERO && profit_point <= Decimal::ZERO) {
|
|
|
- self.mid_rate_focus_close = dec!(-0.12);
|
|
|
- self.fair_price_focus_close = self.mid_price;
|
|
|
-
|
|
|
- info!("----------------------------------------");
|
|
|
- info!("止损逻辑2, 在价格{}处,成本价{},价值={}, p={}。", self.fair_price_focus_close, self.pos_avg_price, self.pos_avg_price*self.pos_amount, self.profit_point);
|
|
|
- info!("----------------------------------------");
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
// // 判断价格是否回归
|
|
|
@@ -590,10 +434,6 @@ impl Predictor {
|
|
|
}
|
|
|
|
|
|
pub fn update_delta(&mut self) {
|
|
|
- // -2表示不想成交
|
|
|
- // -1表示市价成交(委托对手盘的价格,但不一定能市价成交),这里再想想吧,经常委托出去没成交,明显比别人慢了
|
|
|
- // 0是买一/卖一成交
|
|
|
-
|
|
|
if self.fair_price.is_zero() {
|
|
|
return;
|
|
|
}
|
|
|
@@ -602,51 +442,22 @@ impl Predictor {
|
|
|
// let is_open_long = self.spread_sma_1000 - self.spread_sma > self.params.open && self.fair_price > self.mid_price;
|
|
|
// let is_open_short = self.spread_sma_1000 - self.spread_sma < self.params.open * Decimal::NEGATIVE_ONE && self.fair_price < self.mid_price;
|
|
|
// 可能是接针
|
|
|
- let is_open_long = self.mid_rate_focus_open > Decimal::ZERO;
|
|
|
- let is_open_short = self.mid_rate_focus_open < Decimal::ZERO;
|
|
|
- let is_close_long = self.inventory > Decimal::ZERO && (self.mid_rate_focus_close > Decimal::ZERO || self.mid_rate_focus_close < dec!(-0.1));
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO && (self.mid_rate_focus_close < Decimal::ZERO || self.mid_rate_focus_close < dec!(-0.1));
|
|
|
+ let is_open_long = self.mid_price_trend_rate < Decimal::ZERO && self.force_order_value < -self.params.open;
|
|
|
+ let is_open_short = self.mid_price_trend_rate > Decimal::ZERO && self.force_order_value > self.params.open;
|
|
|
+ let is_close_long = self.inventory > Decimal::ZERO && self.mid_price_trend_rate > Decimal::ZERO;
|
|
|
+ let is_close_short = self.inventory < Decimal::ZERO && self.mid_price_trend_rate < Decimal::ZERO;
|
|
|
|
|
|
self.bid_delta = dec!(-2);
|
|
|
self.ask_delta = dec!(-2);
|
|
|
|
|
|
if is_close_long {
|
|
|
- // let close_rate = (self.error_rate / dec!(0.5)) * self.params.close;
|
|
|
- //
|
|
|
- // self.ask_delta = self.mid_price * close_rate;
|
|
|
- if self.mid_rate_focus_close < dec!(-0.1) {
|
|
|
- self.ask_delta = dec!(-1);
|
|
|
- } else {
|
|
|
- self.ask_delta = self.mid_price * self.params.close;
|
|
|
- }
|
|
|
+ self.ask_delta = self.mid_price * self.params.close;
|
|
|
} else if is_close_short {
|
|
|
- // let close_rate = (self.error_rate / dec!(0.5)) * self.params.close;
|
|
|
- //
|
|
|
- // self.bid_delta = self.mid_price * close_rate;
|
|
|
-
|
|
|
- if self.mid_rate_focus_close < dec!(-0.1) {
|
|
|
- self.bid_delta = dec!(-1);
|
|
|
- } else {
|
|
|
- self.bid_delta = self.mid_price * self.params.close;
|
|
|
- }
|
|
|
+ self.bid_delta = self.mid_price * self.params.close;
|
|
|
} else if is_open_long {
|
|
|
- // let is_open_long_market = self.spread_sma_1000 - self.spread_sma > self.params.open_market;
|
|
|
- // self.bid_delta = if is_open_long_market {
|
|
|
- // dec!(-1)
|
|
|
- // } else {
|
|
|
- // dec!(0)
|
|
|
- // };
|
|
|
-
|
|
|
- self.bid_delta = self.params.open * self.mid_price;
|
|
|
+ self.bid_delta = Decimal::ZERO;
|
|
|
} else if is_open_short {
|
|
|
- // let is_open_short_market = self.spread_sma_1000 - self.spread_sma < self.params.open_market * Decimal::NEGATIVE_ONE;
|
|
|
- // self.ask_delta = if is_open_short_market {
|
|
|
- // dec!(-1)
|
|
|
- // } else {
|
|
|
- // dec!(0)
|
|
|
- // }
|
|
|
-
|
|
|
- self.ask_delta = self.params.open * self.mid_price;
|
|
|
+ self.ask_delta = Decimal::ZERO;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -743,16 +554,9 @@ impl Predictor {
|
|
|
let last_price = self.last_price;
|
|
|
let fair_price = Self::DONT_VIEW;
|
|
|
|
|
|
- let (spread, spread_max, spread_min) = if self.mid_price_trend_time_vec.len() > 1 {
|
|
|
- let (rate, _, _) = Self::get_real_rate(&self.mid_price_trend_time_vec);
|
|
|
-
|
|
|
- (rate, Self::DONT_VIEW, Self::DONT_VIEW)
|
|
|
- } else {
|
|
|
- (self.mid_price, Self::DONT_VIEW, Self::DONT_VIEW)
|
|
|
- };
|
|
|
- // let spread = self.price_times_avg;
|
|
|
- // let spread_max = self.fair_price_vec[1] / self.fair_price_vec[0];
|
|
|
- // let spread_min = self.fair_price / self.mid_price;
|
|
|
+ let spread = self.mid_price_trend_rate;
|
|
|
+ let spread_max = self.fair_price_vec[1] / self.fair_price_vec[0];
|
|
|
+ let spread_min = self.fair_price / self.mid_price;
|
|
|
|
|
|
let optimal_ask_price = self.optimal_ask_price;
|
|
|
let optimal_bid_price = self.optimal_bid_price;
|