|
|
@@ -1,376 +0,0 @@
|
|
|
-use std::cmp::{max, min};
|
|
|
-use std::str::FromStr;
|
|
|
-use rust_decimal::{Decimal, MathematicalOps};
|
|
|
-use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
|
|
|
-use rust_decimal_macros::dec;
|
|
|
-use serde::{Deserialize, Serialize};
|
|
|
-use serde_json::{Value};
|
|
|
-use standard::{SimpleDepth, Trade};
|
|
|
-
|
|
|
-
|
|
|
-/// 技术指标结构体
|
|
|
-/// - `msv(Vec<Vec<Decimal>>)`: msv
|
|
|
-/// - `liqs(Vec<Vec<Decimal>>)`: liqs
|
|
|
-/// - `eprs(Vec<Vec<Decimal>>)`: eprs
|
|
|
-/// - `sigmas(Vec<Vec<Decimal>>)`: sigmas
|
|
|
-/// - `sigma_mas(Vec<Vec<Decimal>>)`: sigma_mas
|
|
|
-/// - `total_size(i64)`: total_size
|
|
|
-/// - `result_size(i64)`: result_size
|
|
|
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
-pub struct Indicators {
|
|
|
- pub msv: Vec<Vec<Decimal>>,
|
|
|
- pub liqs: Vec<Vec<Decimal>>,
|
|
|
- pub eprs: Vec<Vec<Decimal>>,
|
|
|
- pub sigmas: Vec<Vec<Decimal>>,
|
|
|
- pub sigma_mas: Vec<Vec<Decimal>>,
|
|
|
- pub total_size: i64,
|
|
|
- pub result_size: i64,
|
|
|
-}
|
|
|
-
|
|
|
-// 将trades转换为具体指标 trades 50 [] stime etime
|
|
|
-pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simple_depths: Vec<SimpleDepth>, start_time: i64, end_time: i64) -> Indicators {
|
|
|
- // 具体波动
|
|
|
- let mut msv_data: Vec<Vec<Decimal>> = vec![];
|
|
|
- // 预期利润幅度(except_profit_rate)
|
|
|
- let mut epr_data: Vec<Vec<Decimal>> = vec![];
|
|
|
- // 波动率sigma
|
|
|
- let mut sigma_data: Vec<Vec<Decimal>> = vec![];
|
|
|
-
|
|
|
- const GAMMA: Decimal = dec!(0.5);
|
|
|
-
|
|
|
- // ================== 计算每个点的具体波动率以及回溯幅度 ===================
|
|
|
- trades.sort_by(|a, b| Decimal::from_str(a.id.as_str()).unwrap().cmp(&Decimal::from_str(b.id.as_str()).unwrap()));
|
|
|
- for (index, trade) in trades.iter().enumerate() {
|
|
|
- if index == 0 {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 该元素向前遍历range毫秒
|
|
|
- let mut range_index = index;
|
|
|
- // 该区间的预定价格
|
|
|
- let mut ref_price = trade.price;
|
|
|
- let mut dissociation = Decimal::ZERO;
|
|
|
- loop {
|
|
|
- // 下标合法性判断
|
|
|
- if range_index == 0 {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- let flag_trade = trades.get(range_index).unwrap();
|
|
|
- let range_time = trade.time - flag_trade.time;
|
|
|
- // 判断该ticker是否是range ms以外
|
|
|
- if range_time > mills_back {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- ref_price = ref_price * GAMMA + flag_trade.price * (Decimal::ONE - GAMMA);
|
|
|
- dissociation = dissociation + flag_trade.size.abs();
|
|
|
-
|
|
|
- range_index -= 1;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取到range毫秒以后的预定价格,计算回去的幅度
|
|
|
- let mut future_ref_price_sum = Decimal::ZERO;
|
|
|
- let mut future_ref_count = Decimal::ZERO;
|
|
|
- let mut future_range_index = index + 1;
|
|
|
- loop {
|
|
|
- // 下标合法性判断
|
|
|
- if future_range_index >= trades.len() {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- let flag_trade = trades.get(future_range_index).unwrap();
|
|
|
- let range_time = flag_trade.time - trade.time;
|
|
|
-
|
|
|
- // 判断该ticker是否是range ms以外
|
|
|
- if range_time > mills_back && future_ref_count > Decimal::ZERO {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- future_range_index += 1;
|
|
|
- future_ref_price_sum += flag_trade.price;
|
|
|
- future_ref_count += Decimal::ONE;
|
|
|
- }
|
|
|
- let future_ref_price = if future_ref_count < Decimal::ONE {
|
|
|
- trade.price
|
|
|
- } else {
|
|
|
- future_ref_price_sum / future_ref_count
|
|
|
- };
|
|
|
-
|
|
|
- // 计算过去至多100条数据的sigma值 sigma^2 = (1 / (tn-t0))*sum((S(tk) - S(tk-1)) ^ 2)
|
|
|
- let mut sigma_index = index - 1;
|
|
|
- let t_last = trade.time;
|
|
|
-
|
|
|
- let mut _t_first = trade.time;
|
|
|
- // 右值
|
|
|
- let mut total_right = Decimal::ZERO;
|
|
|
- loop {
|
|
|
- let flag_trade = trades.get(sigma_index).unwrap();
|
|
|
- let next_trade = trades.get(sigma_index + 1).unwrap();
|
|
|
-
|
|
|
- // 下标合法性判断
|
|
|
- if sigma_index == 0 || sigma_index + 100 <= index {
|
|
|
- _t_first = flag_trade.time;
|
|
|
- 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);
|
|
|
- // 计算过去至多100个sigma值的平均值
|
|
|
- let sigma_ma = if sigma_data.len() > 0 {
|
|
|
- let mut sigma_ma_index = sigma_data.len();
|
|
|
- let mut sigma_total = Decimal::ZERO;
|
|
|
- let mut sigma_count = Decimal::ZERO;
|
|
|
- loop {
|
|
|
- if sigma_ma_index == 0 || sigma_ma_index + 99 < sigma_data.len() {
|
|
|
- break;
|
|
|
- }
|
|
|
- // 步进
|
|
|
- sigma_ma_index -= 1;
|
|
|
- // 计算
|
|
|
- sigma_total += sigma_data[sigma_ma_index][1];
|
|
|
- sigma_count += Decimal::ONE;
|
|
|
- }
|
|
|
- let mut sigma_ma = sigma_total / sigma_count;
|
|
|
- sigma_ma.rescale(6);
|
|
|
-
|
|
|
- sigma_ma
|
|
|
- } else {
|
|
|
- sigma
|
|
|
- };
|
|
|
-
|
|
|
- // ==================== 波动逻辑计算 ====================
|
|
|
- let last_price = trade.price;
|
|
|
- let mut rate = Decimal::ONE_HUNDRED * (last_price - ref_price) / ref_price;
|
|
|
- rate.rescale(2);
|
|
|
- // 去除小数位之后,可以忽略一些太小的波动,减少图表生成压力
|
|
|
- if rate.eq(&Decimal::ZERO) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 预期利润逻辑计算 ====================
|
|
|
- // 首先计算未来一段时间的价格与现在的距离
|
|
|
- let mut future_rate = Decimal::ONE_HUNDRED * (future_ref_price - last_price) / last_price;
|
|
|
- future_rate.rescale(2);
|
|
|
- // 根据具体向上波动还是向下波动来计算预期最大利润
|
|
|
- let mut epr = if rate > Decimal::ZERO {
|
|
|
- -future_rate
|
|
|
- } else {
|
|
|
- future_rate
|
|
|
- };
|
|
|
- epr = min(epr, rate.abs());
|
|
|
-
|
|
|
- // 去重,以及保留最大的波动率
|
|
|
- if msv_data.len() > 0 {
|
|
|
- let last = msv_data[msv_data.len() - 1].clone();
|
|
|
- let last_time = last[0];
|
|
|
- let last_rate = last[1];
|
|
|
-
|
|
|
- // 如果时间相同,则可能会进行remove等操作
|
|
|
- if last_time == trade.time {
|
|
|
- // 如果最新的波动率大于最后波动率
|
|
|
- if rate.abs() > last_rate.abs() {
|
|
|
- msv_data.remove(msv_data.len() - 1);
|
|
|
- msv_data.push(vec![trade.time, rate, dissociation]);
|
|
|
-
|
|
|
- epr_data.remove(epr_data.len() - 1);
|
|
|
- epr_data.push(vec![trade.time, epr]);
|
|
|
-
|
|
|
- sigma_data.remove(sigma_data.len() - 1);
|
|
|
- sigma_data.push(vec![trade.time, sigma, sigma_ma]);
|
|
|
- }
|
|
|
- } else {
|
|
|
- msv_data.push(vec![trade.time, rate, dissociation]);
|
|
|
- epr_data.push(vec![trade.time, epr]);
|
|
|
- sigma_data.push(vec![trade.time, sigma, sigma_ma]);
|
|
|
- }
|
|
|
- } else {
|
|
|
- msv_data.push(vec![trade.time, rate, dissociation]);
|
|
|
- epr_data.push(vec![trade.time, epr]);
|
|
|
- sigma_data.push(vec![trade.time, sigma, sigma_ma]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 按时间序列填充数据
|
|
|
- let mut msv_index = 0;
|
|
|
- let mut final_msv_data: Vec<Vec<Decimal>> = vec![];
|
|
|
- let mut final_epr_data: Vec<Vec<Decimal>> = vec![];
|
|
|
- let mut final_sigma_data: Vec<Vec<Decimal>> = vec![];
|
|
|
- let mut final_sigma_ma_data: Vec<Vec<Decimal>> = vec![];
|
|
|
-
|
|
|
- let mut depth_index = 0;
|
|
|
- let mut final_volume_data: Vec<Vec<Decimal>> = vec![];
|
|
|
-
|
|
|
- let mut index_timestamp = Decimal::from_i64(start_time).unwrap();
|
|
|
- let last_timestamp = Decimal::from_i64(end_time).unwrap();
|
|
|
- let step_timestamp = dec!(1000);
|
|
|
- loop {
|
|
|
- let mut max_msv_data = Decimal::ZERO;
|
|
|
- let mut max_msv_qty_data = Decimal::ZERO;
|
|
|
- let mut max_epr_data = Decimal::ZERO;
|
|
|
- let mut max_sigma_data = Decimal::ZERO;
|
|
|
- let mut max_sigma_ma_data = Decimal::ZERO;
|
|
|
-
|
|
|
- // ====================================== 数据生产 ===============================================
|
|
|
- // 获取时间范围内的波动率数据
|
|
|
- loop {
|
|
|
- // 下标合法性判断
|
|
|
- if msv_index >= msv_data.len() {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- // msv_data的指定下标数据不在时间范围内(时间范围:指的是[index_timestamp-mills_back, index_timestamp]这个范围)
|
|
|
- if index_timestamp < msv_data[msv_index][0] {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- // -------------- 大小判断,取值
|
|
|
- let msv_d = msv_data[msv_index][1];
|
|
|
- let msv_qty_data = msv_data[msv_index][2];
|
|
|
- let epr_d = epr_data[msv_index][1];
|
|
|
- let sigma_d = sigma_data[msv_index][1];
|
|
|
- let sigma_ma_d = sigma_data[msv_index][2];
|
|
|
- // msv波动数据
|
|
|
- if max_msv_data.abs() < msv_d.abs() {
|
|
|
- max_msv_data = msv_d;
|
|
|
- max_msv_qty_data = msv_qty_data;
|
|
|
- max_epr_data = epr_d;
|
|
|
- max_sigma_data = sigma_d;
|
|
|
- max_sigma_ma_data = sigma_ma_d;
|
|
|
- }
|
|
|
- // // 波动率sigma
|
|
|
- // if max_sigma_data.abs() < sigma_d {
|
|
|
- // max_sigma_data = sigma_d;
|
|
|
- // }
|
|
|
-
|
|
|
- // 下标步近
|
|
|
- msv_index = msv_index + 1;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取时间范围内的深度数据、买一及卖一价数据
|
|
|
- let mut max_size = Decimal::ZERO;
|
|
|
- let mut min_size = Decimal::ONE_THOUSAND * Decimal::ONE_THOUSAND;
|
|
|
- loop {
|
|
|
- // 下标合法性判断
|
|
|
- if depth_index >= simple_depths.len() {
|
|
|
- break;
|
|
|
- }
|
|
|
- let depth = &simple_depths[depth_index];
|
|
|
- // 时间范围合法性判断,只统计那一秒以内的深度总交易量
|
|
|
- if index_timestamp < depth.time {
|
|
|
- break;
|
|
|
- }
|
|
|
- // 这一秒的深度最大值、最小值
|
|
|
- max_size = max(max_size, depth.size);
|
|
|
- min_size = min(min_size, depth.size);
|
|
|
- // 下标步近
|
|
|
- depth_index += 1;
|
|
|
- }
|
|
|
-
|
|
|
- // ====================================== 智能填充数据 ===============================================
|
|
|
- // 流动性数据叠加
|
|
|
- // let rst_size = if (max_size == Decimal::ZERO || min_size == Decimal::ONE_THOUSAND * Decimal::ONE_THOUSAND) && final_depth_data.len() > 0 {
|
|
|
- // final_depth_data.last().unwrap()[1]
|
|
|
- // } else {
|
|
|
- // if (max_size == Decimal::ZERO || min_size == Decimal::ONE_THOUSAND * Decimal::ONE_THOUSAND) && simple_depths.len() > 0 {
|
|
|
- // simple_depths[0].size
|
|
|
- // } else {
|
|
|
- // if simple_depths.len() > 0 {
|
|
|
- // (max_size + min_size) / Decimal::TWO
|
|
|
- // } else {
|
|
|
- // Decimal::ZERO
|
|
|
- // }
|
|
|
- // }
|
|
|
- // };
|
|
|
- // final_depth_data.push(vec![index_timestamp, rst_size]);
|
|
|
- //
|
|
|
- // // 建议开仓距离
|
|
|
- // let mut rst_spread = if rst_size == Decimal::ZERO {
|
|
|
- // Decimal::ZERO
|
|
|
- // } else {
|
|
|
- // dec!(10000) / rst_size
|
|
|
- // };
|
|
|
- // rst_spread.rescale(6);
|
|
|
- // final_spread_data.push(vec![index_timestamp, rst_spread]);
|
|
|
-
|
|
|
- // 波动率数据处理
|
|
|
- // 如果这两个值为0,则代表这mills_back毫秒以内是没有数据的,填充0数据,使得x轴是完整的
|
|
|
- if max_msv_data == Decimal::ZERO {
|
|
|
- final_msv_data.push(vec![index_timestamp, Decimal::ZERO, Decimal::ZERO]);
|
|
|
- final_epr_data.push(vec![index_timestamp, Decimal::ZERO]);
|
|
|
- final_volume_data.push(vec![index_timestamp, Decimal::ZERO]);
|
|
|
-
|
|
|
- if final_sigma_data.len() > 0 {
|
|
|
- final_sigma_data.push(vec![index_timestamp, final_sigma_data.last().unwrap()[1]]);
|
|
|
- final_sigma_ma_data.push(vec![index_timestamp, final_sigma_ma_data.last().unwrap()[1]]);
|
|
|
- } else {
|
|
|
- final_sigma_data.push(vec![index_timestamp, Decimal::ZERO]);
|
|
|
- final_sigma_ma_data.push(vec![index_timestamp, Decimal::ZERO]);
|
|
|
- }
|
|
|
-
|
|
|
- // 说明在这个时间范围内是有数据存在的,将各类副图放置完全
|
|
|
- } else {
|
|
|
- final_msv_data.push(vec![index_timestamp, max_msv_data, max_msv_qty_data]);
|
|
|
- final_epr_data.push(vec![index_timestamp, max_epr_data]);
|
|
|
-
|
|
|
- let mut final_qty = max_msv_qty_data / Decimal::ONE_THOUSAND;
|
|
|
- final_qty.rescale(2);
|
|
|
- final_volume_data.push(vec![index_timestamp, final_qty]);
|
|
|
-
|
|
|
- final_sigma_data.push(vec![index_timestamp, max_sigma_data]);
|
|
|
- final_sigma_ma_data.push(vec![index_timestamp, max_sigma_ma_data]);
|
|
|
- }
|
|
|
-
|
|
|
- // ====================================== 时间步进处理 ======================================
|
|
|
- // 对时间进行步近
|
|
|
- index_timestamp = index_timestamp + step_timestamp;
|
|
|
- // 时间越界
|
|
|
- if index_timestamp > last_timestamp {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 结果统计
|
|
|
- let total_size = trades.len().to_i64().unwrap();
|
|
|
- let result_size = final_msv_data.len().to_i64().unwrap();
|
|
|
- Indicators {
|
|
|
- msv: final_msv_data,
|
|
|
- liqs: final_volume_data,
|
|
|
- eprs: final_epr_data,
|
|
|
- sigmas: final_sigma_data,
|
|
|
- sigma_mas: final_sigma_ma_data,
|
|
|
- total_size,
|
|
|
- result_size,
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 将json转换为trades
|
|
|
-pub fn parse_json_to_trades(trades_json: Value) -> Vec<Trade> {
|
|
|
- let mut rst = vec![];
|
|
|
-
|
|
|
- for trade_json in trades_json.as_array().unwrap() {
|
|
|
- let arr = trade_json.as_array().unwrap();
|
|
|
- rst.push(Trade {
|
|
|
- id: arr[0].as_str().unwrap().to_string(),
|
|
|
- time: Decimal::from_str(arr[1].as_str().unwrap()).unwrap(),
|
|
|
- size: Decimal::from_str(arr[2].as_str().unwrap()).unwrap(),
|
|
|
- price: Decimal::from_str(arr[3].as_str().unwrap()).unwrap(),
|
|
|
- symbol: "".to_string(),
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- rst
|
|
|
-}
|