|
|
@@ -85,7 +85,7 @@ impl Predictor {
|
|
|
const TIME_DIFF_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
|
const TRADE_LONG_RANGE_MICROS: i64 = 60_000_000;
|
|
|
// const SPREAD_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
|
- const TRADE_SHORT_RANGE_MICROS: i64 = 2_000_000;
|
|
|
+ const TRADE_SHORT_RANGE_MICROS: i64 = 10_000_000;
|
|
|
// const ONE_MILLION: Decimal = dec!(1_000_000);
|
|
|
// const TWENTY_THOUSAND: Decimal = dec!(20_000);
|
|
|
const DONT_VIEW: Decimal = dec!(14142135623730951);
|
|
|
@@ -290,6 +290,20 @@ impl Predictor {
|
|
|
self.processor().await;
|
|
|
}
|
|
|
|
|
|
+ pub fn get_real_rate(price_vec: &FixedTimeRangeDeque<Decimal>) -> Decimal {
|
|
|
+ let last_fair_price = price_vec.deque.iter().last().unwrap();
|
|
|
+ let min_price = price_vec.deque.iter().min().unwrap();
|
|
|
+ let max_price = price_vec.deque.iter().max().unwrap();
|
|
|
+ let up_rate = (last_fair_price - min_price) / min_price;
|
|
|
+ let down_rate = (max_price - last_fair_price) / max_price;
|
|
|
+
|
|
|
+ if up_rate > down_rate {
|
|
|
+ up_rate
|
|
|
+ } else {
|
|
|
+ -down_rate
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
pub async fn update_fair_price(&mut self, depth: &Depth, index: usize) {
|
|
|
if self.mid_price.is_zero() {
|
|
|
return;
|
|
|
@@ -299,14 +313,14 @@ impl Predictor {
|
|
|
let b1 = &depth.bids[0];
|
|
|
|
|
|
// https://quant.stackexchange.com/questions/50651/how-to-understand-micro-price-aka-weighted-mid-price
|
|
|
- // let total = a1.value + b1.value;
|
|
|
- // let fair_price = a1.price * b1.value / total + b1.price * a1.value / total;
|
|
|
- let fair_price = (a1.price + b1.price) / Decimal::TWO;
|
|
|
+ let total = a1.value + b1.value;
|
|
|
+ let fair_price = a1.price * b1.value / total + b1.price * a1.value / total;
|
|
|
+ // let fair_price = (a1.price + b1.price) / Decimal::TWO;
|
|
|
|
|
|
self.fair_price_vec[index] = if self.fair_price_vec[index].is_zero() {
|
|
|
fair_price
|
|
|
} else {
|
|
|
- self.fair_price_vec[index] * dec!(0.9) + fair_price * dec!(0.1)
|
|
|
+ self.fair_price_vec[index] * dec!(0.5) + fair_price * dec!(0.5)
|
|
|
};
|
|
|
self.fair_price_vec[index].rescale(self.mid_price.scale());
|
|
|
self.volume_vec[index] = a1.size + b1.size;
|
|
|
@@ -316,7 +330,7 @@ impl Predictor {
|
|
|
self.price_times_avg = if self.price_times_avg.is_zero() {
|
|
|
self.fair_price_vec[1] / self.fair_price_vec[0]
|
|
|
} else {
|
|
|
- self.price_times_avg * dec!(0.9999) + dec!(0.0001) * self.fair_price_vec[1] / self.fair_price_vec[0]
|
|
|
+ self.price_times_avg * dec!(0.9995) + dec!(0.0005) * self.fair_price_vec[1] / self.fair_price_vec[0]
|
|
|
};
|
|
|
|
|
|
// 进行价格归一化处理,公平所的价格有可能是带前缀的
|
|
|
@@ -324,10 +338,11 @@ impl Predictor {
|
|
|
let fair_price_part1 = (self.fair_price_vec[1] / self.price_times_avg) * dec!(0.8);
|
|
|
self.fair_price = fair_price_part0 + fair_price_part1;
|
|
|
self.fair_price_time_vec.push_back(self.fair_price);
|
|
|
+ self.fair_price_long_time_vec.push_back(self.fair_price);
|
|
|
self.fair_price_ema_long = if self.fair_price_ema_long.is_zero() {
|
|
|
self.fair_price
|
|
|
} else {
|
|
|
- self.fair_price_ema_long * dec!(0.99967) + self.fair_price * dec!(0.00033)
|
|
|
+ self.fair_price_ema_long * dec!(0.67) + self.fair_price * dec!(0.33)
|
|
|
};
|
|
|
self.fair_price_ema_short = if self.fair_price_ema_short.is_zero() {
|
|
|
self.fair_price
|
|
|
@@ -339,26 +354,18 @@ impl Predictor {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- let last_fair_price = self.fair_price_time_vec.deque.iter().last().unwrap();
|
|
|
- let min_price = self.fair_price_time_vec.deque.iter().min().unwrap();
|
|
|
- let max_price = self.fair_price_time_vec.deque.iter().max().unwrap();
|
|
|
- let up_rate = (last_fair_price - min_price) / min_price;
|
|
|
- let down_rate = (max_price - last_fair_price) / max_price;
|
|
|
-
|
|
|
- let mut rate = if up_rate > down_rate {
|
|
|
- up_rate
|
|
|
- } else {
|
|
|
- -down_rate
|
|
|
- };
|
|
|
+ let mut rate = Self::get_real_rate(&self.fair_price_time_vec);
|
|
|
+ let mut long_rate = Self::get_real_rate(&self.fair_price_long_time_vec);
|
|
|
rate.rescale(8);
|
|
|
+ long_rate.rescale(8);
|
|
|
|
|
|
// 重置开仓焦点,条件1
|
|
|
if !self.fair_rate_focus_open.is_zero() {
|
|
|
- if self.fair_rate_focus_open > Decimal::ZERO && self.error_rate < dec!(0.9) {
|
|
|
+ if self.fair_rate_focus_open > Decimal::ZERO && self.error_rate < dec!(0.7) {
|
|
|
self.fair_rate_focus_open = Decimal::ZERO;
|
|
|
}
|
|
|
|
|
|
- if self.fair_rate_focus_open < Decimal::ZERO && self.error_rate > dec!(-0.9) {
|
|
|
+ if self.fair_rate_focus_open < Decimal::ZERO && self.error_rate > dec!(-0.7) {
|
|
|
self.fair_rate_focus_open = Decimal::ZERO;
|
|
|
}
|
|
|
}
|
|
|
@@ -383,13 +390,13 @@ impl Predictor {
|
|
|
// 只有有强度的rate才有资格被称为针
|
|
|
if rate.abs() > self.params.open_activate {
|
|
|
// 向上涨,并且fair下穿mid,视为观测阶段开始
|
|
|
- if rate > Decimal::ZERO && self.error_rate > dec!(0.9) {
|
|
|
+ if rate > Decimal::ZERO && long_rate > Decimal::ZERO && self.error_rate > dec!(0.7) {
|
|
|
self.fair_rate_focus_open = rate;
|
|
|
self.fair_price_focus_open = self.fair_price;
|
|
|
}
|
|
|
|
|
|
// 向下跌,并且fair上穿mid,视为观测阶段开始
|
|
|
- if rate < Decimal::ZERO && self.error_rate < dec!(-0.9) {
|
|
|
+ if rate < Decimal::ZERO && long_rate < Decimal::ZERO && self.error_rate < dec!(-0.7) {
|
|
|
self.fair_rate_focus_open = rate;
|
|
|
self.fair_price_focus_open = self.fair_price;
|
|
|
}
|