فهرست منبع

加入预期利润。

skyffire 1 سال پیش
والد
کامیت
72f49a977f
2فایلهای تغییر یافته به همراه83 افزوده شده و 43 حذف شده
  1. 3 3
      README.MD
  2. 80 40
      src/msv.rs

+ 3 - 3
README.MD

@@ -31,9 +31,9 @@
             ["1715653817313", "1"],         // [时间戳, 流动性量]
             ["1715653817316", "0"],         // [时间戳, 流动性量]
         ],
-        "spreads": [                        // 价差集合                           
-            ["1715653817313", "1"],         // [时间戳, 价差1]
-            ["1715653817316", "0"],         // [时间戳, 价差2]
+        "eprs": [                           // 预期利润                       
+            ["1715653817313", "2"],         // [时间戳, 预期利润1]
+            ["1715653817316", "-2"],        // [时间戳, 预期利润2]
         ],
         "total_size": 3,                    // 总trades条数
         "result_size": 1,                   // 指标数据条数

+ 80 - 40
src/msv.rs

@@ -104,26 +104,29 @@ pub async fn generate_msv(query_value: Value) -> HttpResponse {
 
 // 将trades转换为具体指标
 pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simple_depths: Vec<SimpleDepth>, start_time: i64, end_time: i64) -> Value {
+    // 具体波动
     let mut msv_data: Vec<Vec<Decimal>> = vec![];
+    // 预期利润幅度(except_profit_rate)
+    let mut epr_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 = if index == 0 {
-            0
-        } else {
-            index
-        };
+        let mut range_index = index;
 
         // 计算区间的预定价格
         let mut ref_price = trade.price;
         let mut dissociation = Decimal::ZERO;
         loop {
-            // 第0个就不搞
-            if range_index == 0 {
+            // 下标合法性判断
+            if range_index <= 0 {
                 break;
             }
 
@@ -140,51 +143,80 @@ pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simpl
             range_index -= 1;
         }
 
-        // 逻辑计算层
-        // 取离当前点最远的点进行测量
-        let last_price = trade.price;
-
-        // 不是初始值,以及不是0波动
-        if index != 0 {
-            let mut rate = Decimal::ONE_HUNDRED * (last_price - ref_price) / ref_price;
+        // 获取到range毫秒以后的预定价格,计算回去的幅度
+        let mut future_ref_price = ref_price;
+        let mut future_range_index = index;
+        loop {
+            // 下标合法性判断
+            if future_range_index >= trades.len() {
+                break;
+            }
 
-            rate.rescale(2);
+            let flag_trade = trades.get(range_index).unwrap();
+            let range_time = flag_trade.time - trade.time;
 
-            // 去除小数位之后,可以忽略一些太小的波动,减少图表生成压力
-            if rate.eq(&Decimal::ZERO) {
-                continue
+            // 判断该ticker是否是range ms以外
+            if range_time > mills_back {
+                break;
             }
+            future_ref_price = future_ref_price * GAMMA + flag_trade.price * (Decimal::ONE - GAMMA);
+
+            future_range_index += 1;
+        }
 
-            // 去重,以及保留最大的波动率
-            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]);
-                    }
-                } else {
+        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 epr = if rate > Decimal::ZERO {
+            -future_rate
+        } else {
+            future_rate
+        };
+
+        // 去重,以及保留最大的波动率
+        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]);
                 }
             } else {
                 msv_data.push(vec![trade.time, rate, dissociation]);
+                epr_data.push(vec![trade.time, epr]);
             }
+        } else {
+            msv_data.push(vec![trade.time, rate, dissociation]);
+            epr_data.push(vec![trade.time, epr]);
         }
     }
 
     // 按时间序列填充数据
     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 depth_index = 0;
-    let mut final_depth_data: Vec<Vec<Decimal>> = vec![];
-
-    let final_spread_data: Vec<Vec<Decimal>> = vec![];
+    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();
@@ -192,6 +224,7 @@ pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simpl
     loop {
         let mut max_msv_data = Decimal::ZERO;
         let mut max_msv_qty_data = Decimal::ZERO;
+        let mut max_epr_data = Decimal::ZERO;
 
         // ====================================== 数据生产 ===============================================
         // 获取时间范围内的波动率数据
@@ -209,11 +242,16 @@ pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simpl
             // -------------- 大小判断,取值
             let msv_d = msv_data[msv_index][1];
             let msv_qty_data = msv_data[msv_index][2];
+            let epr_data = msv_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;
             }
+            // epr数据
+            if max_epr_data.abs() < epr_data.abs() {
+                max_epr_data = epr_data;
+            }
             // 下标步近
             msv_index = msv_index + 1;
         }
@@ -268,15 +306,17 @@ pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simpl
         // 如果这两个值为0,则代表这mills_back毫秒以内是没有数据的,填充0数据,使得x轴是完整的
         if max_msv_data == Decimal::ZERO {
             final_msv_data.push(vec![index_timestamp, Decimal::ZERO, Decimal::ZERO]);
-            final_depth_data.push(vec![index_timestamp, Decimal::ZERO]);
+            final_epr_data.push(vec![index_timestamp, Decimal::ZERO]);
+            final_volume_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_depth_data.push(vec![index_timestamp, final_qty]);
+            final_volume_data.push(vec![index_timestamp, final_qty]);
         }
 
         // ====================================== 时间步进处理 ======================================
@@ -293,8 +333,8 @@ pub fn generate_msv_by_trades(mut trades: Vec<Trade>, mills_back: Decimal, simpl
     let result_size = final_msv_data.len();
     json!({
         "msv": final_msv_data,
-        "liqs": final_depth_data,
-        "spreads": final_spread_data,
+        "liqs": final_volume_data,
+        "epr": final_epr_data,
         "total_size": total_size,
         "result_size": result_size,
     })