def _plot_txt_curve(self, stats): """ Output the statistics for the equity curve """ returns = stats["returns"] cum_returns = stats['cum_returns'] 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) 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) header = ["Performance", "Value"] rows = [["Total Return", "{:.0%}".format(tot_ret)], ["CAGR", "{:.2%}".format(cagr)], ["Sharpe Ratio", "{:.2f}".format(sharpe)], ["Sortino Ratio", "{:.2f}".format(sortino)], [ "Annual Volatility", "{:.2%}".format(returns.std() * np.sqrt(252)) ], ["R-Squared", '{:.2f}'.format(rsq)], ["Max Daily Drawdown", '{:.2%}'.format(dd_max)], ["Max Drawdown Duration", '{:.0f}'.format(dd_dur)], ["Trades per Year", '{:.1f}'.format(trd_yr)]] table = (Table().add(header, rows).set_global_opts( title_opts=opts.ComponentTitleOpts(title="Curve"))) return table
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'] 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, 'Total Return', fontsize=8) ax.text(7.50, 8.9, '{:.0%}'.format(tot_ret), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 7.9, 'CAGR', fontsize=8) ax.text(7.50, 7.9, '{:.2%}'.format(cagr), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 6.9, 'Sharpe Ratio', fontsize=8) ax.text(7.50, 6.9, '{:.2f}'.format(sharpe), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(0.25, 5.9, 'Sortino Ratio', fontsize=8) ax.text(7.50, 5.9, '{:.2f}'.format(sortino), 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.text(0.25, 0.9, 'Trades per Year', fontsize=8) ax.text(7.50, 0.9, '{:.1f}'.format(trd_yr), fontweight='bold', horizontalalignment='right', fontsize=8) 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=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, '{:.2f}'.format(sortino_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 4.9, '{:.2%}'.format(returns_b.std() * np.sqrt(252)), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 3.9, '{:.2f}'.format(rsq_b), fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 2.9, '{:.2%}'.format(dd_max_b), color='red', fontweight='bold', horizontalalignment='right', fontsize=8) ax.text(9.75, 1.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