|
|
@@ -30,6 +30,9 @@ pub struct AvellanedaStoikov {
|
|
|
pub sigma_square: Decimal, // σ^2,波动性的平方
|
|
|
pub gamma: Decimal, // γ,库存风险厌恶参数
|
|
|
pub kappa: Decimal, // κ 订单簿 流动性 参数
|
|
|
+ pub flow_ratio: Decimal, // 资金流比例
|
|
|
+ pub flow_ratio_diff: Decimal, // 一阶导数
|
|
|
+ pub flow_ratio_diff_diff: Decimal, // 二阶导数
|
|
|
|
|
|
pub delta_plus: Decimal, // δa+δb,买卖挂单间距
|
|
|
pub ref_price: Decimal, // 预定价格
|
|
|
@@ -74,6 +77,9 @@ impl AvellanedaStoikov {
|
|
|
is_ready: false,
|
|
|
prev_trade_time: 0,
|
|
|
t_diff: Default::default(),
|
|
|
+ flow_ratio: Decimal::ONE,
|
|
|
+ flow_ratio_diff: Default::default(),
|
|
|
+ flow_ratio_diff_diff: Default::default(),
|
|
|
};
|
|
|
|
|
|
avellaneda_stoikov
|
|
|
@@ -243,6 +249,49 @@ impl AvellanedaStoikov {
|
|
|
self.t_diff = Decimal::ONE;
|
|
|
}
|
|
|
|
|
|
+ pub fn update_flow_ratio(&mut self) {
|
|
|
+ let prev_flow_ratio = self.flow_ratio;
|
|
|
+ let prev_flow_ratio_diff = self.flow_ratio_diff;
|
|
|
+
|
|
|
+ self.flow_ratio = if self.trade_vec.len() < 2 {
|
|
|
+ Decimal::ZERO
|
|
|
+ } else {
|
|
|
+ let mut flow_in_value = Decimal::ZERO;
|
|
|
+ let mut flow_out_value = Decimal::ZERO;
|
|
|
+ for trade in self.trade_vec.deque.iter() {
|
|
|
+ if trade.size > Decimal::ZERO {
|
|
|
+ flow_in_value += trade.value;
|
|
|
+ } else {
|
|
|
+ flow_out_value += trade.value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ info!(?flow_in_value, ?flow_out_value);
|
|
|
+
|
|
|
+ if flow_out_value == Decimal::ZERO {
|
|
|
+ Decimal::ZERO
|
|
|
+ } else {
|
|
|
+ flow_in_value / flow_out_value
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ self.flow_ratio.rescale(2);
|
|
|
+ self.flow_ratio = if self.flow_ratio > Decimal::TEN {
|
|
|
+ Decimal::ZERO
|
|
|
+ } else if self.flow_ratio < dec!(-10) {
|
|
|
+ Decimal::ZERO
|
|
|
+ } else {
|
|
|
+ self.flow_ratio
|
|
|
+ };
|
|
|
+
|
|
|
+ if prev_flow_ratio != Decimal::ZERO && self.flow_ratio != prev_flow_ratio {
|
|
|
+ self.flow_ratio_diff = self.flow_ratio_diff * dec!(0.98) + (self.flow_ratio - prev_flow_ratio) * dec!(0.02)
|
|
|
+ }
|
|
|
+
|
|
|
+ if prev_flow_ratio_diff != Decimal::ZERO && self.flow_ratio_diff != prev_flow_ratio_diff {
|
|
|
+ self.flow_ratio_diff_diff = self.flow_ratio_diff_diff * dec!(0.5) + (self.flow_ratio_diff - prev_flow_ratio_diff) * dec!(0.5)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
pub fn check_ready(&mut self) {
|
|
|
if self.is_ready {
|
|
|
return;
|
|
|
@@ -283,6 +332,7 @@ impl AvellanedaStoikov {
|
|
|
// #[instrument(skip(self), level="TRACE")]
|
|
|
async fn processor(&mut self) {
|
|
|
self.update_t_diff();
|
|
|
+ self.update_flow_ratio();
|
|
|
self.update_sigma_square();
|
|
|
// info!(?self.sigma_square);
|
|
|
self.update_gamma();
|
|
|
@@ -315,8 +365,8 @@ impl AvellanedaStoikov {
|
|
|
optimal_bid_price: self.optimal_bid_price,
|
|
|
|
|
|
inventory: self.inventory,
|
|
|
- sigma_square: self.sigma_square,
|
|
|
- gamma: self.gamma,
|
|
|
+ sigma_square: self.flow_ratio_diff,
|
|
|
+ gamma: self.flow_ratio_diff_diff,
|
|
|
kappa: self.kappa,
|
|
|
|
|
|
delta_plus: self.delta_plus,
|