Feeding Multiple Data Feeds in Indicators



  • Hi! I would like to ask how to add multiple data feeds into indicators. I am using StandardDeviation indicator and instead of using multiple indicators, I am planning to input 3 data into the indicator so that the indicator can give me 3 sd for different data. Thanks :)


  • administrators

    You can pass as many data feeds (or anything that looks like it, like indicators for example) to indicators. The same concepts applied to reach data feeds are applied in indicators.

    See Docs - Platform Concepts



  • Can you give an example about indicator instance initiation? The example you referred, I think, is a build-in class. Can you elaborate on how to self define an indicator class with multiple data as input? Thanks!


  • administrators

    It's already built-in. From the documentation link:

    Data Feeds are automagically provided member variables to the strategy in the form of an array and shortcuts to the array positions

    And the same applies to indicators, with the exception noted in: Docs - Using Indicators in the section Some Notes

    This is intentional. If no data is passed, the 1st data of the parent (in this case the Strategy in which is being created) will be automatically passed in the background

    I.e.: You don't need to define anything. The data(s) are provided automatically to the indicator in the self.datas array.

    And the minimum number that a caller has to provide can be determined. See Blog - Crossing over numbers



  • @backtrader Thanks! I later solved it by passing self.data into the instance initiation and it works. I wonder if there is a way to control the size of indicator panel? The height is too narrow to see the exact value for me. Thanks!



  • @WillDawn24 @backtrader

    Can you please give an example of how passing multiple data feeds into an indicator is done? For example, if you had two feeds (self.datas[0] and self.datas[1] in the parent strategy):

    1. How do you pass the self.datas array to the indicator?
    2. How would you access each feed in the indicator?
    3. How would you access each feed in the indicator if you didn't know how many data feeds sent in before program execution? I.e. without using the self.data[#] notation and using a loop to loop over available data feeds.


  • @_m_d_b said in Feeding Multiple Data Feeds in Indicators:

    Can you please give an example of how passing multiple data feeds into an indicator is done? For example, if you had two feeds (self.datas[0] and self.datas[1] in the parent strategy):

    Have you tried?:

    MySuperIndicator(self.datas[0], self.datas[1])  # or MySuperIndicators(*self.datas[0:2]) or MySuperIndicator(self.data0, self.data1)
    

    @_m_d_b said in Feeding Multiple Data Feeds in Indicators:

    1. How do you pass the self.datas array to the indicator?

    If that is the entire array: MySuperIndicator(*self.datas) or is the question asking something different?

    @_m_d_b said in Feeding Multiple Data Feeds in Indicators:

    1. How would you access each feed in the indicator?

    Same as in the strategy? It's in the document that was quoted above (Platform concepts) and in the answer from @backtrader

    I.e.: You don't need to define anything. The data(s) are provided automatically to the indicator in the self.datas array.

    @_m_d_b said in Feeding Multiple Data Feeds in Indicators:

    1. How would you access each feed in the indicator if you didn't know how many data feeds sent in before program execution? I.e. without using the self.data[#] notation and using a loop to loop over available data feeds.

    for data in self.datas or is the question asking something different?



  • @Paska-Houso

    Thank you! I think I was just missing the *self.datas notation. I'll give this a try.

    I also pasted a more detailed version of this question here.

    I think your solution works and I was just passing the object incorrectly to the indicator.

    How does *self.datas in MySuperIndicator(*self.datas) get mapped to the self.datas object in MySuperIndicator? I didn't expect that. What's the mechanism there?

    I thought parameters had to be passed in by name (e.g. MySuperIndicator(data=self.data)) and accepted as "params" (params = (('data',{}),).



  • It's in the documentation linked above: Platform Concepts: https://www.backtrader.com/docu/concepts.html



  • @Paska-Houso Sorry to be annoying here, I don't see that in the documentation. Can you quote the relevant snippet?



  • It 1st says:

    Data Feeds are automagically provided member variables to the strategy in the
    form of an array and shortcuts to the array positions
    

    And then

    So it is. Data Feeds get added to the platform and they will show up inside the strategy
    in the sequential order in which they were added to the system.
    
    Note
    This also applies to Indicators, should the end user develop his own custom Indicator or
    when having a look at the source code for some of the existing Indicator Reference
    

    The documentation is obviously not going to describe what's done in the source code. It's telling you that you automatically get a self.datas array with the datas. In the case of the indicators, obviously those you pass or only the 0th (as you have named it) if you are not explicit about passing data feeds.



  • @Paska-Houso OK I guess I just didn't understand how *self.datas in MySuperIndicator(*self.datas) get mapped to the self.datas object in MySuperIndicator.

    The docs show examples without the * like this

    class MyStrategy(bt.Strategy):
        params = dict(period=20)
    
        def __init__(self):
    
            sma = btind.SimpleMovingAverage(self.data, period=self.params.period)
    
        ...
    

    But I guess I'm to understand that anything passed in the indicator that is not a named parameter (i.e. not like param=x) is mapped to the self.datas object in the indicator?



  • @_m_d_b said in Feeding Multiple Data Feeds in Indicators:

    But I guess I'm to understand that anything passed in the indicator that is not a named parameter (i.e. not like param=x) is mapped to the self.datas object in the indicator?

    I guess only data feeds are mapped to datas. From the same document:

    No *args or **kwargs are being received by the strategy’s __init__ method (they may still be used)
    

    So *args may still be used and I recall having seen posts (it would probably take too much digging) from people who were using several unnamed arguments in the snippets.

    The alternatives

    • Dig in the source code and find out if that's true

    • Make a small snippet which passes something like this to the indicator

      MySuperIndicator(self, p1, p2)
      

      And see what makes it to your indicator when it is instantiated and you pass some data feeds and a couple of integers for example.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.