123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- module fundit::rbsaCalculator
- use fundit::sqlUtilities;
- use fundit::performanceDataPuller;
- use fundit::operationDataPuller;
- defg cal_rbsa(ret, index_ret, is_long) {
-
- m = ret.size()
-
- n = index_ret.cols()
-
- P0 = matrix(float, n, m+n)
- P1 = concatMatrix([matrix(float, m, n), eye(m)])
- P = concatMatrix([P0, P1], false)
- q = array(float, m+n, (m+n)*10, 0)
-
- A0 = concatMatrix( [matrix(index_ret), -eye(m)])
- A1 = concatMatrix( [matrix(take(1, n)).transpose(), matrix(float, 1, m)])
- A2 = concatMatrix( [eye(n), matrix(float, n, m)])
- A = concatMatrix( [A0, A1, A2], false)
-
-
-
- lb =(ret join 1) join array(float, n, n*10, iif(is_long == true, 0, -2))
-
- ub=(ret join 1) join array(float, n, n*10, iif(is_long == true, 1, 2))
-
- res = osqp( q, P, A, lb, ub)
-
- return res
- }
- def cal_rolling_rbsa(ret, index_ret, is_long, window, step) {
-
- v_start_date = EXEC effective_date.max() AS start_date
- FROM (SELECT entity_id, effective_date.min() AS effective_date FROM index_ret WHERE ret IS NOT NULL GROUP BY entity_id);
- m_index_ret = SELECT ret FROM index_ret WHERE effective_date >= v_start_date PIVOT BY effective_date, entity_id;
-
- t = SELECT * FROM ej(ret, m_index_ret, 'effective_date') ORDER BY ret.effective_date;
- t.nullFill!(0)
-
-
-
- n = m_index_ret.cols() - 1
-
- i = (t.size() - 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]);
- if(t.size() >= max(window, step) && cnt > 0) {
-
- do {
- alpha = 0;
- r2 = 0;
- adj_r2 = 0;
- v_ret = t.ret[i:(i+window)];
-
- t_index_ret = t.slice( i:(i+window), ret.cols(): );
-
-
- res = cal_rbsa(v_ret, t_index_ret, is_long);
- if(res[0] == 'solved') {
- m_predict_ret = t_index_ret.matrix() ** res[1][0:n];
-
- alpha = v_ret.mean() - m_predict_ret.mean();
- SSR = sum2(m_predict_ret - v_ret.mean());
- SST = sum2(v_ret - v_ret.mean());
- if(SST == 0) {
-
- SSE = sum2(v_ret - m_predict_ret);
- SST = SSE + SSR;
- }
-
- if(SST != 0) {
- r2 = SSR/SST;
- adj_r2 = 1 - (1 - r2) * (window - 1) / (window - n - 1);
- }
-
- for(j in 1..n) {
- tb.tableInsert(t.effective_date[i+window-1], t.price_date[i+window-1], m_index_ret.colNames()[j], res[1][j-1].round(4), alpha, r2, adj_r2);
- }
- }
-
- i = i + step
-
- cnt -= 1
-
- } while( cnt > 0)
-
- }
- return tb
- }
- 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) {
- 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]);
- v_entity = array(iif(entity_type=='PF', INT, STRING));
- v_entity.append!(entity_id);
-
- entity_ret = get_entity_return(entity_type, v_entity, freq, start_day, end_day, true);
-
- level = 1
- alternative_id = NULL;
- if(entity_ret.isVoid() || entity_ret.size() < window) {
- if(entity_type IN ['MF', 'HF']) {
- fund_info = get_fund_info(v_entity);
- p_fund_id = fund_info.p_fund_id[0];
- primary_benchmark_id = fund_info.benchmark_id[0];
- if(p_fund_id != NULL) {
- entity_ret = get_entity_return(entity_type, v_entity.replace(entity_id, p_fund_id) , freq, start_day, end_day, true);
- alternative_id = p_fund_id;
- level = 4;
- } else if(primary_benchmark_id != NULL) {
- entity_ret = get_entity_return(entity_type, v_entity.replace(entity_id, primary_benchmark_id) , freq, start_day, end_day, true);
- alternative_id = primary_benchmark_id;
- level = 3;
- } else {
- return tb_result;
- }
- } else if(entity_type == 'PF'){
- portfolio_info = get_portfolio_info(v_entity);
- primary_benchmark_id = portfolio_info.benchmark_id[0];
- if(primary_benchmark_id != NULL) {
- entity_ret = get_entity_return(entity_type, v_entity.replace(entity_id, primary_benchmark_id) , freq, start_day, end_day, true);
- alternative_id = primary_benchmark_id;
- level = 3;
- } else
- return tb_result;
- }
- }
-
- index_ret = get_entity_return(NULL, index_ids, freq, start_day, end_day, true);
- if(index_ret.isVoid() || index_ret.size() == 0) return tb_result;
- tb_result = SELECT entity_id, effective_date, price_date, index_id, weights, alternative_id, level, alpha, r2, adj_r2
- FROM cal_rolling_rbsa(entity_ret, index_ret, is_long, window, step);
- return tb_result;
-
- }
- 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) {
- 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;
-
- level = 1
- alternative_id = NULL;
- if(tb_entity_ret.isVoid() || tb_entity_ret.size() < window) {
-
- 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;
-
- }
|