|
|
@@ -1,8 +1,7 @@
|
|
|
-use std::collections::BTreeMap;
|
|
|
+
|
|
|
use rust_decimal::prelude::*;
|
|
|
use rust_decimal_macros::dec;
|
|
|
use tracing::{debug};
|
|
|
-use standard::Ticker;
|
|
|
use global::public_params;
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
@@ -17,11 +16,11 @@ pub struct PredictorNew {
|
|
|
pub gamma: Decimal, // 定价系数
|
|
|
pub avg_spread_list: Vec<Decimal>, // 平均价差
|
|
|
|
|
|
- pub transaction_prices: Vec<Decimal>, // 成交价记录
|
|
|
- pub variance: f64, // 波动率
|
|
|
- pub max_spread: f64, // 最大点差
|
|
|
- pub min_spread: f64, // 最小点差
|
|
|
- pub gamma_calc: f64 // gamma
|
|
|
+ pub transaction_prices: Vec<Decimal>, // 成交价记录
|
|
|
+ pub max_spread: f64, // 最大点差
|
|
|
+ pub min_spread: f64, // 最小点差
|
|
|
+ pub variance: f64, // 波动率
|
|
|
+ pub balance_value: f64 // 持仓价值
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -41,10 +40,10 @@ impl PredictorNew {
|
|
|
gamma: Decimal::from_f64(0.999).unwrap(),
|
|
|
avg_spread_list: vec![dec!(0); ref_exchange_length],
|
|
|
transaction_prices: Vec::new(),
|
|
|
- variance: Default::default(),
|
|
|
max_spread: Default::default(),
|
|
|
min_spread: Default::default(),
|
|
|
- gamma_calc: Default::default()
|
|
|
+ variance: 0.0,
|
|
|
+ balance_value: 0.0,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -68,8 +67,8 @@ impl PredictorNew {
|
|
|
let mid_price = (bid_price + ask_price) * dec!(0.5);
|
|
|
debug!(?last_market_info);
|
|
|
debug!(?bid_price, ?ask_price, ?mid_price);
|
|
|
- self.mid_price_list.push(mid_price);
|
|
|
-
|
|
|
+ self.mid_price_list.push(mid_price.clone());
|
|
|
+ self.transaction_prices.push(mid_price);
|
|
|
// 更新参考ref_mid_price
|
|
|
let mut ref_mid_price_per_exchange = vec![];
|
|
|
for ref_index in 0..self.ref_exchange_length {
|
|
|
@@ -81,78 +80,81 @@ impl PredictorNew {
|
|
|
ref_mid_price_per_exchange.push(ref_mid_price);
|
|
|
}
|
|
|
debug!(?ref_mid_price_per_exchange);
|
|
|
+ let first_price = ref_mid_price_per_exchange[0].clone();
|
|
|
self.ref_mid_price_per_exchange_per_frame.push(ref_mid_price_per_exchange);
|
|
|
|
|
|
+ self.transaction_prices.push(first_price);
|
|
|
+ // 波动率更新
|
|
|
+ self.update_std();
|
|
|
// 价差更新
|
|
|
- (*self).update_avg_spread()
|
|
|
+ // (*self).update_avg_spread()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
波动率计算(根据最近成交价)
|
|
|
**/
|
|
|
- pub fn get_std(&mut self){
|
|
|
+ pub fn update_std(&mut self) {
|
|
|
let len = self.transaction_prices.len();
|
|
|
- let rtn:f64 = (self.transaction_prices[len - 1].to_f64() / self.transaction_prices[len - 2].to_f64()).ln();
|
|
|
- let result: f64 = self.gamma.to_f64() * rtn.powf(2.0) + (1 - self.gamma.to_f64()) * self.variance.to_f64();
|
|
|
+ let rtn:f64 = (self.transaction_prices[len - 1].to_f64().unwrap() / self.transaction_prices[len - 2].to_f64().unwrap()).ln();
|
|
|
+ let result: f64 = self.gamma.to_f64().unwrap() * rtn.powf(2.0) + (1f64 - self.gamma.to_f64().unwrap()) * self.variance.to_f64().unwrap();
|
|
|
self.variance = result.sqrt();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
计算gamma值
|
|
|
**/
|
|
|
- pub fn calc_gamma(&mut self, q: Decimal) {
|
|
|
- self.gamma_calc = self.max_spread / 2f64 * q.to_f64().unwrap() * self.variance * self.variance;
|
|
|
+ pub fn calc_gamma(&mut self) -> f64 {
|
|
|
+ self.max_spread / 2f64 * self.balance_value * self.variance * self.variance
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
计算预定价格
|
|
|
**/
|
|
|
- pub fn calc_rp(&mut self, q: Decimal) -> f64{
|
|
|
+ pub fn calc_rp(&mut self, gamma: &f64) -> f64{
|
|
|
let last_market_info = self.market_info_list.last().unwrap();
|
|
|
let ref_bid_price = last_market_info[public_params::LENGTH+public_params::BID_PRICE_INDEX];
|
|
|
let ref_ask_price = last_market_info[public_params::LENGTH+public_params::ASK_PRICE_INDEX];
|
|
|
let ref_mid_price = (ref_bid_price + ref_ask_price) * dec!(0.5);
|
|
|
|
|
|
- ref_mid_price.to_f64().unwrap() - q.to_f64() * self.gamma_calc * self.variance * self.variance
|
|
|
+ ref_mid_price.to_f64().unwrap() - self.balance_value * gamma * self.variance * self.variance
|
|
|
}
|
|
|
|
|
|
- pub fn calc_dk(&mut self) -> f64 {
|
|
|
- return ((self.max_spread + self.min_spread)/2f64 * self.gamma_calc - self.variance.powf(2f64) * self.gamma_calc.powf(2f64)) / 2f64;
|
|
|
+ pub fn calc_dk(&mut self, gamma: &f64) -> f64 {
|
|
|
+ return ((self.max_spread + self.min_spread)/2f64 * gamma - self.variance.powf(2f64) * gamma.powf(2f64)) / 2f64;
|
|
|
}
|
|
|
|
|
|
- pub fn calc_kappa(&mut self, deviation_range: f64, ira: f64) -> f64 {
|
|
|
- return ((self.gamma_calc * ira) / ( std::f64::consts::E.powf(self.calc_dk()) - 1f64)) / deviation_range;
|
|
|
+ pub fn calc_kappa(&mut self, gamma: &f64, dk: f64) -> f64 {
|
|
|
+ return gamma / ( std::f64::consts::E.powf(dk) - 1f64);
|
|
|
}
|
|
|
|
|
|
- pub fn calc_theta(&mut self, std: f64, kappa: f64, ira: f64) -> f64 {
|
|
|
- let a = (self.gamma_calc * ira) * std.powf(2f64);
|
|
|
- let b = 2f64 / (self.gamma_calc * ira) * (1f64 + (self.gamma_calc * ira) / kappa).ln();
|
|
|
+ pub fn calc_theta(&mut self, gamma: f64, kappa: f64) -> f64 {
|
|
|
+ let a = gamma * self.variance.powf(2f64);
|
|
|
+ let b = 2f64 / gamma * (1f64 + gamma / kappa).ln();
|
|
|
(a + b) / 2f64
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// 更新平均价差,_update_avg_spread
|
|
|
- fn update_avg_spread(&mut self) {
|
|
|
- let last_ref_mid_price_per_exchange = self.ref_mid_price_per_exchange_per_frame.last().unwrap();
|
|
|
- let mid_price_last = self.mid_price_list.last().unwrap();
|
|
|
-
|
|
|
- for ref_index in 0..self.ref_exchange_length {
|
|
|
- let bias = last_ref_mid_price_per_exchange[ref_index] * self.alpha[ref_index] - mid_price_last;
|
|
|
-
|
|
|
- let mut gamma = self.gamma;
|
|
|
- // 如果程序刚刚启动,gamma值不能太大
|
|
|
- if self.loop_count < 100 {
|
|
|
- gamma = dec!(0.9);
|
|
|
- }
|
|
|
-
|
|
|
- // 检测是否初始化
|
|
|
- if dec!(0).eq(&self.avg_spread_list[ref_index]) {
|
|
|
- self.avg_spread_list[ref_index] = bias;
|
|
|
- } else {
|
|
|
- self.avg_spread_list[ref_index] = self.avg_spread_list[ref_index] * gamma + bias*(dec!(1)-gamma);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // fn update_avg_spread(&mut self) {
|
|
|
+ // let last_ref_mid_price_per_exchange = self.ref_mid_price_per_exchange_per_frame.last().unwrap();
|
|
|
+ // let mid_price_last = self.mid_price_list.last().unwrap();
|
|
|
+ //
|
|
|
+ // for ref_index in 0..self.ref_exchange_length {
|
|
|
+ // let bias = last_ref_mid_price_per_exchange[ref_index] * self.alpha[ref_index] - mid_price_last;
|
|
|
+ //
|
|
|
+ // let mut gamma = self.gamma;
|
|
|
+ // // 如果程序刚刚启动,gamma值不能太大
|
|
|
+ // if self.loop_count < 100 {
|
|
|
+ // gamma = dec!(0.9);
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // // 检测是否初始化
|
|
|
+ // if dec!(0).eq(&self.avg_spread_list[ref_index]) {
|
|
|
+ // self.avg_spread_list[ref_index] = bias;
|
|
|
+ // } else {
|
|
|
+ // self.avg_spread_list[ref_index] = self.avg_spread_list[ref_index] * gamma + bias*(dec!(1)-gamma);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
|
|
|
// 长度限定
|
|
|
fn check_length(&mut self) {
|
|
|
@@ -191,23 +193,112 @@ impl PredictorNew {
|
|
|
}
|
|
|
|
|
|
// 获取预定价格, 也就是python的Get_ref函数
|
|
|
- pub fn get_ref_price(&mut self, ref_ticker_map: &BTreeMap<String, Ticker>) -> Vec<Vec<Decimal>> {
|
|
|
+ // pub fn get_ref_price(&mut self, ref_ticker_map: &BTreeMap<String, Ticker>) -> Vec<Vec<Decimal>> {
|
|
|
+ // let mut ref_price_list = vec![];
|
|
|
+ // let ref_exchange_names: Vec<_> = ref_ticker_map.keys().collect();
|
|
|
+ // for ref_index in 0..ref_exchange_names.len() {
|
|
|
+ // let ref_exchange = ref_exchange_names[ref_index];
|
|
|
+ //
|
|
|
+ // let ticker = ref_ticker_map.get(ref_exchange).unwrap();
|
|
|
+ // let bid_price = ticker.buy;
|
|
|
+ // let ask_price = ticker.sell;
|
|
|
+ // let mid_price = (bid_price + ask_price) / Decimal::TWO;
|
|
|
+ // let ref_bid_price = mid_price * self.alpha[ref_index] - self.avg_spread_list[ref_index];
|
|
|
+ // let ref_ask_price = mid_price * self.alpha[ref_index] + self.avg_spread_list[ref_index];
|
|
|
+ //
|
|
|
+ // ref_price_list.push(vec![ref_bid_price, ref_ask_price]);
|
|
|
+ // }
|
|
|
+ // debug!(?ref_price_list);
|
|
|
+ //
|
|
|
+ // return ref_price_list;
|
|
|
+ // }
|
|
|
+ pub fn get_ref_price(&mut self) -> Vec<Vec<Decimal>>{
|
|
|
let mut ref_price_list = vec![];
|
|
|
- let ref_exchange_names: Vec<_> = ref_ticker_map.keys().collect();
|
|
|
- for ref_index in 0..ref_exchange_names.len() {
|
|
|
- let ref_exchange = ref_exchange_names[ref_index];
|
|
|
-
|
|
|
- let ticker = ref_ticker_map.get(ref_exchange).unwrap();
|
|
|
- let bid_price = ticker.buy;
|
|
|
- let ask_price = ticker.sell;
|
|
|
- let mid_price = (bid_price + ask_price) / Decimal::TWO;
|
|
|
- let ref_bid_price = mid_price * self.alpha[ref_index] - self.avg_spread_list[ref_index];
|
|
|
- let ref_ask_price = mid_price * self.alpha[ref_index] + self.avg_spread_list[ref_index];
|
|
|
-
|
|
|
- ref_price_list.push(vec![ref_bid_price, ref_ask_price]);
|
|
|
- }
|
|
|
- debug!(?ref_price_list);
|
|
|
+ let gamma = self.calc_gamma();
|
|
|
+ let rp = self.calc_rp(&gamma);
|
|
|
+ let dk = self.calc_dk(&gamma);
|
|
|
+ let kappa = self.calc_kappa(&gamma, dk);
|
|
|
+ let theta = self.calc_theta(gamma, kappa);
|
|
|
+ ref_price_list.push(vec![Decimal::from_f64(rp + theta).unwrap() , Decimal::from_f64(rp - theta).unwrap()]);
|
|
|
+ ref_price_list
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use std::collections::BTreeMap;
|
|
|
+ use std::io;
|
|
|
+ use std::io::Write;
|
|
|
+ use rust_decimal_macros::dec;
|
|
|
+ use standard::Ticker;
|
|
|
+ use crate::predictor_new::PredictorNew;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn predictor_build_test() {
|
|
|
+ let mut stdout = io::stdout();
|
|
|
+
|
|
|
+ let predictor1 = PredictorNew::new(2)
|
|
|
+ .alpha(vec![dec!(0.99); 100])
|
|
|
+ .gamma(dec!(0.8));
|
|
|
+ writeln!(stdout, "predictor1:").unwrap();
|
|
|
+ writeln!(stdout, "{:?}", predictor1).unwrap();
|
|
|
+ writeln!(stdout, "").unwrap();
|
|
|
+
|
|
|
+ let predictor2 = PredictorNew::new(2);
|
|
|
+ writeln!(stdout, "predictor2:").unwrap();
|
|
|
+ writeln!(stdout, "{:?}", predictor2).unwrap();
|
|
|
+ writeln!(stdout, "").unwrap();
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn market_info_handler_test() {
|
|
|
+ let mut predictor = PredictorNew::new(1);
|
|
|
+ let market_info_0 = vec![dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89), dec!(0.79), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79)];
|
|
|
+ predictor.market_info_handler(&market_info_0);
|
|
|
+ let market_info_1 = vec![dec!(0.98), dec!(0.99), dec!(0.56), dec!(0.49), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89), dec!(0.79), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79)];
|
|
|
+ predictor.market_info_handler(&market_info_1);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn get_ref_price_test() {
|
|
|
+ let mut predictor = PredictorNew::new(1)
|
|
|
+ .alpha(vec![dec!(0.99); 100])
|
|
|
+ .gamma(dec!(0.8));
|
|
|
+ predictor.balance_value = 1f64;
|
|
|
+ predictor.max_spread = 0.1f64;
|
|
|
+ predictor.min_spread = 0.01f64;
|
|
|
+ //
|
|
|
+ let mut ref_ticker_map: BTreeMap<String, Ticker> = BTreeMap::new();
|
|
|
+ ref_ticker_map.insert("binance".to_string(), Ticker{
|
|
|
+ time: 0,
|
|
|
+ high: Default::default(),
|
|
|
+ low: Default::default(),
|
|
|
+ sell: dec!(0.93),
|
|
|
+ buy: dec!(0.92),
|
|
|
+ last: Default::default(),
|
|
|
+ volume: Default::default(),
|
|
|
+ });
|
|
|
+ // println!("before market info: {:?}", predictor.get_ref_price());
|
|
|
|
|
|
- return ref_price_list;
|
|
|
+ let mut market_info = vec![];
|
|
|
+ market_info = vec![dec!(0.99), dec!(1.0), dec!(0.991), dec!(0.79), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89), dec!(0.79), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79)];
|
|
|
+ predictor.market_info_handler(&market_info);
|
|
|
+ println!("market info 0: {:?}", predictor.get_ref_price());
|
|
|
+ market_info = vec![dec!(0.98), dec!(0.99), dec!(0.981), dec!(0.49), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89)];
|
|
|
+ predictor.market_info_handler(&market_info);
|
|
|
+ println!("market info 1: {:?}", predictor.get_ref_price());
|
|
|
+ market_info = vec![dec!(0.93), dec!(1.0), dec!(0.931), dec!(0.79), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89)];
|
|
|
+ predictor.market_info_handler(&market_info);
|
|
|
+ println!("market info 2: {:?}", predictor.get_ref_price());
|
|
|
+ market_info = vec![dec!(0.98), dec!(0.49), dec!(0.981), dec!(0.49), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89)];
|
|
|
+ predictor.market_info_handler(&market_info);
|
|
|
+ println!("market info 3: {:?}", predictor.get_ref_price());
|
|
|
+ market_info = vec![dec!(0.99), dec!(1.0), dec!(0.991), dec!(0.69), dec!(0.99), dec!(1.0), dec!(0.89), dec!(0.79), dec!(0.89)];
|
|
|
+ predictor.market_info_handler(&market_info);
|
|
|
+ println!("market info 4: {:?}", predictor.get_ref_price());
|
|
|
+ market_info = vec![dec!(0.98), dec!(0.969), dec!(0.981), dec!(0.49), dec!(0.99), dec!(1.0), dec!(1.0), dec!(1.0), dec!(0.89)];
|
|
|
+ predictor.market_info_handler(&market_info);
|
|
|
+ println!("market info 5: {:?}", predictor.get_ref_price());
|
|
|
}
|
|
|
}
|