|
@@ -9,60 +9,60 @@ use fundit::dataPuller
|
|
* TODO: missing pulling data from local
|
|
* TODO: missing pulling data from local
|
|
* TODO: ONLY support month return now
|
|
* TODO: ONLY support month return now
|
|
*
|
|
*
|
|
- * @param fund_ids: 基金ID STRING VECTOR
|
|
|
|
- * @param isFromMySQL: 净值来源 1 - 远程MySQL、 0 - 本地 DolphinDB
|
|
|
|
|
|
+ * @param fund_ids <STRING VECTOR>: 基金ID
|
|
|
|
+ * @param isFromMySQL <BOOL>: 净值来源 1 - 远程MySQL、 0 - 本地 DolphinDB
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
-def cal_hedge_fund_returns(fund_ids, isFromMySQL){
|
|
|
|
|
|
+def cal_fund_monthly_returns(entity_type, fund_ids, isFromMySQL){
|
|
|
|
|
|
tb_rets = null;
|
|
tb_rets = null;
|
|
|
|
+
|
|
|
|
+ // 暂时只支持公募和私募基金
|
|
|
|
+ if(entity_type != 'HF' && entity_type != 'MF' ) return tb_rets;
|
|
|
|
|
|
// 用于保证老基金也能取到所有历史净值
|
|
// 用于保证老基金也能取到所有历史净值
|
|
very_old_price_date = 1990.01.01;
|
|
very_old_price_date = 1990.01.01;
|
|
|
|
|
|
- if(isFromMySQL){
|
|
|
|
-
|
|
|
|
// 基金基本信息,包括初始净值
|
|
// 基金基本信息,包括初始净值
|
|
tb_fund_info = get_fund_info(fund_ids);
|
|
tb_fund_info = get_fund_info(fund_ids);
|
|
|
|
|
|
// 基金净值
|
|
// 基金净值
|
|
- tb_nav = SELECT * FROM get_hedge_fund_nav_by_price_date(fund_ids, very_old_price_date, true);
|
|
|
|
-
|
|
|
|
- tb_month_end = table(100:0, ['fund_id', 'price_date'], [STRING, DATE]);
|
|
|
|
- // 填充好各基金有效期内所有月份的最后一天
|
|
|
|
- for( f in tb_fund_info )
|
|
|
|
- {
|
|
|
|
- INSERT INTO tb_month_end SELECT fund_id, price_date FROM table(f.fund_id.take(1) AS fund_id).cj(table(temporalSeq(f.inception_date, today(), 'M') AS price_date)) ;
|
|
|
|
- }
|
|
|
|
|
|
+ tb_nav = SELECT * FROM get_nav_by_price_date(entity_type, fund_ids, very_old_price_date, isFromMySQL);
|
|
|
|
+
|
|
|
|
+ tb_month_end = table(100:0, ['fund_id', 'price_date'], [STRING, DATE]);
|
|
|
|
+ // 填充好各基金有效期内所有月份的最后一天
|
|
|
|
+ for( f in tb_fund_info )
|
|
|
|
+ {
|
|
|
|
+ INSERT INTO tb_month_end SELECT fund_id, price_date FROM table(f.fund_id.take(1) AS fund_id).cj(table(temporalSeq(f.inception_date, today(), 'M') AS price_date)) ;
|
|
|
|
+ }
|
|
|
|
|
|
- UPDATE tb_month_end SET end_date = price_date.month();
|
|
|
|
|
|
+ UPDATE tb_month_end SET end_date = price_date.month();
|
|
|
|
|
|
- tb_monthly_nav = SELECT fund_id, monthEnd(price_date).month().last() AS end_date, price_date.last() AS price_date, cumulative_nav.last() AS cumulative_nav
|
|
|
|
- FROM tb_nav
|
|
|
|
- GROUP BY fund_id, monthEnd(price_date);
|
|
|
|
|
|
+ tb_monthly_nav = SELECT fund_id, monthEnd(price_date).month().last() AS end_date, price_date.last() AS price_date, cumulative_nav.last() AS cumulative_nav
|
|
|
|
+ FROM tb_nav
|
|
|
|
+ GROUP BY fund_id, monthEnd(price_date);
|
|
|
|
|
|
- // 完整月末日期的净值序列(包括缺失数据为NULL)
|
|
|
|
- tb_monthly_nav = SELECT me.fund_id, me.end_date, n.price_date, n.cumulative_nav
|
|
|
|
- FROM tb_month_end me
|
|
|
|
- LEFT JOIN tb_monthly_nav n ON me.fund_id = n.fund_id AND me.end_date = n.end_date
|
|
|
|
- ORDER BY me.fund_id, me.end_date;
|
|
|
|
|
|
+ // 完整月末日期的净值序列(包括缺失数据为NULL)
|
|
|
|
+ tb_monthly_nav = SELECT me.fund_id, me.end_date, n.price_date, n.cumulative_nav
|
|
|
|
+ FROM tb_month_end me
|
|
|
|
+ LEFT JOIN tb_monthly_nav n ON me.fund_id = n.fund_id AND me.end_date = n.end_date
|
|
|
|
+ ORDER BY me.fund_id, me.end_date;
|
|
|
|
|
|
- // 补一下成立日的初始净值
|
|
|
|
- // NOTE: DolphinDB 遇见 EXISTS 语句时,似乎主表的 alias 失效,只好用全名
|
|
|
|
- INSERT INTO tb_monthly_nav
|
|
|
|
- SELECT fund_id, inception_date.month(), inception_date, ifNull(ini_value, 1)
|
|
|
|
- FROM tb_fund_info fi
|
|
|
|
- WHERE NOT EXISTS ( SELECT * FROM tb_monthly_nav n WHERE fund_id = tb_fund_info.fund_id AND n.price_date = tb_fund_info.inception_date);
|
|
|
|
|
|
+ // 补一下成立日的初始净值
|
|
|
|
+ // NOTE: DolphinDB 遇见 EXISTS 语句时,似乎主表的 alias 失效,只好用全名
|
|
|
|
+ INSERT INTO tb_monthly_nav
|
|
|
|
+ SELECT fund_id, inception_date.month(), inception_date, ifNull(ini_value, 1)
|
|
|
|
+ FROM tb_fund_info fi
|
|
|
|
+ WHERE NOT EXISTS ( SELECT * FROM tb_monthly_nav n WHERE fund_id = tb_fund_info.fund_id AND n.price_date = tb_fund_info.inception_date);
|
|
|
|
|
|
- // 算 ratios 之前先把时间顺序排好
|
|
|
|
- tb_monthly_nav.sortBy!(['fund_id', 'end_date', 'price_date'], [1, 1, 1]);
|
|
|
|
|
|
+ // 算 ratios 之前先把时间顺序排好
|
|
|
|
+ tb_monthly_nav.sortBy!(['fund_id', 'end_date', 'price_date'], [1, 1, 1]);
|
|
|
|
|
|
- // 计算月收益
|
|
|
|
- tb_rets = SELECT fund_id, end_date, price_date, cumulative_nav, cumulative_nav.ratios() - 1 AS ret
|
|
|
|
- FROM tb_monthly_nav
|
|
|
|
- CONTEXT BY fund_id;
|
|
|
|
|
|
+ // 计算月收益
|
|
|
|
+ tb_rets = SELECT fund_id, end_date, price_date, cumulative_nav, cumulative_nav.ratios() - 1 AS ret
|
|
|
|
+ FROM tb_monthly_nav
|
|
|
|
+ CONTEXT BY fund_id;
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
// the records without return calculated but do have nav are still useful for some calculations
|
|
// the records without return calculated but do have nav are still useful for some calculations
|
|
return ( SELECT * FROM tb_rets WHERE cumulative_nav > 0 );
|
|
return ( SELECT * FROM tb_rets WHERE cumulative_nav > 0 );
|
|
@@ -120,7 +120,7 @@ def cal_fund_performance(fund_ids, month_end) {
|
|
def cal_mutual_fund_performance(fund_ids, isFromMySQL) {
|
|
def cal_mutual_fund_performance(fund_ids, isFromMySQL) {
|
|
|
|
|
|
// 计算月收益
|
|
// 计算月收益
|
|
- tb_tmp = cal_hedge_fund_returns(fund_ids, isFromMySQL);
|
|
|
|
|
|
+ tb_tmp = cal_fund_monthly_returns('MF', fund_ids, isFromMySQL);
|
|
|
|
|
|
tb_rets = SELECT fund_id, end_date, ret_1m,
|
|
tb_rets = SELECT fund_id, end_date, ret_1m,
|
|
(1 + ret_1m).mprod(3) - 1 AS ret_3m, (1 + ret_1m).mprod(6) - 1 AS ret_6m, (1 + ret_1m).mprod(12) - 1 AS ret_1y,
|
|
(1 + ret_1m).mprod(3) - 1 AS ret_3m, (1 + ret_1m).mprod(6) - 1 AS ret_6m, (1 + ret_1m).mprod(12) - 1 AS ret_1y,
|
|
@@ -188,7 +188,7 @@ def cal_hedge_fund_weekly_returns(fund_ids, isFromMySQL) {
|
|
// 用于保证老基金也能取到所有历史净值
|
|
// 用于保证老基金也能取到所有历史净值
|
|
very_old_price_date = 1990.01.01
|
|
very_old_price_date = 1990.01.01
|
|
|
|
|
|
- tb_nav = get_hedge_fund_nav_by_price_date(fund_ids, very_old_price_date, isFromMySQL)
|
|
|
|
|
|
+ tb_nav = get_nav_by_price_date('HF', fund_ids, very_old_price_date, isFromMySQL)
|
|
|
|
|
|
UPDATE tb_nav SET year_week = price_date.year()$STRING + (price_date.weekOfYear()$STRING).lpad(2, "0")
|
|
UPDATE tb_nav SET year_week = price_date.year()$STRING + (price_date.weekOfYear()$STRING).lpad(2, "0")
|
|
|
|
|
|
@@ -240,7 +240,7 @@ def cal_hedge_fund_latest_returns(fund_ids, isFromMySQL) {
|
|
// 用于保证老基金也能取到所有历史净值
|
|
// 用于保证老基金也能取到所有历史净值
|
|
very_old_price_date = 1990.01.01
|
|
very_old_price_date = 1990.01.01
|
|
|
|
|
|
- tb_nav = get_hedge_fund_nav_by_price_date(fund_ids, very_old_price_date, isFromMySQL)
|
|
|
|
|
|
+ tb_nav = get_nav_by_price_date('HF', fund_ids, very_old_price_date, isFromMySQL)
|
|
|
|
|
|
tb_last_nav = SELECT fund_id, price_date.last() AS price_date, cumulative_nav.last() AS cumulative_nav
|
|
tb_last_nav = SELECT fund_id, price_date.last() AS price_date, cumulative_nav.last() AS cumulative_nav
|
|
FROM tb_nav
|
|
FROM tb_nav
|