module fundit::task_fundPerformance use fundit::fundCalculator use fundit::dataPuller use fundit::returnCalculator use fundit::indicatorCalculator /* * 通用收益计算 * * */ def calEntityReturns(entityType, freq, entities) { ret = null; if(freq == 'm') { ret = fundit::returnCalculator::cal_entity_monthly_returns(entityType, entities); } return ret; } /* * 通用指标计算 * * * * @return : ['PBI-INCEP', 'PBI-YTD', 'PBI-6M', 'PBI-1Y', 'PBI-2Y', 'PBI-3Y', 'PBI-4Y', 'PBI-5Y', 'PBI-10Y', 'MS-3Y', 'MS-5Y', 'MS-10Y'] * */ def calIndicators(entityType, monthlyReturns) { if(find(['FD', 'PF'], entityType) < 0) return null; if(monthlyReturns.isVoid() || monthlyReturns.size() < 1) return null; oldest_date = EXEC price_date.min() FROM monthlyReturns; v_entity_ids = (SELECT DISTINCT entity_id FROM monthlyReturns).entity_id; entity_info = get_entity_info(entityType, v_entity_ids); if(entity_info.isVoid() || entity_info.size() == 0) { return null }; if(monthlyReturns.isVoid() || monthlyReturns.size() == 0) { return null; } end_day = today(); // 取基金和基准的对照表 primary_benchmark = SELECT entity_id, end_date, iif(benchmark_id.isNull(), 'IN00000008', benchmark_id) AS benchmark_id FROM get_entity_primary_benchmark(entityType, v_entity_ids, oldest_date.month().temporalFormat('yyyy-MM'), end_day.month().temporalFormat('yyyy-MM')) ; // 取所有出现的基准月收益 bmk_ret = get_benchmark_return(primary_benchmark, end_day); if(bmk_ret.isVoid() || bmk_ret.size() == 0) { return null; } risk_free_rate = SELECT fund_id, temporalParse(end_date, 'yyyy-MM') AS end_date, ret FROM get_risk_free_rate(oldest_date, end_day); if(risk_free_rate.isVoid() || risk_free_rate.size() == 0) { return null; } // 标准的指标 t0 = cal_trailing_indicators(entity_info, primary_benchmark, end_day, monthlyReturns, bmk_ret, risk_free_rate); // PBI stands for "Primary Benchmark Index" v_table_name = ['PBI-INCEP', 'PBI-YTD', 'PBI-6M', 'PBI-1Y', 'PBI-2Y', 'PBI-3Y', 'PBI-4Y', 'PBI-5Y', 'PBI-10Y']; // BFI指标 return dict(v_table_name, t0); } /* * 基金指标计算 * * */ def calFundIndicators(rets) { t = calIndicators('FD', rets); return t; } /* * 定时任务:最新净值触发的业绩指标计算 * * TODO: 目前收益表在MySQL中,所以需要将计算的最新收益与MySQL中的历史数据合并 */ def calFundPerformance(entityType, date) { very_old_date = 1990.01.01; if(find(['HF', 'MF'], entityType) < 0) return null; // 取有最新净值变动的私募基金列表 tb_cal_funds = get_fund_list_by_nav_updatetime('MF', NULL, date); // 分批跑 i = 0; batch_size = 1000; do { funds = tb_cal_funds[i:batch_size] funds.rename!('fund_id', 'entity_id'); // 计算月收益 rets = calEntityReturns(entityType, 'm', funds); // 最新更新的收益存入数据库 // 取完整历史收益用于指标计算 all_rets = get_fund_monthly_ret(funds.entity_id, very_old_date, today().month(), true); all_rets.rename!('fund_id', 'entity_id'); // 将MySQL中的 YYYY-MM 格式改为 YYYY.MM end_dates = EXEC end_date.temporalParse('yyyy-MM') FROM all_rets; all_rets.replaceColumn!('end_date', end_dates); // 用新计算的收益覆盖旧的 UPDATE all_rets SET all_rets.ret = rets.ret, all_rets.nav = rets.cumulative_nav FROM ej(all_rets, rets, ['entity_id', 'end_date']); // 用新计算的收益补充旧的, ret_ytd_a, ret_incep_a 没有用 INSERT INTO all_rets SELECT entity_id, end_date, price_date, ret, cumulative_nav, null AS ret_ytd_a, null AS ret_incep_a FROM rets WHERE NOT EXISTS ( SELECT * FROM all_rets WHERE entity_id = rets.entity_id AND end_date = rets.end_date); // 计算月度指标 indicators = calFundIndicators(all_rets); //INSERT INTO tb_indicators SELECT * FROM indicators; i += batch_size; } while (i < batch_size); // } while (i <= tb_cal_funds.size()); return indicators; }