Browse Source

增加算数平均值和几何平均值

Joey 5 months ago
parent
commit
77f75c8c74
1 changed files with 11 additions and 26 deletions
  1. 11 26
      modules/indicatorCalculator.dos

+ 11 - 26
modules/indicatorCalculator.dos

@@ -1,34 +1,11 @@
 module fundit::indicatorCalculator
 
+use fundit::sqlUtilities
 use fundit::dataPuller
 use fundit::returnCalculator
 use fundit::navCalculator
 
 /*
- *  Annulized multiple
- */
-def get_annulization_multiple(freq) {
-
-  ret = 1;
-  
-  if (freq == 'd') {
-    ret = 252; // We have differences here between Java and DolphinDB, Java uses 365.25 days
-  } else if (freq == 'w') {
-    ret = 52;
-  } else if (freq == 'm') {
-    ret = 12;
-  } else if (freq == 'q') {
-    ret = 4;
-  } else if (freq == 's') {
-    ret = 2;
-  } else if (freq == 'a') {
-    ret = 1;
-  }
-  
-  return ret;
-}
-
-/*
  *   将VaR包裹一层,使之成为系统认可的聚集函数 
  *   @param returns <DOUBLE VECTOR>: 非空收益率
  *   @param method <STRING>: 'normal', 'logNormal', 'historical', 'monteCarlo'
@@ -37,6 +14,8 @@ def get_annulization_multiple(freq) {
  */
 defg aggVaR(returns, method, confidenceLevel) {
 
+    if(returns.form() != 1) return null;
+    
 	return returns.VaR(method, confidenceLevel);
 }
 
@@ -49,6 +28,8 @@ defg aggVaR(returns, method, confidenceLevel) {
  */
 defg aggCVaR(returns, method, confidenceLevel) {
 
+    if(returns.form() != 1) return null;
+
 	return returns.CVaR(method, confidenceLevel);
 }
 
@@ -78,6 +59,7 @@ defg maxDrawdown(navs) {
  *            TODO: SQL is missing for portfolio since inception date return
  *            TODO: Java calculates max drawdown even there is no nav
  *            TODO: Java ytd worst month could be wrong (i.e. portfolio 166002, 2024-03)
+ *            TODO: arith_mean & gerom_mean ARE NOT TESTED
  *     
  */
 def cal_basic_performance(entity_info, ret, trailing_month) {
@@ -87,6 +69,7 @@ def cal_basic_performance(entity_info, ret, trailing_month) {
 
         // 需要至少6个数才计算标准差、峰度、偏度
         t0 = SELECT price_date.max() AS price_date, nav, ret,
+                    ret.mean() AS arith_mean, (1+ret).prod().pow(1\count(entity_id))-1 AS geom_mean,
                     iif(count(entity_id) > 5, std(ret), null) AS std_dev,
                     iif(count(entity_id) > 5, skew(ret, false), null) AS skewness,
                     iif(count(entity_id) > 5, kurtosis(ret, false), null)-3 AS kurtosis,
@@ -95,7 +78,7 @@ def cal_basic_performance(entity_info, ret, trailing_month) {
              WHERE ret > -1
              GROUP BY entity_id
              CGROUP BY end_date
-             ORDER BY end_date;
+             ORDER BY entity_id, end_date;
 
         // 年化收益(给后面计算Calmar用)
         t0.addColumn(['trailing_ret', 'trailing_ret_a'], [DOUBLE, DOUBLE]);
@@ -120,10 +103,11 @@ def cal_basic_performance(entity_info, ret, trailing_month) {
         t1 = SELECT t0.*, t_cvar.drawdown, t_cvar.var, t_cvar.cvar
              FROM t0 LEFT JOIN t_cvar ON t0.entity_id = t_cvar.entity_id AND t0.end_date = t_cvar.end_date
              ORDER BY t0.entity_id, t0.end_date;
-
+        
     } else if(trailing_month == 'ytd') {
 
         t1 = SELECT entity_id, end_date, price_date.cummax() AS price_date, nav, ret,
+                    ret.cumavg() AS arith_mean, (1+ret).cumprod().pow(1\cumcount(entity_id))-1 AS geom_mean,
                     cumprod(1+ret)-1 AS trailing_ret,
                     cumprod(1+ret)-1 AS trailing_ret_a, // no need annulization for ytd
                     iif(cumcount(entity_id) > 5, cumstd(ret), null) AS std_dev,
@@ -141,6 +125,7 @@ def cal_basic_performance(entity_info, ret, trailing_month) {
         win = trailing_month$STRING$INT;
 
         t1 = SELECT entity_id, end_date, price_date.mmax(win) AS price_date, nav, ret,
+                    ret.mavg(win) AS arith_mean, (1+ret).mprod(win).pow(1\mcount(entity_id, win))-1 AS geom_mean,
                     mprod(1+ret, win)-1 AS trailing_ret,
                     iif(win > 12,
                         mprod(1+ret, win).pow(12\win)-1,