|
|
@@ -38,6 +38,9 @@ pub struct AvellanedaStoikov {
|
|
|
pub gamma: Decimal, // γ,库存风险厌恶参数
|
|
|
pub kappa: Decimal, // κ 订单簿 流动性 参数
|
|
|
|
|
|
+ pub flow_ratio: Decimal, // 资金流比例
|
|
|
+ pub money_flow_index: Decimal, // MFI
|
|
|
+
|
|
|
pub ask_delta: Decimal, // δa
|
|
|
pub bid_delta: Decimal, // δb
|
|
|
pub base_delta: Decimal, // 基础挂单距离
|
|
|
@@ -102,6 +105,8 @@ impl AvellanedaStoikov {
|
|
|
prev_trade_time: Utc::now().timestamp_micros(),
|
|
|
t_diff: Default::default(),
|
|
|
level: Default::default(),
|
|
|
+ flow_ratio: Default::default(),
|
|
|
+ money_flow_index: Default::default(),
|
|
|
};
|
|
|
|
|
|
avellaneda_stoikov
|
|
|
@@ -235,6 +240,35 @@ impl AvellanedaStoikov {
|
|
|
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)
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
pub async fn update_inventory(&mut self, inventory: &Decimal, min_amount_value: &Decimal) {
|
|
|
@@ -343,6 +377,16 @@ impl AvellanedaStoikov {
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
+ 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;
|
|
|
@@ -417,7 +461,7 @@ impl AvellanedaStoikov {
|
|
|
|
|
|
inventory: self.inventory,
|
|
|
sigma_square: self.sigma_square,
|
|
|
- gamma: self.spread,
|
|
|
+ gamma: self.money_flow_index,
|
|
|
kappa: self.kappa,
|
|
|
|
|
|
flow_ratio: Decimal::ZERO,
|