Browse Source

将BFI指标计算从月度任务移到每日任务

Joey 4 months ago
parent
commit
fa405d6be0
2 changed files with 109 additions and 3 deletions
  1. 105 2
      modules/task_fundPerformance.dos
  2. 4 1
      modules/task_monthlyPerformance.dos

+ 105 - 2
modules/task_fundPerformance.dos

@@ -146,6 +146,109 @@ def calFundPerformanceTask(entityType, date) {
 }
 }
 
 
 
 
+/*
+ *   [定时任务] 计算BFI指标并存入数据库
+ * 
+ *   @param entityType <STRING>: 'MF', 'HF', 'PF'; 前两个是一样的
+ *   @param date <DATETIME>: BFI更新时间, 为空时缺省为当前时间的前1天;为1989.01.01或更早日期时代表初始化,指标会被存入本地数据库
+ *   
+ *   
+ *   Example: calEntityBfiIndicatorTask('MF', 2024.10.28);
+ *            calEntityBfiIndicatorTask('PF', 2024.10.28);
+ */
+def calEntityBfiIndicatorTask(entityType, date) {
+
+// entityType = 'MF'
+// date = 2024.10.01
+
+    rt = '';
+
+    if(!(entityType IN ['MF', 'HF', 'PF'])) return null;
+
+	very_old_day = 1900.01.01;
+
+    if(date.isNothing() || date.isNull())
+    	end_day = temporalAdd(now(), -1d);
+    else
+    	end_day = date;
+
+	// 1989.01.01及以前的日期被认为从本地读数据
+	isFromMySQL = iif(end_day <= 1989.01.01, false, true);
+
+    // 取有最新bfi变动的基金列表 (1s)
+    tb_cal_entities = get_entity_bfi_factors(entityType, NULL, very_old_day.month(), today().month(), end_day);
+
+    if(tb_cal_entities.isVoid() || tb_cal_entities.size() == 0 ) return;
+
+    v_uniq_entity_id = EXEC DISTINCT entity_id FROM tb_cal_entities;
+
+    // 按照 MySQL 建好各表
+    tb_bfi_indicator = create_entity_bfi_indicator(iif(entityType=='PF', true, false));
+
+    // 分批跑
+    i = 0;
+    batch_size = 100;
+
+
+    do {
+
+        entities = SELECT * FROM tb_cal_entities WHERE entity_id IN v_uniq_entity_id[i : min(v_uniq_entity_id.size(), i+batch_size)];
+
+        if(entities.isVoid() || entities.size() == 0) break;
+
+        // 200ms
+        entity_info = SELECT entity_id, end_date.temporalParse('yyyy-MM') AS end_date, inception_date, factor_id AS benchmark_id, ini_value 
+                      FROM ej(entities, get_entity_info(entityType, entities.entity_id), 'entity_id');
+
+        // 取月收益 (12s)
+        rets = get_monthly_ret(entityType, entity_info.entity_id, very_old_day, entity_info.end_date.max().temporalFormat('yyyy-MM-dd').temporalParse('yyyy-MM-dd').monthEnd(), isFromMySQL);
+
+		// 把 yyyy-MM 格式的 end_date 改成 dolphin 的 MONTH
+        v_end_date = rets.end_date.temporalParse('yyyy-MM');
+        rets.replaceColumn!('end_date', v_end_date);
+
+        if(!rets.isVoid() && rets.size() > 0) {
+
+            // 计算月度指标 (5s)
+            indicators = cal_monthly_indicators(entityType, 'BFI', rets);
+
+            // 仿照MySQL的表结构准备好记录 (1s)
+            generate_entity_bfi_indicator(entity_info, indicators, true, tb_bfi_indicator);
+
+        }
+        
+        i += batch_size;
+
+    } while (i <= v_uniq_entity_id.size());
+
+
+    if(! tb_bfi_indicator.isVoid() && tb_bfi_indicator.size() > 0) {
+
+        // save data to MySQL
+        try {
+
+		    t_desc = get_bfi_indicator_table_description(entityType);
+		    
+            chg_columns_for_mysql(tb_bfi_indicator, t_desc.sec_id_col[0]);
+            db_name = t_desc.table_name[0].split('.')[0];
+            save_and_sync(tb_bfi_indicator, t_desc.table_name[0].strReplace(db_name, 'raw_db'), t_desc.table_name[0].strReplace(db_name, 'raw_db'));
+
+            // 数据初始化时将指标存入本地,做排名之用
+            if(end_day <= 1990.01.01) {
+            	save_table(tb_bfi_indicator, t_desc.table_name[0].strReplace(db_name, 'raw_db'), false);
+            }
+
+        } catch(ex) {
+
+            //TODO: Log errors
+            rt = ex;
+        }
+    }
+    
+    return rt;
+	
+}
+
 
 
 /*
 /*
  *   根据收益更新日期计算 RBSA
  *   根据收益更新日期计算 RBSA
@@ -171,9 +274,9 @@ def CalFundRBSATask(entityType, entityIds, updateTime) {
 	d_rbsa = get_rbsa_index();
 	d_rbsa = get_rbsa_index();
 
 
 	for(entity in t) {
 	for(entity in t) {
-//entity=t[0]
+
 		for(asset_type in d_rbsa.keys()) {
 		for(asset_type in d_rbsa.keys()) {
-//asset_type=d_rbsa.keys()[3]	
+
 			// 起始日期是最早更新日期再向前推一个时间窗口
 			// 起始日期是最早更新日期再向前推一个时间窗口
 			res = cal_entity_RBSA(entityType, entity.entity_id, d_rbsa[asset_type], 'w', 
 			res = cal_entity_RBSA(entityType, entity.entity_id, d_rbsa[asset_type], 'w', 
 			                    t.price_date.temporalAdd(-window, 'w')[0], today(), true, window, step);
 			                    t.price_date.temporalAdd(-window, 'w')[0], today(), true, window, step);

+ 4 - 1
modules/task_monthlyPerformance.dos

@@ -3,10 +3,13 @@ module fundit::task_monthlyPerformance
 
 
 use fundit::operationDataPuller;
 use fundit::operationDataPuller;
 use fundit::performanceDataPuller;
 use fundit::performanceDataPuller;
+use fundit::indicatorCalculator;
 use fundit::dataSaver;
 use fundit::dataSaver;
 use fundit::bfiMatcher;
 use fundit::bfiMatcher;
 use fundit::rankingCalculator;
 use fundit::rankingCalculator;
 
 
+
+
 /*
 /*
  *   [定时任务] 计算基金一、二级分类排名并存入数据库
  *   [定时任务] 计算基金一、二级分类排名并存入数据库
  * 
  * 
@@ -113,7 +116,7 @@ def CalRelativeRankingTask(entity_type, entity_ids, end_date, isFromMySQL=true)
     	} else if(ranking_by == 'bfi') {
     	} else if(ranking_by == 'bfi') {
 
 
 			if(entity_ids != NULL || entity_ids != '')
 			if(entity_ids != NULL || entity_ids != '')
-				v_category = EXEC DISTINCT factor_id FROM get_portfolio_bfi_factors(entity_ids, end_date.temporalFormat('yyyy-MM'), end_date.temporalFormat('yyyy-MM'));
+				v_category = EXEC DISTINCT factor_id FROM get_entity_bfi_factors(entity_type, entity_ids, end_date, end_date);
 			else
 			else
 			    v_category = NULL;
 			    v_category = NULL;