|
|
@@ -8,7 +8,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
use std::time::Duration;
|
|
|
use chrono::{Utc};
|
|
|
use rust_decimal::Decimal;
|
|
|
-use rust_decimal::prelude::{ToPrimitive};
|
|
|
+use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
|
|
|
use rust_decimal_macros::dec;
|
|
|
use tokio::spawn;
|
|
|
use tokio::sync::mpsc::{Sender};
|
|
|
@@ -20,7 +20,7 @@ use global::cci::CentralControlInfo;
|
|
|
use global::params::Params;
|
|
|
use global::public_params::{ASK_PRICE_INDEX, BID_PRICE_INDEX, LENGTH};
|
|
|
use global::trace_stack::TraceStack;
|
|
|
-use standard::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, SpecialTicker, Ticker};
|
|
|
+use standard::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, SpecialTicker, Ticker, Trade};
|
|
|
use standard::exchange::{Exchange};
|
|
|
use standard::exchange::ExchangeEnum::{BinanceSwap, BitgetSwap, BybitSwap, CoinexSwap, GateSwap, HtxSwap, KucoinSwap};
|
|
|
|
|
|
@@ -121,6 +121,8 @@ pub struct Core {
|
|
|
pub low_speed_rate: Decimal, // 低速界限,0.5代表最大值的50%
|
|
|
pub low_speed_trade_time_vec: Vec<Decimal>, // 低速的交易时间数组,长度就是时间范围内有多少条交易
|
|
|
pub low_speed_max_trades_count: usize, // 从开机到现在的一定时间范围内的最大交易次数
|
|
|
+ pub is_low_speed: bool, // 当前是否是低速模式
|
|
|
+ pub low_speed_hard_limit: usize, // 这个值以下的都是低速模式
|
|
|
}
|
|
|
|
|
|
impl Core {
|
|
|
@@ -259,9 +261,11 @@ impl Core {
|
|
|
predict: Default::default(),
|
|
|
// 低速率改进的相关参数
|
|
|
low_speed_time_range: Decimal::ONE,
|
|
|
- low_speed_rate: dec!(0.168),
|
|
|
+ low_speed_rate: dec!(0.732),
|
|
|
low_speed_trade_time_vec: vec![],
|
|
|
low_speed_max_trades_count: 0,
|
|
|
+ is_low_speed: true,
|
|
|
+ low_speed_hard_limit: 60,
|
|
|
};
|
|
|
for i in 0..=params.ref_exchange.len() - 1 {
|
|
|
// 拼接不会消耗原字符串
|
|
|
@@ -317,6 +321,75 @@ impl Core {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 移除过期的成交集
|
|
|
+ fn remove_old_elements(&mut self) {
|
|
|
+ // 获取当前时间的毫秒级时间戳
|
|
|
+ let current_time = Utc::now().timestamp_millis();
|
|
|
+
|
|
|
+ // 定义一分钟的毫秒数
|
|
|
+ let one_minute_in_millis = (self.low_speed_time_range.to_f64().unwrap() * 60f64 * 1000f64).to_i64().unwrap();
|
|
|
+
|
|
|
+ // 使用 while 循环检查并移除旧元素
|
|
|
+ while !self.low_speed_trade_time_vec.is_empty() {
|
|
|
+ // 获取第一个元素的时间戳
|
|
|
+ let first_time = self.low_speed_trade_time_vec[0].to_i64().unwrap();
|
|
|
+
|
|
|
+ // 计算时间差
|
|
|
+ let time_difference = current_time - first_time;
|
|
|
+
|
|
|
+ // 如果时间差超过一分钟,移除第一个元素
|
|
|
+ if time_difference > one_minute_in_millis {
|
|
|
+ self.low_speed_trade_time_vec.remove(0);
|
|
|
+ } else {
|
|
|
+ // 如果第一个元素没有超过一分钟,停止检查
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新当前成交集
|
|
|
+ pub async fn update_trades(&mut self, trades: &Vec<Trade>) {
|
|
|
+ // 1. 放入当前的vec里面
|
|
|
+ for trade in trades {
|
|
|
+ self.low_speed_trade_time_vec.push(trade.time);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 移除过期的成交集
|
|
|
+ self.remove_old_elements();
|
|
|
+
|
|
|
+ // 3. 最大值确认
|
|
|
+ let trades_count_in_time_range = self.low_speed_trade_time_vec.len();
|
|
|
+ if trades_count_in_time_range > self.low_speed_max_trades_count {
|
|
|
+ self.low_speed_max_trades_count = trades_count_in_time_range;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 定义当前的速度
|
|
|
+ let prev_is_low_speed = self.is_low_speed;
|
|
|
+ self.is_low_speed = if trades_count_in_time_range < self.low_speed_hard_limit {
|
|
|
+ true
|
|
|
+ } else {
|
|
|
+ let d_count = Decimal::from_usize(trades_count_in_time_range).unwrap();
|
|
|
+ let d_max_count = Decimal::from_usize(self.low_speed_max_trades_count).unwrap();
|
|
|
+ let rate = d_count / d_max_count;
|
|
|
+
|
|
|
+ if rate < self.low_speed_rate {
|
|
|
+ true
|
|
|
+ } else {
|
|
|
+ false
|
|
|
+ }
|
|
|
+ };
|
|
|
+ if prev_is_low_speed != self.is_low_speed {
|
|
|
+ if self.is_low_speed {
|
|
|
+ info!("----------------------------行情速率变化:高->低");
|
|
|
+ } else {
|
|
|
+ info!("----------------------------行情速率变化:低->高");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 同步到策略模块
|
|
|
+ self.strategy.is_low_speed = self.is_low_speed;
|
|
|
+ }
|
|
|
+
|
|
|
// #[instrument(skip(self, data, trace_stack), level="TRACE")]
|
|
|
pub async fn update_local_order(&mut self, data: OrderInfo, trace_stack: TraceStack) {
|
|
|
if data.filled != Decimal::ZERO {
|
|
|
@@ -916,19 +989,6 @@ impl Core {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub async fn update_position_rest_swap(&mut self) {
|
|
|
- let position = self.platform_rest.get_position().await;
|
|
|
- match position {
|
|
|
- Ok(val) => {
|
|
|
- // info!("bybit_swap:定时获取的仓位信息");
|
|
|
- self.update_position(val).await;
|
|
|
- }
|
|
|
- Err(err) => {
|
|
|
- error!("bybit_swap:定时获取仓位信息错误!\nget_position:res_data={:?}", err);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// #[instrument(skip(self), level="TRACE")]
|
|
|
pub async fn update_equity_rest_spot(&mut self) {
|
|
|
match self.platform_rest.get_spot_account().await {
|