|
|
@@ -41,6 +41,10 @@ pub struct Predictor {
|
|
|
pub balance: Decimal, // 初始余额
|
|
|
pub prev_balance: Decimal,
|
|
|
|
|
|
+ pub prev_open_time: Decimal,
|
|
|
+ pub trade_condition: Decimal, // 过去1分钟以内,差价是否满足过扩大行为+行情有针
|
|
|
+ pub trade_condition_time: Decimal, // 满足时的瞬时时间
|
|
|
+
|
|
|
pub ask_delta: Decimal, // δa
|
|
|
pub bid_delta: Decimal, // δb
|
|
|
|
|
|
@@ -89,15 +93,15 @@ impl Predictor {
|
|
|
|
|
|
while let Some(value) = rx.next().await {
|
|
|
// 数据填充到对应位置
|
|
|
- // 第一步:获取插入位置
|
|
|
- let target_ts = value[0]; // 时间戳在values[0]
|
|
|
- let insert_pos = debugs[0]
|
|
|
- .binary_search_by(|ts| {
|
|
|
- ts.as_ref() // 解包Option
|
|
|
- .expect("Timestamp cannot be None")
|
|
|
- .cmp(&target_ts)
|
|
|
- })
|
|
|
- .unwrap_or_else(|e| e);
|
|
|
+ // // 第一步:获取插入位置, 这里有bug,持仓推送并不连续,有时候会导致图表显示错误……
|
|
|
+ // let target_ts = value[0]; // 时间戳在values[0]
|
|
|
+ // let insert_pos = debugs[0]
|
|
|
+ // .binary_search_by(|ts| {
|
|
|
+ // ts.as_ref() // 解包Option
|
|
|
+ // .expect("Timestamp cannot be None")
|
|
|
+ // .cmp(&target_ts)
|
|
|
+ // })
|
|
|
+ // .unwrap_or_else(|e| e);
|
|
|
|
|
|
// 第二步:执行插入操作
|
|
|
for i in 0..debugs.len() {
|
|
|
@@ -108,7 +112,7 @@ impl Predictor {
|
|
|
} else {
|
|
|
Some(value)
|
|
|
};
|
|
|
- debugs[i].insert(insert_pos, elem);
|
|
|
+ debugs[i].push_back(elem)
|
|
|
}
|
|
|
|
|
|
// 长度限制
|
|
|
@@ -170,6 +174,9 @@ impl Predictor {
|
|
|
balance: Default::default(),
|
|
|
prev_balance: Default::default(),
|
|
|
|
|
|
+ trade_condition: Default::default(),
|
|
|
+ trade_condition_time: Default::default(),
|
|
|
+
|
|
|
last_update_time: Default::default(),
|
|
|
last_index: Default::default(),
|
|
|
|
|
|
@@ -182,6 +189,7 @@ impl Predictor {
|
|
|
|
|
|
debug_sender: tx,
|
|
|
trend_rate: Default::default(),
|
|
|
+ prev_open_time: Default::default(),
|
|
|
};
|
|
|
|
|
|
predictor
|
|
|
@@ -294,6 +302,15 @@ impl Predictor {
|
|
|
}
|
|
|
|
|
|
if prev_pos_amount != self.pos_amount {
|
|
|
+ // 重置连续信号
|
|
|
+ self.trade_condition = Decimal::ZERO;
|
|
|
+ self.trade_condition_time = Decimal::ZERO;
|
|
|
+
|
|
|
+ // 开单
|
|
|
+ if prev_pos_amount.is_zero() {
|
|
|
+ self.prev_open_time = Decimal::from(Utc::now().timestamp_millis())
|
|
|
+ }
|
|
|
+
|
|
|
self.processor(update_time, true).await;
|
|
|
}
|
|
|
}
|
|
|
@@ -364,34 +381,72 @@ impl Predictor {
|
|
|
let prev_bid_delta = self.bid_delta;
|
|
|
let prev_ask_delta = self.ask_delta;
|
|
|
|
|
|
- let is_close_long = self.inventory > Decimal::ZERO && (self.fair_price < self.mid_price * (Decimal::ONE + self.params.close));
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO && (self.fair_price > self.mid_price * (Decimal::ONE - self.params.close));
|
|
|
+ let now = Decimal::from(Utc::now().timestamp_millis());
|
|
|
+ let is_holding_time_over = dec!(15) * dec!(60_000);
|
|
|
+
|
|
|
+ let is_close_long = self.inventory > Decimal::ZERO && (
|
|
|
+ // 反转平仓
|
|
|
+ (self.fair_price < self.mid_price * (Decimal::ONE - self.params.close) && self.trend_rate > self.params.open * dec!(5))
|
|
|
+ // 达到最大持仓时间平仓
|
|
|
+ || (now - self.prev_open_time > is_holding_time_over)
|
|
|
+ );
|
|
|
+ let is_close_short = self.inventory < Decimal::ZERO && (
|
|
|
+ // 反转平仓
|
|
|
+ (self.fair_price > self.mid_price * (Decimal::ONE + self.params.close) && self.trend_rate < self.params.open * dec!(-5))
|
|
|
+ // 达到最大持仓时间平仓
|
|
|
+ || (now - self.prev_open_time > is_holding_time_over)
|
|
|
+ );
|
|
|
+ let is_open_long = self.fair_price > self.mid_price * (Decimal::ONE + self.params.open) && self.trend_rate < self.params.open * dec!(-5);
|
|
|
+ let is_open_short = self.fair_price < self.mid_price * (Decimal::ONE - self.params.open) && self.trend_rate > self.params.open * dec!(5);
|
|
|
+
|
|
|
+ // 使信号有一定持续性
|
|
|
+ if is_close_long {
|
|
|
+ self.trade_condition = dec!(1);
|
|
|
+ }
|
|
|
+ if is_close_short {
|
|
|
+ self.trade_condition = dec!(2);
|
|
|
+ }
|
|
|
+ if is_open_long {
|
|
|
+ self.trade_condition = dec!(3);
|
|
|
+ self.trade_condition_time = now;
|
|
|
+ }
|
|
|
+ if is_open_short {
|
|
|
+ self.trade_condition = dec!(4);
|
|
|
+ self.trade_condition_time = now;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开仓信号要过期,只保留10秒
|
|
|
+ if (self.trade_condition == dec!(3) || self.trade_condition == dec!(4))
|
|
|
+ && now - self.trade_condition_time > dec!(10_000) {
|
|
|
+ self.trade_condition = Decimal::ZERO;
|
|
|
+ }
|
|
|
|
|
|
+ // 开单信号处理
|
|
|
self.bid_delta = dec!(-2);
|
|
|
self.ask_delta = dec!(-2);
|
|
|
self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
self.optimal_bid_price = Self::DONT_VIEW;
|
|
|
|
|
|
- if is_close_long {
|
|
|
+ if self.trade_condition == dec!(1) && self.inventory > Decimal::ZERO {
|
|
|
self.ask_delta = dec!(0);
|
|
|
self.bid_delta = dec!(-2);
|
|
|
|
|
|
self.optimal_ask_price = min(self.mid_price, self.fair_price);
|
|
|
self.optimal_bid_price = Self::DONT_VIEW;
|
|
|
- } else if is_close_short {
|
|
|
+ } else if self.trade_condition == dec!(2) && self.inventory < Decimal::ZERO {
|
|
|
self.bid_delta = dec!(0);
|
|
|
self.ask_delta = dec!(-2);
|
|
|
|
|
|
self.optimal_bid_price = max(self.mid_price, self.fair_price);
|
|
|
self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
} else if self.inventory.is_zero() {
|
|
|
- if self.fair_price > self.mid_price * (Decimal::ONE + self.params.open) && self.trend_rate < self.params.open * dec!(-5) {
|
|
|
+ if self.trade_condition == dec!(3) {
|
|
|
self.bid_delta = dec!(0);
|
|
|
self.ask_delta = dec!(-2);
|
|
|
|
|
|
self.optimal_bid_price = self.fair_price;
|
|
|
self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
- } else if self.fair_price < self.mid_price * (Decimal::ONE - self.params.open) && self.trend_rate > self.params.open * dec!(5) {
|
|
|
+ } else if self.trade_condition == dec!(4) {
|
|
|
self.ask_delta = dec!(0);
|
|
|
self.bid_delta = dec!(-2);
|
|
|
|
|
|
@@ -400,9 +455,11 @@ impl Predictor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 价格处理
|
|
|
self.optimal_ask_price.rescale(self.mid_price.scale());
|
|
|
self.optimal_bid_price.rescale(self.mid_price.scale());
|
|
|
|
|
|
+ // 返回方向是否改变过,有改变可以立即在图表上显示
|
|
|
prev_ask_delta != self.ask_delta || prev_bid_delta != self.bid_delta
|
|
|
}
|
|
|
|
|
|
@@ -495,12 +552,14 @@ impl Predictor {
|
|
|
let now = data_time;
|
|
|
let mid_price = self.mid_price;
|
|
|
let ask_price = if self.params.ref_exchange.len() > 0 {
|
|
|
- self.fair_price_std_vec[0]
|
|
|
+ // self.fair_price_std_vec[0]
|
|
|
+ Self::DONT_VIEW
|
|
|
} else {
|
|
|
Self::DONT_VIEW
|
|
|
};
|
|
|
let bid_price = if self.params.ref_exchange.len() > 1 {
|
|
|
- self.fair_price_std_vec[1]
|
|
|
+ // self.fair_price_std_vec[1]
|
|
|
+ Self::DONT_VIEW
|
|
|
} else {
|
|
|
Self::DONT_VIEW
|
|
|
};
|