|
|
@@ -1,5 +1,4 @@
|
|
|
-use std::cmp::{max, min};
|
|
|
-use std::collections::{BTreeMap, VecDeque};
|
|
|
+use std::collections::{BTreeMap, HashMap, VecDeque};
|
|
|
use std::sync::Arc;
|
|
|
use chrono::{Utc};
|
|
|
use futures_channel::mpsc::UnboundedSender;
|
|
|
@@ -16,10 +15,7 @@ use crate::utils;
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct Predictor {
|
|
|
- pub depth_vec: Vec<Depth>, // 深度队列
|
|
|
- pub record_vec: VecDeque<Record>, // 蜡烛队列
|
|
|
-
|
|
|
- // 做市所的计算
|
|
|
+ // MeanReversion概率相关
|
|
|
pub close_price_vec: FixedTimeRangeDeque<Record>,
|
|
|
pub log_return_vec: VecDeque<Decimal>,
|
|
|
pub r_vec: VecDeque<Decimal>,
|
|
|
@@ -29,68 +25,67 @@ pub struct Predictor {
|
|
|
pub phi: Decimal,
|
|
|
pub weights: VecDeque<Decimal>,
|
|
|
|
|
|
- pub prices: Vec<Vec<FixedTimeRangeDeque<Decimal>>>, // [[[做市所], [参考所0]], ...]
|
|
|
- pub ks: Vec<Decimal>,
|
|
|
- pub bs: Vec<Decimal>,
|
|
|
-
|
|
|
+ // 价格相关
|
|
|
pub mid_price: Decimal, // 中间价
|
|
|
- pub ask_price: Decimal, // 中间价
|
|
|
- pub bid_price: Decimal, // 中间价
|
|
|
- pub fair_price: Decimal,
|
|
|
+ pub ask_price: Decimal, // a1
|
|
|
+ pub bid_price: Decimal, // b1
|
|
|
+ pub fair_price: Decimal, // 公平价
|
|
|
pub last_price: Decimal, // 最后成交价
|
|
|
+ pub depth_vec: Vec<Depth>, // 深度队列
|
|
|
|
|
|
- pub optimal_ask_price: Decimal, // 卖出挂单价
|
|
|
- pub optimal_bid_price: Decimal, // 买入挂单价
|
|
|
-
|
|
|
+ // 库存相关
|
|
|
pub inventory: Decimal, // 库存,也就是q
|
|
|
pub pos_amount: Decimal, // 原始持仓量
|
|
|
pub pos_avg_price: Decimal, // 原始持仓价格
|
|
|
pub balance: Decimal, // 初始余额
|
|
|
- pub prev_balance: Decimal,
|
|
|
+ pub one_grid_order_value: Decimal, // 每一网格下单价值
|
|
|
pub profit: Decimal,
|
|
|
- pub profit_high: Decimal,
|
|
|
+ pub profit_high: Decimal, // 总体持仓利润的最大值
|
|
|
|
|
|
- pub prev_open_time: Decimal,
|
|
|
-
|
|
|
- pub trade_condition: Decimal, // 交易信号
|
|
|
+ // 交易信号相关
|
|
|
+ pub trade_condition: Decimal, // 交易信号,用于保存一段时间的交易信号
|
|
|
pub trade_condition_time: Decimal, // 满足时的瞬时时间,用于控制开仓行为的持续时间
|
|
|
-
|
|
|
pub ask_delta: Decimal, // δa
|
|
|
pub bid_delta: Decimal, // δb
|
|
|
+ pub optimal_ask_price: Decimal, // 卖出挂单价
|
|
|
+ pub optimal_bid_price: Decimal, // 买入挂单价
|
|
|
|
|
|
+ // 公平价生成相关
|
|
|
+ pub prev_fitting_time_vec: Vec<Decimal>, // 生成公平价的时间
|
|
|
pub mid_price_vec: Vec<Decimal>, // 每个交易所的中间价
|
|
|
pub fair_price_std_vec: Vec<Decimal>, // 公平价格列表,标准化之后的
|
|
|
- pub price_avg_times_vec: Vec<Decimal>, // 公平所与做市所的价格倍率的平均值
|
|
|
- pub price_avg_times_long_vec: Vec<Decimal>, // 公平所与做市所的价格倍率的平均值
|
|
|
-
|
|
|
- pub is_ready: bool, // 是否已准备好
|
|
|
-
|
|
|
- pub last_update_time: Decimal, // 最后更新时间(depth)
|
|
|
- pub last_index: Decimal, // 最后更新的index
|
|
|
+ pub prices: Vec<Vec<FixedTimeRangeDeque<Decimal>>>, // [[[做市所], [参考所0]], ...]
|
|
|
+ pub ks: Vec<Decimal>, // 拟合的斜率
|
|
|
+ pub bs: Vec<Decimal>, // 拟合的截距
|
|
|
|
|
|
- pub prev_insert_time: Decimal,
|
|
|
- pub prev_save_time: Decimal,
|
|
|
- pub init_time: Decimal,
|
|
|
- pub fitting_delay: Decimal,
|
|
|
- pub prev_fitting_time_vec: Vec<Decimal>,
|
|
|
+ // 网格开平仓相关
|
|
|
+ pub trade_time_vec: VecDeque<Decimal>, // 成交时间队列
|
|
|
+ pub trade_side_map: HashMap<Decimal, String>, // 成交时间对应的是kk,kd两个方向
|
|
|
+ pub trade_amount_map: HashMap<Decimal, Decimal>, // 成交对应的交易数量
|
|
|
+ pub ready_close_amount: Decimal, // 预计平仓数量
|
|
|
|
|
|
+ // 系统相关变量
|
|
|
+ pub is_ready: bool, // 是否已准备好
|
|
|
pub params: Params,
|
|
|
|
|
|
- pub debug_sender: UnboundedSender<Vec<Decimal>>
|
|
|
+ // 马尔可夫链相关
|
|
|
+ // pub prev_update_state_time: Decimal,
|
|
|
+ // pub state: usize,
|
|
|
+ // pub state_matrix: Vec<Vec<Decimal>>,
|
|
|
+
|
|
|
+ // debug、图表相关
|
|
|
+ pub debug_sender: UnboundedSender<Vec<Decimal>>,
|
|
|
+ pub prev_plot_time: Decimal,
|
|
|
}
|
|
|
|
|
|
impl Predictor {
|
|
|
- // 时间窗口大小(微秒)
|
|
|
- // const MAX_TIME_RANGE_MICROS: i64 = 3 * 60_000_000;
|
|
|
- // const TIME_DIFF_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
|
- // const TRADE_LONG_RANGE_MICROS: i64 = 10 * 60_000_000;
|
|
|
- // const SPREAD_RANGE_MICROS: i64 = 15 * 60_000_000;
|
|
|
- // const TRADE_SHORT_RANGE_MICROS: i64 = 10_000_000;
|
|
|
- // const ONE_MILLION: Decimal = dec!(1_000_000);
|
|
|
- // const TWENTY_THOUSAND: Decimal = dec!(20_000);
|
|
|
const DONT_VIEW: Decimal = dec!(14142135623730951);
|
|
|
|
|
|
pub fn new(_cci_arc: Arc<Mutex<CentralControlInfo>>, params: Params) -> Self {
|
|
|
+ if params.close.is_zero() {
|
|
|
+ panic!("做市策略特殊逻辑要求平仓距离不得为0。");
|
|
|
+ }
|
|
|
+
|
|
|
// 创建数据通道
|
|
|
// 创建一个无界通道
|
|
|
let (tx, mut rx) = futures_channel::mpsc::unbounded::<Vec<Decimal>>();
|
|
|
@@ -149,12 +144,9 @@ impl Predictor {
|
|
|
});
|
|
|
|
|
|
let predictor = Self {
|
|
|
- // 接针版本
|
|
|
depth_vec: vec![Depth::new(); params.ref_exchange.len()],
|
|
|
fair_price_std_vec: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
mid_price_vec: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
- price_avg_times_vec: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
- price_avg_times_long_vec: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
|
|
|
prices: vec![vec![FixedTimeRangeDeque::new(600_000_000); 2]; params.ref_exchange.len()],
|
|
|
ks: vec![Decimal::ZERO; params.ref_exchange.len()],
|
|
|
@@ -188,37 +180,37 @@ impl Predictor {
|
|
|
pos_avg_price: Default::default(),
|
|
|
pos_amount: Default::default(),
|
|
|
balance: Default::default(),
|
|
|
- prev_balance: Default::default(),
|
|
|
|
|
|
+ one_grid_order_value: Default::default(),
|
|
|
profit: Default::default(),
|
|
|
profit_high: Default::default(),
|
|
|
|
|
|
trade_condition: Default::default(),
|
|
|
trade_condition_time: Default::default(),
|
|
|
|
|
|
- last_update_time: Default::default(),
|
|
|
- last_index: Default::default(),
|
|
|
-
|
|
|
- prev_insert_time: Default::default(),
|
|
|
- prev_save_time: Decimal::from(Utc::now().timestamp_millis()),
|
|
|
- init_time: Decimal::from(Utc::now().timestamp_millis()),
|
|
|
-
|
|
|
- fitting_delay: Default::default(),
|
|
|
+ prev_plot_time: Default::default(),
|
|
|
params,
|
|
|
|
|
|
debug_sender: tx,
|
|
|
- prev_open_time: Default::default(),
|
|
|
|
|
|
- record_vec: Default::default(),
|
|
|
+ trade_time_vec: VecDeque::new(),
|
|
|
+ trade_side_map: HashMap::new(),
|
|
|
+ trade_amount_map: HashMap::new(),
|
|
|
+ ready_close_amount: Default::default(),
|
|
|
+
|
|
|
+ // prev_update_state_time: Default::default(),
|
|
|
+ // state: 1,
|
|
|
+ // state_matrix: vec![
|
|
|
+ // vec![dec!(0.33), dec!(0.33), dec!(0.33)],
|
|
|
+ // vec![dec!(0.33), dec!(0.33), dec!(0.33)],
|
|
|
+ // vec![dec!(0.33), dec!(0.33), dec!(0.33)],
|
|
|
+ // ],
|
|
|
};
|
|
|
|
|
|
predictor
|
|
|
}
|
|
|
|
|
|
pub async fn on_depth(&mut self, depth: &Depth, index: usize) {
|
|
|
- self.last_update_time = depth.time;
|
|
|
- self.last_index = Decimal::from(index);
|
|
|
-
|
|
|
if index == 233 {
|
|
|
self.ask_price = depth.asks[0].price;
|
|
|
self.bid_price = depth.bids[0].price;
|
|
|
@@ -319,7 +311,6 @@ impl Predictor {
|
|
|
self.ks[mid_index] = k;
|
|
|
self.bs[mid_index] = b;
|
|
|
|
|
|
- self.fitting_delay = Decimal::from(Utc::now().timestamp_millis() - before_fitting);
|
|
|
self.prev_fitting_time_vec[mid_index] = Decimal::from(before_fitting)
|
|
|
} else {
|
|
|
return;
|
|
|
@@ -347,66 +338,64 @@ impl Predictor {
|
|
|
self.last_price = trade.price;
|
|
|
}
|
|
|
|
|
|
- pub async fn on_ticker(&mut self, _ticker: &Ticker) {}
|
|
|
+ // side, pk,pd从HashMap移除,kd,kk添加到HashMap
|
|
|
+ pub async fn on_order(&mut self, side: String, amount: Decimal) {
|
|
|
+ self.inventory = match side.as_str() {
|
|
|
+ "kk" => {
|
|
|
+ self.inventory - Decimal::ONE
|
|
|
+ }
|
|
|
+ "pd" => {
|
|
|
+ self.inventory - Decimal::ONE
|
|
|
+ }
|
|
|
+ "kd" => {
|
|
|
+ self.inventory + Decimal::ONE
|
|
|
+ }
|
|
|
+ "pk" => {
|
|
|
+ self.inventory + Decimal::ONE
|
|
|
+ }
|
|
|
+ &_ => {
|
|
|
+ panic!("不认识的order方向:{}", side);
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
- 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 side == "kk" || side == "kd" {
|
|
|
+ let now = Decimal::from(Utc::now().timestamp_millis());
|
|
|
|
|
|
- if last_record.time == record.time {
|
|
|
- *last_record = record.clone();
|
|
|
- } else if last_record.time < record.time {
|
|
|
- self.record_vec.push_back(record.clone());
|
|
|
- }
|
|
|
+ self.trade_time_vec.push_back(now);
|
|
|
+ self.trade_side_map.insert(now, side);
|
|
|
+ self.trade_amount_map.insert(now, amount);
|
|
|
+ } else if side == "pd" || side == "pk" {
|
|
|
+ let pop_time = self.trade_time_vec.pop_front().unwrap();
|
|
|
+
|
|
|
+ self.trade_side_map.remove(&pop_time);
|
|
|
+ self.trade_amount_map.remove(&pop_time);
|
|
|
}
|
|
|
|
|
|
- if self.record_vec.len() > 5 {
|
|
|
- self.record_vec.pop_front();
|
|
|
+ info!(?self.trade_time_vec);
|
|
|
+ info!(?self.trade_side_map);
|
|
|
+ info!(?self.trade_amount_map);
|
|
|
+ }
|
|
|
+
|
|
|
+ pub async fn on_ticker(&mut self, _ticker: &Ticker) {}
|
|
|
+
|
|
|
+ pub async fn on_record(&mut self, _record: &Record) {}
|
|
|
+
|
|
|
+ pub async fn on_balance(&mut self, balance: Decimal) {
|
|
|
+ self.balance = balance;
|
|
|
+ if self.inventory.is_zero() {
|
|
|
+ self.one_grid_order_value = (self.params.lever_rate * self.balance) / self.params.grid;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub async fn on_inventory(&mut self, pos_amount: &Decimal, pos_avg_price: &Decimal, min_amount_value: &Decimal, update_time: Decimal) {
|
|
|
+ pub async fn on_inventory(&mut self, pos_amount: &Decimal, pos_avg_price: &Decimal, _min_amount_value: &Decimal, update_time: Decimal) {
|
|
|
if self.mid_price.is_zero() {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- let prev_pos_amount = self.pos_amount;
|
|
|
self.pos_amount = pos_amount.clone();
|
|
|
self.pos_avg_price = pos_avg_price.clone();
|
|
|
- self.inventory = (pos_amount / (min_amount_value / self.mid_price)).trunc();
|
|
|
- // 小于1但不为0的情况,需要平完
|
|
|
- if self.inventory.is_zero() && !pos_amount.is_zero() {
|
|
|
- self.inventory = if pos_amount > &Decimal::ZERO {
|
|
|
- Decimal::ONE
|
|
|
- } else {
|
|
|
- Decimal::NEGATIVE_ONE
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- if prev_pos_amount != self.pos_amount {
|
|
|
- // 重置连续信号
|
|
|
- self.trade_condition = Decimal::ZERO;
|
|
|
- self.trade_condition_time = Decimal::ZERO;
|
|
|
-
|
|
|
- // 开仓
|
|
|
- if prev_pos_amount.is_zero() {
|
|
|
- self.prev_open_time = Decimal::from(Utc::now().timestamp_millis())
|
|
|
- }
|
|
|
- // 平仓
|
|
|
- if self.pos_amount.is_zero() {
|
|
|
- self.profit = Decimal::ZERO;
|
|
|
- self.profit_high = Decimal::ZERO;
|
|
|
- }
|
|
|
-
|
|
|
- self.processor(update_time, true).await;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- pub async fn on_balance(&mut self, balance: Decimal) {
|
|
|
- self.balance = balance;
|
|
|
+ self.processor(update_time, true).await;
|
|
|
}
|
|
|
|
|
|
pub async fn update_fair_price(&mut self, latest_price: &Decimal, index: usize) {
|
|
|
@@ -414,11 +403,6 @@ impl Predictor {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // https://quant.stackexchange.com/questions/50651/how-to-understand-micro-price-aka-weighted-mid-price
|
|
|
- // let total = a1.value + b1.value;
|
|
|
- // let fair_price = (a1.price + b1.price) / Decimal::TWO;
|
|
|
-
|
|
|
- // self.fair_price_vec[index] = a1.price * b1.value / total + b1.price * a1.value / total;
|
|
|
let mut mp = latest_price.clone();
|
|
|
mp.rescale(self.mid_price.scale());
|
|
|
self.mid_price_vec[index] = mp;
|
|
|
@@ -438,18 +422,6 @@ impl Predictor {
|
|
|
} else {
|
|
|
dec!(0.9) * self.fair_price + dec!(0.1) * fair_price_sum / Decimal::from(fair_price_count)
|
|
|
};
|
|
|
-
|
|
|
- // let mut spread_abs = ((self.fair_price - self.mid_price) / self.mid_price).abs();
|
|
|
- // spread_abs.rescale(5);
|
|
|
- //
|
|
|
- // self.spread_vec.push_back(spread_abs);
|
|
|
- // if self.spread_vec.len() > 3000 {
|
|
|
- // self.spread_vec.pop_front();
|
|
|
- // }
|
|
|
- //
|
|
|
- // let opt_abs_value = self.spread_vec.iter().max().unwrap().clone();
|
|
|
- //
|
|
|
- // self.params.open = max(max(self.params.min_open, dec!(0.0006)), opt_abs_value);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -458,18 +430,31 @@ impl Predictor {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- let prev_bid_delta = self.bid_delta;
|
|
|
- let prev_ask_delta = self.ask_delta;
|
|
|
-
|
|
|
let now = Decimal::from(Utc::now().timestamp_millis());
|
|
|
+ // 平仓优先级高一些
|
|
|
+ if self.trade_time_vec.len() > 0 {
|
|
|
+ let first = self.trade_time_vec.front().unwrap();
|
|
|
|
|
|
- let is_close_long = self.inventory > Decimal::ZERO && (
|
|
|
- // 硬止损,开单不久之后就在亏
|
|
|
- (self.profit_high < dec!(0.001) && self.profit < dec!(-0.01))
|
|
|
- // 时间到了,追踪止盈
|
|
|
- || (now - self.prev_open_time > dec!(100_000) && self.profit < self.profit_high * dec!(0.75))
|
|
|
- );
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO;
|
|
|
+ if now - *first > self.params.holding_time * Decimal::ONE_THOUSAND {
|
|
|
+ let side = self.trade_side_map.get(first).unwrap();
|
|
|
+ self.ready_close_amount = self.trade_amount_map.get(first).unwrap().clone();
|
|
|
+
|
|
|
+ match side.as_str() {
|
|
|
+ "kd" => {
|
|
|
+ self.ask_delta = self.mid_price * self.params.close;
|
|
|
+ }
|
|
|
+ "kk" => {
|
|
|
+ self.bid_delta = self.mid_price * self.params.close;
|
|
|
+ }
|
|
|
+ &_ => {
|
|
|
+ panic!("什么方向放进来了?side={}", side);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let prev_bid_delta = self.bid_delta;
|
|
|
+ let prev_ask_delta = self.ask_delta;
|
|
|
|
|
|
let is_open_long = self.inventory.is_zero()
|
|
|
&& self.phi > Decimal::ONE
|
|
|
@@ -481,12 +466,6 @@ impl Predictor {
|
|
|
;
|
|
|
|
|
|
// 使信号有一定持续性
|
|
|
- if is_close_long {
|
|
|
- self.trade_condition = dec!(1);
|
|
|
- }
|
|
|
- if is_close_short {
|
|
|
- self.trade_condition = dec!(2);
|
|
|
- }
|
|
|
if is_open_long {
|
|
|
self.trade_condition = dec!(3);
|
|
|
self.trade_condition_time = now;
|
|
|
@@ -496,9 +475,9 @@ impl Predictor {
|
|
|
self.trade_condition_time = now;
|
|
|
}
|
|
|
|
|
|
- // 开仓信号要过期,只保留2秒
|
|
|
+ // 开仓信号要过期,只保留60秒
|
|
|
if (self.trade_condition == dec!(3) || self.trade_condition == dec!(4))
|
|
|
- && now - self.trade_condition_time > dec!(2_000) {
|
|
|
+ && now - self.trade_condition_time > dec!(60_000) {
|
|
|
self.trade_condition = Decimal::ZERO;
|
|
|
}
|
|
|
|
|
|
@@ -508,29 +487,31 @@ impl Predictor {
|
|
|
self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
self.optimal_bid_price = Self::DONT_VIEW;
|
|
|
|
|
|
- if self.trade_condition == dec!(1) && self.inventory > Decimal::ZERO {
|
|
|
- self.ask_delta = dec!(0);
|
|
|
- self.bid_delta = dec!(-2);
|
|
|
-
|
|
|
- self.optimal_ask_price = min(self.fair_price, self.mid_price) * dec!(0.995);
|
|
|
- self.optimal_bid_price = Self::DONT_VIEW;
|
|
|
- } else if self.trade_condition == dec!(2) && self.inventory < Decimal::ZERO {
|
|
|
- self.bid_delta = dec!(0);
|
|
|
- self.ask_delta = dec!(-2);
|
|
|
-
|
|
|
- self.optimal_bid_price = max(self.fair_price, self.mid_price) * dec!(1.005);
|
|
|
- self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
- } else if self.trade_condition == dec!(3) {
|
|
|
+ // if self.trade_condition == dec!(1) && self.inventory > Decimal::ZERO {
|
|
|
+ // self.ask_delta = dec!(0);
|
|
|
+ // self.bid_delta = dec!(-2);
|
|
|
+ //
|
|
|
+ // self.optimal_ask_price = min(self.fair_price, self.mid_price) * dec!(0.995);
|
|
|
+ // self.optimal_bid_price = Self::DONT_VIEW;
|
|
|
+ // } else if self.trade_condition == dec!(2) && self.inventory < Decimal::ZERO {
|
|
|
+ // self.bid_delta = dec!(0);
|
|
|
+ // self.ask_delta = dec!(-2);
|
|
|
+ //
|
|
|
+ // self.optimal_bid_price = max(self.fair_price, self.mid_price) * dec!(1.005);
|
|
|
+ // self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
+ // } else
|
|
|
+
|
|
|
+ if self.trade_condition == dec!(3) {
|
|
|
self.bid_delta = dec!(0);
|
|
|
self.ask_delta = dec!(-2);
|
|
|
|
|
|
- self.optimal_bid_price = max(self.fair_price, self.mid_price) * dec!(1.005);
|
|
|
+ self.optimal_bid_price = self.mid_price;
|
|
|
self.optimal_ask_price = Self::DONT_VIEW;
|
|
|
} else if self.trade_condition == dec!(4) {
|
|
|
self.ask_delta = dec!(0);
|
|
|
self.bid_delta = dec!(-2);
|
|
|
|
|
|
- self.optimal_ask_price = min(self.fair_price, self.mid_price) * dec!(0.995);
|
|
|
+ self.optimal_ask_price = self.mid_price;
|
|
|
self.optimal_bid_price = Self::DONT_VIEW;
|
|
|
}
|
|
|
|
|
|
@@ -774,12 +755,12 @@ impl Predictor {
|
|
|
|
|
|
let flow_ratio = Decimal::ZERO;
|
|
|
|
|
|
- let is_time_over_update = now - self.prev_insert_time > dec!(500);
|
|
|
+ let is_time_over_update = now - self.prev_plot_time > dec!(500);
|
|
|
if !is_time_over_update && !is_hard_update && !is_delta_changed {
|
|
|
return;
|
|
|
}
|
|
|
if is_time_over_update {
|
|
|
- self.prev_insert_time = Decimal::from(Utc::now().timestamp_millis())
|
|
|
+ self.prev_plot_time = Decimal::from(Utc::now().timestamp_millis())
|
|
|
}
|
|
|
let pos_avg_price = self.pos_avg_price;
|
|
|
|