Joey vor 1 Monat
Ursprung
Commit
74da301e3c
1 geänderte Dateien mit 41 neuen und 38 gelöschten Zeilen
  1. 41 38
      modules/returnCalculator.dos

+ 41 - 38
modules/returnCalculator.dos

@@ -3,15 +3,18 @@ use fundit::fundCalculator
 use fundit::dataPuller
 
 /*
- *  根据私募基金净值序列计算月收益序列(适合提供给指标运算)
+ *  根据基金净值序列计算月收益序列(适合提供给指标运算)
  * 
  *  Create:  20240907                                                  Joey
  *                    TODO: missing pulling data from local
  *                    TODO: ONLY support month return now
  *                    
+ *  @param entity_type <STRING>: NAV universe, 'HF','MF','PF','EQ'... defined in get_nav_table_description()
  *  @param fund_ids <STRING VECTOR>: 基金ID
  *  @param isFromMySQL <BOOL>: 净值来源 1 - 远程MySQL、 0 - 本地 DolphinDB
  *  
+ *  Example: cal_fund_monthly_returns('HF', "'HF000004KN','HF000103EU','HF00018WXG'", true);
+ *  
  */
 def cal_fund_monthly_returns(entity_type, fund_ids, isFromMySQL){
 
@@ -23,45 +26,45 @@ def cal_fund_monthly_returns(entity_type, fund_ids, isFromMySQL){
     // 用于保证老基金也能取到所有历史净值
     very_old_price_date = 1990.01.01;
 
-        // 基金基本信息,包括初始净值
-        tb_fund_info = get_fund_info(fund_ids);
-
-        // 基金净值
-        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();
-    
-        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_fund_info = get_fund_info(fund_ids);
 
-        // 完整月末日期的净值序列(包括缺失数据为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;
+    // 基金净值
+    tb_nav = SELECT * FROM get_nav_by_price_date(entity_type, fund_ids, very_old_price_date, isFromMySQL);
 
-        // 补一下成立日的初始净值
-        // 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);
+    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)) ;
+    }
 
-        // 算 ratios 之前先把时间顺序排好
-        tb_monthly_nav.sortBy!(['fund_id', 'end_date', 'price_date'], [1, 1, 1]);
+    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);
+
+    // 完整月末日期的净值序列(包括缺失数据为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);
+
+    // 算 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
@@ -71,8 +74,8 @@ def cal_fund_monthly_returns(entity_type, fund_ids, isFromMySQL){
 /*
  *  月末 fund_performance 表计算
  *  
- *  @param fund_ids: 逗号分隔的ID
- *  @param end_date:
+ *  @param fund_ids <STRING>: 逗号分隔的ID
+ *  @param end_date <STRING>: YYYY-MM 
  * 
  *  Example: cal_fund_performance("'HF000004KN','HF00018WXG','HF000103EU'", '2024-06', true);
  */