Bläddra i källkod

修复一个bug

Joey 1 vecka sedan
förälder
incheckning
7996560b4f
1 ändrade filer med 32 tillägg och 19 borttagningar
  1. 32 19
      modules/indicatorCalculator.dos

+ 32 - 19
modules/indicatorCalculator.dos

@@ -76,7 +76,7 @@ def cal_basic_performance(ret, freq) {
  *   NOTE: risk free rate is used as Minimal Accepted Rate (MAR) here
  * 
  */
-def cal_LPM(ret, risk_free_rate) {
+def cal_LPM(ret, risk_free) {
     
     t = SELECT *, count(entity_id) AS cnt FROM ret WHERE ret > -1 CONTEXT BY entity_id;
 
@@ -85,7 +85,7 @@ def cal_LPM(ret, risk_free_rate) {
                  (sum2(rfr.ret - t.ret) \ (t.cnt[0])).pow(1\2) AS lpm2, 
                  (sum3(rfr.ret - t.ret) \ (t.cnt[0])).pow(1\3) AS lpm3
           FROM t 
-          INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+          INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
           WHERE t.ret < rfr.ret
           GROUP BY t.entity_id;
 
@@ -100,9 +100,9 @@ def cal_LPM(ret, risk_free_rate) {
  *           Java'version of Kappa could be very wrong
  *           
  */
-def cal_omega_sortino_kappa(ret, risk_free_rate) {
+def cal_omega_sortino_kappa(ret, risk_free) {
 
-    lpm = cal_LPM(ret, risk_free_rate);
+    lpm = cal_LPM(ret, risk_free);
 
     tb = SELECT t.entity_id, 
                 l.lpm2[0] AS ds_dev,
@@ -111,7 +111,7 @@ def cal_omega_sortino_kappa(ret, risk_free_rate) {
                 (t.ret - rfr.ret ).mean() \ l.lpm3[0] AS kappa
               FROM ret t
               INNER JOIN lpm l ON t.entity_id = l.entity_id
-              INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+              INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
               GROUP BY t.entity_id;
 
     return tb;
@@ -135,7 +135,7 @@ def cal_alpha_beta(ret, bmk_ret, risk_free) {
     alpha = SELECT t.entity_id, (t.ret - rfr.ret).mean() - beta.beta[0] * (t.ret_bmk - rfr.ret).mean() AS alpha
             FROM t 
             INNER JOIN beta beta ON t.entity_id = beta.entity_id
-            INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+            INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
             GROUP BY t.entity_id;
 
     return ( SELECT * FROM beta AS b INNER JOIN alpha AS a ON a.entity_id = b.entity_id  );
@@ -168,12 +168,12 @@ def cal_benchmark_tracking(ret, bmk_ret) {
  *    Sharpe Ratio
  *    NOTE: Java version is noncompliant-GIPS annulized number
  */
-def cal_sharpe(ret, std_dev, risk_free_rate) {
+def cal_sharpe(ret, std_dev, risk_free) {
 
     sharpe = SELECT t.entity_id, (t.ret - rfr.ret).mean() / std.std_dev[0] AS sharpe
              FROM ret t
              INNER JOIN std_dev std ON t.entity_id = std.entity_id
-             INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+             INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
              WHERE std.std_dev[0] <> 0
              GROUP BY t.entity_id;
 
@@ -183,11 +183,11 @@ def cal_sharpe(ret, std_dev, risk_free_rate) {
 /*
  *    Treynor Ratio
  */
-def cal_treynor(ret, risk_free_rate, beta) {
+def cal_treynor(ret, risk_free, beta) {
 
     t = SELECT *, count(entity_id) AS cnt 
        FROM ret t 
-       INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date 
+       INNER JOIN risk_free rfr ON t.end_date = rfr.end_date 
        WHERE t.ret > -1
          AND rfr.ret > -1
        CONTEXT BY t.entity_id;
@@ -204,12 +204,12 @@ def cal_treynor(ret, risk_free_rate, beta) {
  *    Jensen's Alpha
  *    TODO: the result is slightly off
  */
-def cal_jensen(ret, bmk_ret, risk_free_rate, beta) {
+def cal_jensen(ret, bmk_ret, risk_free, beta) {
 
     jensen = SELECT t.entity_id, t.ret.mean() - rfr.ret.mean() - beta.beta[0] * (bmk.ret.mean() - rfr.ret.mean()) AS jensen
              FROM ret t
              INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
-             INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+             INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
              INNER JOIN beta beta ON t.entity_id = beta.entity_id
              GROUP BY t.entity_id;
                
@@ -234,12 +234,12 @@ def cal_calmar(ret_a){
  *     NOTE: M2 = sharpe * std(benchmark) + risk_free_rate
  *     NOTE: Java version is noncompliant-GIPS annulized number 
  */
-def cal_m2(ret, bmk_ret, risk_free_rate) {
+def cal_m2(ret, bmk_ret, risk_free) {
 
     m2 = SELECT t.entity_id, (t.ret - rfr.ret).mean() / t.ret.std() * bmk.ret.std() + rfr.ret.mean() AS m2
          FROM ret t
          INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
-         INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+         INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
          GROUP BY t.entity_id;
 
     return m2;
@@ -255,13 +255,13 @@ def cal_m2(ret, bmk_ret, risk_free_rate) {
  * 
  * 
  */
-def cal_ms_return(ret, risk_free_rate) {
+def cal_ms_return(ret, risk_free) {
 
     r = SELECT t.entity_id, t.end_date.max() AS end_date, t.price_date.max() AS price_date, t.price_date.min() AS min_date,
                ((1 + t.ret)\(1 + rfr.ret)).prod().pow(12\(t.end_date.max() - t.end_date.min()))-1 AS ms_ret_a,
                (1 + t.ret).pow(-2).mean().pow(-12/2)-1 AS ms_rar_a
         FROM ret t
-        INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
+        INNER JOIN risk_free rfr ON t.end_date = rfr.end_date
         GROUP BY t.entity_id;
 
     return r;
@@ -442,7 +442,7 @@ def cal_all_trailing_indicators(entity_info, mutable tb_ret, end_day, bmk_ret, r
 }
 
 /*
- *   Calculate fund indicators for month-end production
+ *   Calculate fund indicators for one date
  * 
  *   @param entity_type <STRING>: MF, HF
  *   @param fund_ids <STRING>: 逗号和单引号分隔的fund_id
@@ -450,6 +450,8 @@ def cal_all_trailing_indicators(entity_info, mutable tb_ret, end_day, bmk_ret, r
  *   @param isFromNav <BOOL>: 用净值实时计算还是从表中取月收益
  *   @param isFromSQL <BOOL>: TODO: 从MySQL还是本地DolphinDB取净值/收益数据
  * 
+ *   Example: cal_fund_indicators('FD', "'HF000004KN','HF000103EU','HF00018WXG'", 2024.06.28, true);
+ * 
  */
 def cal_fund_indicators(entity_type, fund_ids, end_day, isFromNav) {
 
@@ -475,6 +477,17 @@ def cal_fund_indicators(entity_type, fund_ids, end_day, isFromNav) {
     return cal_all_trailing_indicators(fund_info, tb_ret, end_day, bmk_ret, risk_free_rate, 'm');
 }
 
+/*
+ *  Calculate portfolio indicators for one date
+ *  
+ *  @param portfolio_ids <STRING>: comma-delimited portfolio ids
+ *  @param end_day <DATE>: the date
+ *  @param cal_method <INT>: calculate based on cumulative nav (1) or nav (2)
+ *  @param isFromNav <BOOL>: calculate returns from NAV on-the-fly (true) or get from monthly return table (false)
+ *  
+ *  Example: cal_portfolio_indicators('166002,166114', 2024.08.31, 1, true);
+ * 
+ */
 def cal_portfolio_indicators(portfolio_ids, end_day, cal_method, isFromNav) {
 
     very_old_date = 1990.01.01;
@@ -484,7 +497,7 @@ def cal_portfolio_indicators(portfolio_ids, end_day, cal_method, isFromNav) {
 
     if(isFromNav == true) {
         // 从净值开始计算收益
-        tb_raw_ret = SELECT * FROM cal_portfolio_return(portfolio_ids, very_old_date, cal_method) WHERE price_date <= end_day;
+        tb_raw_ret = SELECT * FROM cal_portfolio_nav(portfolio_ids, very_old_date, cal_method) WHERE price_date <= end_day;
        
         // funky thing is you can't use "AS" for the grouping columns?
         tb_ret = SELECT portfolio_id, price_date.month(), price_date.last() AS price_date, (1+ret).prod()-1 AS ret, nav.last() AS nav
@@ -499,7 +512,7 @@ def cal_portfolio_indicators(portfolio_ids, end_day, cal_method, isFromNav) {
         tb_ret.rename!(['portfolio_id'], ['entity_id']);
     }
 
-    
+    // 沪深300做基准,同SQL保持一致
     bmk_ret = SELECT fund_id, temporalParse(end_date, 'yyyy-MM') AS end_date, ret FROM get_monthly_ret('IX', "'IN00000008'", very_old_date, end_day, true); 
 
     risk_free_rate = SELECT fund_id, temporalParse(end_date, 'yyyy-MM') AS end_date, ret FROM get_risk_free_rate(very_old_date, end_day);