def tear_down(self, code, exception=None): if code != EXIT_CODE.EXIT_SUCCESS or not self._enabled: return # 当 PRE_SETTLEMENT 事件没有被触发当时候,self._total_portfolio 为空list if len(self._total_portfolios) == 0: return strategy_name = os.path.basename( self._env.config.base.strategy_file).split(".")[0] data_proxy = self._env.data_proxy summary = { 'strategy_name': strategy_name, 'start_date': self._env.config.base.start_date.strftime('%Y-%m-%d'), 'end_date': self._env.config.base.end_date.strftime('%Y-%m-%d'), 'strategy_file': self._env.config.base.strategy_file, 'run_type': self._env.config.base.run_type.value, } for account_type, starting_cash in six.iteritems( self._env.config.base.accounts): summary[account_type] = starting_cash risk = Risk( np.array(self._portfolio_daily_returns), np.array(self._benchmark_daily_returns), data_proxy.get_risk_free_rate(self._env.config.base.start_date, self._env.config.base.end_date)) summary.update({ 'alpha': self._safe_convert(risk.alpha, 3), 'beta': self._safe_convert(risk.beta, 3), 'sharpe': self._safe_convert(risk.sharpe, 3), 'information_ratio': self._safe_convert(risk.information_ratio, 3), 'downside_risk': self._safe_convert(risk.annual_downside_risk, 3), 'tracking_error': self._safe_convert(risk.annual_tracking_error, 3), 'sortino': self._safe_convert(risk.sortino, 3), 'volatility': self._safe_convert(risk.annual_volatility, 3), 'max_drawdown': self._safe_convert(risk.max_drawdown, 3), }) summary.update({ 'total_value': self._safe_convert(self._env.portfolio.total_value), 'cash': self._safe_convert(self._env.portfolio.cash), 'total_returns': self._safe_convert(self._env.portfolio.total_returns), 'annualized_returns': self._safe_convert(self._env.portfolio.annualized_returns), 'unit_net_value': self._safe_convert(self._env.portfolio.unit_net_value), 'units': self._env.portfolio.units, }) if self._env.benchmark_portfolio: summary['benchmark_total_returns'] = self._safe_convert( self._env.benchmark_portfolio.total_returns) summary['benchmark_annualized_returns'] = self._safe_convert( self._env.benchmark_portfolio.annualized_returns) trades = pd.DataFrame(self._trades) if 'datetime' in trades.columns: trades = trades.set_index('datetime') df = pd.DataFrame(self._total_portfolios) df['date'] = pd.to_datetime(df['date']) total_portfolios = df.set_index('date').sort_index() result_dict = { 'summary': summary, 'trades': trades, 'portfolio': total_portfolios, } if self._env.benchmark_portfolio is not None: b_df = pd.DataFrame(self._total_benchmark_portfolios) df['date'] = pd.to_datetime(df['date']) benchmark_portfolios = b_df.set_index('date').sort_index() result_dict['benchmark_portfolio'] = benchmark_portfolios if not self._env.get_plot_store().empty: plots = self._env.get_plot_store().get_plots() plots_items = defaultdict(dict) for series_name, value_dict in six.iteritems(plots): for date, value in six.iteritems(value_dict): plots_items[date][series_name] = value plots_items[date]["date"] = date df = pd.DataFrame( [dict_data for date, dict_data in six.iteritems(plots_items)]) df["date"] = pd.to_datetime(df["date"]) df = df.set_index("date").sort_index() result_dict["plots"] = df for account_type, account in six.iteritems( self._env.portfolio.accounts): account_name = account_type.lower() portfolios_list = self._sub_accounts[account_type] df = pd.DataFrame(portfolios_list) df["date"] = pd.to_datetime(df["date"]) account_df = df.set_index("date").sort_index() result_dict["{}_account".format(account_name)] = account_df positions_list = self._positions[account_type] positions_df = pd.DataFrame(positions_list) if "date" in positions_df.columns: positions_df["date"] = pd.to_datetime(positions_df["date"]) positions_df = positions_df.set_index("date").sort_index() result_dict["{}_positions".format(account_name)] = positions_df if self._mod_config.output_file: with open(self._mod_config.output_file, 'wb') as f: pickle.dump(result_dict, f) if self._mod_config.report_save_path: from .report import generate_report generate_report(result_dict, self._mod_config.report_save_path) if self._mod_config.plot or self._mod_config.plot_save_file: from .plot import plot_result plot_result(result_dict, self._mod_config.plot, self._mod_config.plot_save_file) return result_dict
def tear_down(self, code, exception=None): if code != EXIT_CODE.EXIT_SUCCESS or not self._enabled: return # 当 PRE_SETTLEMENT 事件没有被触发当时候,self._total_portfolio 为空list if len(self._total_portfolios) == 0: return strategy_name = os.path.basename( self._env.config.base.strategy_file).split(".")[0] data_proxy = self._env.data_proxy summary = { 'strategy_name': strategy_name, 'start_date': self._env.config.base.start_date.strftime('%Y-%m-%d'), 'end_date': self._env.config.base.end_date.strftime('%Y-%m-%d'), 'strategy_file': self._env.config.base.strategy_file, 'run_type': self._env.config.base.run_type.value, } for account_type, starting_cash in self._env.config.base.accounts.items( ): summary[account_type] = starting_cash risk_free_rate = data_proxy.get_risk_free_rate( self._env.config.base.start_date, self._env.config.base.end_date) risk = Risk(np.array(self._portfolio_daily_returns), np.array(self._benchmark_daily_returns), risk_free_rate) summary.update({ 'alpha': self._safe_convert(risk.alpha, 3), 'beta': self._safe_convert(risk.beta, 3), 'sharpe': self._safe_convert(risk.sharpe, 3), 'excess_sharpe': self._safe_convert(risk.excess_sharpe, 3), 'information_ratio': self._safe_convert(risk.information_ratio, 3), 'downside_risk': self._safe_convert(risk.annual_downside_risk, 3), 'tracking_error': self._safe_convert(risk.annual_tracking_error, 3), 'sortino': self._safe_convert(risk.sortino, 3), 'volatility': self._safe_convert(risk.annual_volatility, 3), 'excess_volatility': self._safe_convert(risk.excess_volatility, 3), 'excess_annual_volatility': self._safe_convert(risk.excess_annual_volatility, 3), 'max_drawdown': self._safe_convert(risk.max_drawdown, 3), 'excess_max_drawdown': self._safe_convert(risk.excess_max_drawdown), 'excess_returns': self._safe_convert(risk.excess_return_rate, 6), 'excess_annual_returns': self._safe_convert(risk.excess_annual_return, 6) }) summary.update({ 'total_value': self._safe_convert(self._env.portfolio.total_value), 'cash': self._safe_convert(self._env.portfolio.cash), 'total_returns': self._safe_convert(self._env.portfolio.total_returns, 6), 'annualized_returns': self._safe_convert(self._env.portfolio.annualized_returns), 'unit_net_value': self._safe_convert(self._env.portfolio.unit_net_value), 'units': self._env.portfolio.units, }) if self._benchmark: benchmark_total_returns = ( np.array(self._benchmark_daily_returns) + 1.0).prod() - 1.0 summary['benchmark_total_returns'] = self._safe_convert( benchmark_total_returns, ndigits=6) date_count = len(self._benchmark_daily_returns) benchmark_annualized_returns = (benchmark_total_returns + 1)**( DAYS_CNT.TRADING_DAYS_A_YEAR / date_count) - 1 summary['benchmark_annualized_returns'] = self._safe_convert( benchmark_annualized_returns, ndigits=6) trades = pd.DataFrame(self._trades) if 'datetime' in trades.columns: trades = trades.set_index('datetime') df = pd.DataFrame(self._total_portfolios) df['date'] = pd.to_datetime(df['date']) total_portfolios = df.set_index('date').sort_index() weekly_nav = df.resample( "W", on="date").last().set_index("date").unit_net_value.dropna() weekly_returns = (weekly_nav / weekly_nav.shift(1).fillna(1)).fillna(0) - 1 result_dict = { 'summary': summary, 'trades': trades, 'portfolio': total_portfolios, } if self._benchmark: df = pd.DataFrame(self._total_benchmark_portfolios) df['date'] = pd.to_datetime(df['date']) benchmark_portfolios = df.set_index('date').sort_index() weekly_b_nav = df.resample( "W", on="date").last().set_index("date").unit_net_value.dropna() weekly_b_returns = (weekly_b_nav / weekly_b_nav.shift(1).fillna(1)).fillna(0) - 1 result_dict['benchmark_portfolio'] = benchmark_portfolios else: weekly_b_returns = pandas.Series(index=weekly_returns.index) weekly_risk = Risk(weekly_returns, weekly_b_returns, risk_free_rate, WEEKLY) summary.update({ "weekly_alpha": weekly_risk.alpha, "weekly_beta": weekly_risk.beta, "weekly_sharpe": weekly_risk.sharpe, "weekly_sortino": weekly_risk.sortino, 'weekly_information_ratio': weekly_risk.information_ratio, "weekly_tracking_error": weekly_risk.tracking_error, "weekly_max_drawdown": weekly_risk.max_drawdown, }) plots = self._plot_store.get_plots() if plots: plots_items = defaultdict(dict) for series_name, value_dict in plots.items(): for date, value in value_dict.items(): plots_items[date][series_name] = value plots_items[date]["date"] = date df = pd.DataFrame( [dict_data for date, dict_data in plots_items.items()]) df["date"] = pd.to_datetime(df["date"]) df = df.set_index("date").sort_index() result_dict["plots"] = df for account_type, account in self._env.portfolio.accounts.items(): account_name = account_type.lower() portfolios_list = self._sub_accounts[account_type] df = pd.DataFrame(portfolios_list) df["date"] = pd.to_datetime(df["date"]) df = df.set_index("date").sort_index() result_dict["{}_account".format(account_name)] = df positions_list = self._positions[account_type] df = pd.DataFrame(positions_list) if "date" in df.columns: df["date"] = pd.to_datetime(df["date"]) df = df.set_index("date").sort_index() result_dict["{}_positions".format(account_name)] = df if self._mod_config.output_file: with open(self._mod_config.output_file, 'wb') as f: pickle.dump(result_dict, f) if self._mod_config.report_save_path: from .report import generate_report generate_report(result_dict, self._mod_config.report_save_path) if self._mod_config.plot or self._mod_config.plot_save_file: from .plot import plot_result plot_config = self._mod_config.plot_config plot_result(result_dict, self._mod_config.plot, self._mod_config.plot_save_file, plot_config.weekly_indicators, plot_config.open_close_points) return result_dict
def get_risker(self, start_date, end_date): self.set_date_range(start_date, end_date) return Risk(self.returns.to_numpy(), self.benchmark_returns.to_numpy(), self.risk_free_rate, self._period)