|
@@ -27,6 +27,7 @@ pub struct Predictor {
|
|
|
pub mu: Decimal,
|
|
pub mu: Decimal,
|
|
|
pub sigma: Decimal,
|
|
pub sigma: Decimal,
|
|
|
pub phi: Decimal,
|
|
pub phi: Decimal,
|
|
|
|
|
+ pub weights: VecDeque<Decimal>,
|
|
|
|
|
|
|
|
pub prices: Vec<Vec<FixedTimeRangeDeque<Decimal>>>, // [[[做市所], [参考所0]], ...]
|
|
pub prices: Vec<Vec<FixedTimeRangeDeque<Decimal>>>, // [[[做市所], [参考所0]], ...]
|
|
|
pub ks: Vec<Decimal>,
|
|
pub ks: Vec<Decimal>,
|
|
@@ -167,6 +168,7 @@ impl Predictor {
|
|
|
mu: Default::default(),
|
|
mu: Default::default(),
|
|
|
sigma: Default::default(),
|
|
sigma: Default::default(),
|
|
|
phi: Default::default(),
|
|
phi: Default::default(),
|
|
|
|
|
+ weights: Self::calculate_weights(60),
|
|
|
|
|
|
|
|
mid_price: Default::default(),
|
|
mid_price: Default::default(),
|
|
|
ask_price: Default::default(),
|
|
ask_price: Default::default(),
|
|
@@ -284,6 +286,15 @@ impl Predictor {
|
|
|
self.log_return_vec.push_back(log_return);
|
|
self.log_return_vec.push_back(log_return);
|
|
|
self.mu = Self::calculate_mean(&self.log_return_vec);
|
|
self.mu = Self::calculate_mean(&self.log_return_vec);
|
|
|
self.sigma = Self::calculate_std(&self.log_return_vec);
|
|
self.sigma = Self::calculate_std(&self.log_return_vec);
|
|
|
|
|
+
|
|
|
|
|
+ let r = if self.sigma.is_zero() {
|
|
|
|
|
+ Decimal::ZERO
|
|
|
|
|
+ } else {
|
|
|
|
|
+ (log_return - self.mu) / self.sigma
|
|
|
|
|
+ };
|
|
|
|
|
+ self.r_vec.push_back(r);
|
|
|
|
|
+
|
|
|
|
|
+ self.phi = Self::calculate_convolve(&self.r_vec, &self.weights);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -453,21 +464,14 @@ impl Predictor {
|
|
|
|
|
|
|
|
let is_close_long = self.inventory > Decimal::ZERO && (
|
|
let is_close_long = self.inventory > Decimal::ZERO && (
|
|
|
// 硬止损,开单不久之后就在亏
|
|
// 硬止损,开单不久之后就在亏
|
|
|
- (self.profit_high < dec!(0.001) && self.profit < dec!(-0.005))
|
|
|
|
|
- // 浮动止损,如果profit_high较高产生了利润,但后续不给力
|
|
|
|
|
- || (self.profit_high - self.profit > dec!(0.0075) && self.profit < Decimal::ZERO)
|
|
|
|
|
- // 利润较大时,追踪止盈
|
|
|
|
|
- || (self.profit > dec!(0.005) && self.profit < self.profit_high * dec!(0.75))
|
|
|
|
|
- );
|
|
|
|
|
- let is_close_short = self.inventory < Decimal::ZERO && (
|
|
|
|
|
- // 硬止损
|
|
|
|
|
- (self.profit < dec!(-0.01))
|
|
|
|
|
- // 利润较大时,追踪止盈
|
|
|
|
|
- || (self.profit > dec!(0.01) && self.profit < self.profit_high * dec!(0.75))
|
|
|
|
|
|
|
+ (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;
|
|
|
|
|
|
|
|
let is_open_long = self.inventory.is_zero()
|
|
let is_open_long = self.inventory.is_zero()
|
|
|
- && self.fair_price > self.mid_price * dec!(1.0001)
|
|
|
|
|
|
|
+ && self.phi > Decimal::ONE
|
|
|
&& self.r_short < -self.params.open
|
|
&& self.r_short < -self.params.open
|
|
|
;
|
|
;
|
|
|
|
|
|
|
@@ -611,6 +615,67 @@ impl Predictor {
|
|
|
sum / Decimal::from(count) // 计算平均值
|
|
sum / Decimal::from(count) // 计算平均值
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ fn calculate_weights(t: i32) -> VecDeque<Decimal> {
|
|
|
|
|
+ let max_n = 5 * t;
|
|
|
|
|
+ let mut raw_weights = VecDeque::with_capacity(max_n as usize);
|
|
|
|
|
+
|
|
|
|
|
+ // 计算 raw_weights
|
|
|
|
|
+ for n in 1..=max_n {
|
|
|
|
|
+ // 将 n 转换为 Decimal
|
|
|
|
|
+ let n_dec = Decimal::from(n);
|
|
|
|
|
+
|
|
|
|
|
+ // 计算 exp(-2 * n / T)
|
|
|
|
|
+ let exp_value = Decimal::from_f64((-2.0 * n as f64 / t as f64).exp())
|
|
|
|
|
+ .unwrap_or(dec!(0));
|
|
|
|
|
+
|
|
|
|
|
+ // 计算 n * exp(-2 * n / T)
|
|
|
|
|
+ let weight = n_dec * exp_value;
|
|
|
|
|
+ raw_weights.push_back(weight);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算 M_T
|
|
|
|
|
+ let sum_squares: Decimal = raw_weights.iter()
|
|
|
|
|
+ .map(|&x| x * x)
|
|
|
|
|
+ .sum();
|
|
|
|
|
+ let m_t = dec!(1) / sum_squares.sqrt().unwrap_or(dec!(1));
|
|
|
|
|
+
|
|
|
|
|
+ // 计算最终权重并反转
|
|
|
|
|
+ let mut weights: VecDeque<Decimal> = raw_weights.iter()
|
|
|
|
|
+ .map(|&x| {
|
|
|
|
|
+ let rst = m_t * x;
|
|
|
|
|
+ rst.round_dp(8)
|
|
|
|
|
+ })
|
|
|
|
|
+ .collect();
|
|
|
|
|
+ weights.make_contiguous().reverse();
|
|
|
|
|
+
|
|
|
|
|
+ weights
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fn calculate_convolve(signal: &VecDeque<Decimal>, kernel: &VecDeque<Decimal>) -> Decimal {
|
|
|
|
|
+ let signal_len = signal.len();
|
|
|
|
|
+ let kernel_len = kernel.len();
|
|
|
|
|
+ let result_len = signal_len + kernel_len - 1;
|
|
|
|
|
+
|
|
|
|
|
+ let mut result = Decimal::ZERO;
|
|
|
|
|
+
|
|
|
|
|
+ // 计算完整卷积
|
|
|
|
|
+ for i in 0..result_len {
|
|
|
|
|
+ let mut sum = Decimal::ZERO;
|
|
|
|
|
+
|
|
|
|
|
+ // 对于每个输出点,计算所有可能的乘积和
|
|
|
|
|
+ for j in 0..kernel_len {
|
|
|
|
|
+ let signal_idx = i as i32 - j as i32;
|
|
|
|
|
+ if signal_idx >= 0 && signal_idx < signal_len as i32 {
|
|
|
|
|
+ sum += signal[signal_idx as usize] * kernel[j];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ result = sum;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ result
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 最小二乘法拟合函数,支持VecDeque
|
|
// 最小二乘法拟合函数,支持VecDeque
|
|
|
pub async fn linear_least_squares(&self, index: usize) -> Option<(Decimal, Decimal)> {
|
|
pub async fn linear_least_squares(&self, index: usize) -> Option<(Decimal, Decimal)> {
|
|
|
let x = &self.prices[index][1];
|
|
let x = &self.prices[index][1];
|
|
@@ -685,19 +750,19 @@ impl Predictor {
|
|
|
let last_price = Self::DONT_VIEW;
|
|
let last_price = Self::DONT_VIEW;
|
|
|
let fair_price = self.fair_price;
|
|
let fair_price = self.fair_price;
|
|
|
|
|
|
|
|
- let spread = Self::DONT_VIEW;
|
|
|
|
|
|
|
+ let spread = if self.r_vec.len() > 0 {
|
|
|
|
|
+ self.r_vec.iter().last().unwrap().clone()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Decimal::ZERO
|
|
|
|
|
+ };
|
|
|
let spread_max = self.mu;
|
|
let spread_max = self.mu;
|
|
|
let spread_min = self.sigma;
|
|
let spread_min = self.sigma;
|
|
|
- // let spread = self.price_times_avg;
|
|
|
|
|
- // let spread_max = self.fair_price_vec[1] / self.fair_price_vec[0];
|
|
|
|
|
- // let spread_min = self.fair_price / self.mid_price;
|
|
|
|
|
|
|
|
|
|
let inventory = self.inventory;
|
|
let inventory = self.inventory;
|
|
|
|
|
|
|
|
- let sigma_square = Decimal::from(Utc::now().timestamp_millis()) - data_time;
|
|
|
|
|
- // let sigma_square = Self::DONT_VIEW;
|
|
|
|
|
- let gamma = Self::DONT_VIEW;
|
|
|
|
|
- let kappa = self.balance;
|
|
|
|
|
|
|
+ let sigma_square = self.phi;
|
|
|
|
|
+ let gamma = self.balance;
|
|
|
|
|
+ let kappa = Decimal::from(Utc::now().timestamp_millis()) - data_time;
|
|
|
|
|
|
|
|
let flow_ratio = Decimal::ZERO;
|
|
let flow_ratio = Decimal::ZERO;
|
|
|
|
|
|