|
@@ -145,14 +145,13 @@ def CalRelativeRankingTask(entity_type, entity_ids, end_date, isFromMySQL=true)
|
|
|
*/
|
|
|
def cal_and_save_mc_nav(entity_type, entity_date, is_save_local) {
|
|
|
|
|
|
- tb_monthly_ret = table(1000:0, ['entity_id', 'curve_type', 'strategy', 'end_date', 'price_date', 'ret', 'nav'],
|
|
|
- [SYMBOL, INT, INT, MONTH, DATE, DOUBLE, DOUBLE]);
|
|
|
+ rt = '';
|
|
|
|
|
|
if(entity_type == 'PL') s_entity_type = 'manager';
|
|
|
else if(entity_type == 'CO') s_entity_type = 'company';
|
|
|
- else return tb_monthly_ret;
|
|
|
+ else return rt;
|
|
|
|
|
|
- if(entity_date.isVoid() || entity_date.size() == 0) return tb_monthly_ret;
|
|
|
+ if(entity_date.isVoid() || entity_date.size() == 0) return rt;
|
|
|
|
|
|
// 准备类似MySQL结构的数据表
|
|
|
tb_entity_nav = create_mc_fitted_curve();
|
|
@@ -191,9 +190,6 @@ def cal_and_save_mc_nav(entity_type, entity_date, is_save_local) {
|
|
|
SELECT entity_id, curve_type, strategy, end_date, nav, incl_cal_cnt
|
|
|
FROM ej(tb_nav, tmp, ['entity_id', 'curve_type', 'strategy', 'end_date']);
|
|
|
|
|
|
- INSERT INTO tb_monthly_ret
|
|
|
- SELECT entity_id, curve_type, strategy, end_date.temporalParse('yyyy-MM').month(), price_date, ret, nav
|
|
|
- FROM ej(tmp, tb_nav, ['entity_id', 'curve_type', 'strategy', 'end_date']);
|
|
|
}
|
|
|
|
|
|
i += batch_size;
|
|
@@ -217,10 +213,11 @@ def cal_and_save_mc_nav(entity_type, entity_date, is_save_local) {
|
|
|
} catch(ex) {
|
|
|
|
|
|
//TODO: Log errors
|
|
|
+ rt += ex;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return tb_monthly_ret;
|
|
|
+ return rt;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -236,60 +233,154 @@ def cal_and_save_mc_indicator(entity_type, entity_date, monthly_returns, is_save
|
|
|
if(!(entity_type IN ['PL', 'CO'])) return rt;
|
|
|
if(entity_date.isVoid() || entity_date.size() == 0) return rt;
|
|
|
|
|
|
- indicators = cal_mc_monthly_indicators(entity_type, 'PBI', monthly_returns);
|
|
|
+ i = 0;
|
|
|
+ batch_size = 1000;
|
|
|
+ v_entity_id = entity_date.entity_id.distinct();
|
|
|
+ max_cnt = v_entity_id.size();
|
|
|
+
|
|
|
+ do {
|
|
|
+
|
|
|
+ t_monthly_ret = SELECT * FROM monthly_returns WHERE entity_id IN v_entity_id[i : min(i+batch_size, max_cnt)];
|
|
|
+
|
|
|
+ d_indicators = cal_mc_monthly_indicators(entity_type, 'PBI', t_monthly_ret);
|
|
|
+
|
|
|
+ if(d_indicators.isVoid()) break;
|
|
|
+
|
|
|
+ // cal_mc_monthly_indicators 返回个两重字典,分别对应 curve_type 和不同区间的数据表,将同样区间的数据表(但不同curve_type)合并
|
|
|
+ // curve_type: 1:私募,4:公募,7:公私募综合
|
|
|
+ trailing_num = d_indicators["7"].keys().size();
|
|
|
+ for(k in d_indicators["7"].keys()) {
|
|
|
+ d_indicators["7"][k].append!(d_indicators["1"][k]);
|
|
|
+ d_indicators["7"][k].append!(d_indicators["4"][k]);
|
|
|
+ }
|
|
|
+ indicators = d_indicators["7"];
|
|
|
+ d_indicators = null;
|
|
|
+
|
|
|
+ // 按照 MySQL 建好各表
|
|
|
+ tb_mc_performance = create_mc_performance();
|
|
|
+ tb_mc_indicator = create_mc_indicator();
|
|
|
+ tb_mc_risk_stats = create_mc_risk_stats();
|
|
|
+ tb_mc_riskadjret_stats = create_mc_riskadjret_stats();
|
|
|
+ tb_mc_style_stats = create_mc_style_stats();
|
|
|
+
|
|
|
+ // 仿照MySQL的表结构准备好记录 (1s)
|
|
|
+ entity_info = SELECT entity_id, curve_type, strategy, price_date.temporalParse('yyyy-MM') AS price_date FROM entity_date;
|
|
|
+
|
|
|
+ generate_entity_performance(entity_info, indicators, true, tb_mc_performance, ['curve_type', 'strategy']);
|
|
|
+ generate_entity_indicator(entity_info, indicators, true, tb_mc_indicator, ['curve_type', 'strategy']);
|
|
|
+ generate_entity_risk_stats(entity_info, indicators, true, tb_mc_risk_stats, ['curve_type', 'strategy']);
|
|
|
+ generate_entity_riskadjret_stats(entity_info, indicators, true, tb_mc_riskadjret_stats, ['curve_type', 'strategy']);
|
|
|
+ generate_entity_style_stats(entity_info, indicators, true, tb_mc_style_stats, ['curve_type', 'strategy']);
|
|
|
+
|
|
|
+ if(! tb_mc_performance.isVoid() && tb_mc_performance.size() > 0) {
|
|
|
+
|
|
|
+ // save data to MySQL (13s)
|
|
|
+ try {
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_mc_performance, iif(entity_type == 'PL', 'manager_id', 'company_id'));
|
|
|
+ save_and_sync(tb_mc_performance, iif(entity_type == 'PL', 'raw_db.manager_performance', 'raw_db.company_performance'), );
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_mc_indicator, iif(entity_type == 'PL', 'manager_id', 'company_id'));
|
|
|
+ save_and_sync(tb_mc_indicator, iif(entity_type == 'PL', 'raw_db.manager_indicator', 'raw_db.company_indicator'), );
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_mc_risk_stats, iif(entity_type == 'PL', 'manager_id', 'company_id'));
|
|
|
+ save_and_sync(tb_mc_risk_stats, iif(entity_type == 'PL', 'raw_db.manager_risk_stats', 'raw_db.company_risk_stats'), );
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_mc_riskadjret_stats, iif(entity_type == 'PL', 'manager_id', 'company_id'));
|
|
|
+ save_and_sync(tb_mc_riskadjret_stats, iif(entity_type == 'PL', 'raw_db.manager_riskadjret_stats', 'raw_db.company_riskadjret_stats'), );
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_mc_style_stats, iif(entity_type == 'PL', 'manager_id', 'company_id'));
|
|
|
+ save_and_sync(tb_mc_style_stats, iif(entity_type == 'PL', 'raw_db.manager_style_stats', 'raw_db.company_style_stats'), );
|
|
|
+
|
|
|
+
|
|
|
+ // 数据初始化时将指标存入本地
|
|
|
+ if(is_save_local == true) {
|
|
|
+ save_table(tb_mc_performance, iif(entity_type == 'PL', 'mfdb.manager_performance', 'mfdb.company_performance'), false);
|
|
|
+ save_table(tb_mc_indicator, iif(entity_type == 'PL', 'mfdb.manager_indicator', 'mfdb.company_indicator'), false);
|
|
|
+ save_table(tb_mc_risk_stats, iif(entity_type == 'PL', 'mfdb.manager_risk_stats', 'mfdb.company_risk_stats'), false);
|
|
|
+ save_table(tb_mc_riskadjret_stats, iif(entity_type == 'PL', 'mfdb.manager_riskadjret_stats', 'mfdb.company_riskadjret_stats'), false);
|
|
|
+ save_table(tb_mc_style_stats, iif(entity_type == 'PL', 'mfdb.manager_style_stats', 'mfdb.company_style_stats'), false);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch(ex) {
|
|
|
+
|
|
|
+ //TODO: Log errors
|
|
|
+ rt += ex + '\n';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ i += batch_size;
|
|
|
+
|
|
|
+ } while (i < max_cnt);
|
|
|
+
|
|
|
+ return rt;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * [定时任务]: 基金经理月净值计算
|
|
|
+ * [定时任务]: 基金经理/公司月净值计算
|
|
|
*
|
|
|
*
|
|
|
*/
|
|
|
-def CalManagerNavTask(updatetime) {
|
|
|
+def CalMCNavTask(entity_type, updatetime) {
|
|
|
//updatetime = 2024.11.05;
|
|
|
|
|
|
- is_save_local = iif(updatetime <= get_ini_data_const()['updatetime'], true, false);
|
|
|
-
|
|
|
- // 31 sec
|
|
|
- entity_date = get_manager_list_by_fund_updatetime(updatetime);
|
|
|
-
|
|
|
- entity_date.rename!('manager_id', 'entity_id');
|
|
|
+ if(!(entity_type IN ['PL', 'CO'])) return;
|
|
|
|
|
|
- tb_monthly_ret = cal_and_save_mc_nav('PL', entity_date, is_save_local);
|
|
|
+ is_save_local = iif(updatetime <= get_ini_data_const()['updatetime'], true, false);
|
|
|
|
|
|
- cal_and_save_mc_indicator('PL', entity_date, tb_monthly_ret, is_save_local);
|
|
|
+ // 31 sec 简化起见,不区分curve_type, strategy
|
|
|
+ if(entity_type == 'PL') {
|
|
|
+ entity_date = get_manager_list_by_fund_updatetime(updatetime);
|
|
|
+ entity_date.rename!('manager_id', 'entity_id');
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ entity_date = get_company_list_by_fund_updatetime(updatetime);
|
|
|
+ entity_date.rename!('company_id', 'entity_id');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 15 sec
|
|
|
+ cal_and_save_mc_nav('PL', entity_date, is_save_local);
|
|
|
|
|
|
entity_date = null;
|
|
|
- tb_monthly_ret = null;
|
|
|
-}
|
|
|
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
- * [定时任务]: 基金公司月净值计算
|
|
|
+ * [定时任务]: 基金经理/公司月收益及指标计算
|
|
|
*
|
|
|
*
|
|
|
*/
|
|
|
-def CalCompanyNavTask(updatetime) {
|
|
|
-//updatetime = 2024.11.05;
|
|
|
+def CalMCIndicatorTask(entity_type, updatetime) {
|
|
|
+// entity_type = 'PL';
|
|
|
+// updatetime = 2024.11.01
|
|
|
+ rt = '';
|
|
|
|
|
|
is_save_local = iif(updatetime <= get_ini_data_const()['updatetime'], true, false);
|
|
|
|
|
|
- // 31 sec
|
|
|
- entity_date = get_company_list_by_fund_updatetime(updatetime);
|
|
|
+ // 3 sec
|
|
|
+ entity_date = get_entity_list_by_nav_updatetime(entity_type, NULL, updatetime, true);
|
|
|
|
|
|
- entity_date.rename!('company_id', 'entity_id');
|
|
|
+ // 取完整月收益 1+ min
|
|
|
+ tb_monthly_ret = get_monthly_ret(entity_type, entity_date.entity_id, 1900.01.01, today(), true);
|
|
|
+ v_end_date = tb_monthly_ret.end_date.temporalParse('yyyy-MM');
|
|
|
+ tb_monthly_ret.replaceColumn!('end_date', v_end_date);
|
|
|
+ UPDATE tb_monthly_ret SET price_date = end_date.temporalFormat('yyyy-MM-dd').temporalParse('yyyy-MM-dd').businessMonthEnd() WHERE price_date IS NULL;
|
|
|
|
|
|
- cal_and_save_mc_nav('CO', entity_date, is_save_local);
|
|
|
+ // 40+ min
|
|
|
+ cal_and_save_mc_indicator('PL', entity_date, tb_monthly_ret, is_save_local);
|
|
|
+
|
|
|
+ tb_monthly_ret = null;
|
|
|
|
|
|
- entity_date = null;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/*
|
|
|
*
|
|
|
* [定时任务]: 基金经理的BFI MATCHING
|
|
|
*
|
|
|
- *
|
|
|
+ * it takes 9.5 hours
|
|
|
*/
|
|
|
def MatchManagerBFITask(updatetime) {
|
|
|
|