question on TestStrategy class



  • ...

    Create a Stratey

    class TestStrategy(bt.Strategy):

    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))
    
    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
    
    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])
    

    ...
    I have a problem understanding how 'dataclose' gets updated when self.dataclose[0] seems to be picking up the next close, as init seems to be getting called only once, and next() seems to be called for each line of data.
    Is there some iterator-type thing going on. I tried to read the code tracing the code, but I am overwhelmed. Needless, to say I am just getting into backtrader working through the tutorials. Thanks.- braman09


  • administrators

    Yes. The components are loosely modeled after the iterator concept in Python, because the lines are iterated from the 1st value to the last.

    Using 0 as the pivot point to get access to the current value avoids having to keep a reference to where the elements actually are, because they are always at instant 0. This also, in the author's modest opinion, cleanly allows to reference past elements with -1, -2, etc.

    And -1 retains the Pythonic meaning of last. Because 0 is the current moment and -1 is the last moment before the actual one.



  • @backtrader Thanks. Just to validate my understanding -
    ....
    if self.dataclose[0] < self.dataclose[-1]:
    # current close less than previous close

            if self.dataclose[-1] < self.dataclose[-2]:
                # previous close less than the previous close
    
                # BUY, BUY, BUY!!! (with all possible default parameters)
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
                self.buy()
    

    ....
    The above should be prefixed by :
    if self.line.idx >= 2:
    right ?
    Thanks- braman09


  • administrators

    Sorry but without formatting it's really unclear what you mean and where self.line.idx comes from. May you repost?



  • @backtrader Let me try again. Just to validate my understanding -
    `

        if self.dataclose[0] < self.dataclose[-1]:
            # current close less than previous close
    
            if self.dataclose[-1] < self.dataclose[-2]:
                # previous close less than the previous close
    
                # BUY, BUY, BUY!!! (with all possible default parameters)
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
                self.buy()
    

    The above should be prefixed by :
    if len(self) >= 2 :
    right ? since [-1] refers to the last line when the current line is the 1st line.
    Thanks- braman09


  • administrators

    If there are no constraints, like indicators in the strategy, which have increased the minimum period, you would then have to guard the access to past indices.

    Please see: Docs - Operating the Platform and specifically the section Minimum Period


Log in to reply
 

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