import time from jinja2 import PackageLoader, Environment from app.service.portfolio_diagnose import portfolio_diagnose from app.service.result_service_v2 import UserCustomerResultAdaptor import numpy as np # 准备数据 from app.utils.draw import draw_month_return_chart, draw_contribution_chart, draw_combination_chart, \ draw_old_combination_chart from app.utils.radar_chart import gen_radar_chart class DataIntegrate: def __init__(self, ifa_id='USER_INFO15914346866762', customer_id='202009281545001', customer_name='王晶'): self.user_customer = UserCustomerResultAdaptor(ifa_id, customer_id) self.customer_name = customer_name self.df = self.user_customer.calculate_total_data() self.d = self.user_customer.calculate_group_result_data() # 组合数据 self.group_result = self.d["default"] # 几月综述部分 self.get_summarize() # 月度回报 self.get_month_return() # 旧持仓组合点评 self.comments_on_position_portfolio() # 贡献分解 self.contribution_deco() # 个基点评 self.single_fund_comment() # 旧相关性 self.get_old_correlation() # 新相关性 self.get_new_correlation() # 新增基金 self.propose_fund() # 目标与业绩 self.objectives_performance(self.group_result) # 旧收益比较 self.get_old_compare_pic() # 新收益比较 self.get_transfer_suggestions() # 渲染模版 self.render_data() def get_summarize(self): """几月综述部分.""" self.total_cost = self.df["total_cost"]/10000 self.now_yield = round((self.df['cumulative_return']-1)*100,2) self.index_yield = round((self.df["index_result"]["return_ratio"]-1)*100, 2) self.now_withdrawal = round(self.df["max_drawdown"][0]*100,2) self.index_withdrawal = round(self.df["index_result"]["max_drawdown"][0]*100, 2) def get_month_return(self): """月度回报.""" xlabels, product_list, cumulative = self.user_customer.get_month_return_chart() self.monthly_return_performance_pic = draw_month_return_chart(xlabels, product_list, cumulative) def comments_on_position_portfolio(self): """旧持仓组合点评.""" self.old_evaluation = portfolio_diagnose.old_evaluation('default', self.d, self.user_customer) def contribution_deco(self): """贡献分解.""" g_data = self.group_result["contribution_decomposition"] self.contribution_decomposition = draw_contribution_chart(g_data['xlabels'], g_data['product_list'], g_data['cumulative']) def single_fund_comment(self): """个基点评.""" self.single_fund_data_list = [] portfolio_evaluation = portfolio_diagnose.old_portfolio_evaluation() radar_chart_data = portfolio_diagnose.single_fund_radar() print('***************************') print(portfolio_evaluation) for i in range(len(portfolio_evaluation)): if portfolio_evaluation[i]['status'] == '保留': portfolio_evaluation[i]['status'] = '
保留
' elif portfolio_evaluation[i]['status'] == '增仓': portfolio_evaluation[i]['status'] = '
增仓
' elif portfolio_evaluation[i]['status'] == '换仓': portfolio_evaluation[i]['status'] = '
换仓
' elif portfolio_evaluation[i]['status'] == '减仓': portfolio_evaluation[i]['status'] = '
减仓
' self.single_fund_data_list.append({ 'fund_name': portfolio_evaluation[i]['name'], 'status': portfolio_evaluation[i]['status'], 'evaluation': portfolio_evaluation[i]['data'], 'radar_chart_path': gen_radar_chart(radar_chart_data[i]) }) def get_old_compare_pic(self): """旧收益比较""" self.suggestions_result, self.suggestions_result_asset, self.return_compare_data,\ self.indicator_compare, self.new_group_evaluation = portfolio_diagnose.new_evaluation("default", self.d, self.user_customer) self.old_return_compare_pic = draw_old_combination_chart(self.return_compare_data["xlabels"], self.return_compare_data["origin_combination"], self.return_compare_data["index"]) def get_transfer_suggestions(self): """新收益比较,调仓建议""" self.return_compare_pic = draw_combination_chart(self.return_compare_data["xlabels"], self.return_compare_data["new_combination"], self.return_compare_data["origin_combination"], self.return_compare_data["index"]) def get_old_correlation(self): """旧相关性分析.""" old_correlation = portfolio_diagnose.old_correlation old_correlation_columns = old_correlation.columns.tolist() old_correlation_values = old_correlation.values.tolist() self.old_correlation = list(zip(range(1, len(old_correlation_columns)+1), old_correlation_columns, old_correlation_values)) def get_new_correlation(self): """新相关性分析.""" new_correlation = portfolio_diagnose.new_correlation new_correlation_columns = new_correlation.columns.tolist() new_correlation_values = new_correlation.values.tolist() self.new_correlation = list(zip(range(1, len(new_correlation_columns)+1), new_correlation_columns, new_correlation_values)) def propose_fund(self): """新增基金""" # 优化组合建议1 -- 新增基金 self.propose_fund_data_list = [] propose_fund_evaluation = portfolio_diagnose.propose_fund_evaluation() propose_radar_chart_data = portfolio_diagnose.propose_fund_radar() for i in range(len(propose_fund_evaluation)): self.propose_fund_data_list.append({ 'fund_name': propose_fund_evaluation[i]['name'], 'status': '增仓', 'evaluation': propose_fund_evaluation[i]['data'], 'radar_chart_path': gen_radar_chart(propose_radar_chart_data[i]) }) def objectives_performance(self, group_result): """目标与业绩""" self.now_month_income = int(group_result["cur_month_profit"]) # 本月收益 self.now_year_income = int(group_result["cur_year_profit"]) # 今年累计收益 self.totoal_rate_of_return = round((group_result['cumulative_return']-1)*100, 2) # 成立以来累计收益率 self.month_rise = round(group_result["cur_month_profit_ratio"]*100, 2) # 本月涨幅s self.year_totoal_rate_of_return = round(group_result["cur_year_profit_ratio"]*100, 2) # 今年累计收益率 self.annualised_return = round(group_result["return_ratio_year"]*100, 2) # 年化收益率 self.volatility = round(group_result["volatility"]*100, 2) self.max_withdrawal = round(group_result["max_drawdown"][0]*100, 2) self.sharpe_ratio = round(group_result["sharpe"], 2) self.cost_of_investment = int(group_result["total_cost"]) # 投资成本 self.final_balance = int(group_result["total_cost"] + group_result["cumulative_profit"]) # 期末资产 self.total_profit = int(group_result["cumulative_profit"]) # 累计盈利 self.index_section_return = round((group_result["index_result"]["return_ratio"]-1)*100, 2) self.index_annualised_return = round(group_result["index_result"]["return_ratio_year"]*100, 2) # 年化收益率 self.index_volatility = round(group_result["index_result"]["volatility"]*100, 2) self.index_max_withdrawal = round(group_result["index_result"]["max_drawdown"][0]*100, 2) self.index_sharpe_ratio = round(group_result["index_result"]["sharpe"], 2) self.group_nav_info = group_result["group_nav_info"] self.group_hoding_info = group_result["group_hoding_info"] def render_data(self): # 全部数据 data = {'customer_name': self.customer_name, 'customer_gender': '女', 'year_month': '2020年10月', 'ifa_company': '飞度工作室', 'title': '10月综述', 'brand_name': '飞度工作室', 'customer_old': 42, 'customer_level': '平衡型', 'position_years': '5年', 'planned_allocation_amount': 2000.00, 'now_allocation_amount': self.total_cost, 'now_yield': self.now_yield, 'index_yield': self.index_yield, 'expected_yield': 20, 'now_withdrawal': self.now_withdrawal, 'index_withdrawal': self.index_withdrawal, 'expected_withdrawal': 20, 'now_year_income': self.now_year_income, 'now_month_income': self.now_month_income, 'totoal_rate_of_return': self.totoal_rate_of_return, 'month_rise': self.month_rise, 'year_totoal_rate_of_return': self.year_totoal_rate_of_return, 'annualised_return': self.annualised_return, 'cost_of_investment': self.cost_of_investment, 'final_balance': self.final_balance, 'total_profit': self.total_profit, 'latest_worth_day': '2020-11-05', 'index_comparison': {'section_return': self.totoal_rate_of_return, 'annualized_returns': self.annualised_return, 'volatility': self.volatility, 'max_withdrawal': self.max_withdrawal, 'sharpe_ratio': self.sharpe_ratio}, 'index_comparison_500': {'section_return': self.index_section_return, 'annualized_returns': self.index_annualised_return, 'volatility': self.index_volatility, 'max_withdrawal': self.index_max_withdrawal, 'sharpe_ratio': self.index_sharpe_ratio}, 'monthly_return_performance_pic': self.monthly_return_performance_pic, 'group_nav_info': self.group_nav_info, 'group_hoding_info': self.group_hoding_info, 'old_evaluation': self.old_evaluation, 'contribution_decomposition': self.contribution_decomposition, 'single_fund_data_list': self.single_fund_data_list, 'old_correlation': self.old_correlation, 'new_correlation': self.new_correlation, 'propose_fund_data_list': self.propose_fund_data_list, 'suggestions_result': self.suggestions_result, 'suggestions_result_asset': self.suggestions_result_asset, 'old_return_compare_pic': self.old_return_compare_pic, 'return_compare_pic': self.return_compare_pic, 'indicator_compare': self.indicator_compare, 'new_group_evaluation': self.new_group_evaluation } # 开始渲染html模板 env = Environment(loader=PackageLoader('app', 'templates')) # 创建一个包加载器对象 # template = env.get_template('monthReport.html') # 获取一个模板文件 template = env.get_template('/v2/monthReportV2.html') # 获取一个模板文件 monthReport_html = template.render(data) # 渲染 # 保存 monthReport_html # save_file = "app/html/monthReport.html" # with open(save_file, 'w', encoding="utf-8") as f: # f.write(monthReport_html) save_file = "app/html/v2/monthReportV2.html" with open(save_file, 'w', encoding="utf-8") as f: f.write(monthReport_html) if __name__ == '__main__': start = time.time() DataIntegrate() print('耗时{}秒'.format(round(time.time()-start, 2)))