Joey 1 неделя назад
Родитель
Сommit
7e80cc425c
2 измененных файлов с 83 добавлено и 1 удалено
  1. 71 0
      modules/rankingCalculator.dos
  2. 12 1
      modules/task_monthlyPerformance.dos

+ 71 - 0
modules/rankingCalculator.dos

@@ -331,9 +331,80 @@ def cal_indicator_ranking(ranking_by, entity_type, entity_info, end_date, isFrom
 
     v_ranking_tables = run_ranking_sql(entity_type, ranking_by, v[0], v[1]);
 
+    // 计算二级策略及BFI的收益和alpha的1-3-5年综合分数
+    if( ranking_by == 'strategy' && v_ranking_tables.size() == 4 || ranking_by == 'bfi') {
+
+    	// 二级策略的排名表是 v_ranking_tables[2]
+    	i = iif(ranking_by == 'bfi', 0, 2);
+		// 三年权重分别是 60% 近5年 + 30% 近3年 + 10% 近1年; 或 75% 近3年 + 25 近1年; 或 100% 近1年
+		v_ranking_tables[i].addColumn(['absrank_summary_score', 'perrank_summary_score', 'summary_score'], [INT, INT, DOUBLE]);
+		UPDATE v_ranking_tables[i]
+			SET summary_score = iif(perrank_1y >= 0 && perrank_3y >= 0 && perrank_5y >= 0, (5- ceil(perrank_1y\25))*0.1 + (5- ceil(perrank_3y\25))*0.3 + (5- ceil(perrank_5y\25))*0.6,
+			                        iif(perrank_1y >= 0 && perrank_3y >= 0, (5- ceil(perrank_1y\25))*0.25 + (5- ceil(perrank_3y\25))*0.75,
+			                            iif(perrank_1y >= 0, 5- ceil(perrank_1y\25), NULL)))
+        WHERE indicator_id IN [1, 11];
+	
+		// 计算综合分数排名
+		UPDATE v_ranking_tables[i]
+			SET absrank_summary_score = rank(summary_score, false),
+			    perrank_summary_score = perRank(summary_score, false)
+		WHERE indicator_id IN [1, 11]
+		CONTEXT BY end_date, category_id, indicator_id;		
+    }
+
     return v_ranking_tables;
 }
 
+/*
+ *   通用主收益因子排名计算 - 用于 tamp 的基金推荐
+ *   
+ *   Example: cal_indicator_ranking_for_propose(2025.01M, true);
+ */
+def cal_indicator_ranking_for_propose(end_date, isFromMySQL=true) {
+
+	// 取基金所有因子
+	tb_fund_factor = get_monthly_indicator_data('pfdb.pf_fund_factor_bfi_by_category_group', end_date, isFromMySQL);
+
+	// 提取主因子 (R2最大的因子)
+    tb_main_factor = SELECT TOP 1 fund_id AS entity_id, end_date, factor_id
+                     FROM tb_fund_factor
+                     WHERE isvalid = 1
+                     CONTEXT BY fund_id CSORT r2 DESC
+                     ORDER BY fund_id;
+
+	if(tb_main_factor.isVoid() || tb_main_factor.size() == 0) return null;
+
+	tb_entity_info = get_entity_info('MF', tb_main_factor.entity_id);
+
+	// 取各区间收益及alpha
+	tb_data_return = get_monthly_indicator_data('mfdb.fund_performance', end_date, isFromMySQL);
+	tb_bfi = get_monthly_indicator_data('mfdb.fund_ty_bfi_bm_indicator', end_date, isFromMySQL);
+
+	if(tb_data_return.isVoid() || tb_data_return.size() == 0 || tb_bfi.isVoid() || tb_bfi.size() == 0) return null;
+	
+	t = SELECT *, factor_id AS category_id FROM ej(tb_entity_info, ej(ej(tb_main_factor, tb_data_return, 'entity_id', 'fund_id'), tb_bfi, ['fund_id', 'factor_id']), 'entity_id');
+
+	// 只需要收益和alpha指标
+	indicator_table = SELECT * FROM get_indicator_info() WHERE id IN [1, 11];
+
+	// 排名
+    v_ranking_tables = run_ranking_sql('MF', 'bfi', t, indicator_table);
+
+    // 计算收益和alpha的1-3-5年综合分数
+    v_ranking_tables[0].addColumn(['absrank_summary_score', 'perrank_summary_score', 'summary_score'], [INT, INT, DOUBLE]);
+	UPDATE v_ranking_tables[0]
+		SET summary_score = iif(perrank_1y >= 0 && perrank_3y >= 0 && perrank_5y >= 0, (5- ceil(perrank_1y\25))*0.1 + (5- ceil(perrank_3y\25))*0.3 + (5- ceil(perrank_5y\25))*0.6,
+		                        iif(perrank_1y >= 0 && perrank_3y >= 0, (5- ceil(perrank_1y\25))*0.25 + (5- ceil(perrank_3y\25))*0.75,
+		                            iif(perrank_1y >= 0, 5- ceil(perrank_1y\25), NULL)));
+
+	// 计算综合分数排名
+	UPDATE v_ranking_tables[0]
+		SET absrank_summary_score = rank(summary_score, false),
+		    perrank_summary_score = perRank(summary_score, false)
+	CONTEXT BY end_date, category_id, indicator_id;		
+
+    return v_ranking_tables;
+}
 
 /*
  *   将源指标表横表变竖表,以方便参考排名计算

+ 12 - 1
modules/task_monthlyPerformance.dos

@@ -24,7 +24,7 @@ use fundit::navCalculator;
  */
 def CalEntityRankingTask(entityType, endDate, isFromMySQL=true) {
 //entityType='MF'
-//endDate = 2024.12M
+//endDate = 2025.01M
 //isFromMySQL = true
 	if(!(entityType in ['MF', 'HF', 'PL', 'CO'])) return NULL;
 	
@@ -57,6 +57,17 @@ def CalEntityBfiRankingTask(entityType, endDate, isFromMySQL=true) {
 	// 39 sec
     save_ranking_tables(entityType, 'bfi', v_ranking_tables);
 
+	// 用于 Tamp 基金推荐的主因子排名
+    v_ranking_tables = cal_indicator_ranking_for_propose(endDate, isFromMySQL);
+
+    t1 = v_ranking_tables[0];
+	t1.rename!(['entity_id', 'category_id'], ['fund_id', 'factor_id']);
+    save_and_sync(t1, 'raw_db.pf_fund_bfi_bm_indicator_ranking_for_propose', , 'fund_id', 'end_date');
+
+    t2 = v_ranking_tables[1];
+    t2.rename!('category_id', 'factor_id');
+    save_and_sync(t2, 'raw_db.pf_fund_bfi_bm_indicator_ranking_for_propose_num', , '', 'end_date');
+
 }
 
 /*