123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- module fundit::task_monthlyPerformance
- use fundit::sqlUtilities;
- use fundit::operationDataPuller;
- use fundit::performanceDataPuller;
- use fundit::indicatorCalculator;
- use fundit::dataSaver;
- use fundit::bfiMatcher;
- use fundit::rankingCalculator;
- use fundit::navCalculator;
- /*
- * [定时任务] 计算基金一、二级分类排名并存入数据库
- *
- * @param entity_type <STRING>: 'MF', 'HF' (MF=HF)
- * @param end_date <MONTH>:
- * @param isFromMySQL <BOOL>: false 时读取dolphin本地的收益及指标表,用于初始化数据
- *
- *
- * Example: CalEntityRankingTask('MF', 2024.09M, true);
- */
- def CalEntityRankingTask(entity_type, end_date, isFromMySQL=true) {
- if(!(entity_type in ['MF', 'HF'])) return NULL;
-
- entity_info = get_entity_info(entity_type, NULL);
- v_ranking_tables = cal_indicator_ranking('strategy', entity_type, entity_info, end_date, isFromMySQL);
- save_ranking_tables(entity_type, v_ranking_tables);
- }
- /*
- * [定时任务] 计算基金BFI排名并存入数据库
- *
- * @param entity_type <STRING>: 'MF', 'HF' (MF=HF)
- * @param end_date <MONTH>:
- * @param isFromMySQL <BOOL>: false 时读取dolphin本地的收益及指标表,用于初始化数据
- *
- *
- * Example: CalEntityBfiRankingTask('MF', 2024.09M, true);
- */
- def CalEntityBfiRankingTask(entity_type, end_date, isFromMySQL=true) {
- if(!(entity_type in ['MF', 'HF'])) return NULL;
-
- entity_info = get_entity_info(entity_type, NULL);
- v_ranking_tables = cal_indicator_ranking('bfi', entity_type, entity_info, end_date, isFromMySQL);
-
- save_ranking_tables(entity_type, v_ranking_tables);
- }
- /*
- * Private Method: 计算相对排名并存入数据库
- *
- *
- */
- 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;
-
- cal_relative_ranking(benchmark_ranking, t_entity_ranking, isFromMySQL);
- 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);
-
- }
- /*
- *
- * [定时任务] 以公募基金为评级参考,计算组合、私有基金收益及指标排名
- *
- * @param entityType <STRING>: PF
- *
- * TODO: customer fund
- * TODO: 计算单个组合时总耗时1.5min, 大部分时间用来获取Mysql数据
- *
- * Example: CalRelativeRankingTask('PF', NULL, 2024.09M, true);
- * CalRelativeRankingTask('PF', 143109, 2024.09M, true);
- */
- def CalRelativeRankingTask(entity_type, entity_ids, end_date, isFromMySQL=true) {
- // entity_type = 'PF'
- // end_date = 2024.09M
- // isFromMySQL = true
- // ranking_by = 'bfi'
- // entity_ids = 143109
- entity_info = get_entity_info(entity_type, entity_ids);
- if(entity_type == 'PF')
- entity_info = SELECT * FROM entity_info WHERE portfolio_type IN (1, 2) // 1: 用户组合、2:客户真实组合,忽略客户推荐组合、总览综合等虚拟组合
- v_ranking_by = ['strategy', 'substrategy', 'bfi'];
- // 暂时以公募混合基金为排名参考
- for(ranking_by in v_ranking_by) {
- if(ranking_by == 'strategy') {
-
- 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, isFromMySQL);
- UPDATE tb_fund_ranking SET category_id = strategy$STRING;
-
- } else if(ranking_by == 'substrategy') {
- 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, isFromMySQL);
- UPDATE tb_fund_ranking SET category_id = substrategy$STRING;
-
- } else if(ranking_by == 'bfi') {
- if(entity_ids != NULL || entity_ids != '')
- v_category = EXEC DISTINCT factor_id FROM get_entity_bfi_factors(entity_type, entity_ids, end_date, end_date);
- else
- v_category = NULL;
- tb_fund_ranking = get_fund_bfi_bm_indicator_ranking(NULL, end_date, v_category, isFromMySQL);
- UPDATE tb_fund_ranking SET category_id = factor_id;
- }
- if(tb_fund_ranking.isVoid() || tb_fund_ranking.size() == 0) return;
- 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);
- }
-
- }
- /*
- * 计算基金经理和公司净值(月度)
- *
- *
- */
- def cal_and_save_mc_nav(entity_type, entity_date, is_save_local) {
- rt = '';
- if(entity_type == 'PL') s_entity_type = 'manager';
- else if(entity_type == 'CO') s_entity_type = 'company';
- else return rt;
- if(entity_date.isVoid() || entity_date.size() == 0) return rt;
- // 准备类似MySQL结构的数据表
- tb_entity_nav = create_entity_fitted_curve();
- // 暂时与 MySQL 保持一致,只计算公募,私募,公私募综合三条时间序列。未来可细化至公、私募+主策略
- d_curve_type = dict(INT, INT);
- d_curve_type[1] = 1; // 私募
- d_curve_type[4] = 2; // 公募
- d_curve_type[7] = -99; // 公私募综合
- // 分批跑
- i = 0;
- batch_size = 1000;
- all_entity_id = entity_date.entity_id.distinct();
- do { // 14 sec
- tb_entity = SELECT * FROM entity_date
- WHERE entity_id IN all_entity_id[i : min(all_entity_id.size(), i+batch_size)];
- if(tb_entity.isVoid() || tb_entity.size() == 0) break;
- s_json = tb_entity.toStdJson();
- t_ret = get_mc_monthly_return(s_entity_type, s_json, 0, 1, true);
-
- for(cur in d_curve_type.keys()) {
- tmp = SELECT entity_id, cur AS curve_type, 0 AS strategy, end_date, price_date, ret, incl_cal_cnt
- FROM t_ret WHERE raise_type = d_curve_type[cur] AND strategy = -99; // 目前只需要全策略
- // 取净值前值
- tb_nav = cal_mc_nav_by_return(entity_type, tmp);
- INSERT INTO tb_entity_nav
- SELECT entity_id, curve_type, strategy, end_date, nav, incl_cal_cnt
- FROM ej(tb_nav, tmp, ['entity_id', 'curve_type', 'strategy', 'end_date']);
- }
- i += batch_size;
- } while (i <= all_entity_id.size());
- if(! tb_entity_nav.isVoid() && tb_entity_nav.size() > 0) {
- // save data to MySQL (12 sec)
- try {
- tb_entity_nav.rename!('entity_id', iif(entity_type == 'PL', 'fund_manager_id', 'company_id'));
- save_and_sync(tb_entity_nav, iif(entity_type == 'PL', 'raw_db.fund_manager_fitted_curve', 'raw_db.company_fitted_curve'), );
- // 数据初始化时将指标存入本地
- if(is_save_local == true) {
- save_table(tb_entity_nav, iif(entity_type == 'PL', 'mfdb.fund_manager_fitted_curve', 'mfdb.company_fitted_curve'), false);
- }
- } catch(ex) {
- //TODO: Log errors
- rt = ex;
- }
- }
- return rt;
-
- }
- /*
- * [定时任务]: 基金经理月净值计算
- *
- *
- */
- def CalManagerNavTask(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');
- cal_and_save_mc_nav('PL', entity_date, is_save_local);
- entity_date = null;
- }
- /*
- * [定时任务]: 基金公司月净值计算
- *
- *
- */
- def CalCompanyNavTask(updatetime) {
- //updatetime = 2024.11.05;
- is_save_local = iif(updatetime <= get_ini_data_const()['updatetime'], true, false);
- // 31 sec
- entity_date = get_company_list_by_fund_updatetime(updatetime);
- entity_date.rename!('company_id', 'entity_id');
- cal_and_save_mc_nav('CO', entity_date, is_save_local);
- entity_date = null;
- }
|