|
@@ -1,7 +1,8 @@
|
|
|
module fundit::rbsaCalculator
|
|
|
|
|
|
-use fundit::performanceDataPuller
|
|
|
-use fundit::operationDataPuller
|
|
|
+use fundit::sqlUtilities;
|
|
|
+use fundit::performanceDataPuller;
|
|
|
+use fundit::operationDataPuller;
|
|
|
|
|
|
/*
|
|
|
* RBSA 计算
|
|
@@ -78,7 +79,7 @@ def cal_rolling_rbsa(ret, index_ret, is_long, window, step) {
|
|
|
i = (t.size() - window) % step
|
|
|
|
|
|
// 运行rbsa计算次数
|
|
|
- cnt = (t.size() - i - window) / step;
|
|
|
+ cnt = (t.size() - i - window) / step + 1;
|
|
|
|
|
|
tb = table(max(cnt,1):0, ["effective_date", "price_date", "index_id", "weights", "alpha", "r2", "adj_r2"], [STRING, DATE, STRING, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
|
|
|
|
|
@@ -125,7 +126,7 @@ def cal_rolling_rbsa(ret, index_ret, is_long, window, step) {
|
|
|
|
|
|
cnt -= 1
|
|
|
|
|
|
- } while( cnt >= 0)
|
|
|
+ } while( cnt > 0)
|
|
|
|
|
|
}
|
|
|
|
|
@@ -150,11 +151,11 @@ def cal_rolling_rbsa(ret, index_ret, is_long, window, step) {
|
|
|
*
|
|
|
* TODO: 数字与界面和数据库都对不上
|
|
|
*
|
|
|
- * Example: cal_entity_RBSA('MF', 'MF00003PW1', ['IN00000008', 'IN00000077', 'IN0000007G', 'IN0000009M'], 'w', 1900.01.01, 2024.11.15, true, 24, 24);
|
|
|
- * cal_entity_RBSA('PF', 166002, ['FA00000VML', 'FA00000VMM', 'FA00000VMN', 'FA00000VMO', 'IN0000007G'], 'w', 2020.01.01, 2024.11.08, true, 24, 24);
|
|
|
- * cal_entity_RBSA('MF', 'MF000200KQ', ['IN00000008', 'IN00000077', 'IN0000007G', 'IN0000009M'], 'w', 1900.01.01, 2024.11.16, true, 24, 24);
|
|
|
+ * Example: cal_single_entity_RBSA('MF', 'MF00003PW1', ['IN00000008', 'IN00000077', 'IN0000007G', 'IN0000009M'], 'w', 1900.01.01, 2024.11.15, true, 24, 24);
|
|
|
+ * cal_single_entity_RBSA('PF', 166002, ['FA00000VML', 'FA00000VMM', 'FA00000VMN', 'FA00000VMO', 'IN0000007G'], 'w', 2020.01.01, 2024.11.08, true, 24, 24);
|
|
|
+ * cal_single_entity_RBSA('MF', 'MF000200KQ', ['IN00000008', 'IN00000077', 'IN0000007G', 'IN0000009M'], 'w', 1900.01.01, 2024.11.16, true, 24, 24);
|
|
|
*/
|
|
|
-def cal_entity_RBSA(entity_type, entity_id, index_ids, freq='w', start_day=1900.01.01, end_day=2099.12.31, is_long=true, window=24, step=24) {
|
|
|
+def cal_single_entity_RBSA(entity_type, entity_id, index_ids, freq='w', start_day=1900.01.01, end_day=2099.12.31, is_long=true, window=24, step=24) {
|
|
|
// entity_type='MF'
|
|
|
// entity_id= 'MF00003PW1'
|
|
|
// index_ids=['IN00000008', 'IN00000077', 'IN0000007G', 'IN0000009M']
|
|
@@ -173,7 +174,7 @@ def cal_entity_RBSA(entity_type, entity_id, index_ids, freq='w', start_day=1900.
|
|
|
|
|
|
entity_ret = get_entity_return(entity_type, v_entity, freq, start_day, end_day, true);
|
|
|
|
|
|
- // 数据长度不够,按照顺序依次分别用母基金(4), 指数(3)的数据来代替
|
|
|
+ // 数据长度不够,按照顺序依次分别用母基金(4), 指数(3)的数据来代替 (level=2, 基金经理的数据在Java里好像没用?)
|
|
|
level = 1
|
|
|
alternative_id = NULL;
|
|
|
if(entity_ret.isVoid() || entity_ret.size() < window) {
|
|
@@ -218,3 +219,98 @@ def cal_entity_RBSA(entity_type, entity_id, index_ids, freq='w', start_day=1900.
|
|
|
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/*
|
|
|
+ * 计算单基金或组合的RBSA
|
|
|
+ *
|
|
|
+ * @param entity_type <STRING>: 目标基金/组合的类型
|
|
|
+ * @param entity_id <STRING>: 目标基金/组合的ID
|
|
|
+ * @param index_ids <VECTOR>: 基准指数IDs
|
|
|
+ * @param freq <STRING>: m, w, d
|
|
|
+ * @param start_day <DATE>
|
|
|
+ * @param end_day <DATE>
|
|
|
+ * @param is_long <BOOL>: 是否只考虑纯多头
|
|
|
+ * @param window <INT>: 窗口(必须多于基准指数个数)
|
|
|
+ * @param step <INT>: 步长
|
|
|
+ *
|
|
|
+ * @return <TABLE>: entity_id, effective_date, price_date, index_id, weights, alternative_id, level, alpha, r2, adj_r2
|
|
|
+ *
|
|
|
+ * TODO: 数字与界面和数据库都对不上
|
|
|
+ *
|
|
|
+ */
|
|
|
+def cal_entity_RBSA(entity_type, entity_ret, index_ret, freq='w', start_day=1900.01.01, end_day=2099.12.31, is_long=true, window=24, step=24) {
|
|
|
+// entity_type='MF'
|
|
|
+// freq='w'
|
|
|
+// start_day=2023.12.28
|
|
|
+// end_day=today()
|
|
|
+// is_long=true
|
|
|
+// window=48
|
|
|
+// step=13
|
|
|
+
|
|
|
+ tb_result = table(100:0, ["entity_id", "effective_date", "index_id", "weights", "alpha", "r2", "adj_r2"],
|
|
|
+ [iif(entity_type=='PF', INT, STRING), STRING, STRING, DOUBLE, DOUBLE, DOUBLE, DOUBLE]);
|
|
|
+
|
|
|
+ if(index_ret.isVoid() || index_ret.size() == 0) return tb_result;
|
|
|
+
|
|
|
+ tb_entity_ret = entity_ret;
|
|
|
+
|
|
|
+ // 数据长度不够,按照顺序依次分别用母基金(4), 指数(3)的数据来代替 (level=2, 基金经理的数据在Java里好像没用?)
|
|
|
+ level = 1
|
|
|
+ alternative_id = NULL;
|
|
|
+ if(tb_entity_ret.isVoid() || tb_entity_ret.size() < window) {
|
|
|
+ if(entity_type IN ['MF', 'HF']) {
|
|
|
+
|
|
|
+ fund_info = get_fund_info(tb_entity_ret.entity_id);
|
|
|
+ p_fund_id = fund_info.p_fund_id;
|
|
|
+ primary_benchmark_id = fund_info.benchmark_id;
|
|
|
+ if(p_fund_id != NULL) {
|
|
|
+ tb_entity_ret = get_entity_return(entity_type, p_fund_id , freq, start_day, end_day, true);
|
|
|
+ alternative_id = p_fund_id[0];
|
|
|
+ level = 4;
|
|
|
+ } else if(primary_benchmark_id != NULL) {
|
|
|
+ tb_entity_ret = get_entity_return(entity_type, primary_benchmark_id, freq, start_day, end_day, true);
|
|
|
+ alternative_id = primary_benchmark_id[0];
|
|
|
+ level = 3;
|
|
|
+ } else {
|
|
|
+ return tb_result;
|
|
|
+ }
|
|
|
+ } else if(entity_type == 'PF'){
|
|
|
+
|
|
|
+ portfolio_info = get_portfolio_info(tb_entity_ret.entity_id);
|
|
|
+ primary_benchmark_id = portfolio_info.benchmark_id;
|
|
|
+ if(primary_benchmark_id != NULL) {
|
|
|
+ tb_entity_ret = get_entity_return(entity_type, primary_benchmark_id, freq, start_day, end_day, true);
|
|
|
+ alternative_id = primary_benchmark_id[0];
|
|
|
+ level = 3;
|
|
|
+ } else
|
|
|
+ return tb_result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tb_entity_ret.addColumn('effective_date', STRING);
|
|
|
+ tb_index_ret = index_ret;
|
|
|
+ tb_index_ret.addColumn('effective_date', STRING);
|
|
|
+
|
|
|
+ if(freq == 'm') {
|
|
|
+
|
|
|
+ UPDATE tb_entity_ret SET effective_date = price_date.temporalFormat('yyyy-MM');
|
|
|
+ UPDATE tb_index_ret SET effective_date = price_date.temporalFormat('yyyy-MM');
|
|
|
+
|
|
|
+ } else if(freq == 'w') {
|
|
|
+
|
|
|
+ UPDATE tb_entity_ret SET effective_date = get_year_week(price_date);
|
|
|
+ UPDATE tb_index_ret SET effective_date = get_year_week(price_date);
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ UPDATE tb_entity_ret SET effective_date = price_date$STRING;
|
|
|
+ UPDATE tb_index_ret SET effective_date = price_date$STRING;
|
|
|
+ }
|
|
|
+
|
|
|
+ tb_result = SELECT entity_ret.entity_id[0] AS entity_id, effective_date, price_date, index_id, weights, alternative_id, level, alpha, r2, adj_r2
|
|
|
+ FROM cal_rolling_rbsa(tb_entity_ret, tb_index_ret, is_long, window, step);
|
|
|
+
|
|
|
+ return tb_result;
|
|
|
+
|
|
|
+}
|
|
|
+
|