| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- use std::cmp::{min};
- use std::collections::HashMap;
- use rust_decimal::{Decimal, MathematicalOps};
- use rust_decimal_macros::dec;
- use serde::{Deserialize, Serialize};
- use serde_json::Value;
- use tokio::sync::MutexGuard;
- use crate::msv::Indicators;
- #[derive(Serialize, Deserialize, Clone)]
- pub struct Rank {
- symbol: String,
- score: Decimal,
- msv_score: Decimal,
- liquidity_score: Decimal,
- frequency_score: Decimal,
- msv_abs_total: Decimal,
- msv_abs_max: Decimal,
- msv_abs_avg: Decimal,
- coverted_open_base: Decimal,
- epr_total: Decimal,
- effective_count: Decimal,
- liquidity_avg: Decimal,
- }
- const TWENTY: Decimal = dec!(20);
- const SIXTY: Decimal = dec!(60);
- const TWO_HUNDRED: Decimal = dec!(200);
- // const TEN_THOUSAND: Decimal = dec!(10000);
- // 根据最终的msv计算排行榜
- pub fn generate_rank_by_indicator_map(indicator_map: &MutexGuard<HashMap<String, Indicators>>) -> Value {
- let mut rank_list: Vec<Rank> = vec![];
- for (key, indicators) in indicator_map.iter() {
- let symbol = key.clone();
- // ============== msv相关数据的计算 =================
- let mut msv_abs_total = Decimal::ZERO;
- let mut msv_abs_max = Decimal::ZERO;
- let mut effective_count = Decimal::ZERO;
- for value in indicators.msv.iter() {
- let msv_abs_value = value[1].abs();
- if msv_abs_value <= Decimal::ZERO {
- continue
- }
- effective_count += Decimal::ONE;
- msv_abs_total += msv_abs_value;
- if msv_abs_value > msv_abs_max {
- msv_abs_max = msv_abs_value
- }
- }
- let mut msv_abs_avg = if effective_count == Decimal::ZERO {
- Decimal::ZERO
- } else {
- msv_abs_total / effective_count
- };
- msv_abs_avg.rescale(6);
- let mut coverted_open_base = (msv_abs_max + msv_abs_avg) / TWO_HUNDRED;
- coverted_open_base.rescale(8);
- // ============== epr相关数据的计算 =================
- let mut epr_total = Decimal::ZERO;
- for value in indicators.eprs.iter() {
- epr_total += value[1];
- }
- // ============== liq相关数据的计算 =================
- let mut liquidity_total = Decimal::ZERO;
- for value in indicators.liqs.iter() {
- liquidity_total += value[1] * Decimal::ONE_THOUSAND;
- }
- let mut liquidity_avg = if effective_count == Decimal::ZERO {
- Decimal::ZERO
- } else {
- liquidity_total / effective_count
- };
- liquidity_avg.rescale(0);
- // ======================== 最终计算 =========================
- // msv_score计算规则
- let mut msv_score = if msv_abs_total > Decimal::ZERO && epr_total > Decimal::ZERO {
- ((msv_abs_max * epr_total / msv_abs_total) * SIXTY).powd(Decimal::TWO)
- } else {
- Decimal::ZERO
- };
- msv_score.rescale(2);
- // liquidity_score
- let mut liquidity_score = min(liquidity_avg / Decimal::ONE_THOUSAND, TWENTY);
- liquidity_score.rescale(2);
- // frequency_score计算规则
- let mut frequency_score = (effective_count / Decimal::ONE_THOUSAND) * TWENTY;
- frequency_score.rescale(2);
- let temp = msv_score * liquidity_score * frequency_score;
- let mut score = if temp > Decimal::ONE {
- Decimal::TEN * temp.log10()
- } else {
- Decimal::ZERO
- };
- score.rescale(2);
- let rank = Rank {
- symbol,
- score,
- msv_score,
- liquidity_score,
- frequency_score,
- msv_abs_total,
- msv_abs_max,
- msv_abs_avg,
- coverted_open_base,
- epr_total,
- effective_count,
- liquidity_avg,
- };
- rank_list.push(rank);
- }
- // 按 score 倒序排序
- rank_list.sort_by(|a, b| b.score.cmp(&a.score));
- return serde_json::to_value(&rank_list).unwrap();
- }
|