|
@@ -19,8 +19,12 @@ pub struct Predictor {
|
|
|
pub depth_vec: Vec<Depth>, // 深度队列
|
|
pub depth_vec: Vec<Depth>, // 深度队列
|
|
|
pub record_vec: VecDeque<Record>, // 蜡烛队列
|
|
pub record_vec: VecDeque<Record>, // 蜡烛队列
|
|
|
pub spread_vec: VecDeque<Decimal>, // 价差队列
|
|
pub spread_vec: VecDeque<Decimal>, // 价差队列
|
|
|
|
|
+ pub mid_price_long_vec: FixedTimeRangeDeque<Decimal>,
|
|
|
pub mid_price_short_vec: FixedTimeRangeDeque<Decimal>,
|
|
pub mid_price_short_vec: FixedTimeRangeDeque<Decimal>,
|
|
|
- pub trend_rate: Decimal,
|
|
|
|
|
|
|
+ pub fair_price_short_vec: FixedTimeRangeDeque<Decimal>,
|
|
|
|
|
+ pub trend_long_rate: Decimal,
|
|
|
|
|
+ pub trend_short_rate: Decimal,
|
|
|
|
|
+ pub fair_rate: Decimal,
|
|
|
|
|
|
|
|
pub prices: Vec<Vec<VecDeque<Decimal>>>, // [[[做市所], [参考所0]], ...]
|
|
pub prices: Vec<Vec<VecDeque<Decimal>>>, // [[[做市所], [参考所0]], ...]
|
|
|
pub ks: Vec<Decimal>,
|
|
pub ks: Vec<Decimal>,
|
|
@@ -42,8 +46,8 @@ pub struct Predictor {
|
|
|
pub prev_balance: Decimal,
|
|
pub prev_balance: Decimal,
|
|
|
|
|
|
|
|
pub prev_open_time: Decimal,
|
|
pub prev_open_time: Decimal,
|
|
|
- pub trade_condition: Decimal, // 过去1分钟以内,差价是否满足过扩大行为+行情有针
|
|
|
|
|
- pub trade_condition_time: Decimal, // 满足时的瞬时时间
|
|
|
|
|
|
|
+ pub trade_condition: Decimal, // 过去1分钟以内,差价是否满足过扩大行为+行情有针
|
|
|
|
|
+ pub trade_condition_time: Decimal, // 满足时的瞬时时间
|
|
|
|
|
|
|
|
pub ask_delta: Decimal, // δa
|
|
pub ask_delta: Decimal, // δa
|
|
|
pub bid_delta: Decimal, // δb
|
|
pub bid_delta: Decimal, // δb
|
|
@@ -75,7 +79,7 @@ impl Predictor {
|
|
|
// const TIME_DIFF_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
// const TIME_DIFF_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
|
// const TRADE_LONG_RANGE_MICROS: i64 = 10 * 60_000_000;
|
|
// const TRADE_LONG_RANGE_MICROS: i64 = 10 * 60_000_000;
|
|
|
// const SPREAD_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
// const SPREAD_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
|
- const TRADE_SHORT_RANGE_MICROS: i64 = 10_000_000;
|
|
|
|
|
|
|
+ // const TRADE_SHORT_RANGE_MICROS: i64 = 10_000_000;
|
|
|
// const ONE_MILLION: Decimal = dec!(1_000_000);
|
|
// const ONE_MILLION: Decimal = dec!(1_000_000);
|
|
|
// const TWENTY_THOUSAND: Decimal = dec!(20_000);
|
|
// const TWENTY_THOUSAND: Decimal = dec!(20_000);
|
|
|
const DONT_VIEW: Decimal = dec!(14142135623730951);
|
|
const DONT_VIEW: Decimal = dec!(14142135623730951);
|
|
@@ -153,7 +157,10 @@ impl Predictor {
|
|
|
|
|
|
|
|
record_vec: VecDeque::new(),
|
|
record_vec: VecDeque::new(),
|
|
|
|
|
|
|
|
- mid_price_short_vec: FixedTimeRangeDeque::new(Self::TRADE_SHORT_RANGE_MICROS),
|
|
|
|
|
|
|
+ mid_price_long_vec: FixedTimeRangeDeque::new(5_000_000),
|
|
|
|
|
+ mid_price_short_vec: FixedTimeRangeDeque::new(1_000_000),
|
|
|
|
|
+ fair_price_short_vec: FixedTimeRangeDeque::new(1_000_000),
|
|
|
|
|
+
|
|
|
spread_vec: VecDeque::new(),
|
|
spread_vec: VecDeque::new(),
|
|
|
mid_price: Default::default(),
|
|
mid_price: Default::default(),
|
|
|
ask_price: Default::default(),
|
|
ask_price: Default::default(),
|
|
@@ -188,8 +195,11 @@ impl Predictor {
|
|
|
params,
|
|
params,
|
|
|
|
|
|
|
|
debug_sender: tx,
|
|
debug_sender: tx,
|
|
|
- trend_rate: Default::default(),
|
|
|
|
|
prev_open_time: Default::default(),
|
|
prev_open_time: Default::default(),
|
|
|
|
|
+
|
|
|
|
|
+ trend_long_rate: Default::default(),
|
|
|
|
|
+ trend_short_rate: Default::default(),
|
|
|
|
|
+ fair_rate: Default::default(),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
predictor
|
|
predictor
|
|
@@ -204,26 +214,27 @@ impl Predictor {
|
|
|
self.bid_price = depth.bids[0].price;
|
|
self.bid_price = depth.bids[0].price;
|
|
|
self.mid_price = (self.ask_price + self.bid_price) / Decimal::TWO;
|
|
self.mid_price = (self.ask_price + self.bid_price) / Decimal::TWO;
|
|
|
|
|
|
|
|
|
|
+ self.mid_price_long_vec.push_back(self.mid_price);
|
|
|
self.mid_price_short_vec.push_back(self.mid_price);
|
|
self.mid_price_short_vec.push_back(self.mid_price);
|
|
|
|
|
|
|
|
- self.trend_rate = if self.mid_price_short_vec.len() > 2 {
|
|
|
|
|
- let max = self.mid_price_short_vec.deque.iter().max().unwrap();
|
|
|
|
|
- let min = self.mid_price_short_vec.deque.iter().min().unwrap();
|
|
|
|
|
|
|
+ self.trend_long_rate = if self.mid_price_long_vec.len() > 2 {
|
|
|
|
|
+ let first = self.mid_price_long_vec.deque.front().unwrap();
|
|
|
|
|
+ let last = self.mid_price_long_vec.deque.back().unwrap();
|
|
|
|
|
|
|
|
|
|
+ (last - first) / first
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Decimal::ZERO
|
|
|
|
|
+ };
|
|
|
|
|
+ self.trend_long_rate.rescale(6);
|
|
|
|
|
+ self.trend_short_rate = if self.mid_price_short_vec.len() > 2 {
|
|
|
|
|
+ let first = self.mid_price_short_vec.deque.front().unwrap();
|
|
|
let last = self.mid_price_short_vec.deque.back().unwrap();
|
|
let last = self.mid_price_short_vec.deque.back().unwrap();
|
|
|
|
|
|
|
|
- // 在下跌
|
|
|
|
|
- if max - last > last - min {
|
|
|
|
|
- (last - max) / max
|
|
|
|
|
- }
|
|
|
|
|
- // 在上涨
|
|
|
|
|
- else {
|
|
|
|
|
- (last - min) / min
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ (last - first) / first
|
|
|
} else {
|
|
} else {
|
|
|
Decimal::ZERO
|
|
Decimal::ZERO
|
|
|
};
|
|
};
|
|
|
- self.trend_rate.rescale(6);
|
|
|
|
|
|
|
+ self.trend_short_rate.rescale(6);
|
|
|
|
|
|
|
|
// 拟合k与b
|
|
// 拟合k与b
|
|
|
for (mid_index, mp) in self.mid_price_vec.iter().enumerate() {
|
|
for (mid_index, mp) in self.mid_price_vec.iter().enumerate() {
|
|
@@ -312,7 +323,9 @@ impl Predictor {
|
|
|
}
|
|
}
|
|
|
// 平仓
|
|
// 平仓
|
|
|
if self.pos_amount.is_zero() {
|
|
if self.pos_amount.is_zero() {
|
|
|
|
|
+ self.mid_price_long_vec.deque.clear();
|
|
|
self.mid_price_short_vec.deque.clear();
|
|
self.mid_price_short_vec.deque.clear();
|
|
|
|
|
+ self.fair_price_short_vec.deque.clear();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
self.processor(update_time, true).await;
|
|
self.processor(update_time, true).await;
|
|
@@ -363,6 +376,18 @@ impl Predictor {
|
|
|
if fair_price_count != 0 {
|
|
if fair_price_count != 0 {
|
|
|
self.fair_price = fair_price_sum / Decimal::from(fair_price_count);
|
|
self.fair_price = fair_price_sum / Decimal::from(fair_price_count);
|
|
|
|
|
|
|
|
|
|
+ self.fair_price_short_vec.push_back(self.fair_price);
|
|
|
|
|
+
|
|
|
|
|
+ self.fair_rate = if self.fair_price_short_vec.len() > 2 {
|
|
|
|
|
+ let first = self.fair_price_short_vec.deque.front().unwrap();
|
|
|
|
|
+ let last = self.fair_price_short_vec.deque.back().unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ (last - first) / first
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Decimal::ZERO
|
|
|
|
|
+ };
|
|
|
|
|
+ self.fair_rate.rescale(6);
|
|
|
|
|
+
|
|
|
// let mut spread_abs = ((self.fair_price - self.mid_price) / self.mid_price).abs();
|
|
// let mut spread_abs = ((self.fair_price - self.mid_price) / self.mid_price).abs();
|
|
|
// spread_abs.rescale(5);
|
|
// spread_abs.rescale(5);
|
|
|
//
|
|
//
|
|
@@ -390,18 +415,28 @@ impl Predictor {
|
|
|
|
|
|
|
|
let is_close_long = self.inventory > Decimal::ZERO && (
|
|
let is_close_long = self.inventory > Decimal::ZERO && (
|
|
|
// 反转平仓1
|
|
// 反转平仓1
|
|
|
- (self.trend_rate > dec!(0.01))
|
|
|
|
|
|
|
+ (self.trend_long_rate > dec!(0.005))
|
|
|
// 达到最大持仓时间还未盈利就平仓
|
|
// 达到最大持仓时间还未盈利就平仓
|
|
|
|| (now - self.prev_open_time > is_holding_time_over && self.mid_price < self.pos_avg_price)
|
|
|| (now - self.prev_open_time > is_holding_time_over && self.mid_price < self.pos_avg_price)
|
|
|
);
|
|
);
|
|
|
let is_close_short = self.inventory < Decimal::ZERO && (
|
|
let is_close_short = self.inventory < Decimal::ZERO && (
|
|
|
// 反转平仓1
|
|
// 反转平仓1
|
|
|
- (self.trend_rate < dec!(-0.01))
|
|
|
|
|
|
|
+ (self.trend_long_rate < dec!(-0.005))
|
|
|
// 达到最大持仓时间还未盈利就平仓
|
|
// 达到最大持仓时间还未盈利就平仓
|
|
|
|| (now - self.prev_open_time > is_holding_time_over && self.mid_price > self.pos_avg_price)
|
|
|| (now - self.prev_open_time > is_holding_time_over && self.mid_price > self.pos_avg_price)
|
|
|
);
|
|
);
|
|
|
- let is_open_long = self.inventory.is_zero() && self.fair_price > self.mid_price * (Decimal::ONE + self.params.open) && self.trend_rate < dec!(-0.01);
|
|
|
|
|
- let is_open_short = self.inventory.is_zero() && self.fair_price < self.mid_price * (Decimal::ONE - self.params.open) && self.trend_rate > dec!(0.01);
|
|
|
|
|
|
|
+ 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.trend_short_rate < dec!(-0.001)
|
|
|
|
|
+ && self.fair_rate > dec!(0.001)
|
|
|
|
|
+ ;
|
|
|
|
|
+ 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.trend_short_rate > dec!(0.001)
|
|
|
|
|
+ && self.fair_rate < dec!(-0.001)
|
|
|
|
|
+ ;
|
|
|
|
|
|
|
|
// 使信号有一定持续性
|
|
// 使信号有一定持续性
|
|
|
if is_close_long {
|
|
if is_close_long {
|
|
@@ -582,7 +617,7 @@ impl Predictor {
|
|
|
let sigma_square = Decimal::from(Utc::now().timestamp_millis()) - data_time;
|
|
let sigma_square = Decimal::from(Utc::now().timestamp_millis()) - data_time;
|
|
|
|
|
|
|
|
let gamma = self.balance;
|
|
let gamma = self.balance;
|
|
|
- let kappa = self.trend_rate;
|
|
|
|
|
|
|
+ let kappa = self.trend_long_rate;
|
|
|
|
|
|
|
|
let flow_ratio = Decimal::ZERO;
|
|
let flow_ratio = Decimal::ZERO;
|
|
|
|
|
|