dataSaver.dos 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
  1. module fundit::dataSaver
  2. use fundit::sqlUtilities
  3. /*
  4. * 存数据表到mySQL或本地dolphindb,原数据表会被TRUNCATE
  5. *
  6. * save_table(tb_fund_performance, "raw_db.fund_performance", false)
  7. */
  8. def save_table(tb, table_name, isToMySQL) {
  9. if(isToMySQL == true) {
  10. conn = connect_mysql('raw_db');
  11. odbc::execute(conn, "TRUNCATE TABLE " + table_name + "_dolphin");
  12. odbc::append(conn, tb, table_name + "_dolphin", false);
  13. conn.close();
  14. } else {
  15. db = get_local_database("fundit", table_name.split(".")[0]);
  16. //local_table = loadTable(db, table_name.split(".")[1]);
  17. saveTable(db, tb, table_name.split(".")[1]);
  18. }
  19. }
  20. /*
  21. * 【临时】 用于将dolphin table 存到 mysql
  22. *
  23. */
  24. def save_table2(tb, table_name, isCreateTable) {
  25. tb.addColumn(['creatorid', 'createtime', 'updaterid', 'updatetime'], [INT, DATETIME, INT, DATETIME]);
  26. conn = connect_mysql('raw_db');
  27. odbc::append(conn, tb, table_name , isCreateTable, false);
  28. conn.close()
  29. }
  30. /*
  31. * 存私募基金净值到本地dolphindb
  32. *
  33. * save_hedge_fund_nav_to_local(tb_nav)
  34. */
  35. def save_hedge_fund_nav_to_local(tb_nav) {
  36. save_table(tb_nav, "mfdb.nav", false)
  37. }
  38. /*
  39. * 将数据存到本地,之后传回MySQL并同步至正式表
  40. *
  41. *
  42. */
  43. def save_and_sync(table, source_table_name, target_table_name) {
  44. save_table(table, source_table_name, true);
  45. t_table_name = iif(target_table_name.isNothing(), source_table_name, target_table_name);
  46. s_query = "CALL raw_db.sp_sync_table_from_dolphin('" + source_table_name + "_dolphin', '" + t_table_name + "');"
  47. conn = connect_mysql('raw_db');
  48. odbc::execute(conn, s_query);
  49. conn.close();
  50. }
  51. /*
  52. * 建表 XXXX_nav
  53. */
  54. def create_entity_nav(is_id_integer=false) {
  55. return table(1000:0,
  56. ['entity_id', 'price_date', 'cumulative_nav'],
  57. [iif(is_id_integer, INT, SYMBOL), DATE, DOUBLE]);
  58. }
  59. /*
  60. * 建公司/经理周净值表 XXXX_nav
  61. */
  62. def create_mc_nav() {
  63. return table(1000:0,
  64. ['entity_id', 'curve_type', 'strategy', 'year_week', 'price_date', 'cumulative_nav', 'ret_1w', 'fund_num'],
  65. [SYMBOL, INT, INT, STRING, DATE, DOUBLE, DOUBLE, INT]);
  66. }
  67. /*
  68. * 建公司/经理净值表 XXXX_fitted_curve
  69. */
  70. def create_mc_fitted_curve() {
  71. return table(1000:0,
  72. ['entity_id', 'curve_type', 'strategy', 'end_date', 'cumulative_nav', 'fund_num'],
  73. [SYMBOL, INT, INT, STRING, DOUBLE, INT]);
  74. }
  75. /*
  76. * 建公司/经理业绩表 xxx_performance
  77. *
  78. */
  79. def create_mc_performance() {
  80. return table(1000:0,
  81. ['entity_id', 'curve_type', 'strategy', 'end_date', 'price_date', 'cumulative_nav',
  82. 'ret_1m', 'ret_1m_a', 'ret_3m', 'ret_3m_a', 'ret_6m', 'ret_6m_a',
  83. 'ret_1y', 'ret_1y_a', 'ret_2y', 'ret_2y_a', 'ret_3y', 'ret_3y_a', 'ret_4y', 'ret_4y_a',
  84. 'ret_5y', 'ret_5y_a', 'ret_10y', 'ret_10y_a', 'ret_ytd', 'ret_ytd_a', 'ret_incep', 'ret_incep_a'],
  85. [SYMBOL, INT, INT, MONTH, DATE, DOUBLE,
  86. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  87. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  88. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  89. }
  90. /*
  91. * 建表 XXXX_performance
  92. */
  93. def create_entity_performance(is_id_integer=false) {
  94. return table(1000:0,
  95. ['entity_id', 'end_date', 'price_date', 'cumulative_nav',
  96. 'ret_1m', 'ret_1m_a', 'ret_3m', 'ret_3m_a', 'ret_6m', 'ret_6m_a',
  97. 'ret_1y', 'ret_1y_a', 'ret_2y', 'ret_2y_a', 'ret_3y', 'ret_3y_a', 'ret_4y', 'ret_4y_a',
  98. 'ret_5y', 'ret_5y_a', 'ret_10y', 'ret_10y_a', 'ret_ytd', 'ret_ytd_a', 'ret_incep', 'ret_incep_a'],
  99. [iif(is_id_integer, INT, SYMBOL), MONTH, DATE, DOUBLE,
  100. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  101. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  102. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  103. }
  104. /*
  105. * 建表 XXX_indicator
  106. */
  107. def create_entity_indicator(is_id_integer=false) {
  108. return table(1000:0,
  109. ['entity_id', 'end_date',
  110. 'info_ratio_6m', 'm2_6m', 'tracking_error_6m',
  111. 'info_ratio_1y', 'm2_1y', 'tracking_error_1y',
  112. 'info_ratio_2y', 'm2_2y', 'tracking_error_2y', 'var_2y', 'cvar_2y',
  113. 'info_ratio_3y', 'm2_3y', 'tracking_error_3y', 'var_3y', 'cvar_3y',
  114. 'info_ratio_4y', 'm2_4y', 'tracking_error_4y', 'var_4y', 'cvar_4y',
  115. 'info_ratio_5y', 'm2_5y', 'tracking_error_5y', 'var_5y', 'cvar_5y',
  116. 'info_ratio_10y', 'm2_10y', 'tracking_error_10y', 'var_10y', 'cvar_10y',
  117. 'info_ratio_ytd', 'm2_ytd', 'tracking_error_ytd',
  118. 'info_ratio_incep', 'm2_incep','tracking_error_incep', 'var_incep', 'cvar_incep'],
  119. [iif(is_id_integer, INT, SYMBOL), MONTH,
  120. DOUBLE, DOUBLE, DOUBLE,
  121. DOUBLE, DOUBLE, DOUBLE,
  122. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  123. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  124. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  125. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  126. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  127. DOUBLE, DOUBLE, DOUBLE,
  128. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  129. }
  130. /*
  131. * 建公司/经理表 XXX_indicator
  132. */
  133. def create_mc_indicator() {
  134. return table(1000:0,
  135. ['entity_id', 'curve_type', 'strategy', 'end_date',
  136. 'info_ratio_6m', 'm2_6m', 'tracking_error_6m',
  137. 'info_ratio_1y', 'm2_1y', 'tracking_error_1y',
  138. 'info_ratio_2y', 'm2_2y', 'tracking_error_2y', 'var_2y', 'cvar_2y',
  139. 'info_ratio_3y', 'm2_3y', 'tracking_error_3y', 'var_3y', 'cvar_3y',
  140. 'info_ratio_4y', 'm2_4y', 'tracking_error_4y', 'var_4y', 'cvar_4y',
  141. 'info_ratio_5y', 'm2_5y', 'tracking_error_5y', 'var_5y', 'cvar_5y',
  142. 'info_ratio_10y', 'm2_10y', 'tracking_error_10y', 'var_10y', 'cvar_10y',
  143. 'info_ratio_ytd', 'm2_ytd', 'tracking_error_ytd',
  144. 'info_ratio_incep', 'm2_incep','tracking_error_incep', 'var_incep', 'cvar_incep'],
  145. [SYMBOL, INT, INT, MONTH,
  146. DOUBLE, DOUBLE, DOUBLE,
  147. DOUBLE, DOUBLE, DOUBLE,
  148. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  149. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  150. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  151. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  152. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  153. DOUBLE, DOUBLE, DOUBLE,
  154. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  155. }
  156. /*
  157. * 建表 XXX_risk_stats
  158. *
  159. * NOTE: mfdb.fund_risk_stats 中 maxdrawdown_6m 和 maxdrawdown_ytd 因不明原因分别是 6m_maxdrawdown 和 ytd_maxdrawdown 的虚拟列!
  160. */
  161. def create_entity_risk_stats(is_id_integer=false) {
  162. return table(1000:0,
  163. ['entity_id', 'end_date',
  164. 'stddev_6m', 'downsidedev_6m', 'alpha_6m', 'winrate_6m', 'beta_6m', 'skewness_6m', 'kurtosis_6m', 'worstmonth_6m', 'maxdrawdown_6m',
  165. 'stddev_1y', 'downsidedev_1y', 'alpha_1y', 'winrate_1y', 'beta_1y', 'skewness_1y', 'kurtosis_1y', 'worstmonth_1y', 'maxdrawdown_1y',
  166. 'stddev_2y', 'downsidedev_2y', 'alpha_2y', 'winrate_2y', 'beta_2y', 'skewness_2y', 'kurtosis_2y', 'worstmonth_2y', 'maxdrawdown_2y',
  167. 'stddev_3y', 'downsidedev_3y', 'alpha_3y', 'winrate_3y', 'beta_3y', 'skewness_3y', 'kurtosis_3y', 'worstmonth_3y', 'maxdrawdown_3y',
  168. 'stddev_4y', 'downsidedev_4y', 'alpha_4y', 'winrate_4y', 'beta_4y', 'skewness_4y', 'kurtosis_4y', 'worstmonth_4y', 'maxdrawdown_4y',
  169. 'stddev_5y', 'downsidedev_5y', 'alpha_5y', 'winrate_5y', 'beta_5y', 'skewness_5y', 'kurtosis_5y', 'worstmonth_5y', 'maxdrawdown_5y',
  170. 'stddev_10y', 'downsidedev_10y','alpha_10y', 'winrate_10y', 'beta_10y', 'skewness_10y', 'kurtosis_10y', 'worstmonth_10y', 'maxdrawdown_10y',
  171. 'stddev_ytd', 'downsidedev_ytd', 'alpha_ytd', 'winrate_ytd', 'beta_ytd', 'skewness_ytd', 'kurtosis_ytd', 'worstmonth_ytd', 'maxdrawdown_ytd',
  172. 'stddev_incep', 'downsidedev_incep', 'alpha_incep', 'winrate_incep', 'beta_incep', 'skewness_incep', 'kurtosis_incep', 'worstmonth_incep', 'maxdrawdown_incep'],
  173. [iif(is_id_integer, INT, SYMBOL), MONTH,
  174. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  175. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  176. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  177. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  178. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  179. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  180. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  181. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  182. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  183. }
  184. /*
  185. * 建基金经理/公司表 XXX_risk_stats
  186. *
  187. */
  188. def create_mc_risk_stats() {
  189. return table(1000:0,
  190. ['entity_id', 'curve_type', 'strategy', 'end_date',
  191. 'stddev_6m', 'downsidedev_6m', 'alpha_6m', 'winrate_6m', 'beta_6m', 'skewness_6m', 'kurtosis_6m', 'worstmonth_6m', 'maxdrawdown_6m',
  192. 'stddev_1y', 'downsidedev_1y', 'alpha_1y', 'winrate_1y', 'beta_1y', 'skewness_1y', 'kurtosis_1y', 'worstmonth_1y', 'maxdrawdown_1y',
  193. 'stddev_2y', 'downsidedev_2y', 'alpha_2y', 'winrate_2y', 'beta_2y', 'skewness_2y', 'kurtosis_2y', 'worstmonth_2y', 'maxdrawdown_2y',
  194. 'stddev_3y', 'downsidedev_3y', 'alpha_3y', 'winrate_3y', 'beta_3y', 'skewness_3y', 'kurtosis_3y', 'worstmonth_3y', 'maxdrawdown_3y',
  195. 'stddev_4y', 'downsidedev_4y', 'alpha_4y', 'winrate_4y', 'beta_4y', 'skewness_4y', 'kurtosis_4y', 'worstmonth_4y', 'maxdrawdown_4y',
  196. 'stddev_5y', 'downsidedev_5y', 'alpha_5y', 'winrate_5y', 'beta_5y', 'skewness_5y', 'kurtosis_5y', 'worstmonth_5y', 'maxdrawdown_5y',
  197. 'stddev_10y', 'downsidedev_10y','alpha_10y', 'winrate_10y', 'beta_10y', 'skewness_10y', 'kurtosis_10y', 'worstmonth_10y', 'maxdrawdown_10y',
  198. 'stddev_ytd', 'downsidedev_ytd', 'alpha_ytd', 'winrate_ytd', 'beta_ytd', 'skewness_ytd', 'kurtosis_ytd', 'worstmonth_ytd', 'maxdrawdown_ytd',
  199. 'stddev_incep', 'downsidedev_incep', 'alpha_incep', 'winrate_incep', 'beta_incep', 'skewness_incep', 'kurtosis_incep', 'worstmonth_incep', 'maxdrawdown_incep'],
  200. [SYMBOL, INT, INT, MONTH,
  201. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  202. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  203. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  204. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  205. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  206. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  207. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  208. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  209. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  210. }
  211. /*
  212. * 建表 XXX_riskadjret_stats
  213. */
  214. def create_entity_riskadjret_stats(is_id_integer=false) {
  215. return table(1000:0,
  216. ['entity_id', 'end_date',
  217. 'sharperatio_6m', 'sortinoratio_6m', 'treynorratio_6m', 'jensen_6m', 'calmarratio_6m', 'omegaratio_6m', 'kapparatio_6m',
  218. 'sharperatio_1y', 'sortinoratio_1y', 'treynorratio_1y', 'jensen_1y', 'calmarratio_1y', 'omegaratio_1y', 'kapparatio_1y',
  219. 'sharperatio_2y', 'sortinoratio_2y', 'treynorratio_2y', 'jensen_2y', 'calmarratio_2y', 'omegaratio_2y', 'kapparatio_2y',
  220. 'sharperatio_3y', 'sortinoratio_3y', 'treynorratio_3y', 'jensen_3y', 'calmarratio_3y', 'omegaratio_3y', 'kapparatio_3y',
  221. 'sharperatio_4y', 'sortinoratio_4y', 'treynorratio_4y', 'jensen_4y', 'calmarratio_4y', 'omegaratio_4y', 'kapparatio_4y',
  222. 'sharperatio_5y', 'sortinoratio_5y', 'treynorratio_5y', 'jensen_5y', 'calmarratio_5y', 'omegaratio_5y', 'kapparatio_5y',
  223. 'sharperatio_10y', 'sortinoratio_10y', 'treynorratio_10y', 'jensen_10y', 'calmarratio_10y', 'omegaratio_10y', 'kapparatio_10y',
  224. 'sharperatio_ytd', 'sortinoratio_ytd', 'treynorratio_ytd', 'jensen_ytd', 'calmarratio_ytd', 'omegaratio_ytd', 'kapparatio_ytd',
  225. 'sharperatio_incep', 'sortinoratio_incep', 'treynorratio_incep', 'jensen_incep', 'calmarratio_incep', 'omegaratio_incep', 'kapparatio_incep'],
  226. [iif(is_id_integer, INT, SYMBOL), MONTH,
  227. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  228. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  229. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  230. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  231. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  232. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  233. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  234. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  235. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  236. }
  237. /*
  238. * 建基金经理/公司表 XXX_riskadjret_stats
  239. */
  240. def create_mc_riskadjret_stats() {
  241. return table(1000:0,
  242. ['entity_id', 'curve_type', 'strategy', 'end_date',
  243. 'sharperatio_6m', 'sortinoratio_6m', 'treynorratio_6m', 'jensen_6m', 'calmarratio_6m', 'omegaratio_6m', 'kapparatio_6m',
  244. 'sharperatio_1y', 'sortinoratio_1y', 'treynorratio_1y', 'jensen_1y', 'calmarratio_1y', 'omegaratio_1y', 'kapparatio_1y',
  245. 'sharperatio_2y', 'sortinoratio_2y', 'treynorratio_2y', 'jensen_2y', 'calmarratio_2y', 'omegaratio_2y', 'kapparatio_2y',
  246. 'sharperatio_3y', 'sortinoratio_3y', 'treynorratio_3y', 'jensen_3y', 'calmarratio_3y', 'omegaratio_3y', 'kapparatio_3y',
  247. 'sharperatio_4y', 'sortinoratio_4y', 'treynorratio_4y', 'jensen_4y', 'calmarratio_4y', 'omegaratio_4y', 'kapparatio_4y',
  248. 'sharperatio_5y', 'sortinoratio_5y', 'treynorratio_5y', 'jensen_5y', 'calmarratio_5y', 'omegaratio_5y', 'kapparatio_5y',
  249. 'sharperatio_10y', 'sortinoratio_10y', 'treynorratio_10y', 'jensen_10y', 'calmarratio_10y', 'omegaratio_10y', 'kapparatio_10y',
  250. 'sharperatio_ytd', 'sortinoratio_ytd', 'treynorratio_ytd', 'jensen_ytd', 'calmarratio_ytd', 'omegaratio_ytd', 'kapparatio_ytd',
  251. 'sharperatio_incep', 'sortinoratio_incep', 'treynorratio_incep', 'jensen_incep', 'calmarratio_incep', 'omegaratio_incep', 'kapparatio_incep'],
  252. [SYMBOL, INT, INT, MONTH,
  253. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  254. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  255. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  256. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  257. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  258. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  259. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  260. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  261. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  262. }
  263. /*
  264. * 建表 XXX_style_stats
  265. */
  266. def create_entity_style_stats(is_id_integer=false) {
  267. return table(1000:0,
  268. ['entity_id', 'end_date',
  269. 'upsidecapture_ret_6m', 'downsidecapture_ret_6m', 'upsidecapture_ratio_6m', 'downsidecapture_ratio_6m',
  270. 'upsidecapture_ret_1y', 'downsidecapture_ret_1y', 'upsidecapture_ratio_1y', 'downsidecapture_ratio_1y',
  271. 'upsidecapture_ret_2y', 'downsidecapture_ret_2y', 'upsidecapture_ratio_2y', 'downsidecapture_ratio_2y',
  272. 'upsidecapture_ret_3y', 'downsidecapture_ret_3y', 'upsidecapture_ratio_3y', 'downsidecapture_ratio_3y',
  273. 'upsidecapture_ret_4y', 'downsidecapture_ret_4y', 'upsidecapture_ratio_4y', 'downsidecapture_ratio_4y',
  274. 'upsidecapture_ret_5y', 'downsidecapture_ret_5y', 'upsidecapture_ratio_5y', 'downsidecapture_ratio_5y',
  275. 'upsidecapture_ret_10y', 'downsidecapture_ret_10y', 'upsidecapture_ratio_10y', 'downsidecapture_ratio_10y',
  276. 'upsidecapture_ret_ytd', 'downsidecapture_ret_ytd', 'upsidecapture_ratio_ytd', 'downsidecapture_ratio_ytd',
  277. 'upsidecapture_ret_incep', 'downsidecapture_ret_incep', 'upsidecapture_ratio_incep', 'downsidecapture_ratio_incep'],
  278. [iif(is_id_integer, INT, SYMBOL), MONTH,
  279. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  280. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  281. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  282. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  283. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  284. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  285. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  286. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  287. DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  288. }
  289. /*
  290. * 建表 XXX_ms_stats
  291. */
  292. def create_entity_ms_stats(is_id_integer=false) {
  293. return table(1000:0,
  294. ['entity_id', 'end_date',
  295. 'ms_return_3y', 'ms_rar_3y', 'ms_risk_3y',
  296. 'ms_return_5y', 'ms_rar_5y', 'ms_risk_5y',
  297. 'ms_return_10y', 'ms_rar_10y', 'ms_risk_10y'],
  298. [iif(is_id_integer, INT, SYMBOL), MONTH,
  299. DOUBLE, DOUBLE, DOUBLE,
  300. DOUBLE, DOUBLE, DOUBLE,
  301. DOUBLE, DOUBLE, DOUBLE]);
  302. }
  303. /*
  304. * 建基金经理/公司表 XXX_style_stats
  305. */
  306. def create_mc_style_stats() {
  307. return table(1000:0,
  308. ['entity_id', 'curve_type', 'strategy', 'end_date',
  309. 'upsidecapture_ret_6m', 'downsidecapture_ret_6m', 'upsidecapture_ratio_6m', 'downsidecapture_ratio_6m',
  310. 'upsidecapture_ret_1y', 'downsidecapture_ret_1y', 'upsidecapture_ratio_1y', 'downsidecapture_ratio_1y',
  311. 'upsidecapture_ret_2y', 'downsidecapture_ret_2y', 'upsidecapture_ratio_2y', 'downsidecapture_ratio_2y',
  312. 'upsidecapture_ret_3y', 'downsidecapture_ret_3y', 'upsidecapture_ratio_3y', 'downsidecapture_ratio_3y',
  313. 'upsidecapture_ret_4y', 'downsidecapture_ret_4y', 'upsidecapture_ratio_4y', 'downsidecapture_ratio_4y',
  314. 'upsidecapture_ret_5y', 'downsidecapture_ret_5y', 'upsidecapture_ratio_5y', 'downsidecapture_ratio_5y',
  315. 'upsidecapture_ret_10y', 'downsidecapture_ret_10y', 'upsidecapture_ratio_10y', 'downsidecapture_ratio_10y',
  316. 'upsidecapture_ret_ytd', 'downsidecapture_ret_ytd', 'upsidecapture_ratio_ytd', 'downsidecapture_ratio_ytd',
  317. 'upsidecapture_ret_incep', 'downsidecapture_ret_incep', 'upsidecapture_ratio_incep', 'downsidecapture_ratio_incep'],
  318. [SYMBOL, INT, INT, MONTH,
  319. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  320. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  321. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  322. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  323. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  324. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  325. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  326. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  327. DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  328. }
  329. /*
  330. * 建表 XXX_bfi_bm_indicator
  331. */
  332. def create_entity_bfi_indicator(is_id_integer=false) {
  333. return table(1000:0,
  334. ['entity_id', 'end_date', 'factor_id',
  335. 'upsidecapture_ret_6m', 'downsidecapture_ret_6m', 'upsidecapture_ratio_6m', 'downsidecapture_ratio_6m',
  336. 'alpha_6m', 'winrate_6m', 'beta_6m', 'info_ratio_6m', 'tracking_error_6m', 'jensen_6m',
  337. 'upsidecapture_ret_1y', 'downsidecapture_ret_1y', 'upsidecapture_ratio_1y', 'downsidecapture_ratio_1y',
  338. 'alpha_1y', 'winrate_1y', 'beta_1y', 'info_ratio_1y', 'tracking_error_1y', 'jensen_1y',
  339. 'upsidecapture_ret_2y', 'downsidecapture_ret_2y', 'upsidecapture_ratio_2y', 'downsidecapture_ratio_2y',
  340. 'alpha_2y', 'winrate_2y', 'beta_2y', 'info_ratio_2y', 'tracking_error_2y', 'jensen_2y',
  341. 'upsidecapture_ret_3y', 'downsidecapture_ret_3y', 'upsidecapture_ratio_3y', 'downsidecapture_ratio_3y',
  342. 'alpha_3y', 'winrate_3y', 'beta_3y', 'info_ratio_3y', 'tracking_error_3y', 'jensen_3y',
  343. 'upsidecapture_ret_4y', 'downsidecapture_ret_4y', 'upsidecapture_ratio_4y', 'downsidecapture_ratio_4y',
  344. 'alpha_4y', 'winrate_4y', 'beta_4y', 'info_ratio_4y', 'tracking_error_4y', 'jensen_4y',
  345. 'upsidecapture_ret_5y', 'downsidecapture_ret_5y', 'upsidecapture_ratio_5y', 'downsidecapture_ratio_5y',
  346. 'alpha_5y', 'winrate_5y', 'beta_5y', 'info_ratio_5y', 'tracking_error_5y', 'jensen_5y',
  347. 'upsidecapture_ret_10y', 'downsidecapture_ret_10y', 'upsidecapture_ratio_10y', 'downsidecapture_ratio_10y',
  348. 'alpha_10y', 'winrate_10y', 'beta_10y', 'info_ratio_10y', 'tracking_error_10y', 'jensen_10y',
  349. 'upsidecapture_ret_ytd', 'downsidecapture_ret_ytd', 'upsidecapture_ratio_ytd', 'downsidecapture_ratio_ytd',
  350. 'alpha_ytd', 'winrate_ytd', 'beta_ytd', 'info_ratio_ytd', 'tracking_error_ytd', 'jensen_ytd',
  351. 'upsidecapture_ret_incep', 'downsidecapture_ret_incep', 'upsidecapture_ratio_incep', 'downsidecapture_ratio_incep',
  352. 'alpha_incep', 'winrate_incep', 'beta_incep', 'info_ratio_incep', 'tracking_error_incep', 'jensen_incep'],
  353. [iif(is_id_integer, INT, SYMBOL), MONTH, SYMBOL,
  354. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  355. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  356. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  357. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  358. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  359. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  360. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  361. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  362. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  363. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  364. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  365. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  366. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  367. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  368. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  369. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  370. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  371. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE] );
  372. }
  373. /*
  374. * 建基金经理/公司表 XXX_bfi_bm_indicator
  375. */
  376. def create_mc_bfi_indicator() {
  377. return table(1000:0,
  378. ['entity_id', 'curve_type', 'strategy', 'end_date', 'factor_id',
  379. 'upsidecapture_ret_6m', 'downsidecapture_ret_6m', 'upsidecapture_ratio_6m', 'downsidecapture_ratio_6m',
  380. 'alpha_6m', 'winrate_6m', 'beta_6m', 'info_ratio_6m', 'tracking_error_6m', 'jensen_6m',
  381. 'upsidecapture_ret_1y', 'downsidecapture_ret_1y', 'upsidecapture_ratio_1y', 'downsidecapture_ratio_1y',
  382. 'alpha_1y', 'winrate_1y', 'beta_1y', 'info_ratio_1y', 'tracking_error_1y', 'jensen_1y',
  383. 'upsidecapture_ret_2y', 'downsidecapture_ret_2y', 'upsidecapture_ratio_2y', 'downsidecapture_ratio_2y',
  384. 'alpha_2y', 'winrate_2y', 'beta_2y', 'info_ratio_2y', 'tracking_error_2y', 'jensen_2y',
  385. 'upsidecapture_ret_3y', 'downsidecapture_ret_3y', 'upsidecapture_ratio_3y', 'downsidecapture_ratio_3y',
  386. 'alpha_3y', 'winrate_3y', 'beta_3y', 'info_ratio_3y', 'tracking_error_3y', 'jensen_3y',
  387. 'upsidecapture_ret_4y', 'downsidecapture_ret_4y', 'upsidecapture_ratio_4y', 'downsidecapture_ratio_4y',
  388. 'alpha_4y', 'winrate_4y', 'beta_4y', 'info_ratio_4y', 'tracking_error_4y', 'jensen_4y',
  389. 'upsidecapture_ret_5y', 'downsidecapture_ret_5y', 'upsidecapture_ratio_5y', 'downsidecapture_ratio_5y',
  390. 'alpha_5y', 'winrate_5y', 'beta_5y', 'info_ratio_5y', 'tracking_error_5y', 'jensen_5y',
  391. 'upsidecapture_ret_10y', 'downsidecapture_ret_10y', 'upsidecapture_ratio_10y', 'downsidecapture_ratio_10y',
  392. 'alpha_10y', 'winrate_10y', 'beta_10y', 'info_ratio_10y', 'tracking_error_10y', 'jensen_10y',
  393. 'upsidecapture_ret_ytd', 'downsidecapture_ret_ytd', 'upsidecapture_ratio_ytd', 'downsidecapture_ratio_ytd',
  394. 'alpha_ytd', 'winrate_ytd', 'beta_ytd', 'info_ratio_ytd', 'tracking_error_ytd', 'jensen_ytd',
  395. 'upsidecapture_ret_incep', 'downsidecapture_ret_incep', 'upsidecapture_ratio_incep', 'downsidecapture_ratio_incep',
  396. 'alpha_incep', 'winrate_incep', 'beta_incep', 'info_ratio_incep', 'tracking_error_incep', 'jensen_incep'],
  397. [SYMBOL, INT, INT, MONTH, SYMBOL,
  398. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  399. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  400. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  401. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  402. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  403. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  404. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  405. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  406. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  407. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  408. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  409. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  410. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  411. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  412. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  413. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  414. DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  415. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE] );
  416. }
  417. /*
  418. * 建表 xxx_performance_weekly
  419. */
  420. def create_entity_performance_weekly(is_id_integer=false) {
  421. return table(1000:0,
  422. ['entity_id', 'year_week', 'end_year', 'week_of_year', 'price_date', 'cumulative_nav', 'ret_1w'],
  423. [iif(is_id_integer, INT, SYMBOL), STRING, STRING, SHORT, DATE, DOUBLE, DOUBLE]);
  424. }
  425. /*
  426. * 建表 xxx_latest_performance
  427. */
  428. def create_entity_latest_performance(is_id_integer=false) {
  429. return table(1000:0,
  430. ['entity_id', 'end_date', 'price_date', 'pre_price_date', 'nav', 'cumulative_nav',
  431. 'net_value_change', 'ret_1d', 'ret_1w', 'ret_1m', 'ret_3m', 'ret_6m',
  432. 'ret_1y', 'ret_2y', 'ret_3y', 'ret_4y', 'ret_5y', 'ret_10y', 'ret_ytd', 'ret_incep', 'ret_incep_a', 'ret_incep_a_all', 'ret_incep_a_gips',
  433. 'maxdrawdown_1m', 'maxdrawdown_3m', 'maxdrawdown_1y', 'maxdrawdown_incep', 'calmarratio_incep',
  434. 'ret_1y_a', 'ret_2y_a', 'ret_3y_a', 'ret_4y_a', 'ret_5y_a', 'ret_10y_a'],
  435. [iif(is_id_integer, INT, SYMBOL), STRING, DATE, DATE, DOUBLE, DOUBLE,
  436. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  437. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  438. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  439. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  440. }
  441. /*
  442. * 建表 xxx_index_coe
  443. *
  444. */
  445. def create_entity_index_coe(is_id_integer=false) {
  446. return table(1000:0,
  447. ['entity_id', 'end_date', 'index_id',
  448. 'coe_1y', 'coe_3y', 'coe_5y', //'info_ratio_1y', 'info_ratio_3y', 'info_ratio_5y',
  449. 't_value_1y', 't_value_3y', 't_value_5y', 'beta_1y', 'beta_3y', 'beta_5y'],
  450. [iif(is_id_integer, INT, SYMBOL), MONTH, SYMBOL,
  451. DOUBLE, DOUBLE, DOUBLE, //DOUBLE, DOUBLE, DOUBLE,
  452. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  453. }
  454. /*
  455. * 建表 xxx_index_coe
  456. *
  457. */
  458. def create_mc_index_coe(is_id_integer=false) {
  459. return table(1000:0,
  460. ['entity_id', 'curve_type', 'strategy', 'end_date', 'index_id',
  461. 'coe_1y', 'coe_3y', 'coe_5y', //'info_ratio_1y', 'info_ratio_3y', 'info_ratio_5y',
  462. 't_value_1y', 't_value_3y', 't_value_5y', 'beta_1y', 'beta_3y', 'beta_5y'],
  463. [SYMBOL, INT, INT, MONTH, SYMBOL,
  464. DOUBLE, DOUBLE, DOUBLE, //DOUBLE, DOUBLE, DOUBLE,
  465. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  466. }
  467. /*
  468. * 建表 xxx_factor_bfi_max_r2
  469. *
  470. */
  471. def create_entity_bfi_max_r2(is_id_integer=false) {
  472. return table(1000:0,
  473. ['entity_id', 'end_date', 'factor_id', 'coe', 'r2', 'performance_flag', 'rz_portrait'],
  474. [iif(is_id_integer, INT, SYMBOL), MONTH, SYMBOL, DOUBLE, DOUBLE, STRING, STRING]);
  475. }
  476. /*
  477. * 建表 xxx_factor_bfi
  478. *
  479. */
  480. def create_entity_factor_bfi(is_id_integer=false) {
  481. return table(1000:0,
  482. ['entity_id', 'end_date', 'factor_id',
  483. 'coe', 'r2', 'performance_flag', 't_value_1y', 'beta_1y'],
  484. [iif(is_id_integer, INT, SYMBOL), MONTH, SYMBOL,
  485. DOUBLE, DOUBLE, STRING, DOUBLE, DOUBLE]);
  486. }
  487. /*
  488. * 建基金经理/公司 bfi连接表 xxx_factor_bfi
  489. *
  490. */
  491. def create_mc_factor_bfi(is_id_integer=false) {
  492. return table(1000:0,
  493. ['entity_id', 'curve_type', 'strategy', 'end_date', 'factor_id',
  494. 'coe', 'r2', 'performance_flag', 't_value_1y', 'beta_1y'],
  495. [SYMBOL, INT, INT, MONTH, SYMBOL,
  496. DOUBLE, DOUBLE, STRING, DOUBLE, DOUBLE]);
  497. }
  498. /*
  499. * 建表 XXXX_indicator_ranking
  500. */
  501. def create_entity_indicator_ranking(is_id_integer=false) {
  502. return table(1000:0,
  503. ['entity_id', 'end_date', 'category_id', 'indicator_id',
  504. 'indicator_1m', 'absrank_1m', 'perrank_1m', 'indicator_3m', 'absrank_3m', 'perrank_3m',
  505. 'indicator_6m', 'absrank_6m', 'perrank_6m', 'indicator_1y', 'absrank_1y', 'perrank_1y',
  506. 'indicator_2y', 'absrank_2y', 'perrank_2y', 'indicator_3y', 'absrank_3y', 'perrank_3y',
  507. 'indicator_5y', 'absrank_5y', 'perrank_5y',
  508. 'indicator_10y', 'absrank_10y', 'perrank_10y', 'indicator_ytd', 'absrank_ytd', 'perrank_ytd'],
  509. [iif(is_id_integer, INT, SYMBOL), STRING, SYMBOL, INT,
  510. DOUBLE, INT, INT, DOUBLE, INT, INT,
  511. DOUBLE, INT, INT, DOUBLE, INT, INT,
  512. DOUBLE, INT, INT, DOUBLE, INT, INT,
  513. DOUBLE, INT, INT,
  514. DOUBLE, INT, INT, DOUBLE, INT, INT]);
  515. }
  516. /*
  517. * 建基金经理/公司表 XXXX_indicator_ranking
  518. */
  519. def create_mc_indicator_ranking(is_id_integer=false) {
  520. return table(1000:0,
  521. ['entity_id', 'curve_type', 'strategy', 'category_id', 'end_date', 'indicator_id',
  522. 'indicator_1m', 'absrank_1m', 'perrank_1m', 'indicator_3m', 'absrank_3m', 'perrank_3m',
  523. 'indicator_6m', 'absrank_6m', 'perrank_6m', 'indicator_1y', 'absrank_1y', 'perrank_1y',
  524. 'indicator_2y', 'absrank_2y', 'perrank_2y', 'indicator_3y', 'absrank_3y', 'perrank_3y',
  525. 'indicator_5y', 'absrank_5y', 'perrank_5y',
  526. 'indicator_10y', 'absrank_10y', 'perrank_10y', 'indicator_ytd', 'absrank_ytd', 'perrank_ytd'],
  527. [SYMBOL, INT, INT, SYMBOL, STRING, INT,
  528. DOUBLE, INT, INT, DOUBLE, INT, INT,
  529. DOUBLE, INT, INT, DOUBLE, INT, INT,
  530. DOUBLE, INT, INT, DOUBLE, INT, INT,
  531. DOUBLE, INT, INT,
  532. DOUBLE, INT, INT, DOUBLE, INT, INT]);
  533. }
  534. /*
  535. * 建表 XXXX_indicator_ranking_num, raise_type 没有用
  536. */
  537. def create_entity_indicator_ranking_num() {
  538. return table(1000:0,
  539. ['end_date', 'category_id', 'raise_type', 'indicator_id',
  540. 'avg_1m', 'avg_1m_cnt', 'perrank_percent_5_1m', 'perrank_percent_10_1m', 'perrank_percent_25_1m', 'perrank_percent_50_1m',
  541. 'perrank_percent_75_1m', 'perrank_percent_90_1m', 'perrank_percent_95_1m', 'best_1m', 'worst_1m',
  542. 'avg_3m', 'avg_3m_cnt', 'perrank_percent_5_3m', 'perrank_percent_10_3m', 'perrank_percent_25_3m', 'perrank_percent_50_3m',
  543. 'perrank_percent_75_3m', 'perrank_percent_90_3m', 'perrank_percent_95_3m', 'best_3m', 'worst_3m',
  544. 'avg_6m', 'avg_6m_cnt', 'perrank_percent_5_6m', 'perrank_percent_10_6m', 'perrank_percent_25_6m', 'perrank_percent_50_6m',
  545. 'perrank_percent_75_6m', 'perrank_percent_90_6m', 'perrank_percent_95_6m', 'best_6m', 'worst_6m',
  546. 'avg_1y', 'avg_1y_cnt', 'perrank_percent_5_1y', 'perrank_percent_10_1y', 'perrank_percent_25_1y', 'perrank_percent_50_1y',
  547. 'perrank_percent_75_1y', 'perrank_percent_90_1y', 'perrank_percent_95_1y', 'best_1y', 'worst_1y',
  548. 'avg_2y', 'avg_2y_cnt', 'perrank_percent_5_2y', 'perrank_percent_10_2y', 'perrank_percent_25_2y', 'perrank_percent_50_2y',
  549. 'perrank_percent_75_2y', 'perrank_percent_90_2y', 'perrank_percent_95_2y', 'best_2y', 'worst_2y',
  550. 'avg_3y', 'avg_3y_cnt', 'perrank_percent_5_3y', 'perrank_percent_10_3y', 'perrank_percent_25_3y', 'perrank_percent_50_3y',
  551. 'perrank_percent_75_3y', 'perrank_percent_90_3y', 'perrank_percent_95_3y', 'best_3y', 'worst_3y',
  552. 'avg_5y', 'avg_5y_cnt', 'perrank_percent_5_5y', 'perrank_percent_10_5y', 'perrank_percent_25_5y', 'perrank_percent_50_5y',
  553. 'perrank_percent_75_5y', 'perrank_percent_90_5y', 'perrank_percent_95_5y', 'best_5y', 'worst_5y',
  554. 'avg_10y', 'avg_10y_cnt', 'perrank_percent_5_10y', 'perrank_percent_10_10y', 'perrank_percent_25_10y', 'perrank_percent_50_10y',
  555. 'perrank_percent_75_10y', 'perrank_percent_90_10y', 'perrank_percent_95_10y', 'best_10y', 'worst_10y',
  556. 'avg_ytd', 'avg_ytd_cnt', 'perrank_percent_5_ytd', 'perrank_percent_10_ytd', 'perrank_percent_25_ytd', 'perrank_percent_50_ytd',
  557. 'perrank_percent_75_ytd', 'perrank_percent_90_ytd', 'perrank_percent_95_ytd', 'best_ytd', 'worst_ytd'],
  558. [STRING, SYMBOL, INT, INT,
  559. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  560. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  561. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  562. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  563. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  564. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  565. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  566. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  567. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  568. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  569. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  570. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  571. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  572. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  573. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  574. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  575. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  576. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE ]);
  577. }
  578. /*
  579. * 建基金经理/公司表 XXXX_indicator_ranking_num, raise_type 没有用
  580. */
  581. def create_mc_indicator_ranking_num() {
  582. return table(1000:0,
  583. ['curve_type', 'strategy', 'category_id', 'end_date', 'indicator_id',
  584. 'avg_1m', 'avg_1m_cnt', 'perrank_percent_5_1m', 'perrank_percent_10_1m', 'perrank_percent_25_1m', 'perrank_percent_50_1m',
  585. 'perrank_percent_75_1m', 'perrank_percent_90_1m', 'perrank_percent_95_1m', 'best_1m', 'worst_1m',
  586. 'avg_3m', 'avg_3m_cnt', 'perrank_percent_5_3m', 'perrank_percent_10_3m', 'perrank_percent_25_3m', 'perrank_percent_50_3m',
  587. 'perrank_percent_75_3m', 'perrank_percent_90_3m', 'perrank_percent_95_3m', 'best_3m', 'worst_3m',
  588. 'avg_6m', 'avg_6m_cnt', 'perrank_percent_5_6m', 'perrank_percent_10_6m', 'perrank_percent_25_6m', 'perrank_percent_50_6m',
  589. 'perrank_percent_75_6m', 'perrank_percent_90_6m', 'perrank_percent_95_6m', 'best_6m', 'worst_6m',
  590. 'avg_1y', 'avg_1y_cnt', 'perrank_percent_5_1y', 'perrank_percent_10_1y', 'perrank_percent_25_1y', 'perrank_percent_50_1y',
  591. 'perrank_percent_75_1y', 'perrank_percent_90_1y', 'perrank_percent_95_1y', 'best_1y', 'worst_1y',
  592. 'avg_2y', 'avg_2y_cnt', 'perrank_percent_5_2y', 'perrank_percent_10_2y', 'perrank_percent_25_2y', 'perrank_percent_50_2y',
  593. 'perrank_percent_75_2y', 'perrank_percent_90_2y', 'perrank_percent_95_2y', 'best_2y', 'worst_2y',
  594. 'avg_3y', 'avg_3y_cnt', 'perrank_percent_5_3y', 'perrank_percent_10_3y', 'perrank_percent_25_3y', 'perrank_percent_50_3y',
  595. 'perrank_percent_75_3y', 'perrank_percent_90_3y', 'perrank_percent_95_3y', 'best_3y', 'worst_3y',
  596. 'avg_5y', 'avg_5y_cnt', 'perrank_percent_5_5y', 'perrank_percent_10_5y', 'perrank_percent_25_5y', 'perrank_percent_50_5y',
  597. 'perrank_percent_75_5y', 'perrank_percent_90_5y', 'perrank_percent_95_5y', 'best_5y', 'worst_5y',
  598. 'avg_10y', 'avg_10y_cnt', 'perrank_percent_5_10y', 'perrank_percent_10_10y', 'perrank_percent_25_10y', 'perrank_percent_50_10y',
  599. 'perrank_percent_75_10y', 'perrank_percent_90_10y', 'perrank_percent_95_10y', 'best_10y', 'worst_10y',
  600. 'avg_ytd', 'avg_ytd_cnt', 'perrank_percent_5_ytd', 'perrank_percent_10_ytd', 'perrank_percent_25_ytd', 'perrank_percent_50_ytd',
  601. 'perrank_percent_75_ytd', 'perrank_percent_90_ytd', 'perrank_percent_95_ytd', 'best_ytd', 'worst_ytd'],
  602. [INT, INT, SYMBOL, STRING, INT,
  603. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  604. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  605. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  606. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  607. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  608. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  609. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  610. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  611. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  612. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  613. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  614. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  615. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  616. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  617. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  618. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  619. DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE,
  620. DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE ]);
  621. }
  622. /*
  623. * 根据 mysql 表改动某些字段
  624. */
  625. def chg_columns_for_mysql(mutable tb_mysql, id_col_name) {
  626. tb_mysql.rename!('entity_id', id_col_name);
  627. // 将 dolphinDB 的 MONTH 换成 MySQL 的 YYYY-MM 格式
  628. v_end_date = EXEC end_date.temporalFormat('yyyy-MM') FROM tb_mysql;
  629. tb_mysql.replaceColumn!('end_date', v_end_date);
  630. }
  631. /*
  632. * 按照 XXX_performance 表结构准备数据记录
  633. *
  634. * @param entity_info <TABLE>: [COLUMNS] entity_id, end_date (用于筛掉不必要的老记录), [curve_type, strategy]
  635. * @param indicators <DICT>: 指标类型-区间:数据表
  636. * @param entity_performance <TABLE>: 被更新的数据表
  637. * @param extra_keys <VECTOR>: 只有基金经理和公司会用到,对应 [curve_type, strategy]
  638. *
  639. * TODO: price_date is NULL for some records
  640. */
  641. def generate_entity_performance(entity_info, indicators, isToMySQL, mutable entity_performance, extra_keys=[]) {
  642. t = null;
  643. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  644. else v_extra_keys = extra_keys;
  645. if(isToMySQL) {
  646. if(indicators['PBI-3M'].isVoid() || indicators['PBI-3M'].size() == 0) return;
  647. t = sql(select =(sqlCol('entity_id'),
  648. sqlCol(v_extra_keys.join('end_date')),
  649. sqlCol('price_date'),
  650. sqlCol(['nav', 'ret', 'ret', 'trailing_ret', 'trailing_ret_a'], , ['cumulative_nav', 'ret_1m', 'ret_1m_a', 'ret_3m', 'ret_3m_a'])
  651. ),
  652. from = ej(indicators['PBI-3M'] AS a, entity_info AS fi, ['entity_id'].join(v_extra_keys)),
  653. where = < end_date >= fi_price_date.month()> // 过滤掉不必更新的旧记录, 这里用系统字段的别名 fi_price_date 有点脏,但目前没办法
  654. ).eval();
  655. v_trailing = ['6m', '1y', '2y', '3y', '4y', '5y', '10y', 'ytd', 'incep'];
  656. for(tr in v_trailing) {
  657. col_name = 'ret_' + tr;
  658. col_a_name = 'ret_' + tr + '_a';
  659. t.addColumn([col_name, col_a_name], [DOUBLE, DOUBLE]);
  660. if(!indicators['PBI-'+tr.upper()].isVoid()) {
  661. sqlUpdate(table = t,
  662. updates = [<trailing_ret as _$col_name>, <trailing_ret_a as _$col_a_name>],
  663. from = <ej(t, indicators['PBI-'+tr.upper()], ['entity_id'].join(v_extra_keys).join(['end_date']))>
  664. ).eval();
  665. }
  666. }
  667. INSERT INTO entity_performance SELECT * FROM t;
  668. } else {
  669. }
  670. }
  671. /*
  672. * 按照 XXX_risk_stats 表结构准备数据记录
  673. *
  674. *
  675. */
  676. def generate_entity_risk_stats(entity_info, indicators, isToMySQL, mutable entity_risk_stats, extra_keys=[]) {
  677. t = null;
  678. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  679. else v_extra_keys = extra_keys;
  680. if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
  681. if(isToMySQL) {
  682. t = sql(select =(sqlCol('entity_id'),
  683. sqlCol(v_extra_keys.join('end_date')),
  684. sqlCol(['std_dev_a', 'ds_dev_a', 'alpha_a', 'winrate', 'beta', 'skewness', 'kurtosis', 'wrst_month', 'drawdown'],
  685. , ['stddev_6m', 'downsidedev_6m', 'alpha_6m', 'winrate_6m', 'beta_6m', 'skewness_6m', 'kurtosis_6m', 'worstmonth_6m', 'maxdrawdown_6m'])
  686. ),
  687. from = ej(indicators['PBI-6M'] AS a, entity_info AS fi, ['entity_id'].join(v_extra_keys)),
  688. where = < end_date >= fi_price_date.month()> // 过滤掉不必更新的旧记录
  689. ).eval();
  690. v_trailing = ['1y', '2y', '3y', '4y', '5y', '10y', 'ytd', 'incep'];
  691. for(tr in v_trailing) {
  692. col_std_dev = 'stddev_' + tr;
  693. col_ds_dev = 'downsidedev_' + tr;
  694. col_alpha = 'alpha_' + tr;
  695. col_winrate = 'winrate_' + tr;
  696. col_beta = 'beta_' + tr;
  697. col_skewness = 'skewness_' + tr;
  698. col_kurtosis = 'kurtosis_' + tr;
  699. col_wrst_month = 'worstmonth_' + tr;
  700. col_drawdown = 'maxdrawdown_' + tr;
  701. t.addColumn([col_std_dev, col_ds_dev, col_alpha, col_winrate, col_beta, col_skewness, col_kurtosis, col_wrst_month, col_drawdown],
  702. [DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  703. if(!indicators['PBI-'+tr.upper()].isVoid()) {
  704. sqlUpdate(table = t,
  705. updates = [<std_dev_a as _$col_std_dev>, <ds_dev_a as _$col_ds_dev>, <alpha_a as _$col_alpha>,
  706. <winrate as _$col_winrate>, <beta as _$col_beta>, <skewness as _$col_skewness>,
  707. <kurtosis as _$col_kurtosis>, <wrst_month as _$col_wrst_month>, <drawdown as _$col_drawdown>],
  708. from = <ej(t, indicators['PBI-'+tr.upper()], ['entity_id'].join(v_extra_keys).join(['end_date']))>
  709. ).eval();
  710. }
  711. }
  712. INSERT INTO entity_risk_stats SELECT * FROM t;
  713. } else {
  714. }
  715. }
  716. /*
  717. * 按照 XXX_riskadjret_stats 表结构准备数据记录
  718. *
  719. *
  720. */
  721. def generate_entity_riskadjret_stats(entity_info, indicators, isToMySQL, mutable entity_riskadjret_stats, extra_keys=[]) {
  722. t = null;
  723. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  724. else v_extra_keys = extra_keys;
  725. if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
  726. if(isToMySQL) {
  727. t = sql(select =(sqlCol('entity_id'),
  728. sqlCol(v_extra_keys.join('end_date')),
  729. sqlCol(['sharpe_a', 'sortino_a', 'treynor', 'jensen_a', 'calmar', 'omega', 'kappa'],
  730. , ['sharperatio_6m', 'sortinoratio_6m', 'treynorratio_6m', 'jensen_6m', 'calmarratio_6m', 'omegaratio_6m', 'kapparatio_6m'])
  731. ),
  732. from = ej(indicators['PBI-6M'] AS a, entity_info AS fi, ['entity_id'].join(v_extra_keys)),
  733. where = < end_date >= fi_price_date.month()> // 过滤掉不必更新的旧记录
  734. ).eval();
  735. v_trailing = ['1y', '2y', '3y', '4y', '5y', '10y', 'ytd', 'incep'];
  736. for(tr in v_trailing) {
  737. col_sharpe = 'sharperatio_' + tr;
  738. col_sortino = 'sortinoratio_' + tr;
  739. col_treynor = 'treynorratio_' + tr;
  740. col_jensen = 'jensen_' + tr;
  741. col_calmar = 'calmarratio_' + tr;
  742. col_omega = 'omegaratio_' + tr;
  743. col_kappa = 'kapparatio_' + tr;
  744. t.addColumn([col_sharpe, col_sortino, col_treynor, col_jensen, col_calmar, col_omega, col_kappa],
  745. [DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  746. if(!indicators['PBI-'+tr.upper()].isVoid()) {
  747. sqlUpdate(table = t,
  748. updates = [<sharpe_a as _$col_sharpe>, <sortino_a as _$col_sortino>, <treynor as _$col_treynor>,
  749. <jensen_a as _$col_jensen>, <calmar as _$col_calmar>, <omega as _$col_omega>,
  750. <kappa as _$col_kappa>],
  751. from = <ej(t, indicators['PBI-'+tr.upper()], ['entity_id'].join(v_extra_keys).join(['end_date']))>
  752. ).eval();
  753. }
  754. }
  755. INSERT INTO entity_riskadjret_stats SELECT * FROM t;
  756. } else {
  757. }
  758. }
  759. /*
  760. * 按照 XXX_indicator 表结构准备数据记录
  761. *
  762. *
  763. */
  764. def generate_entity_indicator(entity_info, indicators, isToMySQL, mutable entity_indicator, extra_keys=[]) {
  765. t = null;
  766. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  767. else v_extra_keys = extra_keys;
  768. if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
  769. if(isToMySQL) {
  770. t = sql(select =(sqlCol('entity_id'),
  771. sqlCol(v_extra_keys.join('end_date')),
  772. sqlCol(['info_a', 'm2_a', 'track_error_a'],
  773. , ['info_ratio_6m', 'm2_6m', 'tracking_error_6m'])
  774. ),
  775. from = ej(indicators['PBI-6M'] AS a, entity_info AS fi, ['entity_id'].join(v_extra_keys)),
  776. where = < end_date >= fi_price_date.month()> // 过滤掉不必更新的旧记录
  777. ).eval();
  778. v_trailing = ['1y', '2y', '3y', '4y', '5y', '10y', 'ytd', 'incep'];
  779. for(tr in v_trailing) {
  780. col_info = 'info_ratio_' + tr;
  781. col_m2 = 'm2_' + tr;
  782. col_track_error = 'tracking_error_' + tr;
  783. col_var = 'var_' + tr;
  784. col_cvar = 'cvar_' + tr;
  785. t.addColumn([col_info, col_m2, col_track_error],
  786. [DOUBLE, DOUBLE, DOUBLE]);
  787. if(tr != 'ytd') // YTD 没有 VAR, CVAR
  788. t.addColumn([col_var, col_cvar], [DOUBLE, DOUBLE]);
  789. if(!indicators['PBI-'+tr.upper()].isVoid()) {
  790. sqlUpdate(table = t,
  791. updates = iif(tr != 'ytd', [<info_a as _$col_info>, <m2_a as _$col_m2>, <track_error_a as _$col_track_error>,
  792. <var as _$col_var>, <cvar as _$col_cvar>], [<info_a as _$col_info>, <m2_a as _$col_m2>, <track_error_a as _$col_track_error>]),
  793. from = <ej(t, indicators['PBI-'+tr.upper()], ['entity_id'].join(v_extra_keys).join(['end_date']))>
  794. ).eval();
  795. }
  796. }
  797. // var, cvar 只有2年及更长时间才计算
  798. t.dropColumns!(['var_1y', 'cvar_1y']);
  799. INSERT INTO entity_indicator SELECT * FROM t;
  800. } else {
  801. }
  802. }
  803. /*
  804. * 按照 XXX_style_stats 表结构准备数据记录
  805. *
  806. *
  807. */
  808. def generate_entity_style_stats(entity_info, indicators, isToMySQL, mutable entity_style_stats, extra_keys=[]) {
  809. t = null;
  810. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  811. else v_extra_keys = extra_keys;
  812. if(indicators['PBI-6M'].isVoid() || indicators['PBI-6M'].size() == 0) return;
  813. if(isToMySQL) {
  814. t = sql(select =(sqlCol('entity_id'),
  815. sqlCol(v_extra_keys.join('end_date')),
  816. sqlCol(['upside_capture_ret', 'downside_capture_ret', 'upside_capture_ratio', 'downside_capture_ratio'],
  817. , ['upsidecapture_ret_6m', 'downsidecapture_ret_6m', 'upsidecapture_ratio_6m', 'downsidecapture_ratio_6m'])
  818. ),
  819. from = ej(indicators['PBI-6M'] AS a, entity_info AS fi, ['entity_id'].join(v_extra_keys)),
  820. where = < end_date >= fi_price_date.month()> // 过滤掉不必更新的旧记录
  821. ).eval();
  822. v_trailing = ['1y', '2y', '3y', '4y', '5y', '10y', 'ytd', 'incep'];
  823. for(tr in v_trailing) {
  824. col_upside_capture_ret = 'upsidecapture_ret_' + tr;
  825. col_downside_capture_ret = 'downsidecapture_ret_' + tr;
  826. col_upside_capture_ratio = 'upsidecapture_ratio_' + tr;
  827. col_downside_capture_ratio = 'downsidecapture_ratio_' + tr;
  828. t.addColumn([col_upside_capture_ret, col_downside_capture_ret, col_upside_capture_ratio, col_downside_capture_ratio],
  829. [DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
  830. if(!indicators['PBI-'+tr.upper()].isVoid()) {
  831. sqlUpdate(table = t,
  832. updates = [<upside_capture_ret as _$col_upside_capture_ret>, <downside_capture_ret as _$col_downside_capture_ret>,
  833. <upside_capture_ratio as _$col_upside_capture_ratio>, <downside_capture_ratio as _$col_downside_capture_ratio>],
  834. from = <ej(t, indicators['PBI-'+tr.upper()], ['entity_id'].join(v_extra_keys).join(['end_date']))>
  835. ).eval();
  836. }
  837. }
  838. INSERT INTO entity_style_stats SELECT * FROM t;
  839. } else {
  840. }
  841. }
  842. /*
  843. * 按照 XXX_ms_stats 表结构准备数据记录
  844. *
  845. *
  846. */
  847. def generate_entity_ms_stats(entity_info, indicators, isToMySQL, mutable entity_ms_stats, extra_keys=[]) {
  848. t = null;
  849. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  850. else v_extra_keys = extra_keys;
  851. if(indicators['PBI-3Y'].isVoid() || indicators['PBI-3Y'].size() == 0) return;
  852. if(isToMySQL) {
  853. t = sql(select =(sqlCol('entity_id'),
  854. sqlCol(v_extra_keys.join('end_date')),
  855. sqlCol(['ms_ret_a', 'ms_rar_a', 'ms_risk_a'],
  856. , ['ms_return_3y', 'ms_rar_3y', 'ms_risk_3y'])
  857. ),
  858. from = ej(indicators['PBI-3Y'] AS a, entity_info AS fi, ['entity_id'].join(v_extra_keys)),
  859. where = < end_date >= fi_price_date.month()> // 过滤掉不必更新的旧记录
  860. ).eval();
  861. v_trailing = ['5y', '10y'];
  862. for(tr in v_trailing) {
  863. col_ms_ret = 'ms_return_' + tr;
  864. col_ms_rar = 'ms_rar_' + tr;
  865. col_ms_risk = 'ms_risk_' + tr;
  866. t.addColumn([col_ms_ret, col_ms_rar, col_ms_risk],
  867. [DOUBLE, DOUBLE, DOUBLE]);
  868. if(!indicators['PBI-'+tr.upper()].isVoid()) {
  869. sqlUpdate(table = t,
  870. updates = [<ms_ret_a as _$col_ms_ret>, <ms_rar_a as _$col_ms_rar>, <ms_risk_a as _$col_ms_risk>],
  871. from = <ej(t, indicators['PBI-'+tr.upper()], ['entity_id'].join(v_extra_keys).join(['end_date']))>
  872. ).eval();
  873. }
  874. }
  875. INSERT INTO entity_ms_stats SELECT * FROM t;
  876. } else {
  877. }
  878. }
  879. /*
  880. * 按照 XXX_bfi_bm_indicator 表结构准备数据记录
  881. *
  882. * @param entity_info <TABLE>: [COLUMNS] entity_id, end_date, benchmark_id, inception_date, ini_value [,curve_type, strategy]
  883. * @param indicators <DICTIONARY>
  884. *
  885. * TODO: why we need isToMySQL here?
  886. * 其它的指标恐怕也要按这个改,因为私募可能会有近6月没有数据但近2年之类的周期有数据的情况!
  887. */
  888. def generate_entity_bfi_indicator(entity_info, indicators, isToMySQL, mutable entity_bfi_indicator, extra_keys=[]) {
  889. t = null;
  890. if(extra_keys.isNothing() || extra_keys.isVoid() || extra_keys.size() == 0) v_extra_keys = array(STRING);
  891. else v_extra_keys = extra_keys;
  892. v_cols_from = ['upside_capture_ret', 'downside_capture_ret', 'upside_capture_ratio', 'downside_capture_ratio', 'alpha_a', 'winrate', 'beta', 'info_a', 'track_error_a', 'jensen_a'];
  893. v_cols_to = ['upsidecapture_ret', 'downsidecapture_ret', 'upsidecapture_ratio', 'downsidecapture_ratio', 'alpha', 'winrate', 'beta', 'info_ratio', 'tracking_error', 'jensen'];
  894. v_cols_useless = ['track_error', 'info', 'alpha', 'treynor', 'jensen', 'm2', 'm2_a']; // 标准指标中不被当前表覆盖的数据点
  895. v_join_key = ['entity_id', 'benchmark_id', 'end_date'].join(v_extra_keys);
  896. if(isToMySQL) {
  897. t = lj(
  898. lj(
  899. lj(
  900. lj(
  901. lj(
  902. lj(
  903. lj(
  904. lj(
  905. lj(entity_info,
  906. indicators['BFI-6M'] AS t_6m, v_join_key).dropColumns!(v_cols_useless),
  907. indicators['BFI-1Y'] AS t_1y, v_join_key).dropColumns!(v_cols_useless),
  908. indicators['BFI-2Y'] AS t_2y, v_join_key).dropColumns!(v_cols_useless),
  909. indicators['BFI-3Y'] AS t_3y, v_join_key).dropColumns!(v_cols_useless),
  910. indicators['BFI-4Y'] AS t_4y, v_join_key).dropColumns!(v_cols_useless),
  911. indicators['BFI-5Y'] AS t_5y, v_join_key).dropColumns!(v_cols_useless),
  912. indicators['BFI-10Y'] AS t_10y, v_join_key).dropColumns!(v_cols_useless),
  913. indicators['BFI-YTD'] AS t_ytd, v_join_key).dropColumns!(v_cols_useless),
  914. indicators['BFI-INCEP'] AS t_incep, v_join_key).dropColumns!(v_cols_useless);
  915. t.rename!(v_cols_from, v_cols_to + '_6m');
  916. t.rename!('t_1y_' + v_cols_from, v_cols_to + '_1y');
  917. t.rename!('t_2y_' + v_cols_from, v_cols_to + '_2y');
  918. t.rename!('t_3y_' + v_cols_from, v_cols_to + '_3y');
  919. t.rename!('t_4y_' + v_cols_from, v_cols_to + '_4y');
  920. t.rename!('t_5y_' + v_cols_from, v_cols_to + '_5y');
  921. t.rename!('t_10y_' + v_cols_from, v_cols_to + '_10y');
  922. t.rename!('t_ytd_' + v_cols_from, v_cols_to + '_ytd');
  923. t.rename!('t_incep_' + v_cols_from, v_cols_to + '_incep');
  924. if(t.columnNames().find('inception_date') >= 0) t.dropColumns!('inception_date');
  925. if(t.columnNames().find('ini_value') >= 0) t.dropColumns!('ini_value');
  926. t.rename!('benchmark_id', 'factor_id');
  927. entity_bfi_indicator.tableInsert(t.reorderColumns!(entity_bfi_indicator.colNames()));
  928. } else {
  929. }
  930. }
  931. /*
  932. * 按照 XXX_performance_weekly 表结构准备数据记录
  933. *
  934. *
  935. */
  936. def generate_entity_performance_weekly(entity_info, ret_w, isToMySQL, mutable entity_performance_weekly) {
  937. t = null;
  938. if(ret_w.isVoid() || ret_w.size() == 0) return;
  939. if(isToMySQL) {
  940. t = SELECT entity_id, year_week, year_week.left(4)$INT AS end_year, year_week.right(2)$INT AS week_of_year, price_date,
  941. cumulative_nav, ret_1w
  942. FROM ret_w r
  943. INNER JOIN entity_info fi ON r.entity_id = fi.entity_id
  944. WHERE r.price_date >= fi.price_date; // 过滤掉不必更新的旧记录
  945. INSERT INTO entity_performance_weekly SELECT * FROM t;
  946. } else {
  947. }
  948. }
  949. /*
  950. * 按照 XXX_latest_performance 表结构准备数据记录
  951. *
  952. *
  953. */
  954. def generate_entity_latest_performance(entity_info, perf_latest, isToMySQL, mutable entity_latest_performance) {
  955. t = null;
  956. if(perf_latest.isVoid() || perf_latest.size() == 0) return;
  957. if(isToMySQL) {
  958. t = SELECT r.*
  959. FROM perf_latest r
  960. INNER JOIN entity_info fi ON r.entity_id = fi.entity_id
  961. WHERE r.price_date >= fi.price_date; // 过滤掉不必更新的旧记录
  962. INSERT INTO entity_latest_performance SELECT * FROM t;
  963. } else {
  964. }
  965. }