|
|
@@ -1,13 +1,13 @@
|
|
|
use tokio::time::Instant;
|
|
|
use std::cmp::max;
|
|
|
-use std::collections::{BTreeMap, HashMap, VecDeque};
|
|
|
+use std::collections::{BTreeMap, HashMap};
|
|
|
use std::io::Error;
|
|
|
use std::str::FromStr;
|
|
|
use std::sync::{Arc};
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
use std::time::Duration;
|
|
|
use chrono::{Utc};
|
|
|
-use rust_decimal::{Decimal, MathematicalOps};
|
|
|
+use rust_decimal::{Decimal};
|
|
|
use rust_decimal::prelude::{ToPrimitive};
|
|
|
use rust_decimal_macros::dec;
|
|
|
use tokio::spawn;
|
|
|
@@ -18,10 +18,8 @@ use tokio::time::sleep;
|
|
|
use tracing::{error, info, warn};
|
|
|
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 global::trade::Trade;
|
|
|
-use standard::{Account, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, SpecialTicker, Ticker};
|
|
|
+use standard::{Account, Depth, Market, Order, OrderCommand, Platform, Position, PositionModeEnum, SpecialTicker, Ticker, Trade};
|
|
|
use standard::exchange::{Exchange};
|
|
|
use standard::exchange::ExchangeEnum::{BinanceSwap, GateSwap};
|
|
|
|
|
|
@@ -116,12 +114,6 @@ pub struct Core {
|
|
|
pub agg_market: Vec<Decimal>,
|
|
|
pub ref_price: Vec<Vec<Decimal>>,
|
|
|
pub predict: Decimal,
|
|
|
-
|
|
|
- // 波动率指标相关数据(最近100条)
|
|
|
- pub trade_vec: VecDeque<Trade>, // 行情数据 此处价格取买一卖一中间价,时间为交易所的数据创建时间
|
|
|
- pub sigma_vec: VecDeque<Decimal>, // 波动率记录
|
|
|
- pub is_sigma_abnormal: bool, // 是否sigma反常
|
|
|
- pub is_sigma_allow_open: bool, // 是否允许开单
|
|
|
}
|
|
|
|
|
|
impl Core {
|
|
|
@@ -258,10 +250,6 @@ impl Core {
|
|
|
agg_market: vec![],
|
|
|
ref_price: vec![],
|
|
|
predict: Default::default(),
|
|
|
- trade_vec: VecDeque::with_capacity(100),
|
|
|
- sigma_vec: VecDeque::with_capacity(100),
|
|
|
- is_sigma_abnormal: false,
|
|
|
- is_sigma_allow_open: true,
|
|
|
};
|
|
|
for i in 0..=params.ref_exchange.len() - 1 {
|
|
|
// 拼接不会消耗原字符串
|
|
|
@@ -389,10 +377,12 @@ impl Core {
|
|
|
filled_order.side = side.clone();
|
|
|
|
|
|
info!("移除本地订单:{:?}, local_by_orders: {:?}", filled_order, self.local_position_by_orders);
|
|
|
- if self.exchange.contains("spot") { // 如果是现货交易 还需要修改equity
|
|
|
+ // 如果是现货交易 还需要修改equity
|
|
|
+ if self.exchange.contains("spot") {
|
|
|
// 现货必须考虑fee 买入fee单位为币 卖出fee单位为u
|
|
|
let fee = data.fee;
|
|
|
- if side == "kd" { // buy 开多
|
|
|
+ // buy 开多
|
|
|
+ if side == "kd" {
|
|
|
self.local_buy_amount += filled - fee;
|
|
|
self.local_buy_value += (filled - fee) * filled_price;
|
|
|
let new_long_pos = self.local_position_by_orders.long_pos + filled - fee;
|
|
|
@@ -406,7 +396,9 @@ impl Core {
|
|
|
}
|
|
|
self.local_cash -= filled * filled_price;
|
|
|
self.local_coin = filled - fee;
|
|
|
- } else if side == "pd" { // sell 平多
|
|
|
+
|
|
|
+ // sell 平多
|
|
|
+ } else if side == "pd" {
|
|
|
self.local_sell_amount += filled;
|
|
|
self.local_sell_value += filled * filled_price;
|
|
|
self.local_profit += filled * (filled_price - self.local_position_by_orders.long_avg);
|
|
|
@@ -419,7 +411,9 @@ impl Core {
|
|
|
}
|
|
|
self.local_cash += filled * filled_price - fee;
|
|
|
self.local_coin -= filled;
|
|
|
- } else if side == "pk" { // buy 平空
|
|
|
+
|
|
|
+ // buy 平空
|
|
|
+ } else if side == "pk" {
|
|
|
self.local_buy_amount += filled - fee;
|
|
|
self.local_buy_value += (filled - fee) * filled_price;
|
|
|
self.local_profit += filled * (self.local_position_by_orders.short_avg - filled_price);
|
|
|
@@ -432,7 +426,9 @@ impl Core {
|
|
|
}
|
|
|
self.local_cash -= filled * filled_price;
|
|
|
self.local_coin += filled - fee;
|
|
|
- } else if side == "kk" { // sell 开空
|
|
|
+
|
|
|
+ // sell 开空
|
|
|
+ } else if side == "kk" {
|
|
|
self.local_sell_amount += filled;
|
|
|
self.local_sell_value += filled * filled_price;
|
|
|
let new_short_pos = self.local_position_by_orders.short_pos + filled;
|
|
|
@@ -449,9 +445,11 @@ impl Core {
|
|
|
} else {
|
|
|
info!("错误的仓位方向{}", side);
|
|
|
}
|
|
|
- } else { // 合约订单流仓位计算
|
|
|
- let mut this_order_profit = Decimal::ZERO;
|
|
|
- if side == "kd" { // buy 开多
|
|
|
+
|
|
|
+ // 合约订单流仓位计算
|
|
|
+ } else {
|
|
|
+ // buy 开多
|
|
|
+ if side == "kd" {
|
|
|
self.local_buy_amount += filled;
|
|
|
self.local_buy_value += filled * filled_price;
|
|
|
let new_long_pos = self.local_position_by_orders.long_pos + filled;
|
|
|
@@ -463,7 +461,9 @@ impl Core {
|
|
|
self.local_position_by_orders.long_avg + filled * filled_price) / new_long_pos;
|
|
|
self.local_position_by_orders.long_pos = self.local_position_by_orders.long_pos + filled;
|
|
|
}
|
|
|
- } else if side == "kk" { // sell 开空
|
|
|
+
|
|
|
+ // sell 开空
|
|
|
+ } else if side == "kk" {
|
|
|
self.local_sell_amount += filled;
|
|
|
self.local_sell_value += filled * filled_price;
|
|
|
let new_short_pos = self.local_position_by_orders.short_pos + filled;
|
|
|
@@ -474,20 +474,20 @@ impl Core {
|
|
|
self.local_position_by_orders.short_avg = (self.local_position_by_orders.short_pos * self.local_position_by_orders.short_avg + filled * filled_price) / new_short_pos;
|
|
|
self.local_position_by_orders.short_pos = self.local_position_by_orders.short_pos + filled;
|
|
|
}
|
|
|
- } else if side == "pd" { // sell 平多
|
|
|
+
|
|
|
+ // sell 平多
|
|
|
+ } else if side == "pd" {
|
|
|
self.local_sell_amount += filled;
|
|
|
self.local_sell_value += filled * filled_price;
|
|
|
- this_order_profit = filled * (filled_price - self.local_position_by_orders.long_avg);
|
|
|
- self.local_profit += this_order_profit;
|
|
|
self.local_position_by_orders.long_pos = self.local_position_by_orders.long_pos - filled;
|
|
|
if self.local_position_by_orders.long_pos == Decimal::ZERO {
|
|
|
self.local_position_by_orders.long_avg = Decimal::ZERO;
|
|
|
}
|
|
|
- } else if side == "pk" { // buy 平空
|
|
|
+
|
|
|
+ // buy 平空
|
|
|
+ } else if side == "pk" {
|
|
|
self.local_buy_amount += filled;
|
|
|
self.local_buy_value += filled * filled_price;
|
|
|
- this_order_profit = filled * (self.local_position_by_orders.short_avg - filled_price);
|
|
|
- self.local_profit += this_order_profit;
|
|
|
self.local_position_by_orders.short_pos = self.local_position_by_orders.short_pos - filled;
|
|
|
if self.local_position_by_orders.short_pos == Decimal::ZERO {
|
|
|
self.local_position_by_orders.short_avg = Decimal::ZERO;
|
|
|
@@ -499,14 +499,6 @@ impl Core {
|
|
|
if data.fee > Decimal::ZERO {
|
|
|
self.local_profit -= data.fee;
|
|
|
}
|
|
|
- // 订单亏损 并且 波动率异常 不允许开单
|
|
|
- if this_order_profit < Decimal::ZERO && self.is_sigma_abnormal {
|
|
|
- self.is_sigma_allow_open = false;
|
|
|
- info!("交易触发亏损,不允许开单!");
|
|
|
- info!("sigma_vec:{:?}" , self.sigma_vec);
|
|
|
- } else {
|
|
|
- self.is_sigma_allow_open = true;
|
|
|
- }
|
|
|
}
|
|
|
// info!("成交单耗时数据:{}", time_record.to_string());
|
|
|
info!("更新推算仓位 {:?}", self.local_position_by_orders);
|
|
|
@@ -532,7 +524,6 @@ impl Core {
|
|
|
&self.local_coin,
|
|
|
&self.ref_price,
|
|
|
&self.predict,
|
|
|
- &self.is_sigma_allow_open,
|
|
|
&trace_stack.ins);
|
|
|
// trace_stack.on_after_strategy();
|
|
|
// 记录指令触发信息
|
|
|
@@ -594,37 +585,38 @@ impl Core {
|
|
|
// #[instrument(skip(self), level="TRACE")]
|
|
|
pub fn check_ready(&mut self) {
|
|
|
// 检查 ticker 行情
|
|
|
- for i in &self.ref_name {
|
|
|
- if self.tickers.is_empty() || !self.tickers.contains_key(i) {
|
|
|
- self.log_ready_status(format!("529参考盘口ticker未准备好: {:?}", self.tickers));
|
|
|
- return;
|
|
|
- } else {
|
|
|
- if self.tickers.get(i).unwrap().buy == dec!(0) || self.tickers.get(i).unwrap().sell == dec!(0) {
|
|
|
- self.log_ready_status(format!("533参考盘口ticker未准备好: {:?}", self.tickers));
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if self.tickers.contains_key(&self.trade_name) {
|
|
|
- if self.tickers.get(&self.trade_name).unwrap().buy == dec!(0) || self.tickers.get(&self.trade_name).unwrap().sell == dec!(0) {
|
|
|
- self.log_ready_status(format!("540交易盘口ticker未准备好: {:?}", self.tickers));
|
|
|
- return;
|
|
|
- }
|
|
|
- } else {
|
|
|
- self.log_ready_status(format!("544交易盘口ticker未准备好: {:?}", self.tickers));
|
|
|
- return;
|
|
|
- }
|
|
|
- // 检查 market 行情
|
|
|
- self.agg_market = self.get_all_market_data();
|
|
|
- if self.agg_market.len() != LENGTH * (1usize + self.ref_num as usize) {
|
|
|
- self.log_ready_status(format!("550聚合行情未准备好: market长度:{}, 检验数: {}", self.agg_market.len(), LENGTH * (1usize + self.ref_num as usize)));
|
|
|
- return;
|
|
|
- } else {
|
|
|
- // 如果准备就绪,则可以开始交易
|
|
|
- info!("----------------------------------聚合行情准备就绪,可以开始交易---------------------------------");
|
|
|
- self.predictor.market_info_handler(&self.agg_market);
|
|
|
- self.ready = 1;
|
|
|
- }
|
|
|
+ // for i in &self.ref_name {
|
|
|
+ // if self.tickers.is_empty() || !self.tickers.contains_key(i) {
|
|
|
+ // self.log_ready_status(format!("529参考盘口ticker未准备好: {:?}", self.tickers));
|
|
|
+ // return;
|
|
|
+ // } else {
|
|
|
+ // if self.tickers.get(i).unwrap().buy == dec!(0) || self.tickers.get(i).unwrap().sell == dec!(0) {
|
|
|
+ // self.log_ready_status(format!("533参考盘口ticker未准备好: {:?}", self.tickers));
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // if self.tickers.contains_key(&self.trade_name) {
|
|
|
+ // if self.tickers.get(&self.trade_name).unwrap().buy == dec!(0) || self.tickers.get(&self.trade_name).unwrap().sell == dec!(0) {
|
|
|
+ // self.log_ready_status(format!("540交易盘口ticker未准备好: {:?}", self.tickers));
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // self.log_ready_status(format!("544交易盘口ticker未准备好: {:?}", self.tickers));
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // // 检查 market 行情
|
|
|
+ // self.agg_market = self.get_all_market_data();
|
|
|
+ // if self.agg_market.len() != LENGTH * (1usize + self.ref_num as usize) {
|
|
|
+ // self.log_ready_status(format!("550聚合行情未准备好: market长度:{}, 检验数: {}", self.agg_market.len(), LENGTH * (1usize + self.ref_num as usize)));
|
|
|
+ // return;
|
|
|
+ // } else {
|
|
|
+ // // 如果准备就绪,则可以开始交易
|
|
|
+ // info!("----------------------------------聚合行情准备就绪,可以开始交易---------------------------------");
|
|
|
+ // self.predictor.market_info_handler(&self.agg_market);
|
|
|
+ // self.ready = 1;
|
|
|
+ // }
|
|
|
+ self.ready = 1;
|
|
|
}
|
|
|
|
|
|
// #[instrument(skip(self, msg), level="TRACE")]
|
|
|
@@ -637,9 +629,13 @@ impl Core {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ pub async fn on_trade(&mut self, trade: &Trade, _name_ref: &String, _trace_stack: &mut TraceStack) {
|
|
|
+ self.predictor.on_trade(trade);
|
|
|
+ }
|
|
|
+
|
|
|
// #[instrument(skip(self, depth, name_ref, trace_stack), level="TRACE")]
|
|
|
- pub async fn on_depth_update(&mut self, depth: &Vec<Decimal>, name_ref: &String, trace_stack: &mut TraceStack) {
|
|
|
- // 要从回调传入的深度信息中获取data.name
|
|
|
+ pub async fn on_depth(&mut self, depth: &Depth, name_ref: &String, trace_stack: &mut TraceStack) {
|
|
|
+ // ================================ 刷新更新间隔 =========================================
|
|
|
let now_time = Utc::now().timestamp_millis();
|
|
|
if self.market_update_time.contains_key(name_ref) && *self.market_update_time.get(name_ref).unwrap() != 0i64 {
|
|
|
let interval = Decimal::from(now_time - self.market_update_time.get(name_ref).unwrap());
|
|
|
@@ -652,82 +648,47 @@ impl Core {
|
|
|
}
|
|
|
self.market_update_time.insert(name_ref.clone(), now_time);
|
|
|
|
|
|
- // 判断是否需要触发on_depth
|
|
|
- // 是否是交易盘口
|
|
|
- if *name_ref == self.trade_name {
|
|
|
- // 允许交易
|
|
|
- if self.mode_signal == 0 && self.ready == 1 {
|
|
|
- self.on_agg_market();
|
|
|
- }
|
|
|
- } else if *name_ref == self.ref_name[0] { // 判断是否为当前跟踪的盘口
|
|
|
- // 写入行情数据
|
|
|
- let ticker = self.tickers.get(name_ref).unwrap();
|
|
|
- if self.trade_vec.len() == 100 {
|
|
|
- self.trade_vec.pop_front();
|
|
|
- }
|
|
|
- self.trade_vec.push_back(Trade::new_by_ticker(ticker.mid_price.clone(), ticker.create_at/1000));
|
|
|
- // 更新波动率
|
|
|
- if self.trade_vec.len() > 99 {
|
|
|
- self.calc_sigma();
|
|
|
- // 波动率正常,但还是不开单信号,允许开单
|
|
|
- if !self.is_sigma_abnormal && !self.is_sigma_allow_open {
|
|
|
- self.is_sigma_allow_open = true;
|
|
|
- }
|
|
|
- }
|
|
|
- // 判断是否需要触发ontick 对行情进行过滤
|
|
|
- // 过滤条件 价格变化很大 时间间隔很长
|
|
|
- let mut flag = 0;
|
|
|
- let bid_price_rate = (depth[BID_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[BID_PRICE_INDEX]).abs() / depth[BID_PRICE_INDEX];
|
|
|
- let ask_price_rate = (depth[ASK_PRICE_INDEX] - self.depths.get(name_ref).unwrap()[ASK_PRICE_INDEX]).abs() / depth[ASK_PRICE_INDEX];
|
|
|
- let rate = dec!(0.0002);
|
|
|
- if bid_price_rate > rate || ask_price_rate > rate || Utc::now().timestamp_millis() - self.on_tick_event_time > 50 {
|
|
|
- // 允许交易
|
|
|
- flag = 1;
|
|
|
- // 更新ontick触发时间记录
|
|
|
- self.on_tick_event_time = Utc::now().timestamp_millis();
|
|
|
- }
|
|
|
- // 允许交易
|
|
|
- if self.mode_signal == 0 && self.ready == 1 && flag == 1 {
|
|
|
- // 更新交易数据
|
|
|
- self.update_trade_msg();
|
|
|
- // 触发事件撤单逻辑
|
|
|
- // 更新策略时间
|
|
|
- self.strategy.local_time = Utc::now().timestamp_millis();
|
|
|
-
|
|
|
- // 产生交易信号
|
|
|
- let mut orders = self.strategy.on_tick(&self.local_orders,
|
|
|
- &self.local_position_by_orders,
|
|
|
- &self.agg_market,
|
|
|
- &self.local_cash,
|
|
|
- &self.local_coin,
|
|
|
- &self.ref_price,
|
|
|
- &self.predict,
|
|
|
- &self.is_sigma_allow_open,
|
|
|
- &trace_stack.ins);
|
|
|
- trace_stack.on_after_strategy();
|
|
|
-
|
|
|
- if orders.is_not_empty() {
|
|
|
- let mut platform_rest_fb = self.platform_rest.clone_box();
|
|
|
- // 先更新本地记录再发单。
|
|
|
- self._update_local_orders(&mut orders);
|
|
|
- // info!("订单指令:{:?}", orders);
|
|
|
- let mut ts = trace_stack.clone();
|
|
|
- spawn(async move {
|
|
|
- platform_rest_fb.command_order(&mut orders, &mut ts).await;
|
|
|
- });
|
|
|
-
|
|
|
- // 更新中控账户相关信息
|
|
|
- {
|
|
|
- let mut now_balance = self.strategy.equity / self.used_pct;
|
|
|
- now_balance.rescale(4);
|
|
|
-
|
|
|
- let mut cci = self.cci_arc.lock().await;
|
|
|
- cci.now_balance = now_balance;
|
|
|
- }
|
|
|
+ // ================================ 在系统已经准备就绪的情况下,更新相关参数 =========================================
|
|
|
+ if self.mode_signal == 0 && self.ready == 1 {
|
|
|
+ // 更新预定价格
|
|
|
+ self.predictor.on_depth(depth);
|
|
|
+ // 触发事件撤单逻辑
|
|
|
+ // 更新策略时间
|
|
|
+ self.strategy.local_time = Utc::now().timestamp_millis();
|
|
|
+
|
|
|
+ // 产生交易信号
|
|
|
+ let mut orders = self.strategy.on_tick(&self.local_orders,
|
|
|
+ &self.local_position_by_orders,
|
|
|
+ &self.agg_market,
|
|
|
+ &self.local_cash,
|
|
|
+ &self.local_coin,
|
|
|
+ &self.ref_price,
|
|
|
+ &self.predict,
|
|
|
+ &trace_stack.ins);
|
|
|
+ trace_stack.on_after_strategy();
|
|
|
+
|
|
|
+ if orders.is_not_empty() {
|
|
|
+ let mut platform_rest_fb = self.platform_rest.clone_box();
|
|
|
+ // 先更新本地记录再发单。
|
|
|
+ self._update_local_orders(&mut orders);
|
|
|
+ // info!("订单指令:{:?}", orders);
|
|
|
+ let mut ts = trace_stack.clone();
|
|
|
+ spawn(async move {
|
|
|
+ platform_rest_fb.command_order(&mut orders, &mut ts).await;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 更新账户余额
|
|
|
+ {
|
|
|
+ let mut now_balance = self.strategy.equity / self.used_pct;
|
|
|
+ now_balance.rescale(4);
|
|
|
+
|
|
|
+ let mut cci = self.cci_arc.lock().await;
|
|
|
+ cci.now_balance = now_balance;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 同步更新余额数据到中控的信息
|
|
|
{
|
|
|
let mut unrealized_pn_l = self.local_profit;
|
|
|
unrealized_pn_l.rescale(4);
|
|
|
@@ -741,87 +702,6 @@ impl Core {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub fn calc_sigma(&mut self) {
|
|
|
- for (index, trade) in self.trade_vec.iter().enumerate() {
|
|
|
- if index == 0 {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- // 计算过去至多100条数据的sigma值 sigma^2 = (1 / (tn-t0))*sum((S(tk) - S(tk-1)) ^ 2)
|
|
|
- let mut sigma_index = index - 1;
|
|
|
- let t_last = Decimal::from_str(&format!("{}", trade.time)).unwrap();
|
|
|
-
|
|
|
- let mut _t_first = Decimal::from_str(&format!("{}", trade.time)).unwrap();
|
|
|
- // 右值
|
|
|
- let mut total_right = Decimal::ZERO;
|
|
|
- loop {
|
|
|
- let flag_trade = self.trade_vec.get(sigma_index).unwrap();
|
|
|
- let next_trade = self.trade_vec.get(sigma_index + 1).unwrap();
|
|
|
-
|
|
|
- // 下标合法性判断
|
|
|
- if sigma_index == 0 || sigma_index + 100 <= index {
|
|
|
- _t_first = Decimal::from_str(&format!("{}", flag_trade.time)).unwrap();
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- // 计算差值
|
|
|
- let diff = Decimal::ONE - flag_trade.price / next_trade.price;
|
|
|
- total_right += diff * diff;
|
|
|
-
|
|
|
- sigma_index = sigma_index - 1;
|
|
|
- }
|
|
|
- let sigma_square = if _t_first == t_last {
|
|
|
- let time_diff = Decimal::ONE;
|
|
|
- (Decimal::ONE / time_diff) * total_right
|
|
|
- } else {
|
|
|
- let time_diff = (t_last - _t_first) / Decimal::ONE_THOUSAND;
|
|
|
- (Decimal::ONE / time_diff) * total_right
|
|
|
- };
|
|
|
- let mut sigma = sigma_square.sqrt().unwrap();
|
|
|
- sigma.rescale(6);
|
|
|
- if self.sigma_vec.len() == 100 {
|
|
|
- self.sigma_vec.pop_front();
|
|
|
- }
|
|
|
- self.sigma_vec.push_back(sigma);
|
|
|
- }
|
|
|
- if self.sigma_vec.len() > 99 {
|
|
|
- let sigma = match self.sigma_vec.back() {
|
|
|
- Some(&value) => value,
|
|
|
- None => Decimal::TEN,
|
|
|
- };
|
|
|
-
|
|
|
- // 计算过去至多100个sigma值的平均值
|
|
|
- let sigma_ma = if self.sigma_vec.len() > 0 {
|
|
|
- let mut sigma_ma_index = self.sigma_vec.len();
|
|
|
- let mut sigma_total = Decimal::ZERO;
|
|
|
- let mut sigma_count = Decimal::ZERO;
|
|
|
- loop {
|
|
|
- if sigma_ma_index == 0 || sigma_ma_index + 99 < self.sigma_vec.len() {
|
|
|
- break
|
|
|
- }
|
|
|
- // 步进
|
|
|
- sigma_ma_index -= 1;
|
|
|
- // 计算
|
|
|
- sigma_total += self.sigma_vec[sigma_ma_index];
|
|
|
- sigma_count += Decimal::ONE;
|
|
|
- }
|
|
|
- let mut sigma_ma = sigma_total / sigma_count;
|
|
|
- sigma_ma.rescale(6);
|
|
|
-
|
|
|
- sigma_ma
|
|
|
- } else {
|
|
|
- sigma
|
|
|
- };
|
|
|
- // sigma值大于平均值定义为波动率异常
|
|
|
- if sigma > sigma_ma {
|
|
|
- self.is_sigma_abnormal = true;
|
|
|
- // info!("sigma: {}, sigma_ma: {}, sigma_vec: {:?}", sigma, sigma_ma, self.sigma_vec);
|
|
|
- } else {
|
|
|
- self.is_sigma_abnormal = false;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// #[instrument(skip(self, data), level="TRACE")]
|
|
|
pub async fn update_position(&mut self, data: Vec<Position>) {
|
|
|
if data.is_empty() {
|
|
|
@@ -867,18 +747,18 @@ impl Core {
|
|
|
}
|
|
|
|
|
|
// #[instrument(skip(self), level="TRACE")]
|
|
|
- pub fn on_agg_market(&mut self) {
|
|
|
- /* 处理聚合行情
|
|
|
- 1. 获取聚合行情
|
|
|
- 2. 更新预测器
|
|
|
- 3. 触发tick回测
|
|
|
- */
|
|
|
- // 更新聚合市场数据
|
|
|
- // 更新聚合市场信息
|
|
|
- self.agg_market = self.get_all_market_data();
|
|
|
- // 更新预测器
|
|
|
- self.predictor.market_info_handler(&self.agg_market);
|
|
|
- }
|
|
|
+ // pub fn on_agg_market(&mut self) {
|
|
|
+ // /* 处理聚合行情
|
|
|
+ // 1. 获取聚合行情
|
|
|
+ // 2. 更新预测器
|
|
|
+ // 3. 触发tick回测
|
|
|
+ // */
|
|
|
+ // // 更新聚合市场数据
|
|
|
+ // // 更新聚合市场信息
|
|
|
+ // self.agg_market = self.get_all_market_data();
|
|
|
+ // // 更新预测器
|
|
|
+ // self.predictor.market_info_handler(&self.agg_market);
|
|
|
+ // }
|
|
|
|
|
|
// #[instrument(skip(self), level="TRACE")]
|
|
|
pub fn update_trade_msg(&mut self) {
|