Commit c70a4add authored by 李宗熹's avatar 李宗熹

添加雷达图数据

parent 307edefa
...@@ -181,7 +181,33 @@ def get_risk_level(substrategy): ...@@ -181,7 +181,33 @@ def get_risk_level(substrategy):
return substrategy2risk[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() fund_rank = get_fund_rank()
# 获取探普产品池
tamp_fund = get_fund_rank()
class PortfolioDiagnose(object): class PortfolioDiagnose(object):
...@@ -216,7 +242,7 @@ class PortfolioDiagnose(object): ...@@ -216,7 +242,7 @@ class PortfolioDiagnose(object):
self.replace_pair = dict() # 由于数据不足半年而被替换为相同基金经理和策略的原基金和替换基金的映射 self.replace_pair = dict() # 由于数据不足半年而被替换为相同基金经理和策略的原基金和替换基金的映射
self.no_data_fund = [] # 未在数据库中找到基金净值或者基金经理记录的基金 self.no_data_fund = [] # 未在数据库中找到基金净值或者基金经理记录的基金
self.abandon_fund_score = [] # 打分不满足要求的基金 self.abandon_fund_score = [] # 打分不满足要求的基金
self.abandon_fund_corr = [] self.abandon_fund_corr = [] # 相关性过高
self.proposal_fund = [] # 建议的基金 self.proposal_fund = [] # 建议的基金
self.old_correlation = None self.old_correlation = None
self.new_correlation = None self.new_correlation = None
...@@ -334,8 +360,6 @@ class PortfolioDiagnose(object): ...@@ -334,8 +360,6 @@ class PortfolioDiagnose(object):
# 待添加策略为所有策略-组合已包含策略 # 待添加策略为所有策略-组合已包含策略
add_strategy = all_strategy - included_strategy add_strategy = all_strategy - included_strategy
# 获取探普产品池
tamp_fund = get_fund_rank()
# 遍历产品池,推荐得分>80且与组合内其他基金相关度低于0.8的属于待添加策略的基金 # 遍历产品池,推荐得分>80且与组合内其他基金相关度低于0.8的属于待添加策略的基金
for proposal in tamp_fund['fund_id']: for proposal in tamp_fund['fund_id']:
...@@ -387,11 +411,11 @@ class PortfolioDiagnose(object): ...@@ -387,11 +411,11 @@ class PortfolioDiagnose(object):
mu = expected_returns.mean_historical_return(propose_portfolio) mu = expected_returns.mean_historical_return(propose_portfolio)
S = risk_models.sample_cov(propose_portfolio) S = risk_models.sample_cov(propose_portfolio)
# if self.client_type == 1: # if self.client_type == 1:
# proposal_risk = [[x, get_risk_level(search_rank(fund_rank, x, metric='substrategy'))] for x in # proposal_risk = [[x, get_risk_level(search_rank(fund_rank, x, metric='substrategy'))] for x in
# self.proposal_fund] # self.proposal_fund]
# self.proposal_fund = list(filter(lambda x: x[1] != 3, proposal_risk)) # 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())) | \ # 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()))) # (set(self.proposal_fund) | set(self.replace_pair.values())))
propose_risk_mapper = dict() propose_risk_mapper = dict()
for fund in propose_portfolio.columns: for fund in propose_portfolio.columns:
propose_risk_mapper[fund] = str(get_risk_level(search_rank(fund_rank, fund, metric='substrategy'))) propose_risk_mapper[fund] = str(get_risk_level(search_rank(fund_rank, fund, metric='substrategy')))
...@@ -405,11 +429,10 @@ class PortfolioDiagnose(object): ...@@ -405,11 +429,10 @@ class PortfolioDiagnose(object):
clean_weights = ef.clean_weights() clean_weights = ef.clean_weights()
# ef.portfolio_performance(verbose=True) # ef.portfolio_performance(verbose=True)
self.new_weights = np.array(list(clean_weights.values())) self.new_weights = np.array(list(clean_weights.values()))
# S = np.asmatrix(S) # S = np.asmatrix(S)
# w_origin = np.asarray([i for i in w_origin.values()]) # w_origin = np.asarray([i for i in w_origin.values()])
# risk_target = np.asarray([1 / len(w_origin)] * len(w_origin)) # risk_target = np.asarray([1 / len(w_origin)] * len(w_origin))
# self.proposal_weights = calcu_w(w_origin, S, risk_target) # self.proposal_weights = calcu_w(w_origin, S, risk_target)
# elif self.client_type == 2: # elif self.client_type == 2:
# elif self.client_type == 3: # elif self.client_type == 3:
...@@ -579,10 +602,26 @@ class PortfolioDiagnose(object): ...@@ -579,10 +602,26 @@ class PortfolioDiagnose(object):
result.append(self.single_evaluation(fund)) result.append(self.single_evaluation(fund))
return result 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)
portfolio_diagnose.optimize()
if __name__ == '__main__': if __name__ == '__main__':
portfolio = ['HF00002JJ2', 'HF00005DBQ', 'HF0000681Q', 'HF00006693', 'HF00006AZF', 'HF00006BGS'] print(portfolio_diagnose.single_fund_radar())
portfolio_diagnose = PortfolioDiagnose(client_type=1, portfolio=portfolio, invest_amount=10000000) print(portfolio_diagnose.propose_fund_radar())
portfolio_diagnose.optimize()
print(portfolio_diagnose.old_correlation)
# print(portfolio_diagnose.propose_fund_evaluation()) # print(portfolio_diagnose.propose_fund_evaluation())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment