def performance_out_sample(self, outfile="performance_out_sample.png"): # extarct data for out-of-sample (OOS) perf_func = pf.timeseries.perf_stats X_oos = self.X[self.test_date:] y_oos = self.y[self.test_date:] y_pred_rf = self.rf.predict_proba(X_oos)[:, 1] y_pred = self.rf.predict(X_oos) fpr_rf, tpr_rf, _ = roc_curve(y_oos, y_pred_rf) test_dates = X_oos.index meta_returns = self.label.loc[test_dates, 'ret'] * y_pred daily_rets_meta = self.get_daily_returns(meta_returns) # save the KPIs in a dataframe perf_stats_all = perf_func(returns=daily_rets_meta, factor_returns=None, positions=None, transactions=None, turnover_denom="AGB") self.perf_stats_df['Meta Model OOS'] = perf_stats_all pf.create_returns_tear_sheet(daily_rets_meta, benchmark_rets=None) plt.savefig(outfile) return (classification_report(y_oos, y_pred, output_dict=True), confusion_matrix(y_oos, y_pred), accuracy_score(y_oos, y_pred), self.perf_stats_df)
def pnl_analyze(self, detailDF_pnl): ''' Function that uses pyfolio developed by quantopian to analyze the pnl curve given by the backTest function Params: total_balance series from detail dataframe generated by backTest Note: you can get pyfolio package simply by typing 'pip install pyfolio' and enter in your command line tool console. No need to install theano since we don't do bayesian analysis here. ''' # Get return series from pnl series, and resample return series on a daily basis pnl_daily = detailDF_pnl.resample('D').last() day_one_return = pnl_daily[0]/self.init_cash - 1. pnl_ret_daily = pnl_daily.pct_change() pnl_ret_daily[0] = day_one_return pnl_ret_daily = pnl_ret_daily.dropna() # Convert datetime to timezone-aware format and change the timezone to Beijing pnl_ret_daily = pnl_ret_daily.tz_localize('UTC').tz_convert('Asia/Shanghai') # PnL plot, drawdown analysis and risk analysis import pyfolio as pf # This benchmark(SHY) is the ETF that tracks 1-3 year US treasury bonds, you can also use # symbols like SPY for S&P500 or ASHR for CSI300 index benchmark = pf.utils.get_symbol_rets('SHY') # Generate different reports according to length of backtest timeIndex = pnl_ret_daily.index if((timeIndex[-1]-timeIndex[0]).days>30): pf.create_returns_tear_sheet(pnl_ret_daily, benchmark_rets=benchmark) else: pf.create_simple_tear_sheet(pnl_ret_daily, benchmark_rets=benchmark) return pnl_ret_daily
def create_tearsheet(self): # to daily try: rets = self._equity.resample('D').last().dropna().pct_change() if self._benchmark is not None: b_rets = self._df_positions['benchmark'].resample('D').last().dropna().pct_change() except: rets = self._equity.pct_change() if self._benchmark is not None: b_rets = self._df_positions['benchmark'].pct_change() rets = rets[1:] if self._benchmark is not None: b_rets = b_rets[1:] #rets.index = rets.index.tz_localize('UTC') #self._df_positions.index = self._df_positions.index.tz_localize('UTC') if not self._df_trades.index.empty: if self._benchmark is not None: # self._df_trades.index = self._df_trades.index.tz_localize('UTC') # pf.create_full_tear_sheet(rets, self._df_positions, self._df_trades) rets.index = pd.to_datetime(rets.index) b_rets.index = rets.index pf.create_returns_tear_sheet(rets) #pf.create_simple_tear_sheet(rets, benchmark_rets=b_rets) else: # self._df_trades.index = self._df_trades.index.tz_localize('UTC') # pf.create_full_tear_sheet(rets, self._df_positions, self._df_trades) rets.index = pd.to_datetime(rets.index) pf.create_returns_tear_sheet(rets)
def tearsheet(self): pp = PdfPages('./backtests/multipage.pdf') fig = pf.create_returns_tear_sheet(self.__strategy, benchmark_rets=self.__base, return_fig=True) fig.savefig(pp, format='pdf') pp.close()
def run_strategy_returns_stats(self, strategy): """ run_strategy_returns_stats - Plots useful statistics for the trading strategy (using PyFolio) Parameters ---------- strategy : StrategyTemplate defining trading strategy """ pnl = strategy.get_strategy_pnl() tz = TimeSeriesTimezone() tsc = TimeSeriesCalcs() # PyFolio assumes UTC time based DataFrames (so force this localisation) try: pnl = tz.localise_index_as_UTC(pnl) except: pass # TODO for intraday strategy make daily # convert DataFrame (assumed to have only one column) to Series pnl = tsc.calculate_returns(pnl) pnl = pnl[pnl.columns[0]] fig = pf.create_returns_tear_sheet(pnl, return_fig=True) try: plt.savefig (strategy.DUMP_PATH + "stats.png") except: pass plt.show()
def run_strategy_returns_stats(self, strategy): """ run_strategy_returns_stats - Plots useful statistics for the trading strategy (using PyFolio) Parameters ---------- strategy : StrategyTemplate defining trading strategy """ pnl = strategy.get_strategy_pnl() tz = TimeSeriesTimezone() tsc = TimeSeriesCalcs() # PyFolio assumes UTC time based DataFrames (so force this localisation) try: pnl = tz.localise_index_as_UTC(pnl) except: pass # TODO for intraday strategy make daily # convert DataFrame (assumed to have only one column) to Series pnl = tsc.calculate_returns(pnl) pnl = pnl[pnl.columns[0]] fig = pf.create_returns_tear_sheet(pnl, return_fig=True) try: plt.savefig(strategy.DUMP_PATH + "stats.png") except: pass plt.show()
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio such as Sharpe Ratio and drawdown information. """ equity_curve = self.get_equity_curve_dataframe() total_return = equity_curve['equity_curve'][-1] returns = equity_curve['returns'] pnl = equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) import warnings warnings.filterwarnings('ignore') pf.create_returns_tear_sheet(equity_curve['returns']) return
def displaySummary(derivative, tInfo, baseline=None, log=False, includeComponents=True, includePrimary=True, full=True): print("Derivative name : " + derivative.name) print("Number of assets : " + str(len(derivative.assets))) if (baseline is not None): print("Baseline name : " + baseline.name) # Summary plot plot(derivative, baseline, log, includeComponents, includePrimary) # Show sample of trades pd.set_option('display.max_rows', 10) display(tInfo) if (baseline is not None): # Show local statistics stats.merton(derivative.returns["Open"][derivative.returns["Open"] != 0], baseline.returns["Open"][baseline.returns["Open"] != 0], display=True) if(full): # Show generic statistics warnings.filterwarnings('ignore') pyfolio.create_returns_tear_sheet(getPeriodReturns(derivative.returns))
def main(run_id): db = records.Database(config['database']['url']) rows = db.query("select * from test_runs where id = :id", id=run_id) results = pickle.loads(rows[0].pickle) returns, positions, transactions, gross_lev = pf.utils.extract_rets_pos_txn_from_zipline( results) # pulled from /Users/jcurzon/anaconda/envs/zipline/lib/python3.4/site-packages/pyfolio benchmark_rets = pf.utils.get_symbol_rets('SPY') # If the strategy's history is longer than the benchmark's, limit strategy if returns.index[0] < benchmark_rets.index[0]: returns = returns[returns.index > benchmark_rets.index[0]] pf.create_returns_tear_sheet(returns, live_start_date=None, cone_std=(1.0, 1.5, 2.0), benchmark_rets=benchmark_rets, set_context=True) plt.savefig("returns_{run_id}.png".format(run_id=run_id))
def draw_returns_tear_sheet(self, save_file=True, out_filename='pyfolio_returns_tear_sheet.png'): import matplotlib if save_file: matplotlib.use('Agg') f = pf.create_returns_tear_sheet( returns=self.trading_df['return_relative_to_past_tick'], return_fig=True) # benchmark_rets= # self.benchmark_trading_df['return_relative_to_past_tick'] # if self.benchmark is not None else None) f.savefig(out_filename)
def test_out_of_sampe(self, outputImagePath="test_out_of_sampe_performance.png", kpiImagePath="test_out_of_kpi.png"): # 15 Extarct data for out-of-sample (OOS) X_oos = self.X[self.test_date:] y_oos = self.y[self.test_date:] # Performance Metrics y_pred_rf = self.top_model.predict_proba(X_oos)[:, 1] y_pred = self.top_model.predict(X_oos) fpr_rf, tpr_rf, _ = roc_curve(y_oos, y_pred_rf) plt.figure(1) plt.plot([0, 1], [0, 1], 'k--') plt.plot(fpr_rf, tpr_rf, label='RF') plt.xlabel('False positive rate') plt.ylabel('True positive rate') plt.title('ROC curve') plt.legend(loc='best') plt.savefig(outputImagePath) test_dates = X_oos.index meta_returns = self.labels.loc[test_dates, 'ret'] * y_pred daily_rets_meta = self.get_daily_returns(meta_returns) perf_func = pf.timeseries.perf_stats # save the KPIs in a dataframe perf_stats_all = perf_func(returns=daily_rets_meta, factor_returns=None, positions=None, transactions=None, turnover_denom="AGB") self.perf_stats_df['Meta Model OOS'] = perf_stats_all self.return_history = daily_rets_meta pf.create_returns_tear_sheet(daily_rets_meta, benchmark_rets=None) plt.savefig(kpiImagePath) return (confusion_matrix(y_oos, y_pred), accuracy_score(y_oos, y_pred), classification_report(y_oos, y_pred, output_dict=True), self.perf_stats_df)
def make_return_tear_sheet_plot(self): for item in self.df_list: df = item[0] daily_profit = df["daily_profit"] tear_sheet_rt = pf.create_returns_tear_sheet(daily_profit, return_fig=True) figname = os.path.join( self.output, self.plot_name + "_tear_sheet_return" + ".png") tear_sheet_rt.savefig(figname, dpi=200) # Drawdown dd_plot = pf.plot_drawdown_periods(daily_profit, top=10) full_tear_sheet_rt_ax = pf.create_full_tear_sheet(daily_profit) # print(full_tear_sheet_rt_ax) ddfigname = os.path.join(self.output, self.plot_name + "_drawdown" + ".png") dd_plot.figure.savefig(ddfigname)
def create_tearsheet(close, signal, file_name, report_type, benchmark_rets=None): logging.info(f"Creating {report_type} tearsheet for {file_name}") # Map long/short to long/flat # signal = (signal + 1) / 2 pos_size = 10000 df, df_wo_costs, cost_stats = simulate_pnl(close, signal, pos_size) returns = calc_returns(df) returns.name = report_type.title() returns_wo_costs = calc_returns(df_wo_costs) returns_wo_costs.name = report_type.title() if report_type == "primary": long_all = pd.DataFrame(1, columns=signal.columns, index=signal.index) df_bench, _, _ = simulate_pnl(close, long_all, pos_size) benchmark_rets = calc_returns(df_bench) benchmark_rets.name = "Benchmark (long all)" fig = pyfolio.create_returns_tear_sheet( returns, benchmark_rets=benchmark_rets, return_fig=True ) fig_file_name = file_name.replace(".json", f"_{report_type}.png") fig.savefig(fig_file_name, bbox_inches="tight", pad_inches=0) p_stats = perf_stats(returns) p_stats_wo_costs = perf_stats(returns_wo_costs) dd_table = gen_drawdown_table(returns, 5) signal = signal.resample("1B").last() # Just-in-case normalize to 1 for reporting signal = signal / signal.max().max() signal.plot() signal = signal.set_index(signal.index.map(lambda x: x.isoformat())) return ( returns, { "fig_file_name": str(Path(fig_file_name).basename()), "p_stats": p_stats.to_dict(), "p_stats_wo_costs": p_stats_wo_costs.to_dict(), "dd_table": dd_table.to_dict(), "signal": signal.to_csv(), # CSVs are a lot more space-efficient for this dense 1500*50 table "cost_stats": cost_stats, }, )
def run_strategy_returns_stats(self, trading_model): """ run_strategy_returns_stats - Plots useful statistics for the trading strategy (using PyFolio) Parameters ---------- trading_model : TradingModel defining trading strategy """ pnl = trading_model.get_strategy_pnl() tz = Timezone() calculations = Calculations() # PyFolio assumes UTC time based DataFrames (so force this localisation) try: pnl = tz.localise_index_as_UTC(pnl) except: pass # set the matplotlib style sheet & defaults # at present this only works in Matplotlib engine try: matplotlib.rcdefaults() plt.style.use( ChartConstants().chartfactory_style_sheet['chartpy-pyfolio']) except: pass # TODO for intraday strategies, make daily # convert DataFrame (assumed to have only one column) to Series pnl = calculations.calculate_returns(pnl) pnl = pnl.dropna() pnl = pnl[pnl.columns[0]] fig = pf.create_returns_tear_sheet(pnl, return_fig=True) try: plt.savefig(trading_model.DUMP_PATH + "stats.png") except: pass plt.show()
def run_strategy_returns_stats(self, strategy): """ run_strategy_returns_stats - Plots useful statistics for the trading strategy (using PyFolio) Parameters ---------- strategy : StrategyTemplate defining trading strategy """ pnl = strategy.get_strategy_pnl() tz = TimeSeriesTimezone() tsc = TimeSeriesCalcs() # PyFolio assumes UTC time based DataFrames (so force this localisation) try: pnl = tz.localise_index_as_UTC(pnl) except: pass # set the matplotlib style sheet & defaults # at present this only works in Matplotlib engine try: matplotlib.rcdefaults() plt.style.use(GraphicsConstants().plotfactory_pythalesians_style_sheet['pythalesians-pyfolio']) except: pass # TODO for intraday strategies, make daily # convert DataFrame (assumed to have only one column) to Series pnl = tsc.calculate_returns(pnl) pnl = pnl.dropna() pnl = pnl[pnl.columns[0]] fig = pf.create_returns_tear_sheet(pnl, return_fig=True) try: plt.savefig (strategy.DUMP_PATH + "stats.png") except: pass plt.show()
def create_returns_tear_sheet(self, live_start_date=None): pf.create_returns_tear_sheet(self.returns, benchmark_rets=self.benchmark_returns, live_start_date=live_start_date) plt.show()
def caculate_performance(self, tearsheet=False): # to daily try: rets = self._equity.resample('D').last().dropna().pct_change() if self._benchmark is not None: b_rets = self._df_positions['benchmark'].resample('D').last().dropna().pct_change() except: rets = self._equity.pct_change() if self._benchmark is not None: b_rets = self._df_positions['benchmark'].pct_change() rets = rets[1:] if self._benchmark is not None: b_rets = b_rets[1:] #rets.index = rets.index.tz_localize('UTC') #self._df_positions.index = self._df_positions.index.tz_localize('UTC') perf_stats_all = None if not self._df_trades.index.empty: if self._benchmark is not None: # self._df_trades.index = self._df_trades.index.tz_localize('UTC') # pf.create_full_tear_sheet(rets, self._df_positions, self._df_trades) rets.index = pd.to_datetime(rets.index) b_rets.index = rets.index perf_stats_strat = pf.timeseries.perf_stats(rets) perf_stats_benchmark = pf.timeseries.perf_stats(b_rets) perf_stats_all = pd.concat([perf_stats_strat, perf_stats_benchmark], axis=1) perf_stats_all.columns = ['Strategy', 'Benchmark'] else: # self._df_trades.index = self._df_trades.index.tz_localize('UTC') # pf.create_full_tear_sheet(rets, self._df_positions, self._df_trades) rets.index = pd.to_datetime(rets.index) perf_stats_all = pf.timeseries.perf_stats(rets) perf_stats_all = perf_stats_all.to_frame(name='Strategy') if tearsheet: # only plot if not self._df_trades.index.empty # pf.create_returns_tear_sheet(rets,benchmark_rets=b_rets) pf.create_returns_tear_sheet(rets) # pf.create_simple_tear_sheet(rets, benchmark_rets=b_rets) # somehow the tearsheet is too crowded. fig, ax = plt.subplots(nrows=1, ncols=2) if self._benchmark is not None: pf.plot_rolling_returns(rets, factor_returns=b_rets, ax=ax[0]) ax[0].set_title('Cumulative returns') ax[1].text(5.0, 9.5, 'Strategy', fontsize=8, fontweight='bold', horizontalalignment='left') ax[1].text(8.0, 9.5, 'Benchmark', fontsize=8, fontweight='bold', horizontalalignment='left') ax[1].text(0.5, 8.5, 'Annual return', fontsize=8, horizontalalignment='left') ax[1].text(6.0, 8.5, round(perf_stats_all.loc['Annual return', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(9.5, 8.5, round(perf_stats_all.loc['Annual return', 'Benchmark'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 7.5, 'Cumulative returns', fontsize=8, horizontalalignment='left', color='green') ax[1].text(6.0, 7.5, round(perf_stats_all.loc['Cumulative returns', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(9.5, 7.5, round(perf_stats_all.loc['Cumulative returns', 'Benchmark'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 6.5, 'Annual volatility', fontsize=8, horizontalalignment='left') ax[1].text(6.0, 6.5, round(perf_stats_all.loc['Annual volatility', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(9.5, 6.5, round(perf_stats_all.loc['Annual volatility', 'Benchmark'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 5.5, 'Sharpe ratio', fontsize=8, horizontalalignment='left', color='green') ax[1].text(6.0, 5.5, round(perf_stats_all.loc['Sharpe ratio', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(9.5, 5.5, round(perf_stats_all.loc['Sharpe ratio', 'Benchmark'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 4.5, 'Calmar ratio', fontsize=8, horizontalalignment='left') ax[1].text(6.0, 4.5, round(perf_stats_all.loc['Calmar ratio', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(9.5, 4.5, round(perf_stats_all.loc['Calmar ratio', 'Benchmark'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 3.5, 'Sortino ratio', fontsize=8, horizontalalignment='left', color='green') ax[1].text(6.0, 3.5, round(perf_stats_all.loc['Sortino ratio', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(9.5, 3.5, round(perf_stats_all.loc['Sortino ratio', 'Benchmark'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 2.5, 'Max drawdown', fontsize=8, horizontalalignment='left') ax[1].text(6.0, 2.5, round(perf_stats_all.loc['Max drawdown', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(9.5, 2.5, round(perf_stats_all.loc['Max drawdown', 'Benchmark'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 1.5, 'Skew', fontsize=8, horizontalalignment='left', color='green') ax[1].text(6.0, 1.5, round(perf_stats_all.loc['Skew', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(9.5, 1.5, round(perf_stats_all.loc['Skew', 'Benchmark'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 0.5, 'Kurtosis', fontsize=8, horizontalalignment='left') ax[1].text(6.0, 0.5, round(perf_stats_all.loc['Kurtosis', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(9.5, 0.5, round(perf_stats_all.loc['Kurtosis', 'Benchmark'], 4), fontsize=8, horizontalalignment='right') else: pf.plot_rolling_returns(rets, ax=ax[0]) ax[0].set_title('Cumulative returns') # pf.plotting.plot_monthly_returns_heatmap(rets, ax=ax[1]) ax[1].text(0.5, 9.0, 'Annual return', fontsize=8, horizontalalignment='left') ax[1].text(9.5, 9.0, round(perf_stats_all.loc['Annual return', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 8.0, 'Cumulative returns', fontsize=8, horizontalalignment='left', color='green') ax[1].text(9.5, 8.0, round(perf_stats_all.loc['Cumulative returns', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 7.0, 'Annual volatility', fontsize=8, horizontalalignment='left') ax[1].text(9.5, 7.0, round(perf_stats_all.loc['Annual volatility', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 6.0, 'Sharpe ratio', fontsize=8, horizontalalignment='left', color='green') ax[1].text(9.5, 6.0, round(perf_stats_all.loc['Sharpe ratio', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 5.0, 'Calmar ratio', fontsize=8, horizontalalignment='left') ax[1].text(9.5, 5.0, round(perf_stats_all.loc['Calmar ratio', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 4.0, 'Sortino ratio', fontsize=8, horizontalalignment='left', color='green') ax[1].text(9.5, 4.0, round(perf_stats_all.loc['Sortino ratio', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 3.0, 'Max drawdown', fontsize=8, horizontalalignment='left') ax[1].text(9.5, 3.0, round(perf_stats_all.loc['Max drawdown', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].text(0.5, 2.0, 'Skew', fontsize=8, horizontalalignment='left', color='green') ax[1].text(9.5, 2.0, round(perf_stats_all.loc['Skew', 'Strategy'], 4), fontsize=8, horizontalalignment='right', color='green') ax[1].text(0.5, 1.0, 'Kurtosis', fontsize=8, horizontalalignment='left') ax[1].text(9.5, 1.0, round(perf_stats_all.loc['Kurtosis', 'Strategy'], 4), fontsize=8, horizontalalignment='right') ax[1].set_title('Performance', fontweight='bold') ax[1].grid(False) # ax[1].spines['top'].set_linewidth(2.0) # ax[1].spines['bottom'].set_linewidth(2.0) ax[1].spines['right'].set_visible(False) ax[1].spines['left'].set_visible(False) ax[1].get_yaxis().set_visible(False) ax[1].get_xaxis().set_visible(False) ax[1].set_ylabel('') ax[1].set_xlabel('') ax[1].axis([0, 10, 0, 10]) plt.show() drawdown_df = pf.timeseries.gen_drawdown_table(rets, top=5) monthly_ret_table = ep.aggregate_returns(rets, 'monthly') monthly_ret_table = monthly_ret_table.unstack().round(3) ann_ret_df = pd.DataFrame(ep.aggregate_returns(rets, 'yearly')) ann_ret_df = ann_ret_df.unstack().round(3) return perf_stats_all, drawdown_df, monthly_ret_table, ann_ret_df
# id_spot = pandas.concat(raw_spot_pnl) # id_index = pandas.concat(raw_index_pnl) # id_trend = pandas.concat(raw_bt_pnl) # trade_count = pandas.Series(raw_bt_count) # daily_w1 = pandas.DataFrame(raw_index_w1) # rolling_w1 = daily_w1.rolling(20).mean() # daily_spot = pandas.DataFrame([i.sum().rename(i.index[0].date()) for i in raw_spot_pnl]) # daily_index = pandas.DataFrame([i.sum().rename(i.index[0].date()) for i in raw_index_pnl]) # daily_trend = pandas.DataFrame([i.sum().rename(i.index[0]) for i in raw_bt_pnl]) # # agg_trend = daily_trend.mul(daily_w1.shift(1).fillna(1 / daily_w1.shape[1])).sum(axis=1) # print(pandas.Series({'ret': agg_trend.mean() * 260, # 'vol': agg_trend.std() * (260 ** 0.5), # 'sharpe': agg_trend.mean() / agg_trend.std() * (260 ** 0.5), # 'neg_days': len(agg_trend[agg_trend < 0]), # 'total_days': len(agg_trend), # 'mdd': (1 - agg_trend.cumsum().div(agg_trend.cumsum().cummax())).max(), # 'daily_trade_count': trade_count.mean()})) # agg_trend.cumsum().plot() with open('pickle', 'rb') as f: import pickle agg_trend = pickle.load(f) retu = (agg_trend.cumsum() / 50 + 1).pct_change() fig = pf.create_returns_tear_sheet(retu, return_fig=True) fig.savefig('/Users/sweetdreams/code/fintend/alpha/alpha.png') plt.show() import ccxt d = ccxt.deribit().fetch_ohlcv
def create_report(perf, filename, now, doc=None, duration=None, param=None, info=None, show_image=True): if not hasattr(perf, 'returns'): perf['returns'] = perf['pnl'] / (perf['portfolio_value'] - perf['pnl']) perf['returns'] = perf['returns'].replace([np.nan, np.inf, -np.inf], 0.0) tot_positions = sum([len(x) for x in perf.positions]) if tot_positions == 0: log.warn("No positions available") return rets, positions, transactions = pf.utils.extract_rets_pos_txn_from_zipline( perf) date_rows = OrderedDict() if len(rets.index) > 0: date_rows['Start date'] = rets.index[0].strftime('%Y-%m-%d') date_rows['End date'] = rets.index[-1].strftime('%Y-%m-%d') date_rows['Total months'] = int(len(rets) / 21) perf_stats_series = pf.timeseries.perf_stats(rets, positions=positions, transactions=transactions) benchmark_rets = returns(symbol('SPY'), rets.index[0], rets.index[-1]) benchmark_perf_stats = pf.timeseries.perf_stats(benchmark_rets) perf_stats_df = pd.DataFrame(perf_stats_series, columns=['Backtest']) perf_stats_df['Benchmark'] = benchmark_perf_stats perf_stats_df[ 'Spread'] = perf_stats_df['Backtest'] - perf_stats_df['Benchmark'] format_perf_stats(perf_stats_df) drawdown_df = pf.timeseries.gen_drawdown_table(rets, top=5) rets_interesting = pf.timeseries.extract_interesting_date_ranges(rets) positions = utils.check_intraday('infer', rets, positions, transactions) transactions_closed = rt.add_closing_transactions(positions, transactions) trades = rt.extract_round_trips( transactions_closed, portfolio_value=positions.sum(axis='columns') / (1 + rets)) if show_image: fig0 = None fig1 = None fig2 = None fig3 = None fig4 = None fig5 = None try: fig0 = create_log_returns_chart(rets, benchmark_rets) except Exception as e: log.warn(e) try: fig1 = pf.create_returns_tear_sheet(rets, positions, transactions, benchmark_rets=benchmark_rets, return_fig=True) except Exception as e: log.warn(e) try: fig2 = pf.create_position_tear_sheet(rets, positions, return_fig=True) except Exception as e: log.warn(e) try: fig3 = pf.create_txn_tear_sheet(rets, positions, transactions, return_fig=True) except Exception as e: log.warn(e) try: fig4 = pf.create_interesting_times_tear_sheet(rets, return_fig=True) except Exception as e: log.warn(e) try: fig5 = pf.create_round_trip_tear_sheet(rets, positions, transactions, return_fig=True) except Exception as e: log.warn(e) report_suffix = "_%s_%.2f_report.htm" % ( now.strftime(DATETIME_FMT), 100. * perf_stats_series['Annual return']) reportfile = change_extension(filename, report_suffix) with open(reportfile, 'w') as f: print("""<!DOCTYPE html> <html> <head> <title>Performance Report</title> <style > body { font-family: Arial, Helvetica, sans-serif; } table { border-collapse: collapse; } tbody tr:nth-child(odd) { background-color: lightgrey; } tbody tr:nth-child(even) { background-color: white; } tr th { border: none; text-align: right; padding: 2px 5px 2px; } tr td { border: none; text-align: right; padding: 2px 5px 2px; } </style> <script type="text/javascript"> function showElement() { element = document.getElementById('code'); element.style.visibility = 'visible'; } function hideElement() { element = document.getElementById('code'); element.style.visibility = 'hidden'; } </script> </head> <body>""", file=f) print("<h1>Performance report for " + os.path.basename(filename) + "</h1>", file=f) print("<p>Created on %s</p>" % (now), file=f) if duration is not None: print("<p>Backtest executed in %s</p>" % (time.strftime("%H:%M:%S", time.gmtime(duration))), file=f) if doc is not None: print('<h3>Description</h3>', file=f) print('<p style="white-space: pre">%s</p>' % doc.strip(), file=f) if param is not None and len(param) > 0: print('<h3>Parameters</h3>', file=f) print('<pre>%s</pre><br/>' % str(param), file=f) if info is not None and len(info) > 0: print('<h3>Info</h3>', file=f) print('<pre>%s</pre><br/>' % str(info), file=f) print(to_html_table(perf_stats_df, float_format='{0:.2f}'.format, header_rows=date_rows), file=f) print("<br/>", file=f) if show_image: if fig0 is not None: print("<h3>Log Returns</h3>", file=f) print(_to_img(fig0), file=f) print("<br/>", file=f) print(to_html_table( drawdown_df.sort_values('Net drawdown in %', ascending=False), name='Worst drawdown periods', float_format='{0:.2f}'.format, ), file=f) print("<br/>", file=f) print(to_html_table(pd.DataFrame(rets_interesting).describe(). transpose().loc[:, ['mean', 'min', 'max']] * 100, name='Stress Events', float_format='{0:.2f}%'.format), file=f) print("<br/>", file=f) if len(trades) >= 5: stats = rt.gen_round_trip_stats(trades) print(to_html_table(stats['summary'], float_format='{:.2f}'.format, name='Summary stats'), file=f) print("<br/>", file=f) print(to_html_table(stats['pnl'], float_format='${:.2f}'.format, name='PnL stats'), file=f) print("<br/>", file=f) print(to_html_table(stats['duration'], float_format='{:.2f}'.format, name='Duration stats'), file=f) print("<br/>", file=f) print(to_html_table(stats['returns'] * 100, float_format='{:.2f}%'.format, name='Return stats'), file=f) print("<br/>", file=f) stats['symbols'].columns = stats['symbols'].columns.map( format_asset) print(to_html_table(stats['symbols'] * 100, float_format='{:.2f}%'.format, name='Symbol stats'), file=f) if show_image: if fig1 is not None: print("<h3>Returns</h3>", file=f) print(_to_img(fig1), file=f) if fig2 is not None: print("<h3>Positions</h3>", file=f) print(_to_img(fig2), file=f) if fig3 is not None: print("<h3>Transactions</h3>", file=f) print(_to_img(fig3), file=f) if fig4 is not None: print("<h3>Interesting Times</h3>", file=f) print(_to_img(fig4), file=f) if fig5 is not None: print("<h3>Trades</h3>", file=f) print(_to_img(fig5), file=f) print('<br/>', file=f) print( '<button onclick="showElement()">Show Code</button> <button onclick="hideElement()">Hide Code</button>', file=f) print('<pre id="code" style="visibility: hidden">', file=f) print(open(filename, "r").read(), file=f) print('</pre>', file=f) print("</body>\n</html>", file=f)
import pyfolio as pf # stock_rets = pf.utils.get_symbol_rets('SPY') stock_rets = pf.utils.get_symbol_rets('FB') print type(stock_rets) from pandas_datareader import data as web px = web.get_data_yahoo('FB', start=None, end=None) rets = px[['Adj Close']].pct_change().dropna() rets.index = rets.index.tz_localize("UTC") rets.columns = ['FB'] print type(rets) rets = rets['FB'] print type(rets) print stock_rets print "###" print rets pf.create_returns_tear_sheet(stock_rets) import matplotlib.pyplot as plt plt.show()
def run_strategy_returns_stats(self, trading_model, index = None, engine = 'pyfolio'): """Plots useful statistics for the trading strategy (using PyFolio) Parameters ---------- trading_model : TradingModel defining trading strategy index: DataFrame define strategy by a time series """ if index is None: pnl = trading_model.get_strategy_pnl() else: pnl = index tz = Timezone() calculations = Calculations() if engine == 'pyfolio': # PyFolio assumes UTC time based DataFrames (so force this localisation) try: pnl = tz.localise_index_as_UTC(pnl) except: pass # set the matplotlib style sheet & defaults # at present this only works in Matplotlib engine try: matplotlib.rcdefaults() plt.style.use(ChartConstants().chartfactory_style_sheet['chartpy-pyfolio']) except: pass # TODO for intraday strategies, make daily # convert DataFrame (assumed to have only one column) to Series pnl = calculations.calculate_returns(pnl) pnl = pnl.dropna() pnl = pnl[pnl.columns[0]] fig = pf.create_returns_tear_sheet(pnl, return_fig=True) try: plt.savefig (trading_model.DUMP_PATH + "stats.png") except: pass plt.show() elif engine == 'finmarketpy': # assume we have TradingModel # to do to take in a time series from chartpy import Canvas, Chart pnl = trading_model.plot_strategy_pnl(silent_plot=True) # plot the final strategy individual = trading_model.plot_strategy_group_pnl_trades(silent_plot=True) # plot the individual trade P&Ls pnl_comp = trading_model.plot_strategy_group_benchmark_pnl(silent_plot=True) # plot all the cumulative P&Ls of each component ir_comp = trading_model.plot_strategy_group_benchmark_pnl_ir(silent_plot=True) # plot all the IR of each component leverage = trading_model.plot_strategy_leverage(silent_plot=True) # plot the leverage of the portfolio ind_lev = trading_model.plot_strategy_group_leverage(silent_plot=True) # plot all the individual leverages canvas = Canvas([[pnl, individual], [pnl_comp, ir_comp], [leverage, ind_lev]] ) canvas.generate_canvas(silent_display=False, canvas_plotter='plain')
def run_strategy_returns_stats(self, trading_model, index=None, engine='finmarketpy'): """Plots useful statistics for the trading strategy using various backends Parameters ---------- trading_model : TradingModel defining trading strategy engine : str 'pyfolio' - use PyFolio as a backend 'finmarketpy' - use finmarketpy as a backend index: DataFrame define strategy by a time series """ if index is None: pnl = trading_model.strategy_pnl() else: pnl = index tz = Timezone() calculations = Calculations() if engine == 'pyfolio': # PyFolio assumes UTC time based DataFrames (so force this localisation) try: pnl = tz.localize_index_as_UTC(pnl) except: pass # set the matplotlib style sheet & defaults # at present this only works in Matplotlib engine try: import matplotlib import matplotlib.pyplot as plt matplotlib.rcdefaults() plt.style.use(ChartConstants(). chartfactory_style_sheet['chartpy-pyfolio']) except: pass # TODO for intraday strategies, make daily # convert DataFrame (assumed to have only one column) to Series pnl = calculations.calculate_returns(pnl) pnl = pnl.dropna() pnl = pnl[pnl.columns[0]] fig = pf.create_returns_tear_sheet(pnl, return_fig=True) try: plt.savefig(trading_model.DUMP_PATH + "stats.png") except: pass plt.show() elif engine == 'finmarketpy': # assume we have TradingModel # to do to take in a time series from chartpy import Canvas, Chart # temporarily make scale factor smaller so fits the window old_scale_factor = trading_model.SCALE_FACTOR trading_model.SCALE_FACTOR = 0.75 pnl = trading_model.plot_strategy_pnl( silent_plot=True) # plot the final strategy individual = trading_model.plot_strategy_group_pnl_trades( silent_plot=True) # plot the individual trade P&Ls pnl_comp = trading_model.plot_strategy_group_benchmark_pnl( silent_plot=True ) # plot all the cumulative P&Ls of each component ir_comp = trading_model.plot_strategy_group_benchmark_pnl_ir( silent_plot=True) # plot all the IR of each component leverage = trading_model.plot_strategy_leverage( silent_plot=True) # plot the leverage of the portfolio ind_lev = trading_model.plot_strategy_group_leverage( silent_plot=True) # plot all the individual leverages canvas = Canvas([[pnl, individual], [pnl_comp, ir_comp], [leverage, ind_lev]]) canvas.generate_canvas( page_title=trading_model.FINAL_STRATEGY + ' Return Statistics', silent_display=False, canvas_plotter='plain', output_filename=trading_model.FINAL_STRATEGY + ".html", render_pdf=False) trading_model.SCALE_FACTOR = old_scale_factor
df=pd.read_csv(r'C:\Users\maoheng\Desktop\高诗涛\netvalue.csv') #etf=pd.read_csv(r'\Users\hmy\Desktop\50etf.csv') #df['netvalue']=df['totalAssets']/df['initialAssets'] #df['ret']=df['totalAssets']/df['totalAssets'].shift(1)-1 #df.loc[0,'ret']=df['totalAssets'][0]/df['initialAssets'][0]-1 data=pd.DataFrame() data['Date']=df.ix[:,0] data['ret']=df['netvalueReturn'] for i in range(len(data)): data.loc[i,'newdate']=datetime.datetime.strptime(data['Date'][i], "%Y/%m/%d %H:%M:%S 000") for i in range(len(data)): data.loc[i,'newdate']=data['newdate'][i].date() data.index=data['newdate'] del(data['newdate']) del(data['Date']) data2=pd.Series(data) data2=data.iloc[:,0] data2[0]=0 data2.index.tz=pytz.timezone('Asia/Shanghai') etfdata=pd.Series() etfdata=df['benchmarkReturn'] etfdata[0]=0 etfdata.index=data2.index etfdata.index.tz=pytz.timezone('Asia/Shanghai') pf.create_returns_tear_sheet(data2,benchmark_rets=etfdata)
options_data = db.YahooApi.retrieve_options_data('GOOGL') print('done') data = pdata.get_data_yahoo(symbols='^RUT', start="01/01/2010", end="05/01/2015") returns = data['Adj Close'] / data['Adj Close'].shift(1) - 1 returns.index = returns.index.normalize() if returns.index.tzinfo is None: returns.index = returns.index.tz_localize('UTC') pyfolio.create_returns_tear_sheet(returns=returns, return_fig=True) test_options = pdata.YahooOptions('AAPL').get_all_data() plt.figure() data['Adj Close'].plot() plt.show() opener = urllib.URLopener() target = 'https://s3.amazonaws.com/static.quandl.com/tickers/SP500.csv' opener.retrieve(target, 'SP500.csv') tickers_file = pd.read_csv('SP500.csv')
# -*- coding: utf-8 -*- """ Created on Wed Oct 21 09:25:05 2015 @author: zhangchenhan """ #from pandas.io.data import DataReader from datetime import datetime from itertools import combinations from math import log import math import operator from scipy import sparse import scipy from string import punctuation import sys from time import gmtime, strftime import time import time from sklearn import metrics, preprocessing, cross_validation from sklearn import svm from sklearn.cross_validation import StratifiedKFold import sklearn.decomposition from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier, ExtraTreesClassifier from sklearn.feature_extraction import DictVectorizer from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics import mean_squared_error, f1_score, precision_score, recall_score, roc_auc_score, accuracy_score from sklearn.neighbors import RadiusNeighborsRegressor, KNeighborsRegressor import talib from talib.abstract import * from ggplot import *
# -*- coding: utf-8 -*- """ Created on Tue Mar 1 22:42:21 2016 @author: davekensinger """ import pyfolio as pf rets = pf.utils.get_symbol_rets('DIS') pf.create_returns_tear_sheet(rets[-756:])
# Plot portfolio and benchmark values analyze(results, bm_value, algo.first_rebal_idx + 1) print('End value portfolio = {:.0f}'.format(results.portfolio_value.ix[-1])) print('End value benchmark = {:.0f}'.format(bm_value[-1])) # Plot end weights pd.DataFrame(results.weights.ix[-1], index=asset_tickers, columns=['w'])\ .sort_values('w', ascending=False).plot(kind='bar', \ title='End Simulation Weights', legend=None); ############################################################################### # Sequel Step - Ex-post performance analysis ############################################################################### import pyfolio as pf returns, positions, transactions, gross_lev = pf.utils.\ extract_rets_pos_txn_from_zipline(results) trade_start = results.index[algo.first_rebal_idx + 1] trade_end = datetime(2016, 5, 31, 0, 0, 0, 0, pytz.utc) print('Annualised volatility of the portfolio = {:.4}'.\ format(pf.timeseries.annual_volatility(returns[trade_start:trade_end]))) print('Annualised volatility of the benchmark = {:.4}'.\ format(pf.timeseries.annual_volatility(bm_rets[trade_start:trade_end]))) print('') pf.create_returns_tear_sheet(returns[trade_start:trade_end], benchmark_rets=bm_rets[trade_start:trade_end], return_fig=False)
(1 + ret_df['port_cum_ret'].shift(1))) - 1).fillna(ret_df['port_cum_ret']) port_ret_df = pd.concat([port_ret_df, ret_df[['port_daily_ret']]]) ret_df = pd.DataFrame(ret_df.iloc[-1, :-2]) stock_ret_df = pd.concat([stock_ret_df, ret_df], axis=1) port_ret_df['port_cum_ret'] = (port_ret_df['port_daily_ret'] + 1).cumprod().fillna(1) - 1 port_ret_df = port_ret_df.reset_index() port_ret_df['date'] = port_ret_df['date'].map( lambda x: datetime.datetime.strptime(x, '%Y-%m-%d')) port_ret_df.set_index(port_ret_df['date'], inplace=True) port_ret_df = port_ret_df[['port_daily_ret', 'port_cum_ret']] # %% pf.create_returns_tear_sheet(port_ret_df['port_daily_ret']) # %% con = sqlite3.connect(os.path.join(data_path, 'kor_stock.db')) sql = "select * from kor_ticker" ticker = pd.read_sql(sql, con) con.close() stock_ret_df = pd.merge(stock_ret_df, ticker[['stock_cd', 'stock_nm', 'fn_sec_nm']], left_on=stock_ret_df.index, right_on='stock_cd', how='left') half_year = stock_ret_df.columns[stock_ret_df.columns.str.startswith( '2020')][0]
assets = ['FB', '^GSPC'] portfolio = pd.DataFrame() for t in assets: portfolio[t] = wb.DataReader(t, data_source='yahoo', start='2015-1-1', end='2017-12-31')['Adj Close'] set_ret = portfolio.asfreq('M', method='ffill') sec_ret = set_ret.pct_change(1) # We assume that there are 250 working days in one year. covariance = sec_ret.cov() * 250 print(covariance) marketcov = covariance.iloc[0, 1] print(marketcov) market_var = sec_ret['^GSPC'].var() * 250 print(market_var) market_beta = marketcov / market_var print(market_beta) # Expected Return Exp_ret = 0.025 + market_beta * 0.05 print(Exp_ret) # Calculation os Sharpe ratio sharpe = (Exp_ret - 0.025) / (sec_ret['FB'].std() * 250**0.5) print(sharpe) # pyfolio 보면서 공부하면 도움 될 듯. import pyfolio as pf stock_rets = pf.utils.get_symbol_rets('FB') pf.create_returns_tear_sheet(stock_rets, live_start_date='2015-12-1')
def analyze(perfdata, benchdata): returns, positions, transactions = pf.utils.extract_rets_pos_txn_from_zipline( perfdata) # pf.create_full_tear_sheet(returns, positions=positions, transactions=transactions, benchmark_rets=benchdata) pf.create_returns_tear_sheet(returns, benchmark_rets=benchdata)
### Huang, Rojas and Convery 2019 ### df = df1.copy() df = df.drop('random_strat', axis=1) df_return_out = {} df_predict_out = {} for type in ['l2']: print(type) for c in np.linspace(0, 1, 20): print(c) if c == 0 or c == 1: continue lasso_model = linear_model.LogisticRegression(penalty=type, C=c, solver='saga') lasso_out = simple_time_series_outofsample_predict(df, lasso_model, 0.7) df_lasso_in = lasso_out[0] df_lasso_out = lasso_out[1] df_lasso_tot = pd.concat([df_lasso_in, df_lasso_out]) df_lasso_tot = pd.merge(es_close, df_lasso_tot['predict'], right_index=True, left_index=True) df_lasso_tot[type + '_return'] = df_lasso_tot['pct_change'] * df_lasso_tot['predict'] df_lasso_tot[type + '_return'] = ((1 + df_lasso_tot[type + '_return']).cumprod()) - 1 df_return_out[type + '_' + str(c)] = df_lasso_tot[type + '_return'] df_predict_out[type + '_' + str(c)] = df_lasso_tot['predict'] df_return_out = pd.DataFrame.from_dict(df_return_out) df_return_out.to_csv(os.path.join(os.path.dirname(os.getcwd()), 'data', 'df_return_es_l1_l2_augmented.csv')) # df_return_out.plot() # plt.show() df_predict_out = pd.DataFrame.from_dict(df_predict_out) df_predict_out.to_csv(os.path.join(os.path.dirname(os.getcwd()), 'data', 'df_predict_es_l1_l2_augmented.csv')) series = df_predict_out[df_predict_out.columns[0]] * df['pct_change'] series.index = pd.to_datetime(series.index) pf.create_returns_tear_sheet(series)
### UKFinancial VAR(p) ##### #comboMV.to_csv("C:/Users/Paidi/CQF/Project/Oildata.csv") #Optiminal lag is 2 by Akaike Information Criterion(AIC) Stabdiff = comboMV.diff(periods=varlag, axis=0).dropna() listOfResults = [] listOfResultsResiduals = [] for col in comboMV.columns: # print combo[col] listOfResults.append(stationary_test(Stabdiff[col])) listOfResultsResiduals.append(stationary_test(residuals[col])) ######### Pyfolio ####### #Snapshot of facebook Characteristics BP = pf.utils.get_symbol_rets('BP') pf.create_returns_tear_sheet(BP, live_start_date='2016-01-01') ##### Backtesting #### bestFit = pd.read_csv("C:/Users/Paidi/CQF/Project/bestFitOilData.csv") print(bestFit) #bestFit.columns = ['~', 'bestFit'] #bestFit = bestFit['bestFit'] bestFit.columns = ['~', 'bestFit'] bestFit = bestFit['bestFit'] coef = pd.read_csv("C:/Users/Paidi/CQF/Project/coefOilData.csv") coef.columns = ['~', 'Coeff'] Coeff = coef['Coeff'] residJo = pd.read_csv("C:/Users/Paidi/CQF/Project/ResidualsJoOilData.csv")
ana_pyfolio = myBT.get_analysis("PyFolio") type(ana_pyfolio) for i in ana_pyfolio.keys(): print(ana_pyfolio[i]) ana_pyfolio["returns"] ana_pyfolio["positions"] ana_pyfolio["transactions"] ana_pyfolio["gross_lev"] #%% # 访问 PyFolio 分析器 (推荐的),由于 pyfolio 默认使用的是美国东部时间,所以需要转换成utc时区。 returns, positions, transactions, gross_lev = myBT.get_pyfolio_analysis( utc=False) type(returns) returns.index #%% import pyfolio as pf # ?不知道为什么不行!!!!!! pf.create_full_tear_sheet(returns, positions=positions, transactions=transactions, benchmark_rets=returns, round_trips=True) pf.create_returns_tear_sheet(returns, benchmark_rets=benchmark_rets, live_start_date=live_start_date) plt.show() myBT.cerebro.plot(iplot=False)
date_string = str(item['Tarih']).split('T')[0] my_date = datetime.strptime(date_string, '%Y-%m-%d') portfolio.ix[i, 'Price'] = item['BirimPayDegeri'] backtrack.ix[my_date, 'MarketValue'] += portfolio.ix[ i, 'Number'] * portfolio.ix[i, 'Price'] backtrack.ix[my_date, 'Cost'] += money_for_stock back_date = my_date - timedelta(days=1) while (backtrack.ix[back_date, 'MarketValue'] == 0): back_date = back_date - timedelta(days=1) backtrack.ix[my_date, 'ReturnSeries'] = ( backtrack.ix[my_date, 'MarketValue'] / (backtrack.ix[back_date, 'MarketValue'] + (backtrack.ix[my_date, 'Cost'] - backtrack.ix[back_date, 'Cost'])) ) - 1 #Doing the montly investment. if (my_date.month != stock_month): money_for_stock += monthly_money * code_list_perc[i] stock_month += 1 if stock_month == 13: stock_month = 1 portfolio.ix[i, 'Number'] += ( monthly_money * code_list_perc[i]) / item['BirimPayDegeri'] #Increasing i for the next stocks percentage. i += 1 backtrack = backtrack[backtrack.MarketValue != 0] plt.plot(backtrack['ReturnSeries']) plt.savefig('x.png') new = backtrack['ReturnSeries'] new = new.tz_localize('utc') print new print pf.create_returns_tear_sheet(new)
def analyze(context, perf): returns, positions, transactions = pf.utils.extract_rets_pos_txn_from_zipline( perf) pf.create_returns_tear_sheet(returns, benchmark_rets=None, return_fig=True) plt.savefig('backtest_macd.png')