Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
milliseconds since epoch representation.
Parameters
----------
curve : `pd.DataFrame`
The equity curve DataFrame.
Returns
-------
`dict`
The statistics dictionary.
"""
stats = {}
# Drawdown, max drawdown, max drawdown duration
dd_s, max_dd, dd_dur = perf.create_drawdowns(curve['CumReturns'])
# Equity curve and returns
stats['equity_curve'] = JSONStatistics._series_to_tuple_list(curve['Equity'])
stats['returns'] = JSONStatistics._series_to_tuple_list(curve['Returns'])
stats['cum_returns'] = JSONStatistics._series_to_tuple_list(curve['CumReturns'])
# Drawdown statistics
stats['drawdowns'] = JSONStatistics._series_to_tuple_list(dd_s)
stats['max_drawdown'] = max_dd
stats['max_drawdown_duration'] = dd_dur
# Performance
stats['cagr'] = perf.create_cagr(curve['CumReturns'], self.periods)
stats['annualised_vol'] = curve['Returns'].std() * np.sqrt(self.periods)
stats['sharpe'] = perf.create_sharpe_ratio(curve['Returns'], self.periods)
stats['sortino'] = perf.create_sortino_ratio(curve['Returns'], self.periods)
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)
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)
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
return statistics
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)