Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Perfomance of specific strategy in cerebro

    Indicators/Strategies/Analyzers
    2
    4
    2121
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • O
      oalexandere last edited by

      Hello,
      my code like this

          cerebro = 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.

      1. Is there any method to get perfomance of each strategies separate after finishing backtesting?
      2. Is there any way to get single strategy returns for past 6 months in next() method?
      B 1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators @oalexandere last edited by

        @oalexandere said in Perfomance of specific strategy in cerebro:

        1. 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.

        O 1 Reply Last reply Reply Quote 0
        • O
          oalexandere @backtrader last edited by oalexandere

          @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
          
          1 Reply Last reply Reply Quote 0
          • O
            oalexandere last edited by oalexandere

            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
            
            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors