Analyzers & Reports¶
Analyzers are essential tools for evaluating strategy performance. Backtrader provides 17+ built-in analyzers and supports custom analyzers for specialized metrics.
Quick Start¶
cerebro = bt.Cerebro()
# Add analyzers
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
cerebro.addanalyzer(bt.analyzers.SQN, _name='sqn')
# Run backtest
results = cerebro.run()
strat = results[0]
# Get results
print(f"Sharpe: {strat.analyzers.sharpe.get_analysis().get('sharperatio', 'N/A')}")
print(f"Max DD: {strat.analyzers.drawdown.get_analysis()['max']['drawdown']:.2f}%")
print(f"SQN: {strat.analyzers.sqn.get_analysis()['sqn']:.2f}")
Built-in Analyzers¶
Analyzer |
Purpose |
|---|---|
SharpeRatio |
Risk-adjusted returns |
DrawDown |
Maximum drawdown analysis |
TradeAnalyzer |
Comprehensive trade statistics |
Returns |
Return calculations |
SQN |
System Quality Number |
Calmar |
Calmar ratio (return/max DD) |
VWR |
Variability-Weighted Return |
TimeReturn |
Period-based returns |
AnnualReturn |
Yearly return breakdown |
Transactions |
All transaction details |
PeriodStats |
Statistical metrics by period |
PositionsValue |
Position value tracking |
PyFolio |
pyfolio-compatible output |
Common Analyzers¶
DrawDown¶
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='dd')
# Access results
dd = strat.analyzers.dd.get_analysis()
print(f"Max Drawdown: {dd.max.drawdown:.2f}%")
print(f"Max Duration: {dd.max.len} bars")
TradeAnalyzer¶
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='ta')
ta = strat.analyzers.ta.get_analysis()
print(f"Total Trades: {ta.total.total}")
print(f"Won: {ta.won.total}")
print(f"Lost: {ta.lost.total}")
print(f"Win Rate: {ta.won.total / ta.total.total:.2%}")
Creating Custom Analyzers¶
class MyAnalyzer(bt.Analyzer):
def __init__(self):
self.trades = []
self.equity_curve = []
def notify_trade(self, trade):
if trade.isclosed:
self.trades.append({
'pnl': trade.pnl,
'pnlcomm': trade.pnlcomm,
'barlen': trade.barlen,
})
def next(self):
self.equity_curve.append(self._owner.broker.getvalue())
def stop(self):
# Calculate final metrics
if self.trades:
pnls = [t['pnl'] for t in self.trades]
self.rets['total_pnl'] = sum(pnls)
self.rets['avg_pnl'] = sum(pnls) / len(pnls)
self.rets['num_trades'] = len(self.trades)
self.rets['equity_curve'] = self.equity_curve
def get_analysis(self):
return self.rets
Professional Reports¶
Backtrader can generate comprehensive HTML reports with a single command.
One-Click Report¶
# Add report analyzers
cerebro.add_report_analyzers(riskfree_rate=0.02)
# Run backtest
results = cerebro.run()
# Generate HTML report
cerebro.generate_report(
filename='backtest_report.html',
user='Trader Name',
memo='SMA Crossover Strategy Analysis',
strategy_name='SMA Cross'
)
Report Contents¶
The generated report includes:
Summary Statistics: Total return, Sharpe ratio, Calmar ratio, SQN
Equity Curve: Interactive portfolio value chart
Drawdown Analysis: Maximum drawdown chart and duration
Trade Statistics: Win rate, profit factor, average trade
Monthly Returns: Heatmap of monthly performance
Position Details: Entry/exit prices and P&L
Printing Results¶
def print_analysis(results):
strat = results[0]
# Sharpe
sharpe = strat.analyzers.sharpe.get_analysis()
print(f"Sharpe Ratio: {sharpe.get('sharperatio', 'N/A')}")
# Drawdown
dd = strat.analyzers.drawdown.get_analysis()
print(f"Max Drawdown: {dd.max.drawdown:.2f}%")
# Trades
ta = strat.analyzers.trades.get_analysis()
print(f"Total Trades: {ta.total.total}")
if ta.won.total > 0:
print(f"Win Rate: {ta.won.total/ta.total.total:.2%}")
print(f"Avg Win: {ta.won.pnl.average:.2f}")
if ta.lost.total > 0:
print(f"Avg Loss: {ta.lost.pnl.average:.2f}")
Export to DataFrame¶
import pandas as pd
# Get transactions as DataFrame
cerebro.addanalyzer(bt.analyzers.Transactions, _name='txn')
results = cerebro.run()
txn = results[0].analyzers.txn.get_analysis()
df = pd.DataFrame.from_dict(txn, orient='index')
df.to_csv('transactions.csv')
See Also¶
Visualization - Chart plotting
Strategies - Strategy development
Optimization - Parameter optimization