Perfomance of specific strategy in cerebro
-
Hello,
my code like thiscerebro = bt.Cerebro() cerebro.broker.set_cash(100000.0) cerebro.broker.set_coc(True) cerebro.broker.addcommissioninfo(CommDivFrance()) # --- Adding some data feeds --- # --- Observers --- cerebro.addobserver(bt.observers.Broker) cerebro.addobservermulti(bt.observers.BuySell) cerebro.addobserver(bt.observers.Benchmark, data=benchdata, _doprenext=True, timeframe=TimeFrame.NoTimeFrame) # --- Analyzers --- cerebro.addanalyzer(bt.analyzers.SharpeRatio, timeframe=TimeFrame.Years) cerebro.addanalyzer(bt.analyzers.Calmar, timeframe=TimeFrame.Years) cerebro.addanalyzer(bt.analyzers.DrawDown) cerebro.addanalyzer(bt.analyzers.AnnualReturn) cerebro.addanalyzer(bt.analyzers.PyFolio, timeframe=TimeFrame.Days, compression=1) cerebro.addanalyzer(bt.analyzers.Transactions) cerebro.addanalyzer(bt.analyzers.Returns) # --- Strategies --- cerebro.addstrategy(strategy=ValueBasket) cerebro.addstrategy(strategy=ValueBasket2) results = cerebro.run() for strat in results: print('='*79) print(strat.__class__.__name__) # Analyzers results strat.analyzers.annualreturn.print() strat.analyzers.drawdown.print() strat.analyzers.sharperatio.print() strat.analyzers.returns.print() # pyfolio pyfoliozer = strat.analyzers.getbyname('pyfolio') returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items() # Perfomance pf.show_perf_stats(returns=returns) # cerebro.plot(plotter=PlotterZoomed())
I added 2 strategies, and would like to extract performance of each ones. But for each strat I get same perfomance (annualreturn, drawdown, profit, sharpe and so on), which comes from backtasting together (printing in section # Analyzers results). There are some capital allocation logic between strategies and they are related to each other.
- Is there any method to get perfomance of each strategies separate after finishing backtesting?
- Is there any way to get single strategy returns for past 6 months in next() method?
-
@oalexandere said in Perfomance of specific strategy in cerebro:
- Is there any method to get perfomance of each strategies separate after finishing backtesting?
The performance is for the account you have in the broker.
-
@backtrader ok. After much thought, one version (for example for calc pnl for each strategy) may be like this:
def notify_order(self, order): if order.status in [order.Completed]: if hasattr(self, 'total_pnl'): self.total_pnl += order.executed.pnl - order.executed.comm else: self.total_pnl = order.executed.pnl - order.executed.comm
-
Solution: using analyzer.
Maybe will be usefull for somebody: next analyzer calculate and save realized pnl and opened positions for each strategy date to date:import backtrader as bt from collections import OrderedDict class TotalReturns(bt.Analyzer): '''This analyzer reports the total pnl for strategy Params: - timeframe (default: ``None``) If ``None`` then the timeframe of the 1st data of the system will be used - compression (default: ``None``) Only used for sub-day timeframes to for example work on an hourly timeframe by specifying "TimeFrame.Minutes" and 60 as compression If ``None`` then the compression of the 1st data of the system will be used Methods: - get_analysis Returns a dictionary with returns as values and the datetime points for each return as keys ''' def __init__(self): self.total_pnl = 0 self.unrealized = 0 # Unrealized pnl for all positions all strategies self.positions = OrderedDict.fromkeys([d._name or 'Data%d' % i for i, d in enumerate(self.datas)], 0) # Current strategy positions def start(self): tf = min(d._timeframe for d in self.datas) self._usedate = tf >= bt.TimeFrame.Days def notify_order(self, order): if order.status in [order.Completed, order.Partial]: self.total_pnl += order.executed.pnl - order.executed.comm self.positions[order.data._name] += order.executed.size def next(self): if self._usedate: self.rets[self.strategy.datetime.date()] = self.total_pnl else: self.rets[self.strategy.datetime.datetime()] = self.total_pnl def stop(self): for dname in self.positions: self.unrealized += (self.strategy.dnames[dname].close[0] - self.strategy.positionsbyname[dname].price) * \ self.strategy.positionsbyname[dname].size