|
|
@@ -17,19 +17,19 @@ use crate::utils;
|
|
|
#[derive(Debug)]
|
|
|
pub struct Predictor {
|
|
|
pub depth_vec: Vec<Depth>, // 深度队列
|
|
|
- pub volume_vec: Vec<Decimal>, // 深度队列
|
|
|
+ pub volume_vec: Vec<Decimal>, // 交易量队列
|
|
|
pub trade_long_vec: FixedTimeRangeDeque<Trade>, // 交易队列
|
|
|
pub trade_short_vec: FixedTimeRangeDeque<Trade>, // 交易队列
|
|
|
- pub spread_vec: Vec<Decimal>, // 市场冲击队列
|
|
|
+ pub spread_vec: Vec<Decimal>, // 价差队列
|
|
|
pub record_vec: VecDeque<Record>, // 蜡烛队列
|
|
|
|
|
|
pub mid_price: Decimal, // 中间价
|
|
|
pub ask_price: Decimal, // 卖一价
|
|
|
pub bid_price: Decimal, // 买一价
|
|
|
pub last_price: Decimal, // 最后成交价
|
|
|
- pub spread: Decimal, // 市场冲击
|
|
|
- pub spread_max: Decimal, // 最大市场冲击
|
|
|
- pub spread_best: Decimal, // 最佳市场冲击
|
|
|
+ pub spread: Decimal, // 当前价差
|
|
|
+ pub spread_sma: Decimal, // 价差的sma
|
|
|
+
|
|
|
pub optimal_ask_price: Decimal, // 卖出挂单价
|
|
|
pub optimal_bid_price: Decimal, // 买入挂单价
|
|
|
|
|
|
@@ -37,21 +37,11 @@ pub struct Predictor {
|
|
|
pub pos_amount: Decimal, // 原始持仓量
|
|
|
pub pos_avg_price: Decimal, // 原始持仓价格
|
|
|
pub level: Decimal, // martin
|
|
|
- pub sigma_square: Decimal, // σ^2,波动性的平方
|
|
|
- pub gamma: Decimal, // γ,库存风险厌恶参数
|
|
|
- pub kappa: Decimal, // κ 订单簿 流动性 参数
|
|
|
|
|
|
- pub flow_ratio: Decimal, // 资金流比例
|
|
|
- pub money_flow_index: Decimal, // MFI
|
|
|
- pub long_trade_len_dec: Decimal,
|
|
|
- pub short_trade_len_dec: Decimal,
|
|
|
pub error_rate: Decimal, // 犯错概率(预估)
|
|
|
- pub dir: Decimal, // 行情方向
|
|
|
|
|
|
pub ask_delta: Decimal, // δa
|
|
|
pub bid_delta: Decimal, // δb
|
|
|
- pub base_delta: Decimal, // 基础挂单距离
|
|
|
- pub ratio_edge: Decimal, // 资金流修正的挂单距离
|
|
|
|
|
|
pub fair_price_vec: Vec<Decimal>, // 预定价格队列
|
|
|
pub fair_price: Decimal, // 预定价格
|
|
|
@@ -59,14 +49,14 @@ pub struct Predictor {
|
|
|
pub price_times_avg: Decimal, // 公平所与做市所的价格倍率的平均值
|
|
|
pub is_regressed: bool, // 做市所的价格是否已经回归
|
|
|
|
|
|
- pub cci_arc: Arc<Mutex<CentralControlInfo>>, // 中控信息
|
|
|
+ pub is_ready: bool, // 是否已准备好
|
|
|
+ pub close_price: Decimal, // 计划平仓价格
|
|
|
|
|
|
- pub is_ready: bool,
|
|
|
pub prev_trade_time: i64, // 上次交易时间,也就是t
|
|
|
- pub close_price: Decimal, // 平仓价格
|
|
|
pub t_diff: Decimal, // (T-t)
|
|
|
- pub last_update_time: Decimal,
|
|
|
- pub last_index: Decimal,
|
|
|
+
|
|
|
+ pub last_update_time: Decimal, // 最后更新时间(depth)
|
|
|
+ pub last_index: Decimal, // 最后更新的index
|
|
|
|
|
|
pub prev_insert_time: Decimal,
|
|
|
pub prev_save_time: Decimal,
|
|
|
@@ -74,6 +64,9 @@ pub struct Predictor {
|
|
|
pub params: Params,
|
|
|
|
|
|
pub debug_sender: UnboundedSender<Vec<Decimal>>,
|
|
|
+
|
|
|
+ pub long_trade_len_dec: Decimal,
|
|
|
+ pub short_trade_len_dec: Decimal,
|
|
|
}
|
|
|
|
|
|
impl Predictor {
|
|
|
@@ -85,9 +78,9 @@ impl Predictor {
|
|
|
const TRADE_SHORT_RANGE_MICROS: i64 = 30_000_000;
|
|
|
// const ONE_MILLION: Decimal = dec!(1_000_000);
|
|
|
// const TWENTY_THOUSAND: Decimal = dec!(20_000);
|
|
|
- const IRA: Decimal = dec!(1);
|
|
|
+ const UN_VIEW: Decimal = dec!(14142135623730951);
|
|
|
|
|
|
- pub fn new(cci_arc: Arc<Mutex<CentralControlInfo>>, params: Params) -> Self {
|
|
|
+ pub fn new(_cci_arc: Arc<Mutex<CentralControlInfo>>, params: Params) -> Self {
|
|
|
// 创建数据通道
|
|
|
// 创建一个无界通道
|
|
|
let (tx, mut rx) = futures_channel::mpsc::unbounded::<Vec<Decimal>>();
|
|
|
@@ -100,7 +93,7 @@ impl Predictor {
|
|
|
while let Some(value) = rx.next().await {
|
|
|
// 数据填充到对应位置
|
|
|
for i in 0..len {
|
|
|
- if value[i] == dec!(14142135623730951) {
|
|
|
+ if value[i] == Self::UN_VIEW {
|
|
|
debugs[i].push_back(None);
|
|
|
} else {
|
|
|
debugs[i].push_back(Some(value[i]));
|
|
|
@@ -146,132 +139,58 @@ impl Predictor {
|
|
|
bid_price: Default::default(),
|
|
|
last_price: Default::default(),
|
|
|
spread: Default::default(),
|
|
|
- spread_max: Default::default(),
|
|
|
- spread_best: Default::default(),
|
|
|
+ spread_sma: Default::default(),
|
|
|
optimal_ask_price: Default::default(),
|
|
|
optimal_bid_price: Default::default(),
|
|
|
|
|
|
inventory: Default::default(),
|
|
|
- gamma: Default::default(),
|
|
|
- sigma_square: Default::default(),
|
|
|
ask_delta: Default::default(),
|
|
|
bid_delta: Default::default(),
|
|
|
- base_delta: Default::default(),
|
|
|
|
|
|
- ratio_edge: Default::default(),
|
|
|
- kappa: Default::default(),
|
|
|
fair_price: Default::default(),
|
|
|
fair_price_when_ordering: Default::default(),
|
|
|
|
|
|
price_times_avg: Default::default(),
|
|
|
is_regressed: false,
|
|
|
- cci_arc,
|
|
|
|
|
|
is_ready: false,
|
|
|
prev_trade_time: Utc::now().timestamp_micros(),
|
|
|
close_price: Default::default(),
|
|
|
t_diff: Default::default(),
|
|
|
level: Default::default(),
|
|
|
- flow_ratio: Default::default(),
|
|
|
- money_flow_index: Default::default(),
|
|
|
pos_amount: Default::default(),
|
|
|
error_rate: Default::default(),
|
|
|
- long_trade_len_dec: Default::default(),
|
|
|
- short_trade_len_dec: Default::default(),
|
|
|
last_update_time: Default::default(),
|
|
|
last_index: Default::default(),
|
|
|
pos_avg_price: Default::default(),
|
|
|
|
|
|
prev_insert_time: Default::default(),
|
|
|
prev_save_time: Decimal::from(Utc::now().timestamp_millis()),
|
|
|
- dir: Default::default(),
|
|
|
+
|
|
|
params,
|
|
|
|
|
|
debug_sender: tx,
|
|
|
- };
|
|
|
|
|
|
- predictor
|
|
|
- }
|
|
|
-
|
|
|
- // 更新最大市场冲击
|
|
|
- pub fn update_spread_max(&mut self) {
|
|
|
- self.spread_max = if let Some(&max_value) = self.spread_vec.iter().max() {
|
|
|
- max_value
|
|
|
- } else {
|
|
|
- Decimal::NEGATIVE_ONE
|
|
|
+ long_trade_len_dec: Default::default(),
|
|
|
+ short_trade_len_dec: Default::default(),
|
|
|
};
|
|
|
- }
|
|
|
-
|
|
|
- // 更新最佳市场冲击
|
|
|
- // pub fn update_spread_best(&mut self) {
|
|
|
- // self.spread_best = self.spread_max;
|
|
|
- // let mut max_count = 0usize;
|
|
|
- //
|
|
|
- // for (spread, count) in self.spread_count_map.iter() {
|
|
|
- // // info!(?spread, ?count);
|
|
|
- //
|
|
|
- // if *count < max_count {
|
|
|
- // continue
|
|
|
- // }
|
|
|
- //
|
|
|
- // self.spread_best = *spread;
|
|
|
- // max_count = *count;
|
|
|
- // }
|
|
|
- // // info!("======================")
|
|
|
- // }
|
|
|
|
|
|
- pub fn update_spread(&mut self) {
|
|
|
- // if self.trade_long_vec.len() > 0 {
|
|
|
- let prev_depth_0 = &self.depth_vec[0];
|
|
|
- if prev_depth_0.time.is_zero() {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- let prev_mid_price = (prev_depth_0.asks[0].price + prev_depth_0.bids[0].price) / Decimal::TWO;
|
|
|
- let now_spread = self.mid_price - prev_mid_price;
|
|
|
-
|
|
|
- if !now_spread.is_zero() {
|
|
|
- self.spread = now_spread;
|
|
|
- self.spread_vec.push(self.spread.abs());
|
|
|
-
|
|
|
- // 看空方向
|
|
|
- if now_spread < self.spread_max * Decimal::NEGATIVE_ONE && !self.spread_max.is_zero() {
|
|
|
- self.dir = Decimal::NEGATIVE_ONE
|
|
|
- }
|
|
|
-
|
|
|
- // 看多方向
|
|
|
- if now_spread > self.spread_max && !self.spread_max.is_zero() {
|
|
|
- self.dir = Decimal::ONE
|
|
|
- }
|
|
|
- // if last_trade_price > first_trade_price {
|
|
|
- // self.spread_long_vec.push(self.spread);
|
|
|
- // } else {
|
|
|
- // self.spread_short_vec.push(self.spread);
|
|
|
- // }
|
|
|
-
|
|
|
- while self.spread_vec.len() > 1_000 && self.inventory.is_zero() {
|
|
|
- self.spread_vec.remove(0);
|
|
|
- }
|
|
|
-
|
|
|
- self.update_spread_max();
|
|
|
- // self.update_spread_best();
|
|
|
- }
|
|
|
- // }
|
|
|
+ predictor
|
|
|
}
|
|
|
|
|
|
pub async fn on_depth(&mut self, depth: &Depth, index: usize) {
|
|
|
self.last_update_time = depth.time;
|
|
|
self.last_index = Decimal::from(index);
|
|
|
- self.update_fair_price(depth, index).await;
|
|
|
|
|
|
if index == 0 {
|
|
|
self.ask_price = depth.asks[0].price;
|
|
|
self.bid_price = depth.bids[0].price;
|
|
|
self.mid_price = (self.ask_price + self.bid_price) / Decimal::TWO;
|
|
|
-
|
|
|
- self.update_spread();
|
|
|
}
|
|
|
|
|
|
+ self.update_fair_price(depth, index).await;
|
|
|
+ self.update_spread();
|
|
|
+
|
|
|
self.depth_vec[index] = depth.clone();
|
|
|
|
|
|
if self.mid_price.is_zero() {
|
|
|
@@ -302,55 +221,7 @@ impl Predictor {
|
|
|
|
|
|
pub async fn on_ticker(&mut self, _ticker: &Ticker) {}
|
|
|
|
|
|
- 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() > 4 {
|
|
|
- self.record_vec.pop_front();
|
|
|
- }
|
|
|
-
|
|
|
- // 如果蜡烛数量足够,则更新mfi
|
|
|
- if self.record_vec.len() >= 4 {
|
|
|
- self.update_mfi();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pub fn update_mfi(&mut self) {
|
|
|
- let mut money_flow_in = Decimal::ZERO;
|
|
|
- let mut money_flow_out = Decimal::ZERO;
|
|
|
- let _3 = dec!(3);
|
|
|
-
|
|
|
- for record in self.record_vec.iter() {
|
|
|
- let typical_price = (record.high + record.low + record.close) / _3;
|
|
|
- let money_flow = typical_price * record.volume;
|
|
|
- if record.close > record.open {
|
|
|
- money_flow_in += money_flow;
|
|
|
- } else if record.close < record.open {
|
|
|
- money_flow_out += money_flow;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- self.money_flow_index = if money_flow_out.is_zero() {
|
|
|
- Decimal::ONE_HUNDRED
|
|
|
- } else {
|
|
|
- let money_flow_ratio = money_flow_in / money_flow_out;
|
|
|
-
|
|
|
- Decimal::ONE_HUNDRED - Decimal::ONE_HUNDRED / (Decimal::ONE + money_flow_ratio)
|
|
|
- };
|
|
|
-
|
|
|
- self.update_flow_ratio();
|
|
|
- }
|
|
|
+ pub async fn on_record(&mut self, _record: &Record) {}
|
|
|
|
|
|
pub async fn on_inventory(&mut self, pos_amount: &Decimal, pos_avg_price: &Decimal, min_amount_value: &Decimal) {
|
|
|
if self.mid_price.is_zero() {
|
|
|
@@ -383,23 +254,6 @@ impl Predictor {
|
|
|
self.processor().await;
|
|
|
}
|
|
|
|
|
|
- pub fn update_sigma_square(&mut self) {
|
|
|
- self.sigma_square = self.fair_price * self.params.open;
|
|
|
- self.sigma_square.rescale(10);
|
|
|
- }
|
|
|
-
|
|
|
- pub fn update_gamma(&mut self) {
|
|
|
- self.gamma = dec!(0.236) * Self::IRA;
|
|
|
- }
|
|
|
-
|
|
|
- pub fn update_kappa(&mut self) {
|
|
|
- if self.mid_price > Decimal::ZERO {
|
|
|
- self.kappa = dec!(888) / self.mid_price;
|
|
|
- } else {
|
|
|
- self.kappa = dec!(1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
pub async fn update_fair_price(&mut self, depth: &Depth, index: usize) {
|
|
|
if self.mid_price.is_zero() {
|
|
|
return;
|
|
|
@@ -451,6 +305,21 @@ impl Predictor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ pub fn update_spread(&mut self) {
|
|
|
+ self.spread = self.mid_price - self.fair_price;
|
|
|
+ self.spread_vec.push(self.spread);
|
|
|
+
|
|
|
+ self.spread_sma = if self.spread_sma.is_zero() {
|
|
|
+ self.spread
|
|
|
+ } else {
|
|
|
+ self.spread_sma * dec!(0.9998) + self.spread * dec!(0.0002)
|
|
|
+ };
|
|
|
+
|
|
|
+ while self.spread_vec.len() > 1_000 {
|
|
|
+ self.spread_vec.remove(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
pub fn update_delta(&mut self) {
|
|
|
// -2表示不想成交
|
|
|
// -1表示市价成交(委托对手盘的价格,但不一定能市价成交),这里再想想吧,经常委托出去没成交,明显比别人慢了
|
|
|
@@ -511,7 +380,7 @@ impl Predictor {
|
|
|
self.optimal_ask_price = if self.ask_delta == dec!(-1) {
|
|
|
self.bid_price
|
|
|
} else if self.ask_delta == dec!(-2) {
|
|
|
- dec!(14142135623730951)
|
|
|
+ Self::UN_VIEW
|
|
|
} else {
|
|
|
max(self.ask_price + self.ask_delta, self.bid_price)
|
|
|
};
|
|
|
@@ -519,7 +388,7 @@ impl Predictor {
|
|
|
self.optimal_bid_price = if self.bid_delta == dec!(-1) {
|
|
|
self.ask_price
|
|
|
} else if self.bid_delta == dec!(-2) {
|
|
|
- dec!(14142135623730951)
|
|
|
+ Self::UN_VIEW
|
|
|
} else {
|
|
|
min(self.bid_price - self.bid_delta, self.ask_price)
|
|
|
};
|
|
|
@@ -537,36 +406,6 @@ impl Predictor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // fn calc_flow_ratio(_prev_flow_ratio: &Decimal, min_volume: &Decimal, trades: &mut FixedTimeRangeDeque<Trade>) -> Decimal {
|
|
|
- // let mut flow_in_value = Decimal::ZERO;
|
|
|
- // let mut flow_out_value = Decimal::ZERO;
|
|
|
- // for trade_iter in trades.deque.iter() {
|
|
|
- // if trade_iter.size > Decimal::ZERO {
|
|
|
- // flow_in_value += trade_iter.value;
|
|
|
- // } else {
|
|
|
- // flow_out_value += trade_iter.value;
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // // 使用EMA來更新資金流,確保平滑性
|
|
|
- // if flow_out_value + flow_in_value > *min_volume {
|
|
|
- // let now = (flow_in_value - flow_out_value) / (flow_out_value + flow_in_value);
|
|
|
- // now
|
|
|
- // } else {
|
|
|
- // Decimal::ZERO
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
- pub fn update_flow_ratio(&mut self) {
|
|
|
- self.flow_ratio = if self.money_flow_index > dec!(80) {
|
|
|
- (self.money_flow_index - dec!(80)) / dec!(20)
|
|
|
- } else if self.money_flow_index < dec!(20) {
|
|
|
- Decimal::NEGATIVE_ONE * (dec!(20) - self.money_flow_index) / dec!(20)
|
|
|
- } else {
|
|
|
- Decimal::ZERO
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
pub fn check_ready(&mut self) {
|
|
|
if self.is_ready {
|
|
|
return;
|
|
|
@@ -607,9 +446,6 @@ impl Predictor {
|
|
|
// #[instrument(skip(self), level="TRACE")]
|
|
|
async fn processor(&mut self) {
|
|
|
self.update_t_diff();
|
|
|
- self.update_sigma_square();
|
|
|
- self.update_gamma();
|
|
|
- self.update_kappa();
|
|
|
self.update_delta();
|
|
|
self.update_optimal_ask_and_bid();
|
|
|
|
|
|
@@ -633,9 +469,9 @@ impl Predictor {
|
|
|
let bid_price = self.bid_price;
|
|
|
let last_price = self.last_price;
|
|
|
|
|
|
- let spread = self.mid_price;
|
|
|
- let spread_max = self.optimal_ask_price;
|
|
|
- let spread_min = self.optimal_bid_price;
|
|
|
+ let spread = self.spread;
|
|
|
+ let spread_max = self.spread_sma;
|
|
|
+ let spread_min = Self::UN_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;
|