浏览代码

支持组合bfi排名

Joey 4 月之前
父节点
当前提交
d3d5c4f14f
共有 4 个文件被更改,包括 164 次插入270 次删除
  1. 42 0
      modules/dataPuller.dos
  2. 80 221
      modules/rankingCalculator.dos
  3. 22 0
      modules/sqlUtilities.dos
  4. 20 49
      modules/task_monthlyPerformance.dos

+ 42 - 0
modules/dataPuller.dos

@@ -1035,6 +1035,48 @@ def get_fund_indicator_substrategy_ranking(fund_ids, end_date, substrategy, isFr
 
 
 }
 }
 
 
+
+/*
+ *  取 pf_fund_bfi_bm_indicator_ranking 表
+ *  
+ *  
+ *  Example: get_fund_bfi_bm_indicator_ranking("'MF00003PW1'", 2024.09M, NULL, true);
+ *  
+ */
+def get_fund_bfi_bm_indicator_ranking(fund_ids, end_date, factor_ids, isFromMySQL=true) {
+
+    t = null;
+
+    s_entity_ids = ids_to_string(fund_ids);
+    sql_entity_id = '';
+    if(s_entity_ids != NULL) sql_entity_id = " AND fund_id IN (" + s_entity_ids + ")";
+
+    s_factor_ids = ids_to_string(factor_ids);
+    sql_factor_id = '';
+    if(s_factor_ids != NULL) sql_factor_id = " AND factor_id IN (" + s_factor_ids + ")";
+
+
+    if(isFromMySQL == true) {
+
+        s_query = "SELECT * 
+                   FROM pfdb.pf_fund_bfi_bm_indicator_ranking 
+                   WHERE isvalid = 1 
+                     AND end_date = '" + end_date.temporalFormat('yyyy-MM') + "'" +
+                     sql_factor_id +
+                     sql_entity_id;
+
+        conn = connect_mysql();
+     
+        t = odbc::query(conn, s_query);
+     
+        conn.close();
+    }
+
+    return t;
+
+}
+
+
 /*
 /*
  *  【Morningstar Integration】取某时间后净值更新的公募基金列表
  *  【Morningstar Integration】取某时间后净值更新的公募基金列表
  *
  *

+ 80 - 221
modules/rankingCalculator.dos

@@ -150,15 +150,15 @@ def gen_ranking_sql(data_table, indicator_table) {
  * 
  * 
  *
  *
  */
  */
-def run_ranking_sql(cal_type, mutable data_table, indicator_table) {
+def run_ranking_sql(ranking_by, mutable data_table, indicator_table) {
 
 
 // data_table = t
 // data_table = t
 // v_tables = v_ranking_tables
 // v_tables = v_ranking_tables
-// cal_type = 'strategy'
+// ranking_by = 'strategy'
 
 
     ret = array(ANY, 0);
     ret = array(ANY, 0);
 
 
-	if(cal_type == 'bfi') {
+	if(ranking_by == 'bfi') {
 
 
         UPDATE data_table SET category_id = factor_id;
         UPDATE data_table SET category_id = factor_id;
 
 
@@ -189,21 +189,18 @@ def run_ranking_sql(cal_type, mutable data_table, indicator_table) {
 	return ret;
 	return ret;
 }
 }
 
 
-
 /*
 /*
- *   通用指标排名计算
+ *   为排名做数据准备
+ *   
+ *   @return <VECTOR>: 包含两个表,一个指标数据表,一个是指标信息表
  *   
  *   
- *   @param cal_type <STRING>: strategy, bfi
- * 
  */
  */
-def cal_indicator_ranking(cal_type, entity_type, entity_info, end_date, isFromMySQL) {
-
-    // 当前只对基金做排名, 其它类型参考基金排名做相对排名
-    if(!(entity_type in ['MF', 'HF'])) return null;
+def prepare_data_for_ranking(ranking_by, entity_type, entity_info, end_date, isFromMySQL=true) {
 
 
 	// return
 	// return
 	table_desc = get_performance_table_description(entity_type);
 	table_desc = get_performance_table_description(entity_type);
 	tb_data_return = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 	tb_data_return = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
+	entity_id_name = table_desc.sec_id_col[0];
 	// risk
 	// risk
 	table_desc = get_risk_stats_table_description(entity_type);
 	table_desc = get_risk_stats_table_description(entity_type);
 	tb_data_risk_stats = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 	tb_data_risk_stats = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
@@ -214,13 +211,15 @@ def cal_indicator_ranking(cal_type, entity_type, entity_info, end_date, isFromMy
 	table_desc = get_indicator_table_description(entity_type);
 	table_desc = get_indicator_table_description(entity_type);
 	tb_data_indicator_stats = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 	tb_data_indicator_stats = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 
 
-	tb_data = SELECT * 
-	          FROM tb_data_return d1
-	          LEFT JOIN tb_data_indicator_stats d2 ON d1.fund_id = d2.fund_id AND d1.end_date = d2.end_date
-	          LEFT JOIN tb_data_risk_stats d3 ON d1.fund_id = d3.fund_id AND d1.end_date = d3.end_date
-	          LEFT JOIN tb_data_riskadjret_stats d4 ON d1.fund_id = d4.fund_id AND d1.end_date = d4.end_date;
+    // 做个大宽表
+	matchingCols = [entity_id_name, 'end_date'];
+	tb_data = lj(lj(lj(tb_data_return, tb_data_indicator_stats, matchingCols), tb_data_risk_stats, matchingCols), tb_data_riskadjret_stats, matchingCols);
 
 
-	if(cal_type == 'bfi') {
+	if(ranking_by == 'bfi') {
+
+		// bfi table
+		table_desc = get_bfi_by_category_group_table_description(entity_type);
+		tb_bfi = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 
 
 		// bfi (as benchmark) indicator
 		// bfi (as benchmark) indicator
 		table_desc = get_bfi_indicator_table_description(entity_type);
 		table_desc = get_bfi_indicator_table_description(entity_type);
@@ -234,8 +233,8 @@ def cal_indicator_ranking(cal_type, entity_type, entity_info, end_date, isFromMy
         
         
         tb_data.dropColumns!(v_dup_col);
         tb_data.dropColumns!(v_dup_col);
 
 
-		tb_data = SELECT * FROM tb_data d1
-		          LEFT JOIN tb_data_bfi_indicator d2 ON d1.fund_id = d2.fund_id AND d1.end_date = d2.end_date;
+		matchingCols2 = [entity_id_name, 'end_date', 'factor_id'];
+		tb_data = lj(ej(tb_data, tb_bfi, matchingCols), tb_data_bfi_indicator, matchingCols2);
 
 
     	v_indicator_id = [1,                                       // 对应 fund_performance, 取消39(年化收益) 因为没有意义
     	v_indicator_id = [1,                                       // 对应 fund_performance, 取消39(年化收益) 因为没有意义
                 	      41, 42, 49,                              // 对应 fund_indicator, 取消37 (per_con), 43, 44, 45, 46, 47 (smdd模型) 因为dolphin 未计算
                 	      41, 42, 49,                              // 对应 fund_indicator, 取消37 (per_con), 43, 44, 45, 46, 47 (smdd模型) 因为dolphin 未计算
@@ -251,8 +250,7 @@ def cal_indicator_ranking(cal_type, entity_type, entity_info, end_date, isFromMy
 		table_desc = get_capture_style_table_description(entity_type);
 		table_desc = get_capture_style_table_description(entity_type);
 		tb_data_capture_stats = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 		tb_data_capture_stats = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
 
 
-		tb_data = SELECT * FROM tb_data d1
-		          LEFT JOIN tb_data_capture_stats d2 ON d1.fund_id = d2.fund_id AND d1.end_date = d2.end_date;
+		tb_data = lj(tb_data, tb_data_capture_stats, matchingCols);
 
 
     	v_indicator_id = [1,                                // 对应 fund_performance, 取消39(年化收益) 因为没有意义
     	v_indicator_id = [1,                                // 对应 fund_performance, 取消39(年化收益) 因为没有意义
     					  38, 41, 42, 48, 49,               // 对应 fund_indicator, 取消37 (per_con), 43, 44, 45, 46, 47 (smdd模型) 因为dolphin 未计算
     					  38, 41, 42, 48, 49,               // 对应 fund_indicator, 取消37 (per_con), 43, 44, 45, 46, 47 (smdd模型) 因为dolphin 未计算
@@ -263,79 +261,86 @@ def cal_indicator_ranking(cal_type, entity_type, entity_info, end_date, isFromMy
 
 
     }
     }
 
 
-	sec_id_col = table_desc.sec_id_col[0];
-	tb_data.rename!(sec_id_col, 'entity_id');
+	tb_data.rename!(entity_id_name, 'entity_id');
 
 
-	t = SELECT *
-        FROM entity_info en 
+	t = SELECT * FROM entity_info en
         INNER JOIN tb_data d ON en.entity_id = d.entity_id
         INNER JOIN tb_data d ON en.entity_id = d.entity_id
 	    WHERE en.strategy IS NOT NULL;
 	    WHERE en.strategy IS NOT NULL;
+
+	if(ranking_by == 'bfi')
+		UPDATE t SET category_id = factor_id;
+	else if(ranking_by == 'substrategy')
+		UPDATE t SET category_id = substrategy$STRING;
+	else
+		UPDATE t SET category_id = strategy$STRING;
+	
     
     
     indicator_table = SELECT * FROM get_indicator_info() WHERE id IN v_indicator_id;
     indicator_table = SELECT * FROM get_indicator_info() WHERE id IN v_indicator_id;
 
 
-    v_ranking_tables = run_ranking_sql(cal_type, t, indicator_table);
+    return t, indicator_table;
+}
+
+/*
+ *   通用指标排名计算
+ *   
+ *   @param ranking_by <STRING>: strategy, bfi
+ * 
+ */
+def cal_indicator_ranking(ranking_by, entity_type, entity_info, end_date, isFromMySQL=true) {
+
+    // 当前只对基金做排名, 其它类型参考基金排名做相对排名
+    if(!(entity_type in ['MF', 'HF'])) return null;
+
+	v = prepare_data_for_ranking(ranking_by, entity_type, entity_info, end_date, isFromMySQL);
+
+    v_ranking_tables = run_ranking_sql(ranking_by, v[0], v[1]);
 
 
     return v_ranking_tables;
     return v_ranking_tables;
 }
 }
 
 
 
 
 /*
 /*
- *   将源指标表横表变竖表,以方便排名计算
+ *   将源指标表横表变竖表,以方便参考排名计算
  * 
  * 
  * 
  * 
  */
  */
-def transform_data_for_ranking(entity_type, data_table, ranking_by, indicator_info) {
-
-    // 只有收益需要1m, 3m
-    if(indicator_info.size() == 1 && indicator_info[0].id == 1 )
-		v_trailing = ['1m', '3m', '6m', '1y', '2y', '3y', '5y', '10y', 'ytd'];
-	else
-	    v_trailing = ['6m', '1y', '2y', '3y', '5y', '10y', 'ytd'];
+def run_transformation_sql(entity_type, data_table, ranking_by, indicator_info) {
 
 
     // 只有 portfolio_id 是整型,其它的都是字符串
     // 只有 portfolio_id 是整型,其它的都是字符串
     is_id_integer = false;
     is_id_integer = false;
     if(entity_type == 'PF') is_id_integer = true;
     if(entity_type == 'PF') is_id_integer = true;
 
 
-    if(ranking_by == 'strategy') 
-		tb_ranking = create_entity_indicator_ranking(is_id_integer).rename!(ranking_by, 'category_id');
-	else if(ranking_by == 'substrategy')
-		tb_ranking = create_entity_indicator_substrategy_ranking(is_id_integer).rename!(ranking_by, 'category_id');
-	else if(ranking_by == 'factor_id')
-	    tb_ranking = NULL;
+	tb_ranking = create_entity_indicator_ranking(is_id_integer);
 
 
     for(indicator in indicator_info) {
     for(indicator in indicator_info) {
 
 
+	    // 只有收益需要1m, 3m
+    	if(indicator.id == 1)
+    		v_trailing = ['1m', '3m', '6m', '1y', '2y', '3y', '5y', '10y', 'ytd'];
+    	else {
+    		v_trailing = ['6m', '1y', '2y', '3y', '5y', '10y', 'ytd'];
+    		v_missing = ['1m', '3m'];
+    	}
+
         t = sql(select = (sqlCol(['entity_id', 'end_date', 'category_id']), <indicator.id as indicator_id>,
         t = sql(select = (sqlCol(['entity_id', 'end_date', 'category_id']), <indicator.id as indicator_id>,
                           sqlCol(indicator.name + '_' + v_trailing,, 'indicator_' + v_trailing)
                           sqlCol(indicator.name + '_' + v_trailing,, 'indicator_' + v_trailing)
                          ),
                          ),
                 from = data_table
                 from = data_table
         	   ).eval();
         	   ).eval();
 
 
-        if(indicator_info.size() > 1 || indicator_info[0].id <> 1 )
+		// 给非收益指标补上1m, 3m的三套指标
+        if(indicator.id != 1 )
         {
         {
-	        t.join!(table(take(double(NULL), t.size()) AS indicator_1m,
-                          take(double(NULL), t.size()) AS indicator_3m) );
+        	v_tmp_col = ['indicator_' + v_missing, 'absrank_' + v_missing, 'perrank_' + v_missing].flatten();
+        	v_tmp_type = [take(DOUBLE, v_missing.size()), take(INT, v_missing.size()), take(INT, v_missing.size())].flatten();
+	    	t.addColumn(v_tmp_col, v_tmp_type);
         }
         }
 
 
-        t.join!(table( take(int(NULL), t.size()) AS absrank_1m,
-                       take(int(NULL), t.size()) AS perrank_1m,
-                       take(int(NULL), t.size()) AS absrank_3m,
-                       take(int(NULL), t.size()) AS perrank_3m,
-                       take(int(NULL), t.size()) AS absrank_6m,
-                       take(int(NULL), t.size()) AS perrank_6m,
-                       take(int(NULL), t.size()) AS absrank_1y,
-                       take(int(NULL), t.size()) AS perrank_1y,
-                       take(int(NULL), t.size()) AS absrank_2y,
-                       take(int(NULL), t.size()) AS perrank_2y,
-                       take(int(NULL), t.size()) AS absrank_3y,
-                       take(int(NULL), t.size()) AS perrank_3y,
-                       take(int(NULL), t.size()) AS absrank_5y,
-                       take(int(NULL), t.size()) AS perrank_5y,
-                       take(int(NULL), t.size()) AS absrank_10y,
-                       take(int(NULL), t.size()) AS perrank_10y,
-                       take(int(NULL), t.size()) AS absrank_ytd,
-                       take(int(NULL), t.size()) AS perrank_ytd )
-    	       );
+		// 给所有指标补上 absrank 和 perrank 两套指标
+    	v_tmp_col = ['absrank_' + v_trailing, 'perrank_' + v_trailing].flatten();
+    	v_tmp_type = [take(INT, v_trailing.size()), take(INT, v_trailing.size())].flatten();
+
+        t.addColumn(v_tmp_col, v_tmp_type);
        
        
         INSERT INTO tb_ranking
         INSERT INTO tb_ranking
             SELECT * FROM (sql(select = sqlCol(tb_ranking.colNames()),
             SELECT * FROM (sql(select = sqlCol(tb_ranking.colNames()),
@@ -345,169 +350,24 @@ def transform_data_for_ranking(entity_type, data_table, ranking_by, indicator_in
     return tb_ranking;
     return tb_ranking;
 }
 }
 
 
-
 /*
 /*
  *   将源风险指标表横表变竖表,以方便排名计算
  *   将源风险指标表横表变竖表,以方便排名计算
  * 
  * 
  *   
  *   
  */
  */
-def transform_return_for_ranking (entity_type, entity_info, end_date, ranking_by, isFromMySQL=true) {
-
-	table_desc = get_performance_table_description(entity_type);
-
-	tb_data = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
-	sec_id_col = table_desc.sec_id_col[0];
-	tb_data.rename!(sec_id_col, 'entity_id');
-
-	data_table = SELECT * FROM entity_info en 
-                 INNER JOIN tb_data d ON en.entity_id = d.entity_id
-	             WHERE en.strategy IS NOT NULL
-
-    data_table.dropColumns!('id');
-    data_table.rename!(ranking_by, 'category_id');
-
-
-    // 目前SQL排名的指标还包含39:年化收益,与收益没有什么差别所以被取消
-    v_indicator_name = ['ret'];
-    v_indicator_id = [1];
-    v_is_ASC = [false];
-    t_indicator = table(v_indicator_name AS name, v_indicator_id AS id, v_is_ASC AS is_ASC);
-
-    tb_ranking = transform_data_for_ranking(entity_type, data_table, ranking_by, t_indicator).rename!('category_id', ranking_by);
-
-    return tb_ranking;
-}
-
-
-/*
- *   将源风险指标表横表变竖表,以方便排名计算
- * 
- *
- */
-def transform_risk_stats_for_ranking (entity_type, entity_info, end_date, ranking_by, isFromMySQL=true) {
-
-	table_desc = get_risk_stats_table_description(entity_type);
-
-	tb_data = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
-	sec_id_col = table_desc.sec_id_col[0];
-	tb_data.rename!(sec_id_col, 'entity_id');
-
-	data_table = SELECT * FROM entity_info en 
-                 INNER JOIN tb_data d ON en.entity_id = d.entity_id
-	             WHERE en.strategy IS NOT NULL
-
-    data_table.dropColumns!('id');
-    data_table.rename!(ranking_by, 'category_id');
-
-
-    // 目前SQL排名的指标
-    v_indicator_name = ['maxdrawdown', 'kurtosis', 'skewness', 'stddev', 'alpha', 'beta', 'downsidedev', 'maxdrawdown_months', 'maxdrawdown_recoverymonths', 'winrate'];
-    v_indicator_id = [2, 6, 9, 10, 11, 12, 21, 50, 52, 59];
-    v_is_ASC = [true, true, false, true, false, false, true, true, true, false];
-    t_indicator = table(v_indicator_name AS name, v_indicator_id AS id, v_is_ASC AS is_ASC);
-
-    tb_ranking = transform_data_for_ranking(entity_type, data_table, ranking_by, t_indicator).rename!('category_id', ranking_by);
-
-    return tb_ranking;
-}
-
-
-/*
- *   将源风险调整指标表横表变竖表,以方便排名计算
- * 
- * 
- */
-def transform_risk_adj_ret_stats_for_ranking (entity_type, entity_info, end_date, ranking_by, isFromMySQL=true) {
-
-	table_desc = get_riskadjret_stats_table_description(entity_type);
-
-	tb_data = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
-	sec_id_col = table_desc.sec_id_col[0];
-	tb_data.rename!(sec_id_col, 'entity_id');
-
-	data_table = SELECT * FROM entity_info en 
-                 INNER JOIN tb_data d ON en.entity_id = d.entity_id
-	             WHERE en.strategy IS NOT NULL
-
-    data_table.dropColumns!('id');
-    data_table.rename!(ranking_by, 'category_id');
-
-    // 目前SQL排名的指标
-    v_indicator_name = ['kapparatio', 'treynorratio', 'jensen', 'omegaratio', 'sharperatio', 'sortinoratio_MAR', 'calmarratio', 'sortinoratio'];
-    v_indicator_id = [14, 15, 16, 17, 18, 19, 40, 58];
-    v_is_ASC = [false, false, false, false, false, false, false, false];
-    t_indicator = table(v_indicator_name AS name, v_indicator_id AS id, v_is_ASC AS is_ASC);
-
-    tb_ranking = transform_data_for_ranking(entity_type, data_table, ranking_by, t_indicator).rename!('category_id', ranking_by);
-
-    return tb_ranking;
-}
-
-
-/*
- *   将源杂项风险指标表横表变竖表,以方便排名计算
- * 
- * 
- */
-def transform_other_indicator_for_ranking (entity_type, entity_info, end_date, ranking_by, isFromMySQL=true) {
+def transform_data_for_ranking (entity_type, entity_info, end_date, ranking_by, isFromMySQL=true) {
 
 
-	table_desc = get_indicator_table_description(entity_type);
+	if(entity_info.isVoid() || entity_info.size() == 0) return null;
 
 
-	tb_data = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
-	sec_id_col = table_desc.sec_id_col[0];
-	tb_data.rename!(sec_id_col, 'entity_id');
+	v = prepare_data_for_ranking(ranking_by, entity_type, entity_info, end_date, isFromMySQL);
 
 
-	data_table = SELECT * FROM entity_info en 
-                 INNER JOIN tb_data d ON en.entity_id = d.entity_id
-	             WHERE en.strategy IS NOT NULL
-
-    data_table.dropColumns!('id');
-    data_table.rename!(ranking_by, 'category_id');
-
-    // 目前SQL排名的指标
-    v_indicator_name = ['per_con', 'info_ratio', 'var', 'cvar', 'smddvar', 'smddcvar', 'smdd_lpm1', 'smdd_lpm2', 'smdd_downside_dev', 'tracking_error', 'm2'];
-    v_indicator_id = [37, 38, 41, 42, 43, 44, 45, 46, 47, 48, 49];
-    v_is_ASC = [false, false, true, true, true, true, true, true, true, true, false];
-    t_indicator = table(v_indicator_name AS name, v_indicator_id AS id, v_is_ASC AS is_ASC);
-
-    tb_ranking = transform_data_for_ranking(entity_type, data_table, ranking_by, t_indicator).rename!('category_id', ranking_by);
+    tb_ranking = run_transformation_sql(entity_type, v[0], ranking_by, v[1]);
 
 
     return tb_ranking;
     return tb_ranking;
 }
 }
 
 
 
 
 /*
 /*
- *   将源杂项风险指标表横表变竖表,以方便排名计算
- * 
- * 
- */
-def transform_capture_style_for_ranking (entity_type, entity_info, end_date, ranking_by, isFromMySQL=true) {
-
-	table_desc = get_capture_style_table_description(entity_type);
-
-	tb_data = get_monthly_indicator_data(table_desc.table_name[0], end_date, isFromMySQL);
-	sec_id_col = table_desc.sec_id_col[0];
-	tb_data.rename!(sec_id_col, 'entity_id');
-
-	data_table = SELECT * FROM entity_info en 
-                 INNER JOIN tb_data d ON en.entity_id = d.entity_id
-	             WHERE en.strategy IS NOT NULL
-
-    data_table.dropColumns!('id');
-    data_table.rename!(ranking_by, 'category_id');
-
-    // 目前SQL排名的指标
-    v_indicator_name = ['upsidecapture_ret', 'downsidecapture_ret', 'upsidecapture_ratio', 'downsidecapture_ratio'];
-    v_indicator_id = [33, 34, 35, 36];
-    v_is_ASC = [false, false, false, true];
-    t_indicator = table(v_indicator_name AS name, v_indicator_id AS id, v_is_ASC AS is_ASC);
-
-    tb_ranking = transform_data_for_ranking(entity_type, data_table, ranking_by, t_indicator).rename!('category_id', ranking_by);
-
-    return tb_ranking;
-}
-
-/*
  * 
  * 
  *   参考某指定类排名,计算相对排名
  *   参考某指定类排名,计算相对排名
  *   
  *   
@@ -571,18 +431,17 @@ def cal_relative_ranking(benchmark_ranking, mutable entity_ranking, isFromMySQL=
 /*
 /*
  *  排名数据入库
  *  排名数据入库
  * 
  * 
- *  @param cal_type
- *  @param ranking_tables <VECTOR>: 当 cal_type = 'strategy' 时包含4个数据表的向量,分别是一级策略排名,一级策略排名阈值,二级策略排名,二级策略排名阈值
- *                                     cal_type = 'bfi' 时包含2个数据表的向量,分别是bfi策略排名,bfi策略排名阈值
+ *  @param ranking_by <STRING>: 'strategy', 'bfi'
+ *  @param ranking_tables <VECTOR>: 当 ranking_by = 'strategy' 时包含4个数据表的向量,分别是一级策略排名,一级策略排名阈值,二级策略排名,二级策略排名阈值
+ *                                     ranking_by = 'bfi' 时包含2个数据表的向量,分别是bfi策略排名,bfi策略排名阈值
  */
  */
-def save_ranking_tables(cal_type, ranking_tables) {
-//cal_type = 'bfi'
-//ranking_tables=v_ranking_tables
+def save_ranking_tables(ranking_by, ranking_tables) {
+
     if(ranking_tables.isVoid()) return;
     if(ranking_tables.isVoid()) return;
 
 
     entity_id_col = 'fund_id';
     entity_id_col = 'fund_id';
     
     
-	if(cal_type == 'bfi') {
+	if(ranking_by == 'bfi') {
 
 
 	  	source_table = 'raw_db.pf_fund_bfi_bm_indicator_ranking';
 	  	source_table = 'raw_db.pf_fund_bfi_bm_indicator_ranking';
    		target_table = 'raw_db.pf_fund_bfi_bm_indicator_ranking';
    		target_table = 'raw_db.pf_fund_bfi_bm_indicator_ranking';
@@ -600,7 +459,7 @@ def save_ranking_tables(cal_type, ranking_tables) {
     t = ranking_tables[1];
     t = ranking_tables[1];
     save_and_sync(t.rename!('category_id', category_id_col), source_table + '_num', target_table + '_num');
     save_and_sync(t.rename!('category_id', category_id_col), source_table + '_num', target_table + '_num');
 
 
-    if(cal_type == 'strategy') {
+    if(ranking_by == 'strategy') {
 
 
 	    source_table = source_table.strReplace('_ranking', '_substrategy_ranking');
 	    source_table = source_table.strReplace('_ranking', '_substrategy_ranking');
 	    target_table = target_table.strReplace('_ranking', '_substrategy_ranking');
 	    target_table = target_table.strReplace('_ranking', '_substrategy_ranking');
@@ -635,10 +494,10 @@ def save_relative_ranking_table(entity_type, ranking_table, ranking_by) {
         if(ranking_by == 'strategy') {
         if(ranking_by == 'strategy') {
 	    	source_table = 'raw_db.pf_portfolio_indicator_ranking';
 	    	source_table = 'raw_db.pf_portfolio_indicator_ranking';
     		target_table = 'raw_db.pf_portfolio_indicator_ranking';
     		target_table = 'raw_db.pf_portfolio_indicator_ranking';
-        } else if(ranking_by == 'substrategy') {
+        } else if(ranking_by == 'substrategy') {save_relative_ranking_table
 	    	source_table = 'raw_db.pf_portfolio_indicator_substrategy_ranking';
 	    	source_table = 'raw_db.pf_portfolio_indicator_substrategy_ranking';
     		target_table = 'raw_db.pf_portfolio_indicator_substrategy_ranking';
     		target_table = 'raw_db.pf_portfolio_indicator_substrategy_ranking';
-        } else if(ranking_by == 'factor_id') {
+        } else if(ranking_by == 'bfi') {
 	    	source_table = 'raw_db.pf_portfolio_bfi_bm_indicator_ranking';
 	    	source_table = 'raw_db.pf_portfolio_bfi_bm_indicator_ranking';
     		target_table = 'raw_db.pf_portfolio_bfi_bm_indicator_ranking';
     		target_table = 'raw_db.pf_portfolio_bfi_bm_indicator_ranking';
         }
         }

+ 22 - 0
modules/sqlUtilities.dos

@@ -231,6 +231,28 @@ def get_bfi_indicator_table_description(entity_type) {
 }
 }
 
 
 /*
 /*
+ *  根据不同类型的主体返回其有效BFI因子的表名、字段名
+ * 
+ *  Example: get_bfi_by_category_group_table_description('HF');
+ */
+
+def get_bfi_by_category_group_table_description(entity_type) {
+
+    tmp_universe = table(100:0, 
+                         ['type', 'table_name', 'sec_id_col'],
+                         [STRING, STRING, STRING]);
+
+    // 分别对应:私募,公募,私有基金,市场指数,图译指数,私有指数,图译因子,组合, 经理
+    INSERT INTO tmp_universe VALUES ( 
+        ['HF', 'MF', 'CF', 'MI', 'FI', 'CI', 'FA', 'PF', 'MG'],
+        ['pfdb.pf_fund_factor_bfi_by_category_group', 'pfdb.pf_fund_factor_bfi_by_category_group', NULL, NULL, NULL, NULL, NULL, 'pfdb.pf_portfolio_factor_bfi_by_category_group', 'pf_manager_factor_bfi_by_category_group'],
+        ['fund_id', 'fund_id', NULL, NULL, NULL, NULL, NULL, 'portfolio_id', 'mamanger_id'] );
+
+    return (SELECT * FROM tmp_universe u WHERE u.type = entity_type);
+}
+
+
+/*
  *  Annulized multiple
  *  Annulized multiple
  */
  */
 def get_annulization_multiple(freq) {
 def get_annulization_multiple(freq) {

+ 20 - 49
modules/task_monthlyPerformance.dos

@@ -55,12 +55,13 @@ def CalEntityBfiRankingTask(entity_type, end_date, isFromMySQL=true) {
  * 
  * 
  */
  */
 def cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL=true) {
 def cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL=true) {
-
+// benchmark_ranking= tb_fund_ranking
     t_entity_ranking = entity_ranking;
     t_entity_ranking = entity_ranking;
     
     
     cal_relative_ranking(benchmark_ranking, t_entity_ranking, isFromMySQL);
     cal_relative_ranking(benchmark_ranking, t_entity_ranking, isFromMySQL);
 
 
-    t_entity_ranking.rename!('category_id', ranking_by);
+    t_entity_ranking.rename!('category_id', iif(ranking_by=='bfi', 'factor_id', ranking_by));
+
     save_relative_ranking_table(entity_type, t_entity_ranking, ranking_by);
     save_relative_ranking_table(entity_type, t_entity_ranking, ranking_by);
 	
 	
 }
 }
@@ -70,17 +71,22 @@ def cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking
  * 
  * 
  *   以公募基金为评级参考,计算组合、私有基金收益及指标排名
  *   以公募基金为评级参考,计算组合、私有基金收益及指标排名
  * 
  * 
+ *   TODO: customer fund
  * 
  * 
  *   Example: CalRelativeRanking('PF', 2024.09M, true);
  *   Example: CalRelativeRanking('PF', 2024.09M, true);
  */
  */
 def CalRelativeRanking(entity_type, end_date, isFromMySQL=true) {
 def CalRelativeRanking(entity_type, end_date, isFromMySQL=true) {
+// entity_type = 'PF'
+// end_date = 2024.09M
+// isFromMySQL = true
+// ranking_by = 'bfi'
 
 
 	entity_info = get_entity_info(entity_type, NULL);
 	entity_info = get_entity_info(entity_type, NULL);
 
 
 	if(entity_type == 'PF')
 	if(entity_type == 'PF')
 	    entity_info = SELECT * FROM entity_info WHERE portfolio_type IN (1, 2) // 1: 用户组合、2:客户真实组合,忽略客户推荐组合、总览综合等虚拟组合
 	    entity_info = SELECT * FROM entity_info WHERE portfolio_type IN (1, 2) // 1: 用户组合、2:客户真实组合,忽略客户推荐组合、总览综合等虚拟组合
 
 
-    v_ranking_by = ['strategy', 'substrategy'/*, 'factor_id'*/];
+    v_ranking_by = ['strategy', 'substrategy', 'bfi'];
 
 
     // 暂时以公募混合基金为排名参考
     // 暂时以公募混合基金为排名参考
     for(ranking_by in v_ranking_by) {
     for(ranking_by in v_ranking_by) {
@@ -88,64 +94,29 @@ def CalRelativeRanking(entity_type, end_date, isFromMySQL=true) {
     	if(ranking_by == 'strategy') {
     	if(ranking_by == 'strategy') {
         
         
         	v_category = EXEC DISTINCT strategy FROM entity_info WHERE strategy IS NOT NULL;
         	v_category = EXEC DISTINCT strategy FROM entity_info WHERE strategy IS NOT NULL;
-	        tb_fund_ranking = get_fund_indicator_ranking(NULL, end_date, v_category, true)
+	        tb_fund_ranking = get_fund_indicator_ranking(NULL, end_date, v_category, isFromMySQL);
+
+	        UPDATE tb_fund_ranking SET category_id = strategy$STRING;
         
         
     	} else if(ranking_by == 'substrategy') {
     	} else if(ranking_by == 'substrategy') {
 
 
    			v_category = EXEC DISTINCT substrategy FROM entity_info WHERE substrategy IS NOT NULL;
    			v_category = EXEC DISTINCT substrategy FROM entity_info WHERE substrategy IS NOT NULL;
-	    	tb_fund_ranking = get_fund_indicator_substrategy_ranking(NULL, end_date, v_category, true)
+	    	tb_fund_ranking = get_fund_indicator_substrategy_ranking(NULL, end_date, v_category, isFromMySQL);
+
+	    	UPDATE tb_fund_ranking SET category_id = substrategy$STRING;
     	
     	
     	} else if(ranking_by == 'bfi') {
     	} else if(ranking_by == 'bfi') {
 
 
-    		tb_fund_ranking = null;
+    		tb_fund_ranking = get_fund_bfi_bm_indicator_ranking(NULL, end_date, NULL, isFromMySQL);
+
+    		UPDATE tb_fund_ranking SET category_id = factor_id;
 	    }
 	    }
 
 
     	if(tb_fund_ranking.isVoid() || tb_fund_ranking.size() == 0) return;
     	if(tb_fund_ranking.isVoid() || tb_fund_ranking.size() == 0) return;
 
 
-	    tb_fund_ranking.rename!(ranking_by, 'category_id');
-
-    	// 收益
-	    v_indicator_id = [1];
-    	benchmark_ranking = SELECT * FROM tb_fund_ranking WHERE indicator_id IN v_indicator_id;
-
-    	entity_ranking = transform_return_for_ranking(entity_type, entity_info, end_date, ranking_by, isFromMySQL).rename!(ranking_by, 'category_id');
-
-        cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL);
-
-
-	    // 风险指标
-    	v_indicator_id = [2, 6, 9, 10, 11, 12, 21, 50, 52, 59];
-	    benchmark_ranking = SELECT * FROM tb_fund_ranking WHERE indicator_id IN v_indicator_id;
-    
-	    entity_ranking = transform_risk_stats_for_ranking(entity_type, entity_info, end_date, ranking_by, isFromMySQL).rename!(ranking_by, 'category_id');
-
-        cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL);
-
-
-    	// 风险调整收益指标
-	    v_indicator_id = [14, 15, 16, 17, 18, 19, 40, 58];
-    	benchmark_ranking = SELECT * FROM tb_fund_ranking WHERE indicator_id IN v_indicator_id;
-    
-	    entity_ranking = transform_risk_adj_ret_stats_for_ranking(entity_type, entity_info, end_date, ranking_by, isFromMySQL).rename!(ranking_by, 'category_id');
-
-        cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL);
-
-	    // 其它风险指标
-    	v_indicator_id = [37, 38, 41, 42, 43, 44, 45, 46, 47, 48, 49];
-	    benchmark_ranking = SELECT * FROM tb_fund_ranking WHERE indicator_id IN v_indicator_id;
-
-    	entity_ranking = transform_other_indicator_for_ranking(entity_type, entity_info, end_date, ranking_by, isFromMySQL).rename!(ranking_by, 'category_id');
-
-        cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL);
-
-	    // 上下行捕获指标
-    	v_indicator_id = [33, 34, 35, 36];
-	    benchmark_ranking = SELECT * FROM tb_fund_ranking WHERE indicator_id IN v_indicator_id;
-
-    	entity_ranking = transform_capture_style_for_ranking(entity_type, entity_info, end_date, ranking_by, isFromMySQL).rename!(ranking_by, 'category_id');
-
-        cal_and_save_relative_ranking(entity_type, benchmark_ranking, entity_ranking, ranking_by, isFromMySQL);
+    	entity_ranking = transform_data_for_ranking(entity_type, entity_info, end_date, ranking_by, isFromMySQL);
 
 
+        cal_and_save_relative_ranking(entity_type, tb_fund_ranking, entity_ranking, ranking_by, isFromMySQL);
 
 
     }
     }
 //    SELECT * FROM entity_ranking WHERE entity_id = 143109
 //    SELECT * FROM entity_ranking WHERE entity_id = 143109