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/

    Executing Buy Sell Strategy for PivotPoint

    General Code/Help
    2
    16
    6432
    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.
    • S
      SShepherd last edited by

      Trying to execute a strategy for buying at the first P and selling at the R1:

      class St(bt.SignalStrategy):
          params = ()
      
      def __init__(self):
          self.pp = bt.ind.PivotPoint(self.data1)
          pp1 = self.pp()  # couple the entire indicators
          self.buysignal = self.data0.close < pp1.p
          self.sellsignal = self.data0.close > pp1.r1
      
          self.signal_add(bt.SIGNAL_LONG, self.buysignal)
          self.signal_add(bt.SIGNAL_LONGEXIT, self.sellsignal)
      

      def runstrat():
      args = parse_args()

      cerebro = bt.Cerebro()
      data = use_clf_data()
      
      # Add commodity
      commCL= bt.CommissionInfo(commission=2.0, margin=1000.0, mult=1000.0)
      cerebro.broker.addcommissioninfo(commCL)
      cerebro.broker.setcash(100000.0)
      
      cerebro.signal_accumulate(True)
      
      # Add the data
      cerebro.adddata(data)
      cerebro.resampledata(data, timeframe=bt.TimeFrame.Months)
      
      cerebro.addstrategy(St)
      cerebro.run(runonce=False)
      if args.plot:
          #cerebro.plot(style='bar')
          cerebro.plot(style='line')
      

      However, I get this: plot

      I'm expecting a lot more buy and sell events. What did I do wrong?

      B 1 Reply Last reply Reply Quote 0
      • S
        SShepherd last edited by SShepherd

        How would I attach a Strategy to this to LONG when it crosses P and SHORT when it crosses R1?

        This does not work:

        class MySignal(bt.Indicator):
            lines = ('signal',)
        
        def __init__(self):
            self.lines.signal = self.data - bt.indicators.PivotPoint(self.data)
        
        S 1 Reply Last reply Reply Quote 0
        • S
          SShepherd @SShepherd last edited by SShepherd

          @SShepherd

          This can initiate the buy but only for the first datapoint:

              self.pp = bt.ind.PivotPoint(self.data1)
              pp1 = self.pp()  # couple the entire indicators
              self.buysignal = self.data0.close < pp1.r1
              self.sellsignal = self.data0.close > pp1.p
          
              self.signal_add(bt.SIGNAL_LONG, self.buysignal)
              self.signal_add(bt.SIGNAL_LONGEXIT, self.sellsignal)
          

          And here's my runstrat():

          cerebro.signal_accumulate(True)
          
          # Add the data
          cerebro.adddata(data)
          cerebro.resampledata(data, timeframe=bt.TimeFrame.Months)
          
          cerebro.addstrategy(St)
          
          1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators last edited by

            The indicator depicted in the 1st post was obviously not working as you found out, because it wasn't checking for a "cross" and was only addressing p (1st line of PivotPoint)

            Your second approach is only checking if something is less than other thing and not checking a cross. It is unclear if you want to do that or really check for a crossing pattern.

            But without some printout of the data and values of the indicators or a reference to which data feed you are using, it is for sure not possible to say anything.

            1 Reply Last reply Reply Quote 0
            • B
              backtrader administrators last edited by

              All the related posts under the blog thread have been moved here.

              1 Reply Last reply Reply Quote 0
              • B
                backtrader administrators @SShepherd last edited by

                @SShepherd You are using a subclass of SignalStrategy and the accumulate you use is therefore not applied, because that applies only to the automatic addition of signals in cerebro. Set it in your subclass.

                (One possibility)

                S 1 Reply Last reply Reply Quote 0
                • S
                  SShepherd @backtrader last edited by

                  @backtrader Thanks for response, I uploaded the entire file and dataset

                  Here is the full code: http://dpaste.com/0FYC29P

                  Here is the dataset: http://dpaste.com/37EGH80 [same as 2005-2006-day-001.txt]

                  I ideally want to buy once a month when it crosses the pivot after a certain day, but not sure how to do that

                  S 1 Reply Last reply Reply Quote 0
                  • S
                    SShepherd @SShepherd last edited by SShepherd

                    @SShepherd said in Executing Buy Sell Strategy for PivotPoint:

                    @backtrader Thanks for response, I uploaded the entire file and dataset

                    Here is the full code: http://dpaste.com/0FYC29P

                    Here is the dataset: http://dpaste.com/37EGH80 [same as 2005-2006-day-001.txt]

                    I ideally want to buy once a month when it crosses the pivot after a certain day, but not sure how to do that

                    I'm copying the code into this forum for archival purposes:

                    from __future__ import (absolute_import, division, print_function,
                                            unicode_literals)
                    
                    import argparse
                    
                    import backtrader as bt
                    import backtrader.feeds as btfeeds
                    import backtrader.utils.flushfile
                    
                    
                    class St(bt.SignalStrategy):
                        params = (('usepp1', False),
                                  ('plot_on_daily', False))
                    
                        def __init__(self):
                            autoplot = self.p.plot_on_daily
                            self.pp = pp = bt.ind.PivotPoint(self.data1, _autoplot=autoplot)
                    
                    
                            ## Here is here I am trying to buy when the daily close is less than the
                            ## pivot on the Xth day and sell whenever it crosses r1
                            pp1 = self.pp()  # couple the entire indicators
                            self.buysignal = self.data0.close < pp1.p
                            self.sellsignal = self.data0.close > pp1.r1
                    
                            self.signal_add(bt.SIGNAL_LONG, self.buysignal)
                            self.signal_add(bt.SIGNAL_LONGEXIT, self.sellsignal)
                    
                    
                        def next(self):
                            txt = ','.join(
                                ['%04d' % len(self),
                                 '%04d' % len(self.data0),
                                 '%04d' % len(self.data1),
                                 self.data.datetime.date(0).isoformat(),
                                 '%04d' % len(self.pp),
                                 '%.2f' % self.pp[0]])
                    
                            print(txt)
                    
                    
                    def runstrat():
                        args = parse_args()
                    
                        cerebro = bt.Cerebro()
                        data = btfeeds.BacktraderCSVData(dataname=args.data)
                        cerebro.adddata(data)
                        cerebro.resampledata(data, timeframe=bt.TimeFrame.Months)
                    
                        cerebro.addstrategy(St,
                                            plot_on_daily=args.plot_on_daily)
                        cerebro.run(runonce=False)
                        if args.plot:
                            cerebro.plot(style='bar')
                    
                    
                    def parse_args():
                        parser = argparse.ArgumentParser(
                            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                            description='Sample for pivot point and cross plotting')
                    
                        parser.add_argument('--data', required=False,
                                            default='../../datas/2005-2006-day-001.txt',
                                            help='Data to be read in')
                    
                        parser.add_argument('--plot', required=False, action='store_true',
                                            help=('Plot the result'))
                    
                        parser.add_argument('--plot-on-daily', required=False, action='store_true',
                                            help=('Plot the indicator on the daily data'))
                    
                        return parser.parse_args()
                    
                    
                    if __name__ == '__main__':
                        runstrat()
                    
                    1 Reply Last reply Reply Quote 0
                    • B
                      backtrader administrators last edited by

                      I ideally want to buy once a month when it crosses the pivot after a certain day

                      The previous statement raises, at least, the following questions, which may help you into coding your strategy:

                      • Which pivot?
                      • Crossing to the upside? To the downside?
                      • Which certain day?
                      S 1 Reply Last reply Reply Quote 0
                      • S
                        SShepherd @backtrader last edited by

                        @backtrader said in Executing Buy Sell Strategy for PivotPoint:

                        I ideally want to buy once a month when it crosses the pivot after a certain day

                        The previous statement raises, at least, the following questions, which may help you into coding your strategy:

                        • Which pivot?

                        The first pivot, and R1

                        • Crossing to the upside? To the downside?

                        Crossing to the upside

                        • Which certain day?

                        The 15th of the month

                        1 Reply Last reply Reply Quote 0
                        • B
                          backtrader administrators last edited by

                          In that case your friends are:

                          • pivotpoint.lines.p and pivotpoint.lines.r1 (already in your 2nd version of the code)

                            because p is the 1st line, any operation directly on the indicator will directly use p, but being specific about lines.p can help when later reading.

                          • bt.indicators.CrossUp Indicator Reference

                          • self.dataX.datetime.date() which gives you the current date of dataX (if you only have 1 data feed, you can simply use self.data) and can compare against the 15th. Although I'd be wary of such a fixed date: it may happen to be a Saturday, Sunday or Bank Holiday.

                          S 1 Reply Last reply Reply Quote 0
                          • S
                            SShepherd @backtrader last edited by

                            @backtrader Let me give it a shot!

                            Also, side question, how are dataX automagically created? I don't see them defined anywhere -- I assume this is in the indicator?

                            1 Reply Last reply Reply Quote 0
                            • S
                              SShepherd last edited by SShepherd

                              OK, baby steps. I got the CrossUp and CrossDown signals generated but it doesn't do LONGEXIT

                              See image: crossup and crossdown no LONGEXIT

                              from __future__ import (absolute_import, division, print_function,
                                                      unicode_literals)
                              
                              import argparse
                              
                              import backtrader as bt
                              import backtrader.feeds as btfeeds
                              import backtrader.utils.flushfile
                              
                              
                              class St(bt.SignalStrategy):
                                  params = (('usepp1', False),
                                            ('plot_on_daily', False))
                              
                                  def __init__(self):
                                      autoplot = self.p.plot_on_daily
                                      self.pp = pp = bt.ind.PivotPoint(self.data1, _autoplot=autoplot)
                              
                                      ## Here is here I am trying to buy when the daily close is less than the
                                      ## pivot on the Xth day and sell whenever it crosses r1
                                      pp1 = self.pp()  # couple the entire indicators
                                      self.buysignal = bt.ind.CrossUp(self.data0.close, pp1)
                                      self.sellsignal = bt.ind.CrossDown(self.data0.close, pp1.r1)
                              
                                      self.signal_add(bt.SIGNAL_LONG, self.buysignal)
                                      self.signal_add(bt.SIGNAL_LONGEXIT, self.sellsignal)
                              
                                  def next(self):
                                      txt = ','.join(
                                          ['%04d' % len(self),
                                           '%04d' % len(self.data0),
                                           '%04d' % len(self.data1),
                                           self.data.datetime.date(0).isoformat(),
                                           '%04d' % len(self.pp),
                                           '%.2f' % self.pp[0]])
                              
                                      print(txt)
                              
                              
                              def runstrat():
                                  args = parse_args()
                              
                                  cerebro = bt.Cerebro()
                                  data = btfeeds.BacktraderCSVData(dataname=args.data)
                                  cerebro.adddata(data)
                                  cerebro.resampledata(data, timeframe=bt.TimeFrame.Months)
                              
                                  cerebro.broker.setcash(100000.0)
                                  #cerebro.signal_accumulate(True)
                              
                                  cerebro.addstrategy(St,
                                                      plot_on_daily=args.plot_on_daily)
                                  cerebro.run(runonce=False)
                                  if args.plot:
                                      cerebro.plot(style='bar')
                              
                              
                              def parse_args():
                                  parser = argparse.ArgumentParser(
                                      formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                                      description='Sample for pivot point and cross plotting')
                              
                                  parser.add_argument('--data', required=False,
                                                      default='../../datas/2005-2006-day-001.txt',
                                                      help='Data to be read in')
                              
                                  parser.add_argument('--plot', required=False, action='store_true',
                                                      help=('Plot the result'))
                              
                                  parser.add_argument('--plot-on-daily', required=False, action='store_true',
                                                      help=('Plot the indicator on the daily data'))
                              
                                  return parser.parse_args()
                              
                              
                              if __name__ == '__main__':
                                  runstrat()
                              
                              1 Reply Last reply Reply Quote 0
                              • B
                                backtrader administrators last edited by

                                You are passing a long indication to an EXIT signal handler, and this type expects a short indication., i.e.: you pass a signal which produce positive values (long) to something which is expecting negative values (short)

                                Described here in Strategy with signals

                                Quote:

                                Signals indications
                                The signals delivers indications when queried with signal[0] and the meaning is:

                                • > 0 -> long indication
                                • < 0 -> short indication
                                • == 0 -> No indication

                                LONGEXIT: short indications are taken to exit long positions

                                This is how signals can be used for many different things. Multiply your signal by -1.0

                                1 Reply Last reply Reply Quote 0
                                • S
                                  SShepherd last edited by

                                  Great! Now the chart is working. Here's what it looks like with your simple tweak:

                                          self.signal_add(bt.SIGNAL_LONGEXIT, -1.0*self.sellsignal)
                                  

                                  LONGEXIT works

                                  And I'd like to add that the community behind this software is fantastic!

                                  My next step will be to figure out the date time. I believe I need to create a new Signal class with an if statement to check the date, correct? Since I won't be using a CrossUp, I'll simply compare the date and data0-pp1.p

                                  1 Reply Last reply Reply Quote 0
                                  • B
                                    backtrader administrators last edited by

                                    One of the latest additions lets you do direct time comparisons directly to lines to generate signals. Probably nobody has used it yet. An example:

                                    class MySignal(bt.Indicator):
                                        lines = ('mysignal',)
                                    
                                        def __init__(self):
                                            self.lines.mysignal = self.data.datetime > datetime.time(10, 30)
                                    

                                    This generates an indicator which can be used as a signal to only execute orders when the daily time goes over 10:30.

                                    But since you are probably looking for day, you'll need to work it out in the next method comparing the self.data.datetime.date() (maybe even getting the weekday) against something of your choosing

                                    1 Reply Last reply Reply Quote 0
                                    • 1 / 1
                                    • First post
                                      Last post
                                    Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors