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

Minor typos on website (self.believes) for @bt



  • The docs and support are already great @backtrader and I have no clue whether you have time and interest in addressing any issues found, but it would be remiss of me and not in the proper spirit at all to fail to capture the minutiae I find, in case I am correct, and you do. Care, that is. I will place them on this thread.

    I believe:
    ----on page: https://www.backtrader.com/docu/induse/, "Indicator Plotting":----------

    close_over_sma = self.data.close > self.sma
    LinePlotterIndicator(close_over_sma, name='Close_over_SMA)
    

    ...is missing a final "'" before ")"

    ------- same page: "The init vs next why" ---------
    "A complete example which generates a buy signal during init:

    class MyStrategy(bt.Strategy):
    
        def __init__(self):
    
            sma1 = btind.SimpleMovingAverage(self.data)
            ema1 = btind.ExponentialMovingAverage()
    
            close_over_sma = self.data.close > sma1
            close_over_ema = self.data.close > ema1
            sma_ema_diff = sma - ema
    
            buy_sig = bt.And(close_over_sma, close_over_ema, sma_ema_diff > 0)
    
        def next(self):
    
            if buy_sig:
                self.buy()
    

    I think we are missing a "1" as in:

    sma_ema_diff = sma1 - ema1 # reference lines objects instantiated just above in strategy.__init__()
    

    Given the magic sauce in bt, the interesting bug-finding I have been doing in my indicators-of-indicators trying to reference the time of the parent strategy, indicator booleans, startup issues on indicators that want to look back in time and such, it is entirely probable that I err in that last, in which case, do carry on, and as I say, minutiae.

    Mostly, I read, think hard, .class() and .dir() myself towards understanding, finally "get it", fix my code, and move on.
    If such administrivia matter, let me know what the correct process might be and I'll follow it.



  • More minutiae, not related to website, but perhaps someone's keyword search will land them here and this will help.
    I find working with dates and times and timedeltas and datetime enough as it is in python, but there are some extra issues to be noted when working in the bt infrastructure with these things.
    First of course is that the datetime lines in bt are in ~matplotlib float format (+ an hour?), and one should use the built-in bt functions, but there is another thing

    The minutiae to be noted is that I find it quite odd, almost misleading, that in bt nomenclature, "dt" stands for "date", "date" stands for "datetime", as in:

    def num2date(x, tz=None, naive=True):
        # Same as matplotlib except if tz is None a naive datetime object
        # will be returned.
    ...
    def num2dt(num, tz=None, naive=True):
        return num2date(num, tz=tz, naive=naive).date()
    ...
    def num2time(num, tz=None, naive=True):
        return num2date(num, tz=tz, naive=naive).time()
    

    My code didn't work using my "obvious" name-interpretation of dt = 'datetime', date ='date' so I looked in bt.utils and lo, my guess was wrong, see above. This is very likely well-documented on the sites, but I went to code instead. There was likely some logic to the convention, but it was not obvious to me. No changing this now I suppose, move on, nothing to see here unless you were having issues with math on dates and times and this post helped!



  • --- https://www.backtrader.com/docu/concepts/ -"Almost everything is a Data Feed"-------

    class MyStrategy(bt.Strategy):
        params = dict(period1=20, period2=25, period3=10, period4)
    
        def __init__(self):
    
            sma1 = btind.SimpleMovingAverage(self.datas[0], period=self.p.period1)
    
            # This 2nd Moving Average operates using sma1 as "data"
            sma2 = btind.SimpleMovingAverage(sma1, period=self.p.period2)
    
            # New data created via arithmetic operation
            something = sma2 - sma1 + self.data.close
    
            # This 3rd Moving Average operates using something  as "data"
            sma3 = btind.SimpleMovingAverage(something, period=self.p.period3)
    
            # Comparison operators work too ...  JBB:  THIS LINE WILL WORK???????
            greater = sma3 > sma
    

    That last line... I dunno, @backtrader either there is more magic than I understand, or that last "sma" would need a digit after it to allow it to cut and paste and work.

    I am bumping into these issues in docs (self.believes) while trying to get boolean lines operations involving time-of-day working when the indicator doing the time-math and bool is buried deep in custom indicator calls of calls. I think it does not help that bt.If() is not yet in my lexicon, though bt.And() is now my familiar friend.

    I read that no time info was passed to indicators on purpose, but was attempting a hack around that. It popped up when I just went one level deeper in my indicator-chain.
    Time snuck it's way in there near the bottom of the call-stack. I wonder if there is an "easy" approach for an indicator to fetch/know the current time, independent of how deep it is in the call-chain... something obvious that I am overlooking. I have found that is usually the case... but I haven't yet found my way through this in the docs...

    Yes, code snippets would assist, and I ask a question on the wrong thread, so, returning to this one, I think a minutial digit is needed at the referenced location above, @backtrader.


  • administrators

    The typos have been fixed.

    Indicators, indeed, don't have a datetime indication because they can be created from sources which don't have any datetime information and can be nested several levels.

    Imho, if you need datetime information after several nesting levels, that's not an indicator. 1st level indicators will in most cases have a data feed which can be used as a clock source. If you need the datetime further beyond, you will have to pass the clock source to the next levels (this actually shows the rationale of why they don't have any datetime payload)

    To work with date, time and hence datetime, you probably want to work directly with the methods provided by the data feeds, which take into account whether timezones are in play or not.



  • I will continue to post any issues with web-content here, then.

    While your response was pending (re: my non-thread question), I was coming to the same conclusion that I was abusing the class, and had moved some temporal functions back up to strategy-level in order to overcome the absence of inherited time-context, the rationale for which I understand.

    With the ability to call

    bt.LinePlotterIndicator(func)
    

    from up there if I want to see it plotted, I think I have all I need.

    Thanks for the notes and for caring enough to update the minor typos:

    "How infinitessimal is the importance of anything I do.
    How infinitely important it is that I do it."

    (approximately Voltaire, but likely slightly mis-quoted, from memory)


Log in to reply
 

});