skyffire 1 жил өмнө
parent
commit
0a2037dfb3
2 өөрчлөгдсөн 132 нэмэгдсэн , 15 устгасан
  1. 2 2
      src/server.rs
  2. 130 13
      src/symbol_filter.rs

+ 2 - 2
src/server.rs

@@ -9,7 +9,7 @@ use serde_json::Value;
 use tracing::{info};
 use crate::msv::generate_msv;
 use crate::params_utils::{get_array, get_str, parse_str_to_decimal};
-use crate::symbol_filter::get_symbols;
+use crate::symbol_filter::get_final_symbols;
 use crate::trades::generate_trades;
 
 #[derive(Serialize, Deserialize, Debug)]
@@ -72,7 +72,7 @@ async fn get_symbols_by_filter(query: web::Json<Value>) -> impl Responder {
         }
     };
 
-    get_symbols(&mode, &exchanges, minute_time_range, &filters).await
+    get_final_symbols(&mode, &exchanges, minute_time_range, &filters).await
 }
 
 // ia: intelligence agency, 情报部门

+ 130 - 13
src/symbol_filter.rs

@@ -54,7 +54,7 @@ fn calc_rise_percentage(records: Value) -> Decimal {
     return rst
 }
 
-pub async fn get_symbols(_mode: &str, exchanges: &Vec<String>, minute_time_range: i64, _filters: &Vec<Value>) -> HttpResponse {
+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!({});
     for exchange in exchanges {
@@ -71,17 +71,17 @@ pub async fn get_symbols(_mode: &str, exchanges: &Vec<String>, minute_time_range
         }
     }
     // 2. 如果是多交易所,则获取所有交易所的交集
-    let mut symbols: Vec<String> = get_public_symbols(&symbols_map);
+    let symbols: Vec<String> = get_public_symbols(&symbols_map);
     // 确保有足够的元素
-    let n = 10;
-    // 获取前20个元素,如果不足20个,则获取全部
-    let top_symbols = if symbols.len() > n {
-        &symbols[0..n]
-    } else {
-        &symbols[..]
-    };
-    // 如果你需要将这些元素放在新的 Vec 中
-    symbols = top_symbols.to_vec();
+    // let n = 10;
+    // // 获取前20个元素,如果不足20个,则获取全部
+    // let top_symbols = if symbols.len() > n {
+    //     &symbols[0..n]
+    // } else {
+    //     &symbols[..]
+    // };
+    // // 如果你需要将这些元素放在新的 Vec 中
+    // symbols = top_symbols.to_vec();
 
     // 3. 获取它们的k线数据,注意时间范围以及保存形式。
     // {
@@ -141,7 +141,7 @@ pub async fn get_symbols(_mode: &str, exchanges: &Vec<String>, minute_time_range
     //         },
     //     }
     // ]
-    let mut response_value = json!([]);
+    let mut temp_value = json!([]);
     for symbol in &symbols {
         let mut rise = json!({});
         let mut volume = json!({});
@@ -161,7 +161,7 @@ pub async fn get_symbols(_mode: &str, exchanges: &Vec<String>, minute_time_range
             "volume": volume
         });
 
-        response_value.as_array_mut().unwrap().push(value);
+        temp_value.as_array_mut().unwrap().push(value);
     }
 
     // 5. 整理完之后,获取指标数据,进行逻辑判断,注意与/或只是指过滤器,如果选择了多交易所,交易所的逻辑部分都是与
@@ -169,6 +169,7 @@ pub async fn get_symbols(_mode: &str, exchanges: &Vec<String>, minute_time_range
     //      选择了gate_usdt_swap与bitget_usdt_swap两个交易所,并且对交易量进行了0.5M的过滤
     //      两个交易所都有xrp,如果gate与bitget的xrp交易量都大于0.5M,则会显示在最终列表中
     // 最终过滤
+    let response_value = symbols_filter(temp_value.as_array().unwrap(), filters, mode, exchanges);
     let response = Response {
         query: Value::Null,
         msg: Some("排行榜生成完毕".to_string()),
@@ -180,6 +181,122 @@ pub async fn get_symbols(_mode: &str, exchanges: &Vec<String>, minute_time_range
     HttpResponse::Ok().content_type("application/json").body(json_string)
 }
 
+fn symbols_filter(symbols: &Vec<Value>, filters: &Vec<Value>, mode: &str, exchanges: &Vec<String>) -> Value {
+    let mut rst = json!([]);
+
+    // 进行symbols的过滤
+    for symbol in symbols {
+        let mut is_valid = match mode {
+            "and" => {
+                true
+            },
+            "or" => {
+                false
+            }
+            _ => {
+                panic!("{}", format!("无法识别的模式: {}", mode))
+            }
+        };
+
+        // 过滤器功能启动
+        for filter in filters {
+            let filter_rst = match filter["target"].as_str().unwrap() {
+                "R" => {
+                    rise_filter(symbol, filter, exchanges)
+                },
+                "V" => {
+                    volume_filter(symbol, filter, exchanges)
+                },
+                "ROA" => {
+                    rise_of_abs_filter(symbol, filter, exchanges)
+                },
+                _ => {
+                    panic!("{}", format!("无法识别的过滤器: {}", filter["target"].as_str().unwrap()))
+                }
+            };
+
+            // 结果识别器
+            is_valid = match mode {
+                "and" => {
+                    is_valid && filter_rst
+                },
+                "or" => {
+                    is_valid || filter_rst
+                }
+                _ => {
+                    panic!("{}", format!("无法识别的模式: {}", mode))
+                }
+            };
+
+            if !is_valid {
+                break
+            }
+        }
+
+        // 如果是有效的币,就塞到结果里
+        if is_valid {
+            rst.as_array_mut().unwrap().push(symbol.clone())
+        }
+    }
+
+    return rst
+}
+
+// 涨跌幅过滤器
+fn rise_filter(symbol: &Value, filter: &Value, exchanges: &Vec<String>) -> bool {
+    let rise_limit = Decimal::from_str(filter["value"].as_str().unwrap().to_string().as_str()).unwrap();
+    let mut rst = true;
+
+    for exchange in exchanges {
+        let rise_map = symbol["rise"].clone();
+        let rise = Decimal::from_str(rise_map[exchange].as_str().unwrap().to_string().as_str()).unwrap();
+
+        rst = rst && rise > rise_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();
+    let mut rst = true;
+
+    for exchange in exchanges {
+        let volume_map = symbol["volume"].clone();
+        let volume = Decimal::from_str(volume_map[exchange].as_str().unwrap().to_string().as_str()).unwrap();
+
+        rst = rst && volume > volume_limit;
+        if !rst {
+            break
+        }
+    }
+
+    return rst
+}
+
+// 涨跌幅绝对值过滤器
+fn rise_of_abs_filter(symbol: &Value, filter: &Value, exchanges: &Vec<String>) -> bool {
+    let rise_limit = Decimal::from_str(filter["value"].as_str().unwrap().to_string().as_str()).unwrap();
+    let mut rst = true;
+
+    for exchange in exchanges {
+        let rise_map = symbol["rise"].clone();
+        let rise = Decimal::from_str(rise_map[exchange].as_str().unwrap().to_string().as_str()).unwrap().abs();
+
+        rst = rst && rise > rise_limit;
+        if !rst {
+            break
+        }
+    }
+
+    return rst
+}
+
+
 #[tokio::test]
 async fn get_public_symbols_test() {
     use global::log_utils::init_log_with_info;