Sfoglia il codice sorgente

新增振幅指标。

skyffire 1 anno fa
parent
commit
cf7ca030e0
2 ha cambiato i file con 64 aggiunte e 0 eliminazioni
  1. 8 0
      README.MD
  2. 56 0
      src/symbol_filter.rs

+ 8 - 0
README.MD

@@ -88,6 +88,10 @@
         {
             "target": "TC",                 // TC是交易次数计数,Trades Count
             "value": "3"                    // 3表示3次
+        },
+        {
+            "target": "AMP",                // AMP是振幅,Amplification
+            "value": "3"                    // 3表示3%
         }
     ]
 }
@@ -105,6 +109,10 @@
                 "gate_usdt_swap": "3",
                 "bitget_usdt_swap": "2.9",
             },
+            "amp": {                        // 振幅,3代表3%
+                "gate_usdt_swap": "3",
+                "bitget_usdt_swap": "2.5"
+            },
             "volume": {                     // 交易量,单位是M(百万)
                 "gate_usdt_swap": "0.1",
                 "bitget_usdt_swap": "0.5",

+ 56 - 0
src/symbol_filter.rs

@@ -59,6 +59,36 @@ fn calc_rise_percentage(records: Value) -> Decimal {
     return rst
 }
 
+// 计算振幅
+fn calc_amplification_percentage(records: Value) -> Decimal {
+    let records_array = records.as_array().unwrap();
+
+    if records_array.len() == 0 {
+        return Decimal::ZERO
+    }
+
+    let mut low = dec!(1e28);
+    let mut high = dec!(-1);
+
+    for record in records_array {
+        let record_high = Decimal::from_str(record["high"].as_str().unwrap().to_string().as_str()).unwrap();
+        let record_low = Decimal::from_str(record["low"].as_str().unwrap().to_string().as_str()).unwrap();
+
+        if record_high > high {
+            high = record_high
+        }
+
+        if record_low < low {
+            low = record_low
+        }
+    }
+
+    let mut rst = Decimal::ONE_HUNDRED * (high - low) / low;
+    rst.rescale(2);
+
+    return rst
+}
+
 pub async fn get_final_symbols(mode: &str, exchanges: &Vec<String>, minute_time_range: i64, filters: &Vec<Value>) -> HttpResponse {
     // 1. 获取所选交易所的所有交易对
     let mut symbols_map = json!({});
@@ -162,6 +192,7 @@ pub async fn get_final_symbols(mode: &str, exchanges: &Vec<String>, minute_time_
     let mut temp_value = json!([]);
     for symbol in &symbols {
         let mut rise = json!({});
+        let mut amp = json!({});
         let mut volume = json!({});
         let mut tc = json!({});
         let mut total_volume_by_symbol = Decimal::ZERO;
@@ -175,6 +206,9 @@ pub async fn get_final_symbols(mode: &str, exchanges: &Vec<String>, minute_time_
             // 上涨幅度处理
             rise[exchange] = json!(calc_rise_percentage(records_map[exchange][symbol].clone()));
 
+            // 振幅处理
+            amp[exchange] = json!(calc_amplification_percentage(records_map[exchange][symbol].clone()));
+
             // 交易量处理
             let volume_by_exchange = calc_total_volume(records_map[exchange][symbol].clone());
             volume[exchange] = json!(volume_by_exchange);
@@ -186,6 +220,7 @@ pub async fn get_final_symbols(mode: &str, exchanges: &Vec<String>, minute_time_
         let value = json!({
             "symbol": symbol.clone(),
             "rise": rise,
+            "amp": amp,
             "volume": volume,
             "tc": tc
         });
@@ -243,6 +278,9 @@ fn symbols_filter(symbols: &Vec<Value>, filters: &Vec<Value>, mode: &str, exchan
                 "ROA" => {
                     rise_of_abs_filter(symbol, filter, exchanges)
                 },
+                "AMP" => {
+                    amp_filter(symbol, filter, exchanges)
+                },
                 _ => {
                     panic!("{}", format!("无法识别的过滤器: {}", filter["target"].as_str().unwrap()))
                 }
@@ -293,6 +331,24 @@ fn rise_filter(symbol: &Value, filter: &Value, exchanges: &Vec<String>) -> bool
     return rst
 }
 
+// 振幅过滤器
+fn amp_filter(symbol: &Value, filter: &Value, exchanges: &Vec<String>) -> bool {
+    let amp_limit = Decimal::from_str(filter["value"].as_str().unwrap().to_string().as_str()).unwrap();
+    let mut rst = true;
+
+    for exchange in exchanges {
+        let amp_map = symbol["amp"].clone();
+        let amp = Decimal::from_str(amp_map[exchange].as_str().unwrap().to_string().as_str()).unwrap();
+
+        rst = rst && amp > amp_limit;
+        if !rst {
+            break
+        }
+    }
+
+    return rst
+}
+
 // 交易量过滤器
 fn volume_filter(symbol: &Value, filter: &Value, exchanges: &Vec<String>) -> bool {
     let volume_limit = Decimal::from_str(filter["value"].as_str().unwrap().to_string().as_str()).unwrap();