|
|
@@ -18,6 +18,7 @@ use crate::utils;
|
|
|
pub struct Predictor {
|
|
|
pub depth_vec: Vec<Depth>, // 深度队列
|
|
|
pub record_vec: VecDeque<Record>, // 蜡烛队列
|
|
|
+ pub prev_insert_price_time: Decimal,
|
|
|
pub spread_vec: VecDeque<Decimal>, // 价差队列
|
|
|
pub mid_price_long_vec: FixedTimeRangeDeque<Decimal>,
|
|
|
pub mid_price_short_vec: FixedTimeRangeDeque<Decimal>,
|
|
|
@@ -35,6 +36,9 @@ pub struct Predictor {
|
|
|
pub bid_price: Decimal, // 中间价
|
|
|
pub fair_price: Decimal,
|
|
|
pub last_price: Decimal, // 最后成交价
|
|
|
+ pub ma_30: Decimal,
|
|
|
+ pub ma_200: Decimal,
|
|
|
+ pub trend_rate: Decimal,
|
|
|
|
|
|
pub optimal_ask_price: Decimal, // 卖出挂单价
|
|
|
pub optimal_bid_price: Decimal, // 买入挂单价
|
|
|
@@ -157,8 +161,6 @@ impl Predictor {
|
|
|
bs: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
prev_fitting_time_vec: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
|
|
|
- record_vec: VecDeque::new(),
|
|
|
-
|
|
|
mid_price_long_vec: FixedTimeRangeDeque::new(10_000_000),
|
|
|
mid_price_short_vec: FixedTimeRangeDeque::new(2_000_000),
|
|
|
fair_price_short_vec: FixedTimeRangeDeque::new(2_000_000),
|
|
|
@@ -169,6 +171,11 @@ impl Predictor {
|
|
|
bid_price: Default::default(),
|
|
|
fair_price: Default::default(),
|
|
|
last_price: Default::default(),
|
|
|
+
|
|
|
+ ma_30: Default::default(),
|
|
|
+ ma_200: Default::default(),
|
|
|
+ trend_rate: Default::default(),
|
|
|
+
|
|
|
optimal_ask_price: Self::DONT_VIEW,
|
|
|
optimal_bid_price: Self::DONT_VIEW,
|
|
|
|
|
|
@@ -205,6 +212,8 @@ impl Predictor {
|
|
|
trend_long_rate: Default::default(),
|
|
|
trend_short_rate: Default::default(),
|
|
|
fair_rate: Default::default(),
|
|
|
+ prev_insert_price_time: Default::default(),
|
|
|
+ record_vec: Default::default(),
|
|
|
};
|
|
|
|
|
|
predictor
|
|
|
@@ -304,7 +313,61 @@ impl Predictor {
|
|
|
|
|
|
pub async fn on_ticker(&mut self, _ticker: &Ticker) {}
|
|
|
|
|
|
- pub async fn on_record(&mut self, _record: &Record) {}
|
|
|
+ pub async fn on_record(&mut self, record: &Record) {
|
|
|
+ // 添加新蜡烛
|
|
|
+ if self.record_vec.len() == 0 {
|
|
|
+ self.record_vec.push_back(record.clone());
|
|
|
+ } else {
|
|
|
+ let last_record = self.record_vec.back_mut().unwrap();
|
|
|
+
|
|
|
+ if last_record.time == record.time {
|
|
|
+ *last_record = record.clone();
|
|
|
+ } else if last_record.time < record.time {
|
|
|
+ self.record_vec.push_back(record.clone());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if self.record_vec.len() > 200 {
|
|
|
+ self.record_vec.pop_front();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算ma30与ma200
|
|
|
+ if self.record_vec.len() == 200 {
|
|
|
+ let len = self.record_vec.len();
|
|
|
+ // ma200
|
|
|
+ let mut i = len - 1;
|
|
|
+ let mut sum: Decimal = Decimal::ZERO;
|
|
|
+ loop {
|
|
|
+ if i == 0 {
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ sum += self.record_vec[i].close;
|
|
|
+
|
|
|
+ i = i - 1;
|
|
|
+ }
|
|
|
+ self.ma_200 = sum / Decimal::from(200);
|
|
|
+ // ma30
|
|
|
+ let mut i = len - 1;
|
|
|
+ let mut sum: Decimal = Decimal::ZERO;
|
|
|
+ loop {
|
|
|
+ if i == len - 31 {
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ sum += self.record_vec[i].close;
|
|
|
+
|
|
|
+ i = i - 1;
|
|
|
+ }
|
|
|
+ self.ma_30 = sum / Decimal::from(30);
|
|
|
+
|
|
|
+ self.ma_30.rescale(self.mid_price.scale());
|
|
|
+ self.ma_200.rescale(self.mid_price.scale());
|
|
|
+
|
|
|
+ self.trend_rate = self.ma_30 / self.ma_200;
|
|
|
+ self.trend_rate.rescale(8);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
pub async fn on_inventory(&mut self, pos_amount: &Decimal, pos_avg_price: &Decimal, min_amount_value: &Decimal, update_time: Decimal) {
|
|
|
if self.mid_price.is_zero() {
|
|
|
@@ -425,6 +488,9 @@ impl Predictor {
|
|
|
if self.mid_price.is_zero() {
|
|
|
return false;
|
|
|
}
|
|
|
+ if self.record_vec.len() < 200 {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
let prev_bid_delta = self.bid_delta;
|
|
|
let prev_ask_delta = self.ask_delta;
|
|
|
@@ -443,17 +509,14 @@ impl Predictor {
|
|
|
// 利润较大时,追踪止盈
|
|
|
|| (self.profit > dec!(0.01) && self.profit < self.profit_high * dec!(0.75))
|
|
|
);
|
|
|
+
|
|
|
+ let last_record = &self.record_vec[self.record_vec.len() - 2];
|
|
|
let is_open_long = self.inventory.is_zero()
|
|
|
- && self.fair_price > self.mid_price * (Decimal::ONE + self.params.open)
|
|
|
- && self.trend_long_rate < dec!(-0.005)
|
|
|
- && self.fair_rate > Decimal::ZERO
|
|
|
- && self.fair_rate > self.trend_short_rate + dec!(0.0001)
|
|
|
+ && last_record.close / last_record.open < (Decimal::ONE - self.params.open)
|
|
|
+ && self.trend_rate < dec!(0.97)
|
|
|
;
|
|
|
let is_open_short = self.inventory.is_zero()
|
|
|
- && self.fair_price < self.mid_price * (Decimal::ONE - self.params.open)
|
|
|
- && self.trend_long_rate > dec!(0.005)
|
|
|
- && self.fair_rate < Decimal::ZERO
|
|
|
- && self.fair_rate < self.trend_short_rate - dec!(0.0001)
|
|
|
+ && false
|
|
|
;
|
|
|
|
|
|
// 使信号有一定持续性
|
|
|
@@ -472,9 +535,9 @@ impl Predictor {
|
|
|
self.trade_condition_time = now;
|
|
|
}
|
|
|
|
|
|
- // 开仓信号要过期,只保留2秒
|
|
|
+ // 开仓信号要过期,只保留60秒
|
|
|
if (self.trade_condition == dec!(3) || self.trade_condition == dec!(4))
|
|
|
- && now - self.trade_condition_time > dec!(2_000) {
|
|
|
+ && now - self.trade_condition_time > dec!(60_000) {
|
|
|
self.trade_condition = Decimal::ZERO;
|
|
|
}
|
|
|
|
|
|
@@ -541,6 +604,14 @@ impl Predictor {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if self.record_vec.len() < 200 {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if self.optimal_bid_price.is_zero() {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if self.balance.is_zero() {
|
|
|
return;
|
|
|
}
|
|
|
@@ -623,17 +694,17 @@ impl Predictor {
|
|
|
let last_price = Self::DONT_VIEW;
|
|
|
let fair_price = self.fair_price;
|
|
|
|
|
|
- let spread = Self::DONT_VIEW;
|
|
|
- let spread_max = self.bs[0];
|
|
|
- let spread_min = self.ks[0];
|
|
|
+ let spread = self.mid_price;
|
|
|
+ let spread_max = self.ma_30;
|
|
|
+ let spread_min = self.ma_200;
|
|
|
// 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 inventory = self.inventory;
|
|
|
|
|
|
- let sigma_square = Decimal::from(Utc::now().timestamp_millis()) - data_time;
|
|
|
-
|
|
|
+ // let sigma_square = Decimal::from(Utc::now().timestamp_millis()) - data_time;
|
|
|
+ let sigma_square = self.trend_rate;
|
|
|
let gamma = self.balance;
|
|
|
let kappa = self.profit;
|
|
|
|