Backtrader Community

    • 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/

    Discrepancy with PnL in the Stop function vs TradeAnalyzer Net PnL

    Indicators/Strategies/Analyzers
    5
    11
    512
    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
      overcash last edited by

      I'm trying to figure out what I'm doing wrong.

      I've been calculating PnL using the Stop function and am switching to using TradeAnalyzer and Returns from the analyzers.

      def stop(self):
          # calculate the actual returns
          self.roi = (self.broker.get_value() / self.val_start) - 1.0
          self.PNL = (self.broker.get_value() - self.val_start )
      
          print('Starting value:     {:.4f}'.format(self.val_start))
          print('Final value:        {:.4f}'.format(self.broker.get_value()))       
          print('PNL:                {:.4f}'.format(self.PNL))
          print('ROI:                {:.4f}%'.format(100.0 * self.roi))
          print('\n')
      

      PnL_Net:
      cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta")

      PnL: 8441.32, Pnl_Net: 3595.05

      PnL: 3455.63, Pnl_Net: -78.39

      And then sometimes they two measures of PnL match.
      PnL: -3047.4, Pnl_Net: -3047.4

      Any help would be much appreciated. TIA

      1 Reply Last reply Reply Quote 0
      • run-out
        run-out last edited by

        Your calculation is the full value of the account at the end minus the beginning. The trade list analyzer calculates the pnl of closed trades. Perhaps at the end of your backtests there are open trades?

        RunBacktest.com

        M 1 Reply Last reply Reply Quote 1
        • O
          overcash last edited by

          Thank you. That would make sense.
          If there is an open trade and price has increased then the value of that trade would be a paper gain in the account.

          1 Reply Last reply Reply Quote 1
          • M
            manos @run-out last edited by

            Agree - I ran into this as well.

            @overcash
            My solution was:

                    # if we're backtesting and out of data, close open positions so they get counted properly.
                    # must be done on the 2nd to last, as market orders wait to get another candle, to execute based on open price.
                    if self.position and len(self.data) == self.data.buflen() - 1 and "live" not in self.environment:
                        logger.debug("Closing open position to conclude backtesting")
                        self.close()
            
            O 1 Reply Last reply Reply Quote 0
            • O
              overcash @manos last edited by

              @manos

              Thanks for posting. Does it matter where you put that block of code?

              M 1 Reply Last reply Reply Quote 0
              • M
                manos @overcash last edited by

                @overcash apologies, I didn't get a notification of your reply :)

                I have that at the end of my stategy's next() method.

                O Federico Bld 2 Replies Last reply Reply Quote 0
                • O
                  overcash @manos last edited by

                  @manos You rock, thanks for checking back-in. Works great!

                  1 Reply Last reply Reply Quote 0
                  • A
                    amplified last edited by

                    Great code snippet - thanks

                    1 Reply Last reply Reply Quote 0
                    • Federico Bld
                      Federico Bld @manos last edited by

                      @manos would it make a better sense to put it in the stop() method?

                      Federico Bld 1 Reply Last reply Reply Quote 0
                      • Federico Bld
                        Federico Bld @Federico Bld last edited by

                         def stop(self):
                                # if we're backtesting and out of data, close open positions so they get counted properly.
                                # must be done on the 2nd to last, as market orders wait to get another candle, to execute based on open price.
                                
                                for data in self.datas:
                                    if self.position and len(self.data) == self.data.buflen() - 1 and "live" not in self.environment:
                                        logger.debug("Closing open position to conclude backtesting")
                                        self.close(data=d)
                        
                        Federico Bld 1 Reply Last reply Reply Quote 0
                        • Federico Bld
                          Federico Bld @Federico Bld last edited by

                          Errata corr.:

                          @federico-bld said in Discrepancy with PnL in the Stop function vs TradeAnalyzer Net PnL:

                           def stop(self):
                                  # if we're backtesting and out of data, close open positions so they get counted properly.
                                  # must be done on the 2nd to last, as market orders wait to get another candle, to execute based on open price.
                                  
                                  for data in self.datas:
                                      if self.getposition(data) and len(data) == data.buflen() - 1 and "live" not in self.environment:
                                          logger.debug("Closing open position to conclude backtesting")
                                          self.close(data=data)
                          
                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          • First post
                            Last post
                          Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors