For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Indicator using multi datafeed: operate only on overlapping bar



  • I've created an indicator that take 2 datafeeds and return a line of the ratio between them.
    the issue i'm straggling with is to add a condition that will only calculate the ratio if data is coming from the same time. by same time I mean overlapping bars.

    I'm trying to study correlations between 2 sets of data.
    with one of them having very low volume making a lot of 1 minute timeframe bars be empty of data.

    if my understanding is correct the system will keep reference to the last known value and use it.
    but for my case if the data doesn't overlap in time I would like to skip it as it not really relevant (cause I will get a ratio that never actually happened)

    [side note: because the code operate on lines and is only called once in init I can't see the actual calculation while debugging... thoughts on this are also welcome]

    this is my relevant code so far from the indicator init:

    def init(self, *args, **kwargs):

        if 'datas_name' not in kwargs:
            raise bt.errors.BacktraderError()
    
        self.datasByName = kwargs['datas_name']
        self.firstData = self.datasByName['1']
        self.secondData = self.datasByName['2']
    
        # need a condition that will be valid only if bars are overlaping in period
        # something like this... if(self.firstData .lines.datetime== self.secondData .lines.datetime):
            self.l.ratio= self.secondData .lines.close / self.firstData .lines.close

  • administrators

    When a data feed doesn't move forward its len doesn't change. That's the indication you need.



  • @backtrader I experimented a bit using '...lines.datetime.lencount' (not sure if that what you meant).
    and I got some questions regarding the behavior I witness.

    I use 2 sets of data, first one gave count of about 180,000 and the other around 60,000 for the same period of time. still need to check that indeed the bar are in sync with each other.

    but what i found interesting and left me a bit confused is when I used 'resample' on the data instead of just the raw data. now both data sets returned count of about 1600 (not the same) and it was regardless of time frame or compression params that I've tried

    cerebro.resampledata(data, name='main', timeframe=bt.TimeFrame.Seconds, compression=180)

    not sure what it says about the bars being synced? why and how count remain the same? why the count is so low?


  • administrators

    @jacob said in Indicator using multi datafeed: operate only on overlapping bar:

    @backtrader I experimented a bit using '...lines.datetime.lencount' (not sure if that what you meant).
    and I got some questions regarding the behavior I witness

    No, len is the built-in function, len. As in: len_of_my_data = len(mydata), which can of course be applied to an individual line also, but all lines in a data feed have the same len.

    @jacob said in Indicator using multi datafeed: operate only on overlapping bar:

    not sure what it says about the bars being synced? why and how count remain the same? why the count is so low?

    It seems a scenario which would need some code to see how it works and make some assumptions about your case



  • As i'm still learning the system the code I used is based on the Quickstart example and the modifications seem very trivial.

    I striped away as much as I could to focus on the issue:
    when using adddata => count 180000
    when using resample => count 1600

    in main:

    if __name__ == '__main__':    
    file = 'some/file.csv'
    
    cerebro = bt.Cerebro()
    
    # Add a strategy
    cerebro.addstrategy(TestStrategy)
    
    # add data from custom csv file
    data = MyHLOC(dataname=file)
    
    # Add the resample data instead of the original
    # cerebro.adddata(data, name='main')
    cerebro.resampledata(data, name='main', timeframe=bt.TimeFrame.Minutes, compression=60)
    
    cerebro.run()
    

    in strategy:

    class TestStrategy(bt.Strategy):
    ...
    ...
    def __init__(self):
    ...
    ...
        self.testIndicator = IndicatorTest(datas=self.dnames)
    

    in Indicator:

    class IndicatorTest(bt.Indicator):
    
    def __init__(self, *args, **kwargs):
        if 'datas' not in kwargs:
            raise bt.errors.BacktraderError()
    
        self.datasByName = kwargs['datas']
        self.mainData = self.datasByName['main']
    
    def next(self, *args, **kwargs):
        print(self.mainData.lines.datetime.lencount)

  • administrators

    @jacob said in Indicator using multi datafeed: operate only on overlapping bar:

    def next(self, *args, **kwargs):
        print(self.mainData.lines.datetime.lencount)
    

    You should use the builtin len: len(self.mainData)

    @jacob said in Indicator using multi datafeed: operate only on overlapping bar:

    when using adddata => count 180000
    when using resample => count 1600

    It seemed a lot more complex with loads of text and it now seems a simple issue, so the truth lies probably in the middle, but:

    • When you resample something you are bound to get less bars, because you combine several bars into one, i.e.: 60 1-minute bars into 1 60-minutes bar.

      As such, the len cannot be the same.



  • of course, I understand the idea of time frames and compression.
    but as I wrote in the original post:
    "now both data sets returned count of about 1600 (not the same) and it was regardless of time frame or compression params that I've tried"

    I have change different time frames with different compression but it the count remain the same.
    this is the part that I don't understand why