|
|
@@ -50,6 +50,7 @@ pub struct AvellanedaStoikov {
|
|
|
pub prev_trade_time: i64, // 上次交易时间,也就是t
|
|
|
pub cross_time: i64, // 上次穿過0軸的時間
|
|
|
pub cross_time_diff: i64, // 穿越0軸的diff
|
|
|
+ pub cross_time_diff_avg: i64, // 穿越0軸的diff的平均值
|
|
|
pub t_diff: Decimal, // (T-t)
|
|
|
pub prev_close_time: i64, // 上次平倉時間
|
|
|
pub prev_prev_close_time: i64, // 上上次平倉時間
|
|
|
@@ -100,6 +101,7 @@ impl AvellanedaStoikov {
|
|
|
prev_trade_time: Utc::now().timestamp_micros(),
|
|
|
cross_time: 0,
|
|
|
cross_time_diff: 0,
|
|
|
+ cross_time_diff_avg: 0,
|
|
|
t_diff: Default::default(),
|
|
|
flow_ratio_long: Decimal::ONE,
|
|
|
level: Default::default(),
|
|
|
@@ -244,12 +246,20 @@ impl AvellanedaStoikov {
|
|
|
self.ask_delta += pos_edge;
|
|
|
}
|
|
|
|
|
|
+ if self.flow_ratio_long.is_zero() || self.cross_time_diff < 30 {
|
|
|
+ self.ask_delta += self.base_delta;
|
|
|
+ self.bid_delta += self.base_delta;
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if self.flow_ratio_long < Decimal::ZERO {
|
|
|
if self.flow_ratio_short > Decimal::ZERO {
|
|
|
self.ask_delta -= self.base_delta * (self.flow_ratio_short.abs() * Decimal::PI);
|
|
|
self.bid_delta += self.base_delta;
|
|
|
} else if self.flow_ratio_short < Decimal::ZERO && self.inventory < Decimal::ZERO {
|
|
|
self.ask_delta += self.base_delta;
|
|
|
+ // self.bid_delta -= self.base_delta * (self.flow_ratio_short.abs() + self.flow_ratio_long.abs());
|
|
|
self.bid_delta -= self.base_delta * (self.flow_ratio_short.abs() * dec!(1.5));
|
|
|
} else {
|
|
|
self.ask_delta += self.base_delta;
|
|
|
@@ -257,6 +267,7 @@ impl AvellanedaStoikov {
|
|
|
}
|
|
|
} else if self.flow_ratio_long > Decimal::ZERO {
|
|
|
if self.flow_ratio_short > Decimal::ZERO && self.inventory > Decimal::ZERO {
|
|
|
+ // self.ask_delta -= self.base_delta * (self.flow_ratio_short.abs() + self.flow_ratio_long.abs());
|
|
|
self.ask_delta -= self.base_delta * (self.flow_ratio_short.abs() * dec!(1.5));
|
|
|
self.bid_delta += self.base_delta;
|
|
|
} else if self.flow_ratio_short < Decimal::ZERO {
|
|
|
@@ -266,13 +277,6 @@ impl AvellanedaStoikov {
|
|
|
self.ask_delta += self.base_delta;
|
|
|
self.bid_delta += self.base_delta;
|
|
|
}
|
|
|
- } else {
|
|
|
- self.ask_delta += self.base_delta;
|
|
|
- self.bid_delta += self.base_delta;
|
|
|
- }
|
|
|
-
|
|
|
- if self.init_delta_plus.is_zero() {
|
|
|
- self.init_delta_plus = (self.bid_delta + self.ask_delta) / Decimal::TWO
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -379,13 +383,25 @@ impl AvellanedaStoikov {
|
|
|
pub fn update_flow_ratio(&mut self) {
|
|
|
let prev_flow_ratio_long = self.flow_ratio_long;
|
|
|
self.flow_ratio_long = Self::calc_flow_ratio(&self.flow_ratio_long, &dec!(0), &mut self.trade_long_vec);
|
|
|
+ let time = Utc::now().timestamp_millis();
|
|
|
+ let mut is_cross = false;
|
|
|
if (self.flow_ratio_long > Decimal::ZERO && prev_flow_ratio_long <= Decimal::ZERO)
|
|
|
|| (self.flow_ratio_long < Decimal::ZERO && prev_flow_ratio_long >= Decimal::ZERO) {
|
|
|
- self.cross_time = Utc::now().timestamp_millis();
|
|
|
+ self.cross_time = time;
|
|
|
+ is_cross = true;
|
|
|
}
|
|
|
|
|
|
if self.cross_time != 0 {
|
|
|
- self.cross_time_diff = (Utc::now().timestamp_millis() - self.cross_time) / 1000;
|
|
|
+ let prev_cross_time_diff = self.cross_time_diff;
|
|
|
+ self.cross_time_diff = (time - self.cross_time) / 1000;
|
|
|
+
|
|
|
+ if is_cross {
|
|
|
+ self.cross_time_diff_avg = if self.cross_time_diff_avg == 0 {
|
|
|
+ prev_cross_time_diff
|
|
|
+ } else {
|
|
|
+ (self.cross_time_diff_avg * 5 + prev_cross_time_diff * 5) / 10
|
|
|
+ };
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
self.flow_ratio_short = Self::calc_flow_ratio(&self.flow_ratio_short, &dec!(0), &mut self.trade_short_vec);
|
|
|
@@ -469,7 +485,7 @@ impl AvellanedaStoikov {
|
|
|
inventory: self.inventory,
|
|
|
sigma_square: self.flow_ratio_long,
|
|
|
gamma: self.flow_ratio_short,
|
|
|
- kappa: Decimal::from(self.cross_time_diff),
|
|
|
+ kappa: Decimal::from(self.cross_time_diff_avg),
|
|
|
|
|
|
flow_ratio: self.flow_ratio_long,
|
|
|
ref_price: self.ref_price,
|