Test_portfolioIndicatorCalculation.dos 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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. use fundit::navCalculator
  9. /* init values for test cases */
  10. end_day = 2024.08.31; //2024.06.28;
  11. isFromNav = false;
  12. portfolio_ids = '166002,166114';
  13. cal_method = 1;
  14. /* codes from cal_fund_indicators */
  15. very_old_date = 1990.01.01;
  16. start_month = very_old_date.month();
  17. portfolio_info = get_portfolio_info(portfolio_ids);
  18. if(portfolio_info.isVoid() || portfolio_info.size() == 0) { return null };
  19. portfolio_info.rename!('portfolio_id', 'entity_id');
  20. if(isFromNav == true) {
  21. // 从净值开始计算收益
  22. tb_raw_ret = SELECT * FROM cal_portfolio_nav(portfolio_ids, very_old_date, cal_method) WHERE price_date <= end_day;
  23. if(tb_raw_ret.isVoid() || tb_raw_ret.size() == 0) return null;
  24. // funky thing is you can't use "AS" for the grouping columns?
  25. tb_ret = SELECT portfolio_id, price_date.month(), price_date.last() AS price_date, (1+ret).prod()-1 AS ret, nav.last() AS nav
  26. FROM tb_raw_ret
  27. WHERE price_date <= end_day
  28. GROUP BY portfolio_id, price_date.month();
  29. tb_ret.rename!(['portfolio_id', 'month_price_date'], ['entity_id', 'end_date']);
  30. } else {
  31. // 从pf_portfolio_performance表里读月收益
  32. tb_ret = get_monthly_ret('PF', portfolio_ids, very_old_date, end_day, true);
  33. tb_ret.rename!(['portfolio_id'], ['entity_id']);
  34. v_end_date = tb_ret.end_date.temporalParse('yyyy-MM');
  35. tb_ret.replaceColumn!('end_date', v_end_date);
  36. }
  37. // 混合因子做基准,同SQL保持一致
  38. t_dates = table(start_month..end_day.month() AS end_date);
  39. primary_benchmark = SELECT ei.entity_id, dt.end_date, 'FA00000VNB' AS benchmark_id
  40. FROM portfolio_info ei JOIN t_dates dt
  41. WHERE dt.end_date >= ei.inception_date.month();
  42. // 取所有出现的基准月收益
  43. bmk_ret = get_benchmark_return(primary_benchmark, end_day);
  44. 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);
  45. /* Test START */
  46. entity_info = portfolio_info;
  47. entity_ids = portfolio_ids.split(',')$INT;
  48. // trailing 2 year standard indicators
  49. rtn = cal_basic_performance(entity_info, tb_ret, '24');
  50. @testing: case = 'trailing 2y return'
  51. assert (select rtn.trailing_ret.round(5) as trailing_ret
  52. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).trailing_ret == [-0.450874,-0.561324,-0.023055].round(5);
  53. @testing: case = 'trailing 2y std_dev_a' //
  54. assert (select (rtn.std_dev * sqrt(12)).round(2) as std_dev_a
  55. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).std_dev_a == [0.324279,0.276651,0.095596].round(2);
  56. @testing: case = 'trailing 2y skewness' // [FAIL] slightly off
  57. assert (select rtn.skewness.round(3) as skewness
  58. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).skewness == [-0.249279,-0.525918,0.179583].round(3);
  59. @testing: case = 'trailing 2y kurtosis' // [FAIL] slightly off
  60. assert (select rtn.kurtosis.round(2) as kurtosis
  61. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).kurtosis == [1.493033 ,3.775385 ,-0.910534].round(2);
  62. @testing: case = 'trailing 2y wrst_month' // [FAIL] slightly off
  63. assert (select rtn.wrst_month.round(3) as wrst_month
  64. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).wrst_month == [-0.275322,-0.275002,-0.045004].round(2);
  65. @testing: case = 'trailing 2y max drawdown' // values from swagger and disable max drawdown when there is no NAV
  66. assert (select rtn.drawdown.round(3) as drawdown
  67. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).drawdown == [0.577912,0.536835,0.090399].round(3);
  68. @testing: case = 'trailing 2y var'
  69. assert (select rtn.var.round(4) as var // [FAIL]
  70. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).var == [0.244860,0.239825,0.043650].round(4);
  71. @testing: case = 'trailing 2y cvar'
  72. assert (select rtn.cvar.round(4) as cvar // [FAIL]
  73. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).cvar == [0.275322,0.275002,0.045004].round(4);
  74. @testing: case = 'trailing 2y calmar'
  75. assert (select rtn.calmar.round(4) as calmar // [FAIL]
  76. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).calmar == [-0.410715,-0.570759,-0.140442].round(4);
  77. // year-to-day standard indicators
  78. rtn = cal_basic_performance(entity_info, tb_ret, 'ytd');
  79. @testing: case = 'ytd return'
  80. assert (select rtn.trailing_ret.round(5) as trailing_ret
  81. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).trailing_ret == [-0.161847,-0.313497,-0.026577].round(5);
  82. @testing: case = 'ytd std_dev_a'
  83. assert (select (rtn.std_dev * sqrt(12)).round(4) as std_dev_a
  84. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).std_dev_a == [NULL ,0.415779,NULL].round(4);
  85. @testing: case = 'skewness'
  86. assert (select rtn.skewness.round(2) as skewness
  87. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).skewness == [NULL ,-0.644514,NULL].round(2);
  88. @testing: case = 'ytd kurtosis'
  89. assert (select rtn.kurtosis.round(3) as kurtosis
  90. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).kurtosis == [NULL ,2.637834,NULL ].round(3);
  91. @testing: case = 'ytd wrst_month' // [FAIL] Java's bug? 2024.03M is missing
  92. assert (select rtn.wrst_month.round(4) as wrst_month
  93. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).wrst_month == [NULL ,-0.275002,NULL].round(4);
  94. @testing: case = 'ytd max drawdown' // values from swagger
  95. assert (select rtn.drawdown.round(4) as drawdown
  96. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).drawdown == [0, 0.180933, 0.008318].round(4);
  97. @testing: case = 'ytd calmar' // [FAIL] Java's bug? why calculate calmar when drawdown is 0
  98. assert (select rtn.calmar.round(4) as calmar
  99. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).calmar == [-0.453785,-0.949412,-0.667054].round(4);
  100. // since-inception-date standard indicators
  101. rtn = cal_basic_performance(entity_info, tb_ret, 'incep');
  102. @testing: case = 'incep return' // data from SWAGGER, SQL is NULL
  103. assert (select rtn.trailing_ret.round(4) as trailing_ret
  104. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).trailing_ret == [0.077187,-0.117711,0.074025].round(4);
  105. @testing: case = 'incep std_dev_a'
  106. assert (select (rtn.std_dev * sqrt(12)).round(2) as std_dev_a
  107. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).std_dev_a == [0.353238,0.341759,0.075581].round(2);
  108. @testing: case = 'incep skewness' // [FAIL] SLIGHTLY OFF
  109. assert (select rtn.skewness.round(3) as skewness
  110. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).skewness == [-0.005075, 0.093952 , -0.285354].round(3);
  111. @testing: case = 'incep kurtosis' // [FAIL] SLIGHTLY OFF
  112. assert (select rtn.kurtosis.round(2) as kurtosis
  113. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).kurtosis == [0.308324,0.454231,0.797176].round(2);
  114. @testing: case = 'incep wrst_month'
  115. assert (select rtn.wrst_month.round(3) as wrst_month
  116. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).wrst_month == [-0.275322, -0.275002, -0.060459].round(3);
  117. @testing: case = 'incep drawdown' // values from swagger and comparing disabled while NAV is not available
  118. assert (select rtn.drawdown.round(4) as drawdown
  119. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).drawdown == [0.688703,0.705232,0.126529].round(4);
  120. @testing: case = 'incep var' // [FAIL]
  121. assert (select rtn.var.round(4) as var
  122. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).var == [0.154051,0.150854,0.038232].round(4);
  123. @testing: case = 'incep cvar' // [FAIL]
  124. assert (select rtn.cvar.round(4) as cvar
  125. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).cvar == [0.218524,0.218365,0.047898].round(4);
  126. @testing: case = 'incep calmar' // [FAIL]
  127. assert (select rtn.calmar.round(4) as calmar
  128. from rtn where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).calmar == [0.011767 , -0.045007, 0.095769].round(4);
  129. // trailing 2 year lpms
  130. lpms = cal_omega_sortino_kappa(tb_ret, risk_free_rate, '24');
  131. @testing: case = 'trailing 2y downside deviation' // [FAIL] data from SWAGGER, slightly off
  132. assert (select (lpms.ds_dev).round(2) as ds_dev
  133. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).ds_dev == [0.079688,0.076460,0.020911].round(2);
  134. @testing: case = 'trailing 2y omega' // [FAIL]
  135. assert (select lpms.omega.round(4) as omega
  136. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).omega == [0.353282,0.398373,0.872859].round(4);
  137. @testing: case = 'trailing 2y sortino' // [FAIL]
  138. assert (select (lpms.sortino * sqrt(12)).round(4) as sortino_a
  139. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).sortino_a == [-0.873490,-1.453471,-0.080323].round(4);
  140. @testing: case = 'trailing 2y kappa' // [FAIL]
  141. assert (select lpms.kappa.round(4) as kappa
  142. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).kappa == [-1.688884,-1.500436,-0.235215].round(4);
  143. // ytd lpms
  144. lpms = cal_omega_sortino_kappa(tb_ret, risk_free_rate, 'ytd');
  145. @testing: case = 'ytd downside deviation' // data from SWAGGER, slightly off
  146. assert (select (ds_dev).round(2) as ds_dev_a
  147. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).ds_dev_a == [NULL, 0.109539 , NULL].round(2);
  148. @testing: case = 'ytd omega' // [FAIL]
  149. assert (select lpms.omega.round(4) as omega
  150. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).omega == [NULL,0.453621,NULL].round(4);
  151. @testing: case = 'ytd sortino' // [FAIL]
  152. assert (select (lpms.sortino * sqrt(12)).round(4) as sortino_a
  153. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).sortino_a == [NULL,-1.228103,NULL].round(4);
  154. @testing: case = 'ytd kappa' // [FAIL]
  155. assert (select lpms.kappa.round(4) as kappa
  156. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).kappa == [NULL, -1.324956, NULL].round(4);
  157. // since inception lpms
  158. lpms = cal_omega_sortino_kappa(tb_ret, risk_free_rate, 'incep');
  159. @testing: case = 'incep downside deviation' // data from SWAGGER, slightly off
  160. assert (select (lpms.ds_dev)round(2) as ds_dev_a
  161. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).ds_dev_a == [0.070906,0.069713,0.016293].round(2);
  162. @testing: case = 'incep omega' // [FAIL] slightly off
  163. assert (select lpms.omega.round(4) as omega
  164. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).omega == [ 1.231226, 0.908086, 1.110811].round(4);
  165. @testing: case = 'incep sortino' // [FAIL]
  166. assert (select (lpms.sortino * sqrt(12)).round(4) as sortino_a
  167. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).sortino_a == [0.590138,0.063619,0.179043].round(4);
  168. @testing: case = 'incep kappa' // [FAIL]
  169. assert (select lpms.kappa.round(4) as kappa
  170. from lpms where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).kappa == [ 0.510057 , -0.207099, 0.163405].round(4);
  171. // 2y bechmark tracking
  172. bmk_tracking = cal_benchmark_tracking(tb_ret, primary_benchmark, bmk_ret, '24');
  173. @testing: case = 'trailing2y win rate' // data from SWAGGER
  174. assert (select winrate.round(4) as winrate
  175. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).winrate == [0.375000,0.250000,0.458333].round(4);
  176. @testing: case = 'trailing2y tracking error' // data from SWAGGER
  177. assert (select (track_error * sqrt(12)).round(4) as track_error_a
  178. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).track_error_a == [0.276632,0.237425,0.092227].round(4);
  179. @testing: case = 'trailing2y information ratio' // [FAIL]
  180. assert (select info.round(4) as info
  181. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).info == [2.672563 ,2.860281 ,10.190751].round(4);
  182. // ytd bechmark tracking
  183. bmk_tracking = cal_benchmark_tracking(tb_ret, primary_benchmark, bmk_ret, 'ytd');
  184. @testing: case = 'ytd win rate'
  185. assert (select winrate.round(4) as winrate
  186. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).winrate == [NULL,0.125000,NULL].round(4);
  187. @testing: case = 'ytd tracking error' // dat from SWAGGER
  188. assert (select (track_error * sqrt(12)).round(4) as track_error_a
  189. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).track_error_a == [NULL,0.345445,NULL].round(4);
  190. @testing: case = 'ytd information ratio' // [FAIL]
  191. assert (select info.round(4) as info
  192. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).info == [NULL,1.450085,NULL].round(4);
  193. // incep bechmark tracking
  194. bmk_tracking = cal_benchmark_tracking(tb_ret, primary_benchmark, bmk_ret, 'incep');
  195. @testing: case = 'incep win rate' // SWAGGER
  196. assert (select winrate.round(4) as winrate
  197. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).winrate == [0.538462,0.491228,0.516667].round(4);
  198. @testing: case = 'incep tracking error' // SWAGGER
  199. assert (select (track_error * sqrt(12)).round(4) as track_error_a
  200. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).track_error_a == [0.317142,0.306286,0.083942].round(4);
  201. @testing: case = 'incep information ratio' // [FAIL]
  202. assert (select info.round(4) as info
  203. from bmk_tracking where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).info == [3.107132 ,3.118240 ,11.039744].round(4);
  204. // 2y alpha, beta
  205. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  206. @testing: case = 'trailing2y beta' // SWAGGER
  207. assert (select beta.round(4) as beta
  208. from alpha_beta where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).beta == [2.254328,2.092425,0.591983].round(4);
  209. @testing: case = 'trailing2y alpha' // [FAIL]
  210. assert (select (alpha * 12).round(3) as alpha_a
  211. from alpha_beta where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).alpha_a == [-0.224853,-0.323083,-0.002128].round(3);
  212. // ytd alpha, beta
  213. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  214. @testing: case = 'ytd beta' // SWAGGER
  215. assert (select beta.round(4) as beta
  216. from alpha_beta where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).beta == [NULL,4.674789,NULL].round(4);
  217. @testing: case = 'ytd alpha' // [FAIL]
  218. assert (select (alpha * 12).round(3) as alpha_a
  219. from alpha_beta where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).alpha_a == [NULL,-0.559542,NULL].round(3);
  220. // incep alpha, beta
  221. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  222. @testing: case = 'incep beta' // SWAGGER
  223. assert (select beta.round(4) as beta
  224. from alpha_beta where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).beta == [2.084304,2.129578,0.426432].round(4);
  225. @testing: case = 'incep alpha' // [FAIL]
  226. assert (select (alpha * 12).round(3) as alpha_a
  227. from alpha_beta where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).alpha_a == [0.029 , -0.004361, 0.007401].round(3);
  228. // 2y capture indicators
  229. capture_r = cal_capture_ratio(tb_ret, primary_benchmark, bmk_ret, '24');
  230. @testing: case = 'trailing2y upside capture return' // SWAGGER
  231. assert (select upside_capture_ret.round(4) as upside_capture_ret
  232. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).upside_capture_ret == [0.021896,-0.000820,0.012359].round(4);
  233. @testing: case = 'trailing2y upside capture ratio' // SWAGGER
  234. assert (select upside_capture_ratio.round(4) as upside_capture_ratio
  235. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).upside_capture_ratio == [1.003778 ,-0.048845,0.566586].round(4);
  236. @testing: case = 'trailing2y downside capture return' // SWAGGER
  237. assert (select downside_capture_ret.round(4) as downside_capture_ret
  238. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).downside_capture_ret == [-0.062405, -0.060766, -0.012114].round(4);
  239. @testing: case = 'trailing2y downside capture ratio' // SWAGGER
  240. assert (select downside_capture_ratio.round(4) as downside_capture_ratio
  241. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).downside_capture_ratio == [3.137552,3.471522,0.609053].round(4);
  242. // ytd capture indicators
  243. capture_r = cal_capture_ratio(tb_ret, primary_benchmark, bmk_ret, 'ytd');
  244. @testing: case = 'ytd upside capture return' // [FAIL] because Java doesn't calculate ytd for first 5 months
  245. assert (select upside_capture_ret.round(4) as upside_capture_ret
  246. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).upside_capture_ret == [NULL, 0.033020 ,NULL].round(4);
  247. @testing: case = 'ytd upside capture ratio' // [FAIL] because Java doesn't calculate ytd for first 5 months
  248. assert (select upside_capture_ratio.round(4) as upside_capture_ratio
  249. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).upside_capture_ratio == [NULL, 1.984191, NULL].round(4);
  250. @testing: case = 'ytd downside capture return' // [FAIL] because Java doesn't calculate ytd for first 5 months
  251. assert (select downside_capture_ret.round(4) as downside_capture_ret
  252. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).downside_capture_ret == [NULL, -0.118846, NULL].round(4);
  253. @testing: case = 'ytd downside capture ratio' // [FAIL] because Java doesn't calculate ytd for first 5 months
  254. assert (select downside_capture_ratio.round(4) as downside_capture_ratio
  255. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).downside_capture_ratio == [NULL, 8.745656, NULL].round(4);
  256. // incep capture indicators
  257. capture_r = cal_capture_ratio(tb_ret, primary_benchmark, bmk_ret, 'incep');
  258. @testing: case = 'incep upside capture return' // SWAGGER
  259. assert (select upside_capture_ret.round(4) as upside_capture_ret
  260. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).upside_capture_ret == [0.040915,0.037614,0.008132].round(4);
  261. @testing: case = 'incep upside capture ratio' // SWAGGER
  262. assert (select upside_capture_ratio.round(4) as upside_capture_ratio
  263. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).upside_capture_ratio == [2.009389,1.964035,0.434803].round(4);
  264. @testing: case = 'incep downside capture return' // SWAGGER
  265. assert (select downside_capture_ret.round(4) as downside_capture_ret
  266. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).downside_capture_ret == [-0.04274,-0.044638,-0.00723].round(4);
  267. @testing: case = 'incep downside capture ratio' // SWAGGER
  268. assert (select downside_capture_ratio.round(4) as downside_capture_ratio
  269. from capture_r where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).downside_capture_ratio == [2.172258,2.405102,0.383957].round(4);
  270. // 2y sharpe
  271. rtn = cal_basic_performance(entity_info, tb_ret, '24');
  272. sharpe = cal_sharpe(tb_ret, rtn, risk_free_rate, '24');
  273. @testing: case = 'trailing2y sharpe' // SWAGGER
  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.03M, 2024.08M)).sharpe_a == [ -0.801451, -1.380549, -0.239731].round(4);
  276. // ytd sharpe
  277. rtn = cal_basic_performance(entity_info, tb_ret, 'ytd');
  278. sharpe = cal_sharpe(tb_ret, rtn, risk_free_rate, 'ytd');
  279. @testing: case = 'ytd sharpe' // SWAGGER
  280. assert (select (sharpe *sqrt(12)).round(3) as sharpe_a
  281. from sharpe where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).sharpe_a == [ NULL,-1.159093,NULL].round(3);
  282. // incep sharpe
  283. rtn = cal_basic_performance(entity_info, tb_ret, 'incep');
  284. sharpe = cal_sharpe(tb_ret, rtn, risk_free_rate, 'incep');
  285. @testing: case = 'incep sharpe' // SWAGGER
  286. assert (select (sharpe *sqrt(12)).round(4) as sharpe_a
  287. from sharpe where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).sharpe_a == [0.175911, 0.043442, 0.010115].round(4);
  288. // 2y treynor
  289. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  290. treynor = cal_treynor(tb_ret, risk_free_rate, alpha_beta, '24');
  291. @testing: case = 'trailing2y treynor' // SWAGGER
  292. assert (select treynor.round(2) as treynor
  293. from treynor where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).treynor == [-0.122531,-0.169323,-0.048736].round(2);
  294. // ytd treynor
  295. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  296. treynor = cal_treynor(tb_ret, risk_free_rate, alpha_beta, 'ytd');
  297. @testing: case = 'ytd treynor' // [FAIL]
  298. assert (select treynor.round(4) as treynor
  299. from treynor where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).treynor == [NULL,-0.09536,NULL].round(4);
  300. // incep treynor
  301. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  302. treynor = cal_treynor(tb_ret, risk_free_rate, alpha_beta, 'incep');
  303. @testing: case = 'incep treynor' // SWAGGER
  304. assert (select treynor.round(3) as treynor
  305. from treynor where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).treynor == [0.000023,-0.020028,-0.005189].round(3);
  306. // 2y jensen
  307. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  308. jensen = cal_jensen(tb_ret, bmk_ret, risk_free_rate, alpha_beta, '24');
  309. @testing: case = 'trailing2y treynor' // SWAGGER
  310. assert (select (jensen*12).round(4) as jensen_a
  311. from jensen where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).jensen_a == [-0.203378,-0.305063,-0.009113].round(4);
  312. // ytd jensen
  313. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  314. jensen = cal_jensen(tb_ret, bmk_ret, risk_free_rate, alpha_beta, 'ytd');
  315. @testing: case = 'ytd treynor' // SWAGGER
  316. assert (select (jensen*12).round(4) as jensen_a
  317. from jensen where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).jensen_a == [NULL,-0.506273,NULL].round(4);
  318. // incep jensen
  319. alpha_beta = cal_alpha_beta(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  320. jensen = cal_jensen(tb_ret, bmk_ret, risk_free_rate, alpha_beta, 'incep');
  321. @testing: case = 'incep treynor' // SWAGGER
  322. assert (select (jensen*12).round(4) as jensen_a
  323. from jensen where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).jensen_a == [0.047106, 0.014283 ,-0.002047].round(4);
  324. // 2y m2
  325. m2 = cal_m2(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, '24');
  326. @testing: case = 'trailing2y m2' // SWAGGER
  327. assert (select (m2*12).round(4) as m2_a
  328. from m2 where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).m2_a == [-0.055401, -0.093355 , -0.004574].round(4);
  329. // ytd m2
  330. m2 = cal_m2(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'ytd');
  331. @testing: case = 'ytd m2' // SWAGGER
  332. assert (select (m2*12).round(4) as m2_a
  333. from m2 where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).m2_a == [NULL,-0.07832, NULL].round(4);
  334. // incep m2
  335. m2 = cal_m2(tb_ret, primary_benchmark, bmk_ret, risk_free_rate, 'incep');
  336. @testing: case = 'incep m2' // SWAGGER
  337. assert (select (m2*12).round(4) as m2_a
  338. from m2 where entity_id in entity_ids and end_date in (2024.03M, 2024.08M)).m2_a == [0.032060,0.020154,0.017319].round(4);
  339. /* Tests for BFI indicators. CURRENTLY IT IS UN-TESTABLE BECAUSE LOGIC OF BENCHMARK COMPARING IS CHANGED */