def get_results(self): for ticker in self.portfolio.positions: daily_return = pd.DataFrame(self.portfolio.positions[ticker].log)["price"].astype(float).pct_change().fillna(0.0) cum_return = np.exp(np.log(1+daily_return).cumsum()) drawdown,max_drawdown,drawdown_duration = perf.create_drawdowns(cum_return) statistics = {} statistics["sharpe"] = perf.create_sharpe_ratio(daily_return,self.periods) statistics["drawdowns"] = drawdown statistics["max_drawdown"] = max_drawdown statistics["max_drawdown_pct"] = max_drawdown statistics["max_drawdown_duration"] = drawdown_duration statistics["daily_returns"] = daily_return statistics["cum_returns"] = cum_return statistics["date"] = pd.DataFrame(self.portfolio.positions[ticker].log)["date"] self.constituents[ticker] = statistics if self.benchmark is not None: "Need to change the benchamrk here" daily_return_b = pd.DataFrame(self.portfolio.positions[ticker].log)["price"].astype(float).pct_change().fillna(0.0) cum_returns_b = np.exp(np.log(1 + daily_return_b).cumsum()) dd_b, max_dd_b, dd_dur_b = perf.create_drawdowns(cum_returns_b) statistics["sharpe_b"] = perf.create_sharpe_ratio(returns_b) statistics["drawdowns_b"] = dd_b statistics["max_drawdown_pct_b"] = max_dd_b statistics["max_drawdown_duration_b"] = dd_dur_b statistics["security_b"] = security_b statistics["returns_b"] = returns_b statistics["rolling_sharpe_b"] = rolling_sharpe_b statistics["cum_returns_b"] = cum_returns_b self.constituents[ticker] = statistics
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio Outputs: equity.csv Can be loaded into a Matplotlib script, or spreadsheet software for analysis """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns, period=252*60*6.5) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % \ ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] # Days, hours, minutes or seconds if self.periods == "D": periods = 252 elif self.periods == "H": periods = 252 * 6.5 elif self.periods == "M": periods = 252 * 6.5 * 60 elif self.periods == "S": periods = 252 * 6.5 * 60 * 60 cagr = create_cagr(pnl, periods=periods) sharpe_ratio = create_sharpe_ratio(returns, periods=periods) drawdown, max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("CAGR", "%0.2f%%" % (cagr * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve["drawdown"] = drawdown # Output equity curve statistics self.equity_curve.to_csv("equity.csv") return stats
def output_summary_stats(self): """ Calulate states(total_return, sharpe_ratio, max_drawdown, max_duration). :return: list; summary data. """ total_return=self.equity_curve['equity_curve'][-1] returns=self.equity_curve['returns'] pnl=self.equity_curve['equity_curve'] sharpe_ratio=create_sharpe_ratio(returns,periods=252*60*6.5) drawdown,max_dd,max_duration=create_drawdowns(pnl) self.equity_curve['drawdown']=drawdown stats=[("Total Return","%0.2f%%"%((total_return-1.0)*100.0)), ("Sharpe Ratio","%0.2f%%"%sharpe_ratio), ("Max Drawdown","%0.2f%%"%(max_dd*100.0)), ("Drawdown Duration","%d"%max_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['return'] pnl = self.equity_curve['equity_curve'] # periods = 252 * 60 * 6.5 earn_rate_year = (1 + np.mean(returns))**252 - 1 print("平均年化收益率:", earn_rate_year) sharpe_ratio = create_sharpe_ratio(returns, periods=252) max_dd, dd_duration = create_drawdowns(pnl) # drawdown, max_dd, dd_duration = create_drawdowns(pnl) # # self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Avg Year Return", "%0.2f%%" % (earn_rate_year * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f" % (max_dd)), ("Drawdown Duration", "%d" % dd_duration)] filesavepath = os.path.join(self.savepath, 'equity.csv') self.equity_curve.to_csv(filesavepath, index=False) # 绘制累计日收益率曲线 self.plot_equity_curve() return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] # Days, hours, minutes or seconds if self.periods == "D": periods = 252 elif self.periods == "H": periods = 252*6.5 elif self.periods == "M": periods = 252*6.5*60 elif self.periods == "S": periods = 252*6.5*60*60 cagr = create_cagr(pnl, periods=periods) sharpe_ratio = create_sharpe_ratio(returns, periods=periods) drawdown, max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("CAGR", "%0.2f%%" % (cagr * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve["drawdown"] = drawdown # Output equity curve statistics self.equity_curve.to_csv("equity.csv") return stats
def output_summary_stats(self): total_return = self.equity_curve['equity_curve'][-1] drawdown, duration = create_drawdowns( self.equity_curve['equity_curve']) return [('Total return', (total_return - 1) * 100), ('Sharpe ratio', create_sharpe_ratio(self.equity_curve['returns'])), ('Max drawdown', drawdown * 100), ('Drawdown duration', duration)]
def output_summary_stats(self): total_return=self.equity_curve['equity_curve'][-1] returns=self.equity_curve['returns'] pnl=self.equity_curve['equity_curve'] sharpe_ratio=create_sharpe_ratio(returns) max_dd,dd_duration=create_drawdowns(pnl) stats=[("Total Return","%0.2f%%" % ((total_return-1.0)*1000.0)),("Sharpe Ratio", "%0.2f" % sharpe_ratio),("Max Drawdown", "%0.2f%%" % (max_dd*100.0)),("Drawdown Duration", "%d" % dd_duration)] plt.clf() plt.plot(self.equity_curve.index,pnl) plt.savefig('cumulative_return') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1)*100)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd*100.0)), ("Drawdown Duration", "%d" %dd_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_summary_stats(self): total_return=self.equity_curve['equity_curve'][-1] returns=self.equity_curve['returns'] pnl=self.equity_curve['equity_curve'] sharpe_ratio=create_sharpe_ratio(returns) max_dd,dd_duration=create_drawdowns(pnl) stats=[("total return","%0.2f%%"%((total_return-1.0)*100.0)), ("sharpe ratio","%0.2f"%sharpe_ratio), ("Max Drawdown","%0.2f%%"%(max_dd*100)), ("Drawdown duration","%d"%dd_duration)] return stats
def output_summary_stats(self): total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 1000.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] plt.clf() plt.plot(self.equity_curve.index, pnl) plt.savefig('cumulative_return') return stats
def output_summary_stats(self): # creates a list of summary statistics for the portfolio (ie. sharpie and markdown info) total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] return stats
def output_summary_stats(self): equity_curve = self.create_equity_curve_df() 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) stats = [('Total Return', '%0.2f%%' % ((total_return - 1.0) * 100.0)), ('sharpe Ratio', '%0.2f' % sharpe_ratio), ('Max Drawdown', '%0.2f%%' % (max_dd * 100.0)), ('Drawdown Duration', '%s' % dd_duration)] return stats
def output_summary_stats(self): """ Создает список статистических показателей для портфолио — коэффициент Шарпа и данные по просадке. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] return stats
def output_summary_stats(self): """ 统计夏普率, 回测等信息。 """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] return stats
def output_summary_stats(self): total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_summary_stats(self, frequency = 252): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns, periods=frequency) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown self.equity_curve['drawdown'][0] = 0.0 stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv('EquityCurve.csv') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio such as Sharpe Ratio and drawdown information. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_cure['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_dd, dd_duration = create_drawdowns(pnl) stats = [("Total Return: %0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio: %0.2f" % sharpe_ratio), ("Max Drawdown: %0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration: %d" % dd_duration)] return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns, periods=252) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return: {:.2f}%".format((total_return - 1) * 100)), ("Sharpe Ratio: {:.2f} ".format(sharpe_ratio)), ("Max Drawdown: {:.2f}%".format(max_dd * 100)), ("Drawdown Duration: {:.2f}".format(dd_duration))] # self.equity_curve.to_csv("equity.csv") return stats
def output_summary_stats(self): #Returns a list of tuples self.equity_curve = self.create_equity_curve() total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] equity_curve = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) max_drawdown, duration = create_drawdowns(self.equity_curve) stats = [('Total Return', '{}'.format((total_return - 1) * 100)), ('Sharpe Ratio', '{}'.format(sharpe_ratio)), ('Max Drawdown', '{}'.format(max_drawdown)), ('Drawdown Duration', '{}'.format(duration))] return stats
def output_summary_stats(self): total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] print(total_return, returns, pnl) sharpe_ratio = create_sharpe_ratio(returns, periods=252 * 60 * 6.5) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [('Total Return', '%0.2f%%' % ((total_return - 1.0) * 100.0)), ('Sharpe Ratio', '%0.2f' % sharpe_ratio), ('Max Drawdown', '%0.2f%%' % (max_dd * 100.0)), ('Drawdown Duration', '%d' % dd_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_summary_stats(self, filename): """ Statistiche create per il portfolio """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns, periods=252) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % \ ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f%%" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%f" % dd_duration)] self.equity_curve.to_csv(filename) return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve["equity_curve"][-1] returns = self.equity_curve["returns"] pnl = self.equity_curve["equity_curve"] sharpe_ratio = create_sharpe_ratio(returns, periods=252) #*60*6.5) # здесь похоже не верно считал, так как все же мы статистику ведём пока по дням, а не по часам drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve["drawdown"] = drawdown stats = [("Total Return", "%0.2f%%" % \ ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv("equity.csv") draw(self.equity_curve['equity_curve']) # TODO Здесь рисует график. В идеале перенести его нужно по результатам выполнения бэктестинга return stats
def output_summary_stats(self): #用performance的两个方程算sharp ratio/drawdown """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns, periods=252 * 60 * 6.5) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown trades_avg_duration = floor( self.trades['duration'].mean().total_seconds() / 60) trades_avg_return = self.trades['returns'].mean() * 100 trades_total_win = self.trades['win_trades'].sum() trades_total_loss = self.trades['loss_trades'].sum() trades_win_loss_ratio = trades_total_win / trades_total_loss total_trades = len(self.trades) trades_win_pct = trades_total_win / total_trades * 100 trades_loss_pct = trades_total_loss / total_trades * 100 stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Avg Return (%)", trades_avg_return), ("Avg Trade Duration (min)", trades_avg_duration), ("Total win trades", trades_total_win), ("Total loss trades", trades_total_loss), ("Win/Loss Ratio", trades_win_loss_ratio), ("% Wins", trades_win_pct), ("% Losses", trades_loss_pct), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] dir_path = f'{Path().absolute()}/backtest_results' self.equity_curve.to_csv(f'{dir_path}/equity.csv') self.trades.to_csv(f'{dir_path}/trades.csv') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio This method outputs the equity curve and varioys performance statistics related to the strategy. The final line ouputs a file, equity.csv, to the same directory as the code, whcih can be loaded into a Matplotlib Python script for subsequent analysis. Note: The drawdown duration is given in terms of the absolute number of "bars" that teh drawdown carried on for, as opposed to a particular timeframe. Returns ------- 'list' Returns a list of stats relating to portfolio performance """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio( returns, periods=252) # For Minute level bars: periods=252*6.5*60 drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % ((total_return - 1) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv('equity.csv') return stats
def output_results(self): # Chiusura del file csv del backtest.csv cosiì da poter # essere caricato con Pandas senza errori self.backtest_file.close() in_filename = "backtest.csv" out_filename = "equity.csv" in_file = os.path.join(OUTPUT_RESULTS_DIR, in_filename) out_file = os.path.join(OUTPUT_RESULTS_DIR, out_filename) # Crea il dataframe della curva di equity df = pd.read_csv(in_file, index_col=0) df.dropna(inplace=True) df["Total"] = df.sum(axis=1) df["Returns"] = df["Total"].pct_change() df["Equity"] = (1.0 + df["Returns"]).cumprod() # Crea le statistiche di drawdown drawdown, max_dd, dd_duration = create_drawdowns(df["Equity"]) df["Drawdown"] = drawdown df.to_csv(out_file, index=True) print("Simulation complete and results exported to %s" % out_filename)
def output_results(self): # Closes off the Backtest.csv file so it can be # read via Pandas without problems self.backtest_file.close() in_filename = "backtest.csv" out_filename = "equity.csv" in_file = os.path.join(OUTPUT_RESULTS_DIR, in_filename) out_file = os.path.join(OUTPUT_RESULTS_DIR, out_filename) # Create equity curve dataframe df = pd.read_csv(in_file, index_col=0) df.dropna(inplace=True) df["Total"] = df.sum(axis=1) df["Returns"] = df["Total"].pct_change() df["Equity"] = (1.0+df["Returns"]).cumprod() # Create drawdown statistics drawdown, max_dd, dd_duration = create_drawdowns(df["Equity"]) df["Drawdown"] = drawdown df.to_csv(out_file, index=True) print("Simulation complete and results exported to %s" % out_filename)
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown if len(dd_duration) == 1: dd_duration = dd_duration[0] stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%s" % dd_duration)] self.equity_curve.to_csv('equity.csv') self.positions.to_csv('positions.csv') self.prices.to_csv('prices.csv') return stats
def output_summary_stats(self, strategy_title): ''' Creates a list of summary statistics for the portfolio. ''' total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio( returns, periods=252) # i guess this is for minute resolution drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [ 'Total Return', '%0.2f%%' % ((total_return - 1.0) * 100.0), ('Sharpe Ratio', '%0.2f' % sharpe_ratio), ('Max Drawdown', '%0.2f%%' % (max_dd * 100.0)), ('Drawdown Duration', '%d' % dd_duration) ] self.equity_curve.to_csv('equity.csv') self.print_chart(max_dd, dd_duration, total_return, sharpe_ratio, strategy_title) return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. :return: """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] # self.equity_curve.to_csv("prac_equity_curve.csv") # pd.DataFrame(self.all_positions).to_csv("prac_position.csv") sharpe_ratio = create_sharpe_ratio(returns, periods='minutely') drawdown, max_dd, max_dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [('Total_Return', "%0.2f%%" % ((total_return - 1.0) * 100.0)), ('Sharpe_Ratio', "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Max Drawdown Dur.", "%d" % max_dd_duration)] self.equity_curve.to_csv('equity_curve.csv') # pnl.plot() # plt.show() return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve['equity_curve'][-1] returns = self.equity_curve['returns'] pnl = self.equity_curve['equity_curve'] sharpe_ratio = create_sharpe_ratio(returns, periods=252*60*6.5) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve['drawdown'] = drawdown stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] output = {'Total Return': "%0.2f%%" % ((total_return - 1.0) * 100.0), 'Sharpe Ratio': "%0.2f" % sharpe_ratio, 'Max Drawdown': "%0.2f%%" % (max_dd * 100.0), 'Drawdown Duration': dd_duration} df = pd.Series(output).to_frame() df.columns = ['value'] df.to_csv('output.csv', index_label='parameter') self.equity_curve.to_csv('../equity.csv') return stats
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve[’equity_curve’][-1] returns = self.equity_curve[’returns’] pnl = self.equity_curve[’equity_curve’] sharpe_ratio = create_sharpe_ratio(returns, periods=252*60*6.5) drawdown, max_dd, dd_duration = create_drawdowns(pnl) self.equity_curve[’drawdown’] = drawdown stats = [("Total Return", "%0.2f%%" % \ ((total_return - 1.0) * 100.0)), ("Sharpe Ratio", "%0.2f" % sharpe_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration)] self.equity_curve.to_csv('eqiuity.csv') return stats
periods = 252 # Adjust lookback period from 50 to 200 in increments # of 10 in order to produce sensitivities for lb in lookbacks: print "Calculating lookback=%s..." % lb pairs = create_pairs_dataframe(datadir, symbols) pairs = calculate_spread_zscore(pairs, symbols, lookback=lb) pairs = create_long_short_market_signals(pairs, symbols, z_entry_threshold=2.0, z_exit_threshold=1.0) portfolio = create_portfolio_returns(pairs, symbols) returns.append(portfolio.ix[-1]['cum_returns']) sharps.append(create_sharpe_ratio(portfolio['returns'])) drawdown, max_dd, dd_duration = create_drawdowns(portfolio['cum_returns']) draw_downs.append(max_dd) df = pd.DataFrame(lookbacks) df.columns = ['LookBack'] df['Returns'] = returns df['Sharps'] = sharps df['Max Draw Down'] = draw_downs print df print "Plot the lookback-performance scatterchart..." plt.plot(lookbacks, returns, '-o') plt.show()
def output_summary_stats(self): """ Creates a list of summary statistics for the portfolio. """ total_return = self.equity_curve["equity_curve"][-1] returns = self.equity_curve["returns"] pnl = self.equity_curve["equity_curve"] periods = self.equity_curve.shape[0] start_date = self.equity_curve.index[ 1] #注意,一般來說應該要是[0],選擇[1]是因為資料不足一年以上 end_date = self.equity_curve.index[-1] time_delta_days = (end_date - start_date).days cmd_list = ["TXFC2", "TXFD1", "TXFE1", "TXFL1"] #先寫死,之後再改成讀入 win = 0 #賺錢次數 lose = 0 #賠錢次數 entry_amount = 0 #進場金額 out_amount = 0 #出場金額 record_amount = {} record_amount["entry_amount"] = [] record_amount["out_amount"] = [] record_amount["profit"] = [] record_amount["loss"] = [] for commodity in cmd_list: for j in range(0, len(self.equity_curve[commodity]) - 1): if ((self.equity_curve[commodity][j + 1] > self.equity_curve[commodity][j]) and self.equity_curve[commodity][j] == 0): entry_amount = self.equity_curve[commodity][j + 1] record_amount["entry_amount"].append(entry_amount) if (self.equity_curve[commodity][j] != 0 and self.equity_curve[commodity][j + 1] == 0): out_amount = self.equity_curve[commodity][j] record_amount["out_amount"].append(out_amount) for i in range(0, len(record_amount["out_amount"])): profit = record_amount["out_amount"][i] - record_amount[ "entry_amount"][i] if profit > 0: win = win + 1 record_amount["profit"].append(profit) elif profit <= 0: lose = lose + 1 record_amount["loss"].append(profit) win_rate = win / (win + lose) #勝率 #賺賠比 = gross profit / gross loss profit_factor = (-1) * sum(record_amount["profit"]) / sum( record_amount["loss"]) #CAGR = (初始價值/結束價值)**(1/年化期數)-1 CAGR = (self.equity_curve["total"][-1] / self.equity_curve["total"][0])**(1 / (time_delta_days / 252)) - 1 yearly_sharpe_ratio, minutely_sharpe_ratio = create_sharpe_ratio( returns, periods) yearly_sortino_ratio, minutely_sortino_ratio = create_sortino_ratio( returns, periods) minutely_skewness = create_skewness(returns, periods) minutely_kurtosis = create_kurtosis(returns, periods) drawdown, max_dd, dd_duration = create_drawdowns(pnl) minutely_calmar_ratio = create_calmar_ratio(returns, periods, max_dd) self.equity_curve["drawdown"] = drawdown stats = [ "Start Date:" + str(start_date), "End Date:" + str(end_date), ("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), ("Minutely Sharpe Ratio", "%0.4f" % minutely_sharpe_ratio), ("Minutely Sortino Ratio", "%0.4f" % minutely_sortino_ratio), ("Minutely Skewness", "%0.3f" % minutely_skewness), ("Minutely Kurtosis", "%0.3f" % minutely_kurtosis), ("Minutely Calmar Ratio", "%0.6f" % minutely_calmar_ratio), ("CAGR", "%0.5f%%" % (CAGR * 100.0)), ("Yearly Sharpe Ratio", "%0.2f" % yearly_sharpe_ratio), ("Yearly Sortino Ratio", "%0.2f" % yearly_sortino_ratio), ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), ("Drawdown Duration", "%d" % dd_duration), ("Win Rate", "%0.2f" % win_rate), ("Profit Factor", "%0.2f" % profit_factor) ] self.equity_curve.to_csv('equity.csv') return stats
def get_results(self): """ Return a dict with all important results & stats. """ # Equity # equity_s = pd.Series(self.equity).sort_index() # Returns # returns_s = equity_s.pct_change().fillna(0.0) bench = pd.read_pickle(self.benchmark) rets = pd.concat([bench.loc[self.equity.index[0]:self.equity.index[-1]], self.equity.rename("equity")], axis=1).fillna(0.0) # returns_s=self.equity.sort_index().fillna(0.0) returns_s = rets['equity'] # Rolling Annualised Sharpe rolling = returns_s.rolling(window=self.periods) rolling_sharpe_s = np.sqrt(self.periods) * ( rolling.mean() / rolling.std() ) # Cummulative Returns cum_returns_s = np.exp(np.log(1 + returns_s).cumsum()) # Drawdown, max drawdown, max drawdown duration dd_s, max_dd, dd_dur = perf.create_drawdowns(cum_returns_s) statistics = {} # Equity statistics statistics["sharpe"] = perf.create_sharpe_ratio( returns_s, self.periods ) statistics["drawdowns"] = dd_s # TODO: need to have max_drawdown so it can be printed at end of test statistics["max_drawdown"] = max_dd statistics["max_drawdown_pct"] = max_dd statistics["max_drawdown_duration"] = dd_dur # statistics["equity"] = equity_s statistics["returns"] = returns_s statistics["rolling_sharpe"] = rolling_sharpe_s statistics["cum_returns"] = cum_returns_s # positions = self._get_positions() # if positions is not None: # statistics["positions"] = positions # Benchmark statistics if benchmark ticker specified # if self.benchmark is not None: # equity_b = pd.Series(self.equity_benchmark).sort_index() # returns_b = equity_b.pct_change().fillna(0.0) # returns_b=self.equity_benchmark.sort_index().fillna(0.0) returns_b = rets['rets'] rolling_b = returns_b.rolling(window=self.periods) rolling_sharpe_b = np.sqrt(self.periods) * ( rolling_b.mean() / rolling_b.std() ) cum_returns_b = np.exp(np.log(1 + returns_b).cumsum()) dd_b, max_dd_b, dd_dur_b = perf.create_drawdowns(cum_returns_b) statistics["sharpe_b"] = perf.create_sharpe_ratio(returns_b) statistics["drawdowns_b"] = dd_b statistics["max_drawdown_pct_b"] = max_dd_b statistics["max_drawdown_duration_b"] = dd_dur_b # statistics["equity_b"] = equity_b statistics["returns_b"] = returns_b statistics["rolling_sharpe_b"] = rolling_sharpe_b statistics["cum_returns_b"] = cum_returns_b alphas = rets['equity'] - rets['rets'] statistics["IR"] = np.mean(alphas) / np.std(alphas) return statistics
def _plot_txt_curve(self, stats, ax=None, **kwargs): """ Outputs the statistics for the equity curve. """ def format_perc(x, pos): return '%.0f%%' % x returns = stats["returns"] cum_returns = stats['cum_returns'] IR=stats['IR'] # if 'positions' not in stats: # trd_yr = 0 # else: # positions = stats['positions'] # trd_yr = positions.shape[0] / ( # (returns.index[-1] - returns.index[0]).days / 365.0 # ) if ax is None: ax = plt.gca() y_axis_formatter = FuncFormatter(format_perc) ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter)) tot_ret = cum_returns[-1] - 1.0 cagr = perf.create_cagr(cum_returns, self.periods) sharpe = perf.create_sharpe_ratio(returns, self.periods) sortino = perf.create_sortino_ratio(returns, self.periods) rsq = perf.rsquared(range(cum_returns.shape[0]), cum_returns) dd, dd_max, dd_dur = perf.create_drawdowns(cum_returns) ax.text(0.25, 8.9, '总收益率', fontsize=30) ax.text(7.50, 8.9, '{:.0%}'.format( tot_ret), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 7.9, '复合年均增长率', fontsize=30) ax.text(7.50, 7.9, '{:.2%}'.format( cagr), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 6.9, '夏普比率', fontsize=30) ax.text(7.50, 6.9, '{:.2f}'.format( sharpe), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 5.9, '索提诺比率', fontsize=30) ax.text(7.50, 5.9, '{:.2f}'.format( sortino), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 4.9, '年化波动率', fontsize=30) ax.text(7.50, 4.9, '{:.2%}'.format(returns.std() * np.sqrt(252)), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 3.9, 'R-Squared', fontsize=30) ax.text(7.50, 3.9, '{:.2f}'.format( rsq), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 2.9, '最大日回撤', fontsize=30) ax.text(7.50, 2.9, '{:.2%}'.format(dd_max), color='red', fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 1.9, '最大回撤持续期', fontsize=30) ax.text(7.50, 1.9, '{:.0f}'.format( dd_dur), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(0.25, 0.9, '信息比率', fontsize=30) ax.text(7.50, 0.9, '{:.2%}'.format( IR), fontweight='bold', horizontalalignment='right', fontsize=30) ax.set_title('Curve', fontweight='bold') if self.benchmark is not None: returns_b = stats['returns_b'] equity_b = stats['cum_returns_b'] tot_ret_b = equity_b[-1] - 1.0 cagr_b = perf.create_cagr(equity_b) sharpe_b = perf.create_sharpe_ratio(returns_b) sortino_b = perf.create_sortino_ratio(returns_b) rsq_b = perf.rsquared(range(equity_b.shape[0]), equity_b) dd_b, dd_max_b, dd_dur_b = perf.create_drawdowns(equity_b) ax.text(9.75, 8.9, '{:.0%}'.format( tot_ret_b), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 7.9, '{:.2%}'.format( cagr_b), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 6.9, '{:.2f}'.format( sharpe_b), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 5.9, '{:.2f}'.format( sortino_b), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 4.9, '{:.2%}'.format(returns_b.std( ) * np.sqrt(252)), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 3.9, '{:.2f}'.format( rsq_b), fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 2.9, '{:.2%}'.format(dd_max_b), color='red', fontweight='bold', horizontalalignment='right', fontsize=30) ax.text(9.75, 1.9, '{:.0f}'.format( dd_dur_b), fontweight='bold', horizontalalignment='right', fontsize=30) ax.set_title('策略 vs. 基准', fontweight='bold',size='xx-large') ax.grid(False) ax.spines['top'].set_linewidth(2.0) ax.spines['bottom'].set_linewidth(2.0) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False) ax.get_yaxis().set_visible(False) ax.get_xaxis().set_visible(False) ax.set_ylabel('') ax.set_xlabel('') ax.axis([0, 10, 0, 10]) return ax
def _plot_txt_curve(self, stats, ax=None, **kwargs): """ Outputs the statistics for the security curve. """ def format_perc(x, pos): return '%.0f%%' % x stats = pd.DataFrame(stats) stats['date']=pd.to_datetime(stats['date']) stats.set_index('date',inplace=True) returns = stats["daily_returns"] cum_returns = stats['cum_returns'] y_axis_formatter = FuncFormatter(format_perc) ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter)) tot_ret = cum_returns[-1] - 1.0 cagr = perf.create_cagr(cum_returns, self.periods) sharpe = perf.create_sharpe_ratio(returns, self.periods) rsq = perf.rsuqare(range(cum_returns.shape[0]), cum_returns) dd, dd_max, dd_dur = perf.create_drawdowns(cum_returns) ax.text(0.25, 7.9, 'Total Return', fontsize=8) ax.text(7.50, 7.9, '{:.0%}'.format(tot_ret), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 6.9, 'CAGR', fontsize=8) ax.text(7.50, 6.9, '{:.2%}'.format(cagr), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 5.9, 'Sharpe Ratio', fontsize=8) ax.text(7.50, 5.9, '{:.2f}'.format(sharpe), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 4.9, 'Annual Volatility', fontsize=8) ax.text(7.50, 4.9, '{:.2%}'.format(returns.std() * np.sqrt(252)), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 3.9, 'R-Squared', fontsize=8) ax.text(7.50, 3.9, '{:.2f}'.format(rsq), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 2.9, 'Max Daily Drawdown', fontsize=8) ax.text(7.50, 2.9, '{:.2%}'.format(dd_max), color='red', fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 1.9, 'Max Drawdown Duration', fontsize=8) ax.text(7.50, 1.9, '{:.0f}'.format(dd_dur), fontweight='bold', horizontalalignment='right', fontsize=8) ax.set_title('Curve', fontweight='bold') if self.benchmark is not None: returns_b = stats['returns_b'] security_b = stats['cum_returns_b'] tot_ret_b = security_b[-1] - 1.0 cagr_b = perf.create_cagr(security_b) sharpe_b = perf.create_sharpe_ratio(returns_b) rsq_b = perf.rsquared(range(security_b.shape[0]), security_b) dd_b, dd_max_b, dd_dur_b = perf.create_drawdowns(security_b) ax.text(9.75, 8.9, '{:.0%}'.format(tot_ret_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 7.9, '{:.2%}'.format(cagr_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 6.9, '{:.2f}'.format(sharpe_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 5.9, '{:.2%}'.format(returns_b.std() * np.sqrt(252)), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 4.9, '{:.2f}'.format(rsq_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 3.9, '{:.2%}'.format(dd_max_b), color='red', fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 2.9, '{:.0f}'.format(dd_dur_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.set_title('Curve vs. Benchmark', fontweight='bold') ax.grid(False) ax.spines['top'].set_linewidth(2.0) ax.spines['bottom'].set_linewidth(2.0) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False) ax.get_yaxis().set_visible(False) ax.get_xaxis().set_visible(False) ax.set_ylabel('') ax.set_xlabel('') ax.axis([0, 10, 0, 10]) return ax