sample_cal_indicator.dos 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. login(`admin, `123456)
  2. loadPlugin("ODBC")
  3. clearCachedModules()
  4. use fundit::fundCalculator
  5. use fundit::dataPuller
  6. use fundit::returnCalculator
  7. end_day = 2024.06.28
  8. //end_day = today()
  9. bmk_ret = get_fund_monthly_ret("'IN00000008'", 1990.01.01, end_day, true)
  10. risk_free_rate = get_risk_free_rate("'IN0000000M'", 1990.01.01, end_day)
  11. /* TEST CASE 1 */
  12. // tb_ret = get_fund_monthly_ret("'MF00003PW1','MF00003PW2'", 1990.01.01, end_day, true)
  13. // hedge fund test
  14. tb_ret = get_fund_monthly_ret("'HF000004KN','HF000103EU','HF00018WXG'", 1990.01.01, end_day, true)
  15. /* TEST CASE 2
  16. tb_updated_funds = get_fund_list_by_nav_updatetime(2024.07.19T10:00:00)
  17. // take 1000 funds for testing
  18. fund_ids = "'" + tb_updated_funds.fund_id[0:1000].concat("','") + "'"
  19. tb_ret = get_fund_monthly_ret(fund_ids, 1990.01.01, end_day, false)
  20. */
  21. /* annualized return GIPS */
  22. // 0.122622 -0.163869 -0.077696
  23. ret_incep_a = SELECT fund_id, ret_incep_a FROM tb_ret WHERE end_date = end_day.datetimeFormat("yyyy-MM")
  24. ret_ytd_a = SELECT fund_id, ret_ytd_a FROM tb_ret WHERE end_date = end_day.datetimeFormat("yyyy-MM")
  25. /* annualized standard deviation */
  26. // 0.210105 null null
  27. std_incep = SELECT ret.std() FROM tb_ret GROUP BY fund_id
  28. std_incep_a = std_incep * pow(12, 0.5)
  29. // 0.357842 null null
  30. std_ytd = (SELECT ret.std() FROM tb_ret WHERE end_date >= end_day.year()$STRING + "-01" GROUP BY fund_id)
  31. std_ytd_a = std_ytd * pow(12, 0.5)
  32. // 0.357842 null null
  33. std_6m = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-6, "M").temporalFormat("yyyy-MM") GROUP BY fund_id)
  34. std_6m_a = std_6m * pow(12, 0.5)
  35. // 0.270642 null null
  36. std_1y = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-1, "y").temporalFormat("yyyy-MM") GROUP BY fund_id)
  37. std_1y_a = std_1y * pow(12, 0.5)
  38. // 0.249324 null null
  39. std_2y = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-2, "y").temporalFormat("yyyy-MM") GROUP BY fund_id)
  40. std_2y_a = std_2y * pow(12, 0.5)
  41. // 0.248138 null null
  42. std_3y = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-3, "y").temporalFormat("yyyy-MM") GROUP BY fund_id)
  43. std_3y_a = std_3y * pow(12, 0.5)
  44. // 0.242779 null null
  45. std_4y = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-4, "y").temporalFormat("yyyy-MM") GROUP BY fund_id)
  46. std_4y_a = std_4y * pow(12, 0.5)
  47. // 0.224387 null null
  48. std_5y = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-5, "y").temporalFormat("yyyy-MM") GROUP BY fund_id)
  49. std_5y_a = std_5y * pow(12, 0.5)
  50. // 0.210569 null null
  51. std_10y = (SELECT ret.std() FROM tb_ret WHERE end_date > end_day.temporalAdd(-10, "y").temporalFormat("yyyy-MM") GROUP BY fund_id)
  52. std_10y_a = std_10y * pow(12, 0.5)
  53. /* annualized downside stdev numbers are slightly off !
  54. NOTE: not sure why cnt[0] need to minus 1 copied from Java implementation*/
  55. // risk_free_rate = 0.001208
  56. // 0.130429 null null
  57. t = SELECT *, count(fund_id) AS cnt FROM tb_ret CONTEXT BY fund_id
  58. ds_std_dev_incep = SELECT t.fund_id, (sum2(t.ret - rfr.ret) / (t.cnt[0]-1)).pow(0.5) AS ds_std_dev
  59. FROM t
  60. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  61. WHERE t.ret < rfr.ret
  62. GROUP BY t.fund_id
  63. ds_std_dev_incep_a = ds_std_dev_incep * pow(12, 0.5)
  64. // 0.277208 null null
  65. t = SELECT *, count(fund_id) AS cnt FROM tb_ret WHERE end_date >= end_day.year()$STRING + "-01" CONTEXT BY fund_id
  66. ds_std_dev_ytd = SELECT fund_id, (sum2(ret - rfr.ret) / (t.cnt[0]-1)).pow(0.5) AS ds_std_dev
  67. FROM t
  68. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  69. WHERE t.ret < rfr.ret
  70. GROUP BY fund_id
  71. ds_std_dev_ytd_a = ds_std_dev_ytd * pow(12, 0.5)
  72. /* beta */
  73. // 0.530483 null null
  74. t = SELECT t.fund_id, t.end_date, t.ret, bmk.ret AS ret_bmk
  75. FROM tb_ret t
  76. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  77. beta_incep = SELECT ret.beta(ret_bmk) AS beta FROM t GROUP BY fund_id
  78. // 1.819822 null null
  79. t = SELECT t.fund_id, t.end_date, t.ret, bmk.ret AS ret_bmk
  80. FROM tb_ret t
  81. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  82. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  83. beta_ytd =SELECT ret.beta(ret_bmk) AS beta FROM t GROUP BY fund_id
  84. /* annualized alpha -- numbers are off ! because Java doesn't substract risk free rate */
  85. // 0.110500 null null
  86. t = SELECT t.fund_id, t.end_date, t.ret, bmk.ret AS ret_bmk
  87. FROM tb_ret t
  88. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  89. alpha_incep = SELECT t.fund_id, (t.ret - rfr.ret).mean() - beta.beta[0] * (t.ret_bmk - rfr.ret).mean() AS alpha
  90. FROM t
  91. INNER JOIN beta_incep beta ON t.fund_id = beta.fund_id
  92. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  93. GROUP BY t.fund_id
  94. alpha_incep_a = alpha_incep * 12
  95. // -0.11019 null null
  96. t = SELECT t.fund_id, t.end_date, t.ret, bmk.ret AS ret_bmk
  97. FROM tb_ret t
  98. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  99. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  100. alpha_ytd = SELECT t.fund_id, (t.ret - rfr.ret).mean() - beta.beta[0] * (t.ret_bmk - rfr.ret).mean() AS alpha
  101. FROM t
  102. INNER JOIN beta_ytd beta ON t.fund_id = beta.fund_id
  103. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  104. GROUP BY t.fund_id
  105. alpha_ytd_a = alpha_ytd * 12
  106. /* win rate -- numbers are slightly way off !effective data count issue? */
  107. // 0.585185 null null
  108. t = SELECT t.fund_id, t.end_date, t.ret, bmk.ret AS ret_bmk, count(fund_id) AS cnt
  109. FROM tb_ret t
  110. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  111. CONTEXT BY t.fund_id
  112. winrate_incep = SELECT fund_id, count(fund_id) \ cnt[0] AS winrate
  113. FROM t
  114. WHERE ret > ret_bmk
  115. GROUP BY fund_id
  116. // 0.666667 null null
  117. t = SELECT t.fund_id, t.end_date, t.ret, bmk.ret AS ret_bmk, count(fund_id) AS cnt
  118. FROM tb_ret t
  119. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  120. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  121. CONTEXT BY t.fund_id
  122. winrate_ytd = SELECT fund_id, count(fund_id) \ cnt[0] AS winrate
  123. FROM t
  124. WHERE ret > ret_bmk
  125. GROUP BY fund_id
  126. /* skewness */
  127. // -0.090416
  128. skewness_incep = SELECT fund_id, ret.skew(false) AS skewness FROM tb_ret GROUP BY fund_id
  129. // -0.513185
  130. skewness_ytd = SELECT fund_id, ret.skew(false) AS skewness FROM tb_ret WHERE end_date >= end_day.datetimeFormat("yyyy-01") GROUP BY fund_id
  131. /* kurtosis */
  132. // 0.527901
  133. kurtosis_incep = SELECT fund_id, ret.kurtosis(false) - 3 AS kurtosis FROM tb_ret GROUP BY fund_id
  134. // 0.961329
  135. kurtosis_ytd = SELECT fund_id, ret.kurtosis(false) - 3 AS kurtosis FROM tb_ret WHERE end_date >= end_day.datetimeFormat("yyyy-01") GROUP BY fund_id
  136. /* worst month */
  137. // --0.172580
  138. wrst_month_incep = SELECT ret.min() AS ret FROM tb_ret GROUP BY fund_id
  139. // -0.172580
  140. wrst_month_ytd = SELECT ret.min() AS ret FROM tb_ret WHERE end_date >= end_day.datetimeFormat("yyyy-01") GROUP BY fund_id
  141. /* longest down month*/
  142. /* max drawdown */
  143. // 0.305496 0.5621 0.120200
  144. drawdown_incep = SELECT fund_id, max( 1 - nav \ nav.cummax() ) AS drawdown FROM tb_ret GROUP BY fund_id
  145. // 0.05645 0 0.06553
  146. drawdown_ytd = SELECT fund_id, max( 1 - nav \ nav.cummax() ) AS drawdown FROM tb_ret WHERE end_date >= end_day.datetimeFormat("yyyy-01") GROUP BY fund_id
  147. /* sharpe ratio */
  148. // 0.568739
  149. sharpe_incep = SELECT t.fund_id, (t.ret - rfr.ret).mean() / std.std_ret[0] AS sharpe
  150. FROM tb_ret t
  151. INNER JOIN std_incep std ON t.fund_id = std.fund_id
  152. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  153. GROUP BY t.fund_id
  154. sharpe_incep_a = sharpe_incep * pow(12, 0.5)
  155. // -0.186892
  156. sharpe_ytd = SELECT t.fund_id, (t.ret - rfr.ret).mean() / std.std_ret[0] AS sharpe
  157. FROM tb_ret t
  158. INNER JOIN std_ytd std ON t.fund_id = std.fund_id
  159. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  160. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  161. GROUP BY t.fund_id
  162. sharpe_ytd_a = sharpe_ytd * pow(12, 0.5)
  163. // -0.568024
  164. sharpe_1y = SELECT t.fund_id, (t.ret - rfr.ret).mean() / std.std_ret[0] AS sharpe
  165. FROM tb_ret t
  166. INNER JOIN std_1y std ON t.fund_id = std.fund_id
  167. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  168. WHERE t.end_date > end_day.temporalAdd(-1, "y").temporalFormat("yyyy-MM")
  169. GROUP BY t.fund_id
  170. sharpe_1y_a = sharpe_1y * pow(12, 0.5)
  171. // -0.131570
  172. sharpe_2y = SELECT t.fund_id, (t.ret - rfr.ret).mean() / std.std_ret[0] AS sharpe
  173. FROM tb_ret t
  174. INNER JOIN std_2y std ON t.fund_id = std.fund_id
  175. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  176. WHERE t.end_date > end_day.temporalAdd(-2, "y").temporalFormat("yyyy-MM")
  177. GROUP BY t.fund_id
  178. sharpe_2y_a = sharpe_2y * pow(12, 0.5)
  179. /* sortino ratio NOTE: sortino is LPM2*/
  180. // 0.916167
  181. sortino_incep = SELECT t.fund_id, (t.ret - rfr.ret ).mean() / std.ds_std_dev[0] AS sortino
  182. FROM tb_ret t
  183. INNER JOIN ds_std_dev_incep std ON t.fund_id = std.fund_id
  184. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  185. GROUP BY t.fund_id
  186. sortino_incep_a = sortino_incep * pow(12, 0.5)
  187. // -0.241256
  188. sortino_ytd = SELECT t.fund_id, (t.ret - rfr.ret ).mean() / std.ds_std_dev[0] AS sortino
  189. FROM tb_ret t
  190. INNER JOIN ds_std_dev_ytd std ON t.fund_id = std.fund_id
  191. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  192. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  193. GROUP BY t.fund_id
  194. sortino_ytd_a = sortino_ytd * pow(12, 0.5)
  195. /* sortino MAR -- what's the MAR number? */
  196. /* treynor ratio ytd numbers are way off ! because current java calcuation is not follow GIPS annualization rule*/
  197. // 0.195812
  198. t= SELECT *, count(fund_id) AS cnt FROM tb_ret t INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date CONTEXT BY t.fund_id
  199. treynor_incep = SELECT t.fund_id, ((1 + t.ret).prod().pow(12\iif(t.cnt[0]<12, 12, t.cnt[0])) - (1 + t.rfr_ret).prod().pow(12\iif(t.cnt[0]<12, 12, t.cnt[0]))) / beta.beta[0] AS treynor
  200. FROM t
  201. INNER JOIN beta_incep beta ON t.fund_id = beta.fund_id
  202. GROUP BY t.fund_id
  203. // -0.064390
  204. t= SELECT *, count(fund_id) AS cnt FROM tb_ret t INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date WHERE t.end_date >= end_day.datetimeFormat("yyyy-01") CONTEXT BY t.fund_id
  205. treynor_ytd = SELECT t.fund_id, ((1 + t.ret).prod().pow(12\iif(t.cnt[0]<12, 12, t.cnt[0])) - (1 + t.rfr_ret).prod().pow(12\iif(t.cnt[0]<12, 12, t.cnt[0]))) / beta.beta[0] AS treynor
  206. FROM t
  207. INNER JOIN beta_ytd beta ON t.fund_id = beta.fund_id
  208. GROUP BY t.fund_id
  209. /* jensen's alpha numbers are slightly off ! */
  210. // 0.101781
  211. jensen_incep = SELECT t.fund_id, t.ret.mean() - rfr.ret.mean() - beta.beta[0] * (bmk.ret.mean() - rfr.ret.mean()) AS jensen
  212. FROM tb_ret t
  213. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  214. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  215. INNER JOIN beta_incep beta ON t.fund_id = beta.fund_id
  216. GROUP BY t.fund_id
  217. jensen_incep_a = jensen_incep * 12
  218. // -0.098310
  219. jensen_ytd = SELECT t.fund_id, t.ret.mean() - rfr.ret.mean() - beta.beta[0] * (bmk.ret.mean() - rfr.ret.mean()) AS jensen
  220. FROM tb_ret t
  221. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  222. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  223. INNER JOIN beta_ytd beta ON t.fund_id = beta.fund_id
  224. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  225. GROUP BY t.fund_id
  226. jensen_ytd_a = jensen_ytd * 12
  227. /* calmar ratio numbers are way off ! */
  228. // 0.376378 -0.279307 -0.81280
  229. calmar_incep = SELECT fund_id, ar.ret_incep_a \ dd.drawdown AS calmar
  230. FROM ret_incep_a ar
  231. INNER JOIN drawdown_incep dd ON ar.fund_id = dd.fund_id
  232. // 2.567034 999999. -0.81280
  233. calmar_ytd = SELECT fund_id, ar.ret_ytd_a \ dd.drawdown AS calmar
  234. FROM ret_ytd_a ar
  235. INNER JOIN drawdown_ytd dd ON ar.fund_id = dd.fund_id
  236. /* omega ratio numbers are off ! could because Java uses annualized returns and cnt-1 NOTE: omega is LPM1 */
  237. // 1.471981
  238. t0 = SELECT *, fund_id.count() AS cnt FROM tb_ret t INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date CONTEXT BY t.fund_id
  239. t1 = SELECT fund_id, (ret - rfr_ret).sum() \ cnt[0] AS ex_ret
  240. FROM t0
  241. WHERE ret > rfr_ret
  242. GROUP BY fund_id
  243. t2 = SELECT fund_id, (rfr_ret - ret).sum() \ cnt[0] AS ds_ret
  244. FROM t0
  245. WHERE ret < rfr_ret
  246. GROUP BY fund_id
  247. omega_incep = SELECT t1.fund_id, t1.ex_ret \ t2.ds_ret AS omega
  248. FROM t1
  249. INNER JOIN t2 ON t1.fund_id = t2.fund_id
  250. // 0.790864
  251. t0 = SELECT *, fund_id.count() AS cnt FROM tb_ret t INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date WHERE t.end_date >= end_day.datetimeFormat("yyyy-01") CONTEXT BY t.fund_id
  252. t1 = SELECT fund_id, (ret - rfr_ret).mean() AS ex_ret
  253. FROM t0
  254. GROUP BY fund_id
  255. t2 = SELECT fund_id, (rfr_ret - ret).sum() \ cnt[0] AS ds_ret
  256. FROM t0
  257. WHERE ret < rfr_ret
  258. GROUP BY fund_id
  259. omega_ytd = SELECT t1.fund_id, 1 + t1.ex_ret \ t2.ds_ret AS omega
  260. FROM t1
  261. INNER JOIN t2 ON t1.fund_id = t2.fund_id
  262. /* kappa ratio NOTE: kappa is LMP3 numbers are off ! Java's implementation could be very wrong */
  263. // 0.848648
  264. t0 = SELECT *, fund_id.count() AS cnt FROM tb_ret t INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date CONTEXT BY t.fund_id
  265. t1 = SELECT fund_id, (ret - rfr_ret).mean() AS ex_ret
  266. FROM t0
  267. GROUP BY fund_id
  268. t2 = SELECT fund_id, (rfr_ret - ret).sum3() \ cnt[0] AS ds_ret
  269. FROM t0
  270. WHERE ret < rfr_ret
  271. GROUP BY fund_id
  272. kappa_incep = SELECT t1.fund_id, 1 + t1.ex_ret \ t2.ds_ret.pow(1\3) AS kappa
  273. FROM t1
  274. INNER JOIN t2 ON t1.fund_id = t2.fund_id
  275. // -0.501813
  276. t0 = SELECT *, fund_id.count() AS cnt FROM tb_ret t INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date WHERE t.end_date >= end_day.datetimeFormat("yyyy-01") CONTEXT BY t.fund_id
  277. t1 = SELECT fund_id, (ret - rfr_ret).mean() AS ex_ret
  278. FROM t0
  279. GROUP BY fund_id
  280. t2 = SELECT fund_id, (rfr_ret - ret).sum3() \ cnt[0] AS ds_ret
  281. FROM t0
  282. WHERE ret < rfr_ret
  283. GROUP BY fund_id
  284. kappa_ytd = SELECT t1.fund_id, 1+ t1.ex_ret \ t2.ds_ret.pow(1\3) AS kappa
  285. FROM t1
  286. INNER JOIN t2 ON t1.fund_id = t2.fund_id
  287. /* tracking error */
  288. // 0.203268
  289. track_error_incep = SELECT fund_id, (t.ret - bmk.ret).std() AS track_error
  290. FROM tb_ret t
  291. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  292. GROUP BY t.fund_id
  293. track_error_incep_a = track_error_incep * pow(12, 0.5)
  294. // 0.193291
  295. track_error_ytd = SELECT fund_id, (t.ret - bmk.ret).std() AS track_error
  296. FROM tb_ret t
  297. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  298. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  299. GROUP BY t.fund_id
  300. track_error_ytd_a = track_error_ytd * pow(12, 0.5)
  301. /* information ratio numbers are way off! */
  302. // 5.472180
  303. info_incep = SELECT fund_id, (t.ret - bmk.ret).mean() / (t.ret - bmk.ret).std() AS info
  304. FROM tb_ret t
  305. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  306. GROUP BY t.fund_id
  307. info_incep_a = info_incep * pow(12, 0.5)
  308. /* modigliani = sharpe * std(benchmark) + risk_free_rate )*/
  309. // 0.141025
  310. m2_incep = SELECT t.fund_id, (t.ret - rfr.ret).mean() / t.ret.std() * bmk.ret.std() + rfr.ret.mean()
  311. FROM tb_ret t
  312. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  313. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  314. GROUP BY t.fund_id
  315. m2_incep_a = m2_incep * 12
  316. // -0.020145
  317. m2_ytd = SELECT t.fund_id, (t.ret - rfr.ret).mean() / t.ret.std() * bmk.ret.std() + rfr.ret.mean()
  318. FROM tb_ret t
  319. INNER JOIN bmk_ret bmk ON t.end_date = bmk.end_date
  320. INNER JOIN risk_free_rate rfr ON t.end_date = rfr.end_date
  321. WHERE t.end_date >= end_day.datetimeFormat("yyyy-01")
  322. GROUP BY t.fund_id
  323. m2_ytd_a = m2_ytd * 12
  324. /* historical var numbers are off ! due to different implementations */
  325. CONFIDENCE_LEVAL = 95
  326. // 0.093206
  327. var_incep = SELECT fund_id, - ret.percentile(100-CONFIDENCE_LEVAL) AS var
  328. FROM tb_ret
  329. GROUP BY fund_id
  330. // 0.162951
  331. var_2y = SELECT fund_id, - ret.percentile(100-CONFIDENCE_LEVAL) AS var
  332. FROM tb_ret
  333. WHERE end_date > end_day.temporalAdd(-2, "y").datetimeFormat("yyyy-MM")
  334. GROUP BY fund_id
  335. /* historical cvar numbers are slightly off ! due to different implementations of var */
  336. // 0.129327
  337. cvar_incep = SELECT t.fund_id, - t.ret.mean() AS cvar
  338. FROM tb_ret t
  339. INNER JOIN var_incep var ON t.fund_id = var.fund_id
  340. WHERE t.ret < - var.var
  341. GROUP BY t.fund_id
  342. // 0.17258
  343. cvar_2y = SELECT t.fund_id, - t.ret.mean() AS cvar
  344. FROM tb_ret t
  345. INNER JOIN var_2y var ON t.fund_id = var.fund_id
  346. WHERE end_date > end_day.temporalAdd(-2, "y").datetimeFormat("yyyy-MM")
  347. AND t.ret < - var.var
  348. GROUP BY t.fund_id
  349. /* SMDD var */
  350. /* stutzer index, used by Tian Xiang rating */
  351. // stutzer = (tb_ret - risk_free_rate) \ cvar