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): """ 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] 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): # 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) 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): """ 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
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): """ 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): """ 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): #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): """ 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. """ 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. :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, 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. """ 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): """ 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 _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
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()