Test_indicatorCalculator.dos 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. login(`admin, `123456)
  2. loadPlugin("ODBC")
  3. clearCachedModules()
  4. use fundit::fundCalculator
  5. use fundit::dataPuller
  6. use fundit::returnCalculator
  7. use fundit::indicatorCalculator
  8. /* init values for test cases */
  9. end_day = 2024.08.31; //2024.06.28;
  10. fund_ids = "'MF00003PW1','MF00003RS0'"; //"'HF000004KN','HF000103EU','HF00018WXG'";
  11. entity_type = "MF"; //'HF';
  12. isFromNav = true;
  13. /* codes from cal_fund_indicators */
  14. very_old_date = 1990.01.01;
  15. start_month = very_old_date.month();
  16. fund_info = get_fund_info(fund_ids);
  17. fund_info.rename!('fund_id', 'entity_id');
  18. if(isFromNav == true) {
  19. // 从净值开始计算收益
  20. tb_ret = SELECT * FROM cal_fund_monthly_returns(entity_type, fund_ids, true) WHERE price_date <= end_day;
  21. tb_ret.rename!(['fund_id', 'cumulative_nav'], ['entity_id', 'nav']);
  22. } else {
  23. // 从fund_performance表里读月收益
  24. tb_ret = get_monthly_ret('FD', fund_ids, very_old_date, end_day, true);
  25. tb_ret.rename!(['fund_id'], ['entity_id']);
  26. }
  27. // 取基金和基准的对照表
  28. primary_benchmark = SELECT fund_id AS entity_id, end_date, iif(benchmark_id.isNull(), 'IN00000008', benchmark_id) AS benchmark_id
  29. FROM get_fund_primary_benchmark(fund_ids, start_month.temporalFormat('yyyy-MM'), end_day.month().temporalFormat('yyyy-MM')) ;
  30. // 取所有出现的基准月收益
  31. bmk_ret = get_benchmark_return(primary_benchmark, end_day);
  32. 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);
  33. entity_info = fund_info;
  34. entity_ids = fund_ids.strReplace("'", "").split(',');
  35. /* Test START */
  36. // trailing 2 year standard indicators
  37. rtn = cal_basic_performance(entity_info, tb_ret, '24');
  38. @testing: case = 'trailing 2y return'
  39. assert (select rtn.trailing_ret.round(4) as trailing_ret
  40. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).trailing_ret == [-0.285094, -0.297968, 0.031337, 0.013295].round(4);
  41. @testing: case = 'trailing 2y std_dev_a'
  42. assert (select (rtn.std_dev * sqrt(12)).round(4) as std_dev_a
  43. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).std_dev_a == [0.152789, 0.153595, 0.035974, 0.037412].round(4);
  44. @testing: case = 'trailing 2y skewness'
  45. assert (select rtn.skewness.round(2) as skewness
  46. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).skewness == [-0.311358, -0.258296, 0.301213, 0.364476].round(2);
  47. @testing: case = 'trailing 2y kurtosis'
  48. assert (select rtn.kurtosis.round(2) as kurtosis
  49. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).kurtosis == [2.425262, 2.284389, 4.222244, 3.397426].round(2);
  50. @testing: case = 'trailing 2y wrst_month'
  51. assert (select rtn.wrst_month.round(4) as wrst_month
  52. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).wrst_month == [-0.134443, -0.134443, -0.026231, -0.026231].round(4);
  53. @testing: case = 'trailing 2y max drawdown'
  54. assert (select rtn.drawdown.round(4) as drawdown // values from swagger
  55. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).drawdown == [0.376406, 0.376406, 0.044551, 0.044551].round(4);
  56. @testing: case = 'trailing 2y var'
  57. assert (select rtn.var.round(4) as var // [FAIL]
  58. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).var == [0.120004, 0.120004, 0.023467, 0.023467].round(4);
  59. @testing: case = 'trailing 2y cvar'
  60. assert (select rtn.cvar.round(4) as cvar // [FAIL]
  61. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).cvar == [0.134443, 0.134443, 0.026231, 0.026231].round(4);
  62. @testing: case = 'trailing 2y calmar'
  63. assert (select rtn.calmar.round(4) as calmar // [FAIL]
  64. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).calmar == [-0.381017, -0.404476, 0.283223, 0.123738].round(4);
  65. // year-to-day standard indicators
  66. rtn = cal_basic_performance(entity_info, tb_ret, 'ytd');
  67. @testing: case = 'ytd return'
  68. assert (select rtn.trailing_ret.round(4) as trailing_ret
  69. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).trailing_ret == [-0.026889, -0.061460, 0.025689, 0.011772].round(4);
  70. @testing: case = 'ytd std_dev_a'
  71. assert (select (rtn.std_dev * sqrt(12)).round(4) as std_dev_a
  72. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).std_dev_a == [0.236684, 0.222985, 0.060555, 0.059946].round(4);
  73. @testing: case = 'skewness'
  74. assert (select rtn.skewness.round(2) as skewness
  75. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).skewness == [-1.007946, -0.748978, -0.150076, 0.186127].round(2);
  76. @testing: case = 'ytd kurtosis' // [FAIL]
  77. assert (select rtn.kurtosis.round(2) as kurtosis
  78. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).kurtosis == [3.206713, 2.737161, 1.998417, 1.046022].round(2);
  79. @testing: case = 'ytd wrst_month'
  80. assert (select rtn.wrst_month.round(4) as wrst_month
  81. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).wrst_month == [-0.134443, -0.134443, -0.026231, -0.026231].round(4);
  82. @testing: case = 'ytd max drawdown' // [FAIL] values from swagger
  83. assert (select rtn.drawdown.round(4) as drawdown
  84. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).drawdown == [0.006631, 0.038057, 0.002126, 0.014966].round(4);
  85. @testing: case = 'ytd calmar' // [FAIL]
  86. assert (select rtn.calmar.round(4) as calmar
  87. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).calmar == [-0.131580, -0.368421, 0.885691, 0.432796].round(4);
  88. // since-inception-date standard indicators
  89. rtn = cal_basic_performance(entity_info, tb_ret, 'incep');
  90. @testing: case = 'incep return'
  91. assert (select rtn.trailing_ret.round(4) as trailing_ret
  92. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).trailing_ret == [3.918337, 3.743607, 0.268718, 0.251503].round(4);
  93. @testing: case = 'incep std_dev_a'
  94. assert (select (rtn.std_dev * sqrt(12)).round(2) as std_dev_a
  95. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).std_dev_a == [0.215823, 0.215617, 0.026656, 0.027113].round(2);
  96. @testing: case = 'incep skewness' // [FAIL] SLIGHTLY OFF
  97. assert (select rtn.skewness.round(2) as skewness
  98. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).skewness == [0.032796, 0.039251, -0.172258, -0.189262].round(2);
  99. @testing: case = 'incep kurtosis' // [FAIL] SLIGHTLY OFF
  100. assert (select rtn.kurtosis.round(2) as kurtosis
  101. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).kurtosis == [1.882971, 1.884570, 3.413939, 3.097421].round(2);
  102. @testing: case = 'incep wrst_month'
  103. assert (select rtn.wrst_month.round(4) as wrst_month
  104. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).wrst_month == [-0.221418, -0.221418, -0.026231, -0.026231].round(4);
  105. @testing: case = 'incep drawdown' // values from swagger
  106. assert (select rtn.drawdown.round(4) as drawdown
  107. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).drawdown == [0.545799, 0.545799, 0.044551, 0.044551].round(4);
  108. @testing: case = 'incep var' // [FAIL]
  109. assert (select rtn.var.round(4) as var
  110. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).var == [0.098647, 0.098641, 0.012435, 0.012578].round(4);
  111. @testing: case = 'incep cvar' // [FAIL]
  112. assert (select rtn.cvar.round(4) as cvar
  113. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).cvar == [0.139853, 0.139853, 0.016819, 0.017078].round(4);
  114. @testing: case = 'incep calmar' // [FAIL]
  115. assert (select rtn.calmar.round(4) as calmar
  116. from rtn where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).calmar == [0.123467, 0.120115, 0.564536, 0.526222].round(4);
  117. // trailing 2 year lpms
  118. lpms = cal_omega_sortino_kappa(tb_ret, risk_free_rate, '24');
  119. @testing: case = 'trailing 2y downside deviation' // slightly off
  120. assert (select (lpms.ds_dev * sqrt(12))round(2) as ds_dev
  121. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).ds_dev == [0.139780, 0.141592, 0.024837, 0.027034].round(2);
  122. @testing: case = 'trailing 2y omega' // [FAIL]
  123. assert (select lpms.omega.round(4) as omega
  124. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).omega == [0.412705, 0.405461, 0.971179, 0.797404].round(4);
  125. @testing: case = 'trailing 2y sortino' // [FAIL]
  126. assert (select (lpms.sortino * sqrt(12)).round(4) as sortino_a
  127. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).sortino_a == [-1.228926, -1.274774, -0.022708, -0.341091].round(4);
  128. @testing: case = 'trailing 2y kappa' // [FAIL]
  129. assert (select lpms.kappa.round(4) as kappa
  130. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).kappa == [-1.400459, -1.456120, -0.050796, -0.406572].round(4);
  131. // ytd lpms
  132. lpms = cal_omega_sortino_kappa(tb_ret, risk_free_rate, 'ytd');
  133. @testing: case = 'ytd downside deviation' // [FAIL] slightly off
  134. assert (select (lpms.ds_dev * sqrt(12))round(2) as ds_dev_a
  135. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).ds_dev_a == [0.192270, 0.184391, 0.039096, 0.041043].round(2);
  136. @testing: case = 'ytd omega' // [FAIL]
  137. assert (select lpms.omega.round(4) as omega
  138. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).omega == [0.799024,0.670686,1.477292,1.039491].round(4);
  139. @testing: case = 'ytd sortino' // [FAIL]
  140. assert (select (lpms.sortino * sqrt(12)).round(4) as sortino_a
  141. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).sortino_a == [-0.187914,-0.470279,0.783559,0.113041].round(4);
  142. @testing: case = 'ytd kappa' // [FAIL]
  143. assert (select lpms.kappa.round(4) as kappa
  144. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).kappa == [-0.352469,-0.644631, 0.862919, 0.090396].round(4);
  145. // since inception lpms
  146. lpms = cal_omega_sortino_kappa(tb_ret, risk_free_rate, 'incep');
  147. @testing: case = 'incep downside deviation'
  148. assert (select (lpms.ds_dev * sqrt(12))round(2) as ds_dev_a
  149. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).ds_dev_a == [0.140304, 0.140258, 0.017540, 0.018214].round(2);
  150. @testing: case = 'incep omega' // [FAIL] slightly off
  151. assert (select lpms.omega.round(4) as omega
  152. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).omega == [1.217150,1.208021,1.541471,1.437023].round(4);
  153. @testing: case = 'incep sortino' // [FAIL] slightly off
  154. assert (select (lpms.sortino * sqrt(12)).round(4) as sortino_a
  155. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).sortino_a == [0.509534,0.496273,0.809670,0.671315].round(4);
  156. @testing: case = 'incep kappa' // [FAIL]
  157. assert (select lpms.kappa.round(4) as kappa
  158. from lpms where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).kappa == [0.372816,0.358662,0.817694,0.684683].round(4);
  159. // 2y bechmark tracking
  160. bmk_tracking = cal_benchmark_tracking(tb_ret, primary_benchmark, bmk_ret, '24');
  161. @testing: case = 'trailing2y win rate'
  162. assert (select winrate.round(4) as winrate
  163. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).winrate == [0.416667,0.416667,0.375000,0.375000].round(4);
  164. @testing: case = 'trailing2y tracking error'
  165. assert (select (track_error * sqrt(12)).round(3) as track_error_a
  166. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).track_error_a == [0.153428,0.153685,0.039662,0.040514].round(3);
  167. @testing: case = 'trailing2y information ratio' // [FAIL]
  168. assert (select info.round(4) as info
  169. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).info == [5.609963 ,5.569559 ,24.083419,23.449405].round(4);
  170. // ytd bechmark tracking
  171. bmk_tracking = cal_benchmark_tracking(tb_ret, primary_benchmark, bmk_ret, 'ytd');
  172. @testing: case = 'ytd win rate'
  173. assert (select winrate.round(4) as winrate
  174. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).winrate == [0.428571,0.375000,0.571429,0.500000].round(4);
  175. @testing: case = 'ytd tracking error'
  176. assert (select (track_error * sqrt(12)).round(2) as track_error_a
  177. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).track_error_a == [0.172443,0.161193,0.066815,0.063451].round(2);
  178. @testing: case = 'ytd information ratio' // [FAIL]
  179. assert (select info.round(4) as info
  180. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).info == [5.170620 ,5.392240 ,14.194093,14.655729].round(4);
  181. // incep bechmark tracking
  182. bmk_tracking = cal_benchmark_tracking(tb_ret, primary_benchmark, bmk_ret, 'incep');
  183. @testing: case = 'incep win rate' // [FAIL]
  184. assert (select winrate.round(4) as winrate
  185. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).winrate == [0.446494,0.444853,0.458333,0.453608].round(4);
  186. @testing: case = 'incep tracking error'
  187. assert (select (track_error * sqrt(12)).round(3) as track_error_a
  188. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).track_error_a == [0.133228,0.133079,0.026158,0.026478].round(3);
  189. @testing: case = 'incep information ratio' // [FAIL]
  190. assert (select info.round(4) as info
  191. from bmk_tracking where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).info == [7.727110 ,7.713382 ,37.492177,36.942698].round(4);
  192. // 2y alpha, beta
  193. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  194. @testing: case = 'trailing2y beta'
  195. assert (select beta.round(2) as beta
  196. from alpha_beta where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).beta == [0.484263,0.497796,0.035154,0.087369].round(2);
  197. @testing: case = 'trailing2y alpha' // [FAIL]
  198. assert (select (alpha * 12).round(3) as alpha_a
  199. from alpha_beta where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).alpha_a == [-0.147936,-0.155315,0.014126 ,0.002815].round(3);
  200. // ytd alpha, beta
  201. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  202. @testing: case = 'ytd beta' // [FAIL] slightly off
  203. assert (select beta.round(4) as beta
  204. from alpha_beta where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).beta == [2.461836 ,2.444270 ,-1.772254,-0.576641].round(4);
  205. @testing: case = 'ytd alpha' // [FAIL]
  206. assert (select (alpha * 12).round(3) as alpha_a
  207. from alpha_beta where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).alpha_a == [-0.148226,-0.140843,0.199161 ,0.064237].round(3);
  208. // incep alpha, beta
  209. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  210. @testing: case = 'incep beta' // [FAIL] slightly off
  211. assert (select beta.round(4) as beta
  212. from alpha_beta where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).beta == [1.418055,1.418947,0.530804,0.540277].round(4);
  213. @testing: case = 'incep alpha' // [FAIL]
  214. assert (select (alpha * 12).round(3) as alpha_a
  215. from alpha_beta where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).alpha_a == [-0.001796,-0.002707,0.007096 ,0.004842].round(3);
  216. // 2y capture indicators
  217. capture_r = cal_capture_ratio(tb_ret, primary_benchmark, bmk_ret, '24');
  218. @testing: case = 'trailing2y upside capture return' // [FAIL]
  219. assert (select upside_capture_ret.round(4) as upside_capture_ret
  220. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).upside_capture_ret == [-0.003743,-0.003743, 0.002156, 0.001314].round(4);
  221. @testing: case = 'trailing2y upside capture ratio' // [FAIL]
  222. assert (select upside_capture_ratio.round(4) as upside_capture_ratio
  223. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).upside_capture_ratio == [-0.223084,-0.223084, 0.365611, 0.237662].round(4);
  224. @testing: case = 'trailing2y downside capture return' // [FAIL]
  225. assert (select downside_capture_ret.round(4) as downside_capture_ret
  226. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).downside_capture_ret == [-0.022388,-0.023754,-0.004776,-0.004776].round(4);
  227. @testing: case = 'trailing2y downside capture ratio' // [FAIL]
  228. assert (select downside_capture_ratio.round(4) as downside_capture_ratio
  229. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).downside_capture_ratio == [1.341475,1.391050,1.014519,1.014519].round(4);
  230. // ytd capture indicators
  231. capture_r = cal_capture_ratio(tb_ret, primary_benchmark, bmk_ret, 'ytd');
  232. @testing: case = 'ytd upside capture return'
  233. assert (select upside_capture_ret.round(4) as upside_capture_ret
  234. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).upside_capture_ret == [0.027001,0.027001,0.003630,0.001464].round(4);
  235. @testing: case = 'ytd upside capture ratio'
  236. assert (select upside_capture_ratio.round(4) as upside_capture_ratio
  237. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).upside_capture_ratio == [1.622489,1.622489,0.501649,0.224863].round(4);
  238. @testing: case = 'ytd downside capture return' // [FAIL] we don't have null values
  239. assert (select downside_capture_ret.round(4) as downside_capture_ret
  240. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).downside_capture_ret == [-0.043629,-0.041610,null,null].round(4);
  241. @testing: case = 'ytd downside capture ratio' // [FAIL] we don't have null values
  242. assert (select downside_capture_ratio.round(4) as downside_capture_ratio
  243. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).downside_capture_ratio == [3.491326,3.412813,null,null].round(4);
  244. // incep capture indicators
  245. capture_r = cal_capture_ratio(tb_ret, primary_benchmark, bmk_ret, 'incep');
  246. @testing: case = 'incep upside capture return'
  247. assert (select upside_capture_ret.round(3) as upside_capture_ret
  248. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).upside_capture_ret == [0.039939,0.039939,0.003983,0.003744].round(3);
  249. @testing: case = 'incep upside capture ratio' // [FAIL] slightly off
  250. assert (select upside_capture_ratio.round(3) as upside_capture_ratio
  251. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).upside_capture_ratio == [1.411524,1.411524,0.644453,0.612097].round(3);
  252. @testing: case = 'incep downside capture return'
  253. assert (select downside_capture_ret.round(2) as downside_capture_ret
  254. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).downside_capture_ret == [-0.044225,-0.044131,-0.002280,-0.002280].round(2);
  255. @testing: case = 'incep downside capture ratio' // [FAIL] slightly off
  256. assert (select downside_capture_ratio.round(4) as downside_capture_ratio
  257. from capture_r where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).downside_capture_ratio == [1.490631,1.497454,0.498609,0.498609].round(4);
  258. // 2y sharpe
  259. rtn = cal_basic_performance(entity_info, tb_ret, '24');
  260. sharpe = cal_sharpe(tb_ret, rtn, risk_free_rate, '24');
  261. @testing: case = 'trailing2y sharpe'
  262. assert (select (sharpe *sqrt(12)).round(4) as sharpe_a
  263. from sharpe where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).sharpe_a == [-1.124291,-1.175150,-0.015678,-0.246472].round(4);
  264. // ytd sharpe
  265. rtn = cal_basic_performance(entity_info, tb_ret, 'ytd');
  266. sharpe = cal_sharpe(tb_ret, rtn, risk_free_rate, 'ytd');
  267. @testing: case = 'ytd sharpe'
  268. assert (select (sharpe *sqrt(12)).round(3) as sharpe_a
  269. from sharpe where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).sharpe_a == [-0.152652,-0.388883, 0.505893, 0.077395].round(3);
  270. // incep sharpe
  271. rtn = cal_basic_performance(entity_info, tb_ret, 'incep');
  272. sharpe = cal_sharpe(tb_ret, rtn, risk_free_rate, 'incep');
  273. @testing: case = 'incep sharpe' // [FAIL] slightly off
  274. assert (select (sharpe *sqrt(12)).round(4) as sharpe_a
  275. from sharpe where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).sharpe_a == [0.331242,0.322824,0.532794,0.450987].round(4);
  276. // 2y treynor
  277. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  278. treynor = cal_treynor(tb_ret, risk_free_rate, alpha_beta, '24');
  279. @testing: case = 'trailing2y treynor'
  280. assert (select treynor.round(2) as treynor
  281. from treynor where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).treynor == [-0.353583,-0.359078,-0.034126,-0.114400].round(2);
  282. // ytd treynor
  283. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  284. treynor = cal_treynor(tb_ret, risk_free_rate, alpha_beta, 'ytd');
  285. @testing: case = 'ytd treynor' // [FAIL]
  286. assert (select treynor.round(4) as treynor
  287. from treynor where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).treynor == [-0.024472,-0.043101,-0.016843,-0.005406].round(4);
  288. // incep treynor
  289. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  290. treynor = cal_treynor(tb_ret, risk_free_rate, alpha_beta, 'incep');
  291. @testing: case = 'incep treynor' // [FAIL] slightly off
  292. assert (select treynor.round(4) as treynor
  293. from treynor where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).treynor == [0.035549,0.034146,0.026646,0.022403].round(4);
  294. // 2y jensen
  295. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  296. jensen = cal_jensen(tb_ret, bmk_ret, risk_free_rate, alpha_beta, '24');
  297. @testing: case = 'trailing2y treynor'
  298. assert (select (jensen*12).round(2) as jensen_a
  299. from jensen where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).jensen_a == [-0.156508,-0.163600,-0.001910,-0.012240].round(2);
  300. // ytd jensen
  301. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  302. jensen = cal_jensen(tb_ret, bmk_ret, risk_free_rate, alpha_beta, 'ytd');
  303. @testing: case = 'ytd treynor' // [FAIL] slightly off if annulize it
  304. assert (select jensen.round(4) as jensen_a
  305. from jensen where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).jensen_a == [-0.127035,-0.119907,0.158975 ,0.041382].round(4);
  306. // incep jensen
  307. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  308. jensen = cal_jensen(tb_ret, bmk_ret, risk_free_rate, alpha_beta, 'incep');
  309. @testing: case = 'incep treynor' // [FAIL] slightly off
  310. assert (select (jensen*12).round(4) as jensen_a
  311. from jensen where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).jensen_a == [ 0.006436 , 0.005535 , -0.000363, -0.002461].round(4);
  312. // 2y m2
  313. m2 = cal_m2(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  314. @testing: case = 'trailing2y m2' // [FAIL] slightly off
  315. assert (select (m2*12).round(4) as m2_a
  316. from m2 where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).m2_a == [-0.072046, -0.076473, 0.016349 , 0.012278].round(4);
  317. // ytd m2
  318. m2 = cal_m2(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  319. @testing: case = 'ytd m2' // [FAIL] slightly off
  320. assert (select (m2*12).round(4) as m2_a
  321. from m2 where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).m2_a == [0.002002, -0.015889, 0.021197, 0.015593].round(4);
  322. // incep m2
  323. m2 = cal_m2(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  324. @testing: case = 'incep m2' // [FAIL] slightly off
  325. assert (select (m2*12).round(4) as m2_a
  326. from m2 where entity_id in entity_ids and end_date in (2024.07M, 2024.08M)).m2_a == [0.064601,0.063365,0.026901,0.025155].round(4);
  327. //
  328. ms = cal_ms_return(tb_ret, risk_free_rate);
  329. /* codes from cal_fund_bfi_indicators */
  330. start_month = 1990.01M;
  331. // 取基金和基准的对照表
  332. bfi_benchmark = SELECT fund_id AS entity_id, end_date.temporalParse('yyyy-MM') AS end_date, factor_id AS benchmark_id
  333. FROM get_fund_bfi_factors(fund_ids, start_month.temporalFormat('yyyy-MM'), end_day.temporalFormat('yyyy-MM'));
  334. bfi_bmk_ret = get_benchmark_return(bfi_benchmark, end_day);
  335. /* Tests for BFI indicators */
  336. bfi_bmk_tracking = cal_benchmark_tracking(tb_ret, bfi_benchmark, bfi_bmk_ret);
  337. bfi_alpha_beta = cal_alpha_beta(tb_ret, bfi_benchmark, bfi_bmk_ret, risk_free_rate);
  338. bfi_treynor = cal_treynor(tb_ret, risk_free_rate, bfi_alpha_beta);
  339. bfi_indicators = cal_indicators_with_benchmark(tb_ret, bfi_benchmark, bfi_bmk_ret, risk_free_rate);
  340. dic_bfi = cal_fund_bfi_indicators(entity_type, fund_ids, end_day, isFromNav)
  341. SELECT * FROM bfi_indicators ORDER BY entity_id, end_date desc, benchmark_id
  342. SELECT * from dic_bfi['BFI-1Y']