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/

    Detect new resampled price

    General Code/Help
    2
    9
    1587
    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.
    • A
      algoguy235 last edited by

      I have a code that uses both a tick data and a resampled data, let's call it 5 min period. I have a set of logics that only need to occur when a NEW 5m candle comes in. This will save a ton of computation. In order to detect this new price, here's what I've been doing:

      (Lf = low frequency, meaning resampled data)

      class St(bt.Strategy)
          def __init__(self):
              self.Lf_dt = self.datas[1].datetime
              # memeory functionality
              self.__previous_Lf_dt = None
      
          def next(self):
              # Check to see if there's a new Lf candle printed this period
              self.__new_Lf_print   = (self.Lf_dt[0] != self.__previous_Lf_dt)
              self.__previous_Lf_dt = self.Lf_dt[0]
      
              if self.__new_Lf_print:
                  execute_Lf_logics()
      

      Is there an easier way to do this? something built-in perhaps?

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

        Use the length of the data feed: len(data1). It will only change when new data is available.

        1 Reply Last reply Reply Quote 3
        • A
          algoguy235 last edited by algoguy235

          Ahh yes that makes sense. Something like this.

          class St(bt.Strategy)
              def __init__(self):
                  # memeory functionality
                  self.__previous_Lf_len = 0
          
              def next(self):
          
                  if len(data1) != self.__previous_Lf_len:
                      execute_Lf_logics()
                      self.__previous_Lf_len = len(data1)
          
          1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators last edited by

            In any case I would recommend against prefixing your member attributes with __. But it is your code of course.

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

              Yes fair enough. But you would agree this is the most efficient way to accomplish this?

              class St(bt.Strategy)
                  def __init__(self):
                      # memeory functionality
                      self.previous_Lf_len = 0
              
                  def next(self)
                      if len(data1) != self.previous_Lf_len:
                          self.new_Lf_print = True
                          self.previous_Lf_len = len(data1)
              
                      if self.new_Lf_print:
                          execute_Lf_logics()
              
              1 Reply Last reply Reply Quote 0
              • B
                backtrader administrators last edited by

                Efficiency depends on your entire logic. If you simply want to act on a new bar, that's efficient enough for sure.

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

                  for reference - very similar issue here:

                  Strategy execution on different timeframes and multi-data

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

                    This is the most efficient solution I've found.

                    class St(bt.Strategy)
                        def __init__(self):
                            self.new_Lf_print = self.data1.datetime() != self.data1.datetime()(-1)
                    
                        def next(self)
                            if self.new_Lf_print[0]:
                                execute_Lf_logics()
                    

                    By putting the empty brackets after the line object (datetime) it creates a linecoupler that is coupled to the base sample rate. Documentation here.

                    This slightly outperforms the len() calculation from the previous. I wasn't able to get len() as a line object in the init function, so datetime works well enough.

                    I also like this solution because the code is clean. Only requires a single line in init.

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

                      @algoguy235 said in Detect new resampled price:

                      I wasn't able to get len() as a line object in the init function

                      len is a builtin and cannot be overridden. Given it is only meant to check a single value (because it increase monotonically) it seems pointless to have a replacement function for it to deliver a lines object.

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