|
|
@@ -15,12 +15,15 @@ pub struct PredictorNew {
|
|
|
pub alpha: Vec<Decimal>, // 价格系数
|
|
|
pub gamma: Decimal, // 定价系数
|
|
|
pub avg_spread_list: Vec<Decimal>, // 平均价差
|
|
|
-
|
|
|
- pub transaction_prices: Vec<Decimal>, // 成交价记录
|
|
|
- pub max_spread: f64, // 最大点差
|
|
|
- pub min_spread: f64, // 最小点差
|
|
|
- pub variance: f64, // 波动率
|
|
|
- pub balance_value: f64 // 持仓价值
|
|
|
+//
|
|
|
+ pub transaction_prices: Vec<Decimal>, // 中间价记录
|
|
|
+ pub variance: Decimal, // 波动率
|
|
|
+ pub balance_value: Decimal, // 持仓价值
|
|
|
+// 手动输入
|
|
|
+ pub max_spread: Decimal, // 最大点差
|
|
|
+ pub min_spread: Decimal, // 最小点差
|
|
|
+ pub rl_num: Decimal, // 取价坐标
|
|
|
+ pub max_position_value: Decimal // 最大持仓(u)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -28,7 +31,7 @@ pub struct PredictorNew {
|
|
|
下面的单元测试有使用示例
|
|
|
*/
|
|
|
impl PredictorNew {
|
|
|
- pub fn new(ref_exchange_length: usize) -> Self {
|
|
|
+ pub fn new(ref_exchange_length: usize, max_spread: Decimal, min_spread: Decimal, rl_num: Decimal, max_position_value: Decimal) -> Self {
|
|
|
Self {
|
|
|
loop_count: 0,
|
|
|
market_info_list: vec![],
|
|
|
@@ -40,10 +43,12 @@ impl PredictorNew {
|
|
|
gamma: Decimal::from_f64(0.999).unwrap(),
|
|
|
avg_spread_list: vec![dec!(0); ref_exchange_length],
|
|
|
transaction_prices: Vec::new(),
|
|
|
- max_spread: Default::default(),
|
|
|
- min_spread: Default::default(),
|
|
|
- variance: 0.0,
|
|
|
- balance_value: 0.0,
|
|
|
+ max_spread,
|
|
|
+ min_spread,
|
|
|
+ variance: Decimal::ZERO,
|
|
|
+ balance_value: Decimal::ZERO,
|
|
|
+ rl_num,
|
|
|
+ max_position_value
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -91,46 +96,63 @@ impl PredictorNew {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- 波动率计算(根据最近成交价)
|
|
|
+ 波动率计算(根据最近成交价,EWMA波动率算法)
|
|
|
**/
|
|
|
pub fn update_std(&mut self) {
|
|
|
+ let gamma = self.gamma.to_f64().unwrap();
|
|
|
+ // 如果程序刚刚启动,gamma值不能太大
|
|
|
+ // if self.loop_count < 100 {
|
|
|
+ // gamma = 0.9f64;
|
|
|
+ // }
|
|
|
let len = self.transaction_prices.len();
|
|
|
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();
|
|
|
+ let result: f64 = gamma * rtn.powf(2.0) + (1f64 - gamma) * self.variance.to_f64().unwrap();
|
|
|
+ self.variance = Decimal::from_f64(result.sqrt()).unwrap();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
计算gamma值
|
|
|
**/
|
|
|
- pub fn calc_gamma(&mut self) -> f64 {
|
|
|
- self.max_spread / 2f64 * self.balance_value * self.variance * self.variance
|
|
|
+ pub fn calc_gamma(&mut self, ira: Decimal) -> Decimal {
|
|
|
+ self.max_spread / Decimal::TWO * self.balance_value * self.variance * self.variance * ira
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ 计算价格偏差范围
|
|
|
+ **/
|
|
|
+ pub fn calc_deviation_range(&mut self, ira: Decimal) -> Decimal {
|
|
|
+ return (self.rl_num - ira) * self.max_spread + ira * self.min_spread;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
计算预定价格
|
|
|
**/
|
|
|
- pub fn calc_rp(&mut self, gamma: &f64) -> f64{
|
|
|
+ pub fn calc_rp(&mut self, gamma: &Decimal) -> Decimal{
|
|
|
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() - self.balance_value * gamma * self.variance * self.variance
|
|
|
+ println!("mid_price: {}", ref_mid_price);
|
|
|
+ ref_mid_price - self.balance_value * gamma * self.variance * self.variance
|
|
|
}
|
|
|
|
|
|
- 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_dk(&mut self, gamma: &Decimal) -> Decimal {
|
|
|
+ return ((self.max_spread + self.min_spread)/Decimal::TWO * gamma - self.variance * self.variance * gamma * gamma) / Decimal::TWO;
|
|
|
}
|
|
|
|
|
|
- pub fn calc_kappa(&mut self, gamma: &f64, dk: f64) -> f64 {
|
|
|
- return gamma / ( std::f64::consts::E.powf(dk) - 1f64);
|
|
|
+ pub fn calc_kappa(&mut self, gamma: &Decimal, dk: Decimal, deviation_range: Decimal) -> Decimal {
|
|
|
+ let e = std::f64::consts::E.powf(dk.to_f64().unwrap()) - 1f64;
|
|
|
+ gamma / Decimal::from_f64(e).unwrap() / deviation_range
|
|
|
}
|
|
|
|
|
|
- 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
|
|
|
+ /**
|
|
|
+ 计算价差
|
|
|
+ **/
|
|
|
+ pub fn calc_theta(&mut self, gamma: Decimal, kappa: Decimal) -> Decimal {
|
|
|
+ let a = gamma * self.variance * self.variance;
|
|
|
+ let ln = (Decimal::ONE + gamma / kappa).to_f64().unwrap().ln();
|
|
|
+ let b = Decimal::TWO / gamma * Decimal::from_f64(ln).unwrap();
|
|
|
+ (a + b) / Decimal::TWO
|
|
|
}
|
|
|
|
|
|
// 更新平均价差,_update_avg_spread
|
|
|
@@ -214,12 +236,15 @@ impl PredictorNew {
|
|
|
// }
|
|
|
pub fn get_ref_price(&mut self) -> Vec<Vec<Decimal>>{
|
|
|
let mut ref_price_list = vec![];
|
|
|
- let gamma = self.calc_gamma();
|
|
|
+ let ira = Decimal::from_str("5").unwrap();
|
|
|
+ let dd = self.calc_deviation_range(ira.clone());
|
|
|
+ let gamma = self.calc_gamma(ira);
|
|
|
let rp = self.calc_rp(&gamma);
|
|
|
let dk = self.calc_dk(&gamma);
|
|
|
- let kappa = self.calc_kappa(&gamma, dk);
|
|
|
+ let kappa = self.calc_kappa(&gamma, dk, dd);
|
|
|
let theta = self.calc_theta(gamma, kappa);
|
|
|
- ref_price_list.push(vec![Decimal::from_f64(rp + theta).unwrap() , Decimal::from_f64(rp - theta).unwrap()]);
|
|
|
+ println!("gamma: {}, rp: {}, dk: {}, kappa: {}, theta: {}, std: {}", gamma, rp, dk, kappa, theta, self.variance);
|
|
|
+ ref_price_list.push(vec![rp + theta , rp - theta]);
|
|
|
ref_price_list
|
|
|
}
|
|
|
}
|
|
|
@@ -230,6 +255,8 @@ mod tests {
|
|
|
use std::collections::BTreeMap;
|
|
|
use std::io;
|
|
|
use std::io::Write;
|
|
|
+ use std::str::FromStr;
|
|
|
+ use rust_decimal::Decimal;
|
|
|
use rust_decimal_macros::dec;
|
|
|
use standard::Ticker;
|
|
|
use crate::predictor_new::PredictorNew;
|
|
|
@@ -238,14 +265,14 @@ mod tests {
|
|
|
fn predictor_build_test() {
|
|
|
let mut stdout = io::stdout();
|
|
|
|
|
|
- let predictor1 = PredictorNew::new(2)
|
|
|
+ let predictor1 = PredictorNew::new(2, Default::default(), Default::default(), Default::default())
|
|
|
.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);
|
|
|
+ let predictor2 = PredictorNew::new(2, Default::default(), Default::default(), Default::default());
|
|
|
writeln!(stdout, "predictor2:").unwrap();
|
|
|
writeln!(stdout, "{:?}", predictor2).unwrap();
|
|
|
writeln!(stdout, "").unwrap();
|
|
|
@@ -253,7 +280,7 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn market_info_handler_test() {
|
|
|
- let mut predictor = PredictorNew::new(1);
|
|
|
+ let mut predictor = PredictorNew::new(1, Default::default(), Default::default(), Default::default());
|
|
|
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)];
|
|
|
@@ -262,12 +289,12 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn get_ref_price_test() {
|
|
|
- let mut predictor = PredictorNew::new(1)
|
|
|
+ let mut predictor = PredictorNew::new(1, Default::default(), Default::default(), Default::default())
|
|
|
.alpha(vec![dec!(0.99); 100])
|
|
|
.gamma(dec!(0.8));
|
|
|
- predictor.balance_value = 1f64;
|
|
|
- predictor.max_spread = 0.1f64;
|
|
|
- predictor.min_spread = 0.01f64;
|
|
|
+ predictor.balance_value = Decimal::from_str("0.5").unwrap();
|
|
|
+ predictor.max_spread = Decimal::from_str("0.5").unwrap();
|
|
|
+ predictor.min_spread = Decimal::from_str("0.01").unwrap();
|
|
|
//
|
|
|
let mut ref_ticker_map: BTreeMap<String, Ticker> = BTreeMap::new();
|
|
|
ref_ticker_map.insert("binance".to_string(), Ticker{
|
|
|
@@ -281,8 +308,7 @@ mod tests {
|
|
|
});
|
|
|
// println!("before market info: {:?}", predictor.get_ref_price());
|
|
|
|
|
|
- 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)];
|
|
|
+ let mut 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)];
|