|
|
@@ -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();
|