jinjia2html.py 9.11 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
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

# 准备数据
from app.utils.draw import draw_month_return_chart, draw_contribution_chart
from app.utils.radar_chart import gen_radar_chart


class DataIntegrate:
    def __init__(self, ifa_id='USER_INFO15914346866762', customer_id='202009281545001'):
        self.user_customer = UserCustomerResultAdaptor(ifa_id, customer_id)
        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.propose_fund()
        # 目标与业绩
        self.objectives_performance(self.group_result)
赵杰's avatar
赵杰 committed
37
        self.get_transfer_suggestions()
38 39 40
        # 渲染模版
        self.render_data()

赵杰's avatar
赵杰 committed
41

42 43 44 45 46 47 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 76 77
    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()
        for i in range(len(portfolio_evaluation)):
            self.single_fund_data_list.append({
                'fund_name': portfolio_evaluation[i]['name'],
                'status': '保留',
                'evaluation': portfolio_evaluation[i]['data'],
                'radar_chart_path': gen_radar_chart(radar_chart_data[i])
            })

# 调仓建议
赵杰's avatar
赵杰 committed
78 79
    def get_transfer_suggestions(self):
        self.suggestions_result, self.suggestions_result_asset = portfolio_diagnose.new_evaluation("default", self.d, self.user_customer)
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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

# 收益比较


    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 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)       # 本月涨幅
        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': '成龙', '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,
赵杰's avatar
赵杰 committed
162 163 164
                'propose_fund_data_list': self.propose_fund_data_list,
                'suggestions_result': self.suggestions_result,
                'suggestions_result_asset': self.suggestions_result_asset
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
                }
        # 开始渲染html模板
        env = Environment(loader=PackageLoader('app', 'templates'))  # 创建一个包加载器对象
        template = env.get_template('monthReport.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)

if __name__ == '__main__':
    start = time.time()
    DataIntegrate()
    print('耗时{}秒'.format(round(time.time()-start, 2)))