jinjia2html.py 11.7 KB
Newer Older
1 2 3 4 5 6 7 8 9
import time

from jinja2 import PackageLoader, Environment

from app.service.portfolio_diagnose import portfolio_diagnose
from app.service.result_service import UserCustomerResultAdaptor
import numpy as np

# 准备数据
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
10 11
from app.utils.draw import draw_month_return_chart, draw_contribution_chart, draw_combination_chart, \
    draw_old_combination_chart
12 13 14 15
from app.utils.radar_chart import gen_radar_chart


class DataIntegrate:
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
16
    def __init__(self, ifa_id='USER_INFO15914346866762', customer_id='202009281545001', customer_name='王晶'):
17
        self.user_customer = UserCustomerResultAdaptor(ifa_id, customer_id)
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
18
        self.customer_name = customer_name
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
        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()
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
35 36
        # 新相关性
        self.get_new_correlation()
37 38 39 40
        # 新增基金
        self.propose_fund()
        # 目标与业绩
        self.objectives_performance(self.group_result)
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
41 42 43
        # 旧收益比较
        self.get_old_compare_pic()
        # 新收益比较
赵杰's avatar
赵杰 committed
44
        self.get_transfer_suggestions()
45 46 47
        # 渲染模版
        self.render_data()

赵杰's avatar
赵杰 committed
48

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    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()
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
76 77
        print('***************************')
        print(portfolio_evaluation)
78
        for i in range(len(portfolio_evaluation)):
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
79 80 81 82 83 84 85 86
            if portfolio_evaluation[i]['status'] == '保留':
                portfolio_evaluation[i]['status'] = '<div class="self_type fl">保留</div>'
            elif portfolio_evaluation[i]['status'] == '增仓':
                portfolio_evaluation[i]['status'] = '<div class="self_type fl red">增仓</div>'
            elif portfolio_evaluation[i]['status'] == '换仓':
                portfolio_evaluation[i]['status'] = '<div class="self_type fl green">换仓</div>'
            elif portfolio_evaluation[i]['status'] == '减仓':
                portfolio_evaluation[i]['status'] = '<div class="self_type fl green">减仓</div>'
87 88
            self.single_fund_data_list.append({
                'fund_name': portfolio_evaluation[i]['name'],
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
89
                'status': portfolio_evaluation[i]['status'],
90 91 92 93
                'evaluation': portfolio_evaluation[i]['data'],
                'radar_chart_path': gen_radar_chart(radar_chart_data[i])
            })

pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
94 95 96
    def get_old_compare_pic(self):
        """旧收益比较"""
        self.suggestions_result, self.suggestions_result_asset, self.return_compare_data,\
赵杰's avatar
赵杰 committed
97
        self.indicator_compare, self.new_group_evaluation = portfolio_diagnose.new_evaluation("default", self.d, self.user_customer)
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
98
        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"])
99

pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
100 101 102 103
    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"])
104 105 106 107 108 109 110 111 112 113


    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))


pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
114 115 116 117 118 119 120 121
    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))


122 123 124 125 126 127 128 129 130
    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'],
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
131
                'status': '增仓',
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
                '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)       # 本月涨幅
        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):
        # 全部数据
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
163
        data = {'customer_name': self.customer_name, 'customer_gender': '女',
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
                '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,
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
192
                'new_correlation': self.new_correlation,
赵杰's avatar
赵杰 committed
193 194
                'propose_fund_data_list': self.propose_fund_data_list,
                'suggestions_result': self.suggestions_result,
赵杰's avatar
赵杰 committed
195
                'suggestions_result_asset': self.suggestions_result_asset,
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
196
                'old_return_compare_pic': self.old_return_compare_pic,
197
                'return_compare_pic': self.return_compare_pic,
赵杰's avatar
赵杰 committed
198 199 200
                'indicator_compare': self.indicator_compare,
                'new_group_evaluation': self.new_group_evaluation

201 202 203
                }
        # 开始渲染html模板
        env = Environment(loader=PackageLoader('app', 'templates'))  # 创建一个包加载器对象
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
204 205
        # template = env.get_template('monthReport.html')  # 获取一个模板文件
        template = env.get_template('/v2/monthReportV2.html')  # 获取一个模板文件
206 207 208
        monthReport_html = template.render(data)  # 渲染

        # 保存 monthReport_html
pengxiong@wealthgrow.cn's avatar
pengxiong@wealthgrow.cn committed
209 210 211 212 213
        # 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"
214 215 216 217 218 219 220
        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)))