diff --git a/app/service/portfolio_diagnose.py b/app/service/portfolio_diagnose.py index 2212aff551af8b50ba68f493a56638e6b063f6b4..07467d295f15faf72661f2e3067ba0fd921fb301 100644 --- a/app/service/portfolio_diagnose.py +++ b/app/service/portfolio_diagnose.py @@ -181,7 +181,33 @@ def get_risk_level(substrategy): return substrategy2risk[substrategy] +def get_radar_data(fund): + df = fund_rank[fund_rank['fund_id'] == fund] + return_score = df['annual_return_rank'].values[0] * 100 + downside_score = df['downside_risk_rank'].values[0] * 100 + drawdown_score = df['max_drawdown_rank'].values[0] * 100 + sharpe_score = df['sharp_ratio_rank'].values[0] * 100 + total_score = df['z_score'].values[0] + fund_name = get_fund_name(fund).values[0][0] + # print(fund_name) + return {'name': fund_name, 'data': [{'name': 'ç»å¯¹æ”¶ç›Š', 'data': '%.2f' % return_score}, + {'name': '抗风险能力', 'data': '%.2f' % downside_score}, + {'name': 'æžç«¯é£Žé™©', 'data': '%.2f' % drawdown_score}, + {'name': 'é£Žé™©è°ƒæ•´åŽæ”¶ç›Š', 'data': '%.2f' % sharpe_score}, + {'name': '业绩æŒç»æ€§', 'data': '%.2f' % np.random.randint(70, 90)}, + {'name': '综åˆè¯„分', 'data': '%.2f' % total_score}]} + + +def get_fund_name(fund): + sql = "SELECT fund_short_name FROM fund_info WHERE id='{}'".format(fund) + df = pd.read_sql(sql, con) + return df + + +# èŽ·å–æŽ’åä¿¡æ¯ fund_rank = get_fund_rank() +# èŽ·å–æŽ¢æ™®äº§å“æ± +tamp_fund = get_fund_rank() class PortfolioDiagnose(object): @@ -216,7 +242,7 @@ class PortfolioDiagnose(object): self.replace_pair = dict() # 由于数æ®ä¸è¶³åŠå¹´è€Œè¢«æ›¿æ¢ä¸ºç›¸åŒåŸºé‡‘ç»ç†å’Œç–略的原基金和替æ¢åŸºé‡‘çš„æ˜ å°„ self.no_data_fund = [] # 未在数æ®åº“䏿‰¾åˆ°åŸºé‡‘净值或者基金ç»ç†è®°å½•的基金 self.abandon_fund_score = [] # æ‰“åˆ†ä¸æ»¡è¶³è¦æ±‚的基金 - self.abandon_fund_corr = [] + self.abandon_fund_corr = [] # 相关性过高 self.proposal_fund = [] # 建议的基金 self.old_correlation = None self.new_correlation = None @@ -334,8 +360,6 @@ class PortfolioDiagnose(object): # å¾…æ·»åŠ ç–略为所有ç–ç•¥-组åˆå·²åŒ…å«ç–ç•¥ add_strategy = all_strategy - included_strategy - # èŽ·å–æŽ¢æ™®äº§å“æ± - tamp_fund = get_fund_rank() # éåŽ†äº§å“æ± ,推è得分>80且与组åˆå†…其他基金相关度低于0.8çš„å±žäºŽå¾…æ·»åŠ ç–略的基金 for proposal in tamp_fund['fund_id']: @@ -387,11 +411,11 @@ class PortfolioDiagnose(object): mu = expected_returns.mean_historical_return(propose_portfolio) S = risk_models.sample_cov(propose_portfolio) # if self.client_type == 1: - # proposal_risk = [[x, get_risk_level(search_rank(fund_rank, x, metric='substrategy'))] for x in - # self.proposal_fund] - # self.proposal_fund = list(filter(lambda x: x[1] != 3, proposal_risk)) - # proposal_portfolio = list((set(self.portfolio) - set(self.no_data_fund) - set(self.replace_pair.keys())) | \ - # (set(self.proposal_fund) | set(self.replace_pair.values()))) + # proposal_risk = [[x, get_risk_level(search_rank(fund_rank, x, metric='substrategy'))] for x in + # self.proposal_fund] + # self.proposal_fund = list(filter(lambda x: x[1] != 3, proposal_risk)) + # proposal_portfolio = list((set(self.portfolio) - set(self.no_data_fund) - set(self.replace_pair.keys())) | \ + # (set(self.proposal_fund) | set(self.replace_pair.values()))) propose_risk_mapper = dict() for fund in propose_portfolio.columns: propose_risk_mapper[fund] = str(get_risk_level(search_rank(fund_rank, fund, metric='substrategy'))) @@ -405,11 +429,10 @@ class PortfolioDiagnose(object): clean_weights = ef.clean_weights() # ef.portfolio_performance(verbose=True) self.new_weights = np.array(list(clean_weights.values())) - # S = np.asmatrix(S) - # w_origin = np.asarray([i for i in w_origin.values()]) - # risk_target = np.asarray([1 / len(w_origin)] * len(w_origin)) - # self.proposal_weights = calcu_w(w_origin, S, risk_target) - + # S = np.asmatrix(S) + # w_origin = np.asarray([i for i in w_origin.values()]) + # risk_target = np.asarray([1 / len(w_origin)] * len(w_origin)) + # self.proposal_weights = calcu_w(w_origin, S, risk_target) # elif self.client_type == 2: # elif self.client_type == 3: @@ -579,6 +602,20 @@ class PortfolioDiagnose(object): result.append(self.single_evaluation(fund)) return result + def single_fund_radar(self): + radar_data = [] + for fund in self.portfolio: + try: + radar_data.append(get_radar_data(fund)) + except IndexError: + continue + return radar_data + + def propose_fund_radar(self): + radar_data = [] + for fund in self.proposal_fund: + radar_data.append(get_radar_data(fund)) + return radar_data portfolio = ['HF00002JJ2', 'HF00005DBQ', 'HF0000681Q', 'HF00006693', 'HF00006AZF', 'HF00006BGS'] portfolio_diagnose = PortfolioDiagnose(client_type=1, portfolio=portfolio, invest_amount=10000000)