|
@@ -19,6 +19,8 @@ def generate_entity_performance(entity_info, indicators, isToMySQL, mutable enti
|
|
|
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
+ if(indicators['PBI-3M'].isVoid() || indicators['PBI-3M'].size() == 0) return;
|
|
|
+
|
|
|
t = SELECT entity_id, end_date, price_date, nav AS cumulative_nav, ret AS ret_1m, ret AS ret_1m_a, trailing_ret AS ret_3m, trailing_ret_a AS ret_3m_a
|
|
|
FROM indicators['PBI-3M'] AS ind
|
|
|
INNER JOIN entity_info fi ON ind.entity_id = fi.entity_id
|
|
@@ -77,6 +79,8 @@ def generate_entity_risk_stats(entity_info, indicators, isToMySQL, mutable entit
|
|
|
|
|
|
t = null;
|
|
|
|
|
|
+ if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
|
|
|
+
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
t = SELECT entity_id, end_date, std_dev_a AS stddev_6m, ds_dev_a AS downsidedev_6m, alpha_a AS alpha_6m, winrate AS winrate_6m, beta AS beta_6m,
|
|
@@ -141,6 +145,8 @@ def generate_entity_riskadjret_stats(entity_info, indicators, isToMySQL, mutable
|
|
|
|
|
|
t = null;
|
|
|
|
|
|
+ if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
|
|
|
+
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
t = SELECT entity_id, end_date,
|
|
@@ -206,6 +212,8 @@ def generate_entity_indicator(entity_info, indicators, isToMySQL, mutable entity
|
|
|
|
|
|
t = null;
|
|
|
|
|
|
+ if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
|
|
|
+
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
t = SELECT entity_id, end_date, info_a AS info_ratio_6m, m2_a AS m2_6m, track_error_a AS tracking_error_6m
|
|
@@ -261,6 +269,8 @@ def generate_entity_style_stats(entity_info, indicators, isToMySQL, mutable enti
|
|
|
|
|
|
t = null;
|
|
|
|
|
|
+ if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
|
|
|
+
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
t = SELECT entity_id, end_date, upside_capture_ret AS upsidecapture_ret_6m, downside_capture_ret AS downsidecapture_ret_6m,
|
|
@@ -326,6 +336,8 @@ def generate_entity_performance_weekly(entity_info, ret_w, isToMySQL, mutable en
|
|
|
|
|
|
t = null;
|
|
|
|
|
|
+ if(ret_w.isVoid() || ret_w.size() == 0) return;
|
|
|
+
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
t = SELECT entity_id, year_week, year_week.left(4)$INT AS end_year, year_week.right(2)$INT AS week_of_year, price_date,
|
|
@@ -350,6 +362,8 @@ def generate_entity_latest_performance(entity_info, perf_latest, isToMySQL, muta
|
|
|
|
|
|
t = null;
|
|
|
|
|
|
+ if(perf_latest.isVoid() || perf_latest.size() == 0) return;
|
|
|
+
|
|
|
if(isToMySQL) {
|
|
|
|
|
|
t = SELECT r.*
|
|
@@ -487,6 +501,132 @@ def calFundPerformance(entityType, date) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
+/*
|
|
|
+ * 【临时】用于数据初始化:只计算收益
|
|
|
+ *
|
|
|
+ * @param entityType <STRING>: 'MF', 'HF'...
|
|
|
+ * @param date <DATETIME>: 净值更新时间
|
|
|
+ *
|
|
|
+ */
|
|
|
+def ms_calFundReturns() {
|
|
|
+
|
|
|
+ rt = '';
|
|
|
+
|
|
|
+ very_old_date = 1990.01.01;
|
|
|
+
|
|
|
+ // 取基金列表 (27s)
|
|
|
+ tb_cal_funds = ms_get_fund_list_by_nav_createtime(NULL, very_old_date);
|
|
|
+
|
|
|
+ if(tb_cal_funds.isVoid() || tb_cal_funds.size() == 0 ) return;
|
|
|
+
|
|
|
+ tb_fund_performance = create_entity_performance();
|
|
|
+
|
|
|
+ tb_fund_indicator = create_entity_indicator();
|
|
|
+ tb_fund_risk_stats = create_entity_risk_stats();
|
|
|
+ tb_fund_riskadjret_stats = create_entity_riskadjret_stats();
|
|
|
+ tb_fund_style_stats = create_entity_style_stats();
|
|
|
+
|
|
|
+ tb_fund_performance_weekly = create_entity_performance_weekly();
|
|
|
+ tb_fund_latest_performance = create_entity_latest_performance();
|
|
|
+
|
|
|
+ // 分批跑
|
|
|
+ i = 0;
|
|
|
+ batch_size = 1000;
|
|
|
+
|
|
|
+
|
|
|
+ do {
|
|
|
+
|
|
|
+ funds = tb_cal_funds[i : min(tb_cal_funds.size(), i+batch_size)];
|
|
|
+
|
|
|
+ if(funds.isVoid() || funds.size() == 0) break;
|
|
|
+
|
|
|
+ // 200ms
|
|
|
+ fund_info = SELECT entity_id, price_date, inception_date, benchmark_id, ini_value
|
|
|
+ FROM ej(funds, ms_get_fund_info(funds.entity_id), 'entity_id', 'fund_id');
|
|
|
+
|
|
|
+ // 计算月收益 (19s)
|
|
|
+ tb_nav = ms_get_fund_monthly_nav(fund_info.entity_id);
|
|
|
+
|
|
|
+ rets = cal_monthly_returns_by_nav(fund_info, tb_nav);
|
|
|
+
|
|
|
+ if(!rets.isVoid() && rets.size() > 0) {
|
|
|
+
|
|
|
+ // 计算月度指标 (67s)
|
|
|
+ rets.rename!('cumulative_nav', 'nav');
|
|
|
+ indicators = cal_monthly_indicators('MF', 'PBI', rets);
|
|
|
+
|
|
|
+ // 仿照MySQL的表结构准备好记录 (1s)
|
|
|
+ generate_entity_performance(fund_info, indicators, true, tb_fund_performance);
|
|
|
+
|
|
|
+ generate_entity_indicator(fund_info, indicators, true, tb_fund_indicator);
|
|
|
+ generate_entity_risk_stats(fund_info, indicators, true, tb_fund_risk_stats);
|
|
|
+ generate_entity_riskadjret_stats(fund_info, indicators, true, tb_fund_riskadjret_stats);
|
|
|
+ generate_entity_style_stats(fund_info, indicators, true, tb_fund_style_stats);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算周收益 (49s)
|
|
|
+ rets_w = cal_weekly_returns('MF', fund_info);
|
|
|
+
|
|
|
+ if(! rets_w.isVoid() && rets_w.size() > 0) {
|
|
|
+ generate_entity_performance_weekly(fund_info, rets_w, true, tb_fund_performance_weekly);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算最新收益 (23s)
|
|
|
+ perf_latest = cal_latest_performance('MF', fund_info, true);
|
|
|
+
|
|
|
+ if(! perf_latest.isVoid() && perf_latest.size() > 0) {
|
|
|
+ generate_entity_latest_performance(fund_info, perf_latest, true, tb_fund_latest_performance);
|
|
|
+ }
|
|
|
+
|
|
|
+ i += batch_size;
|
|
|
+
|
|
|
+// } while (i < batch_size);
|
|
|
+ } while (i <= tb_cal_funds.size());
|
|
|
+
|
|
|
+
|
|
|
+ if(! tb_fund_performance.isVoid() && tb_fund_performance.size() > 0) {
|
|
|
+
|
|
|
+ // save data to MySQL (26m)
|
|
|
+ try {
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_fund_performance, 'fund_id');
|
|
|
+ save_and_sync(tb_fund_performance, 'raw_db.fund_performance', 'raw_db.fund_performance');
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_fund_indicator, 'fund_id');
|
|
|
+ save_and_sync(tb_fund_indicator, 'raw_db.fund_indicator', 'raw_db.fund_indicator');
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_fund_risk_stats, 'fund_id');
|
|
|
+ // mfdb.fund_performance 表中 maxdrawdown_6m & maxdrawdown_ytd 是虚拟列,这里用数据列顺序强行写入真实列 6m_maxdrawdown & ytd_maxdrawdown (DolphinDB 不允许字段名以数字开头)
|
|
|
+ save_and_sync(tb_fund_risk_stats, 'raw_db.fund_risk_stats', 'raw_db.fund_risk_stats');
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_fund_riskadjret_stats, 'fund_id');
|
|
|
+ save_and_sync(tb_fund_riskadjret_stats, 'raw_db.fund_riskadjret_stats', 'raw_db.fund_riskadjret_stats');
|
|
|
+
|
|
|
+ chg_columns_for_mysql(tb_fund_style_stats, 'fund_id');
|
|
|
+ save_and_sync(tb_fund_style_stats, 'raw_db.fund_style_stats', 'raw_db.fund_style_stats');
|
|
|
+
|
|
|
+ save_and_sync(tb_fund_performance_weekly, 'raw_db.fund_performance_weekly', 'raw_db.fund_performance_weekly');
|
|
|
+
|
|
|
+ save_and_sync(tb_fund_latest_performance, 'raw_db.fund_latest_performance', 'raw_db.fund_latest_nav_performance');
|
|
|
+
|
|
|
+ } catch(ex) {
|
|
|
+
|
|
|
+ //TODO: Log errors
|
|
|
+ rt = ex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return rt;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * 实验性质的API
|
|
|
+ *
|
|
|
+ *
|
|
|
+ */
|
|
|
def calFundIndexCorrelation(entityType, date) {
|
|
|
|
|
|
if(find(['HF', 'MF'], entityType) < 0) return null;
|
|
@@ -501,4 +641,4 @@ def calFundIndexCorrelation(entityType, date) {
|
|
|
coe = cal_entity_index_coe(entityType, tb_cal_funds[0:1000]);
|
|
|
|
|
|
return coe;
|
|
|
-}
|
|
|
+}
|