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 with look back



  • Hi
    I am at wits end after searching for answers and also reading the dox. I reckon my understanding is still not good enough and hoping for some expert advice. My indicator is not complete yet, but stuck at some parts. I am trying to do it as declarative in __init__as it possibly can as I feel a part of me missing if I dont.

    Code as follows and I keep getting an empty array in ys which I think its the problem.

    class CandlePower(bt.Indicator):
        """
        1. Buyers or Sellers in control - e.g green candle - close price is closer to top or bottom of candle
        2. Is there strength in the move - size of candle relative to the others in the period. Use a plot of xs and ys, find slope of the line through the points. xs is just the x axis 1, 2 & 3. ys are size of candle bar. 
    
        """
        lines = ('candle_power', 'perc_of_range', 'slope')
        params = (dict(period=3, safediv=True))
    
        plotlines = dict(
                    candle_power=dict(_name='CP', marker='v', markersize=6.0, ls='', color='pink', _skipnan=True),
                    slope=dict(_name='slope', _plotskip=True),
                    perc_of_range=dict(_name='perc_of_range', _plotskip=True),
    
                    )
    
        plotinfo = dict(subplot=True)
    
        def __init__(self):
            # Any operation involving lines objects during __init__ generates another lines object
            # self.candle_size = [self.data.open(i) - self.data.close(i) for i in range(0 - self.p.period + 1, 1, 1)]  # returns list [-0.2,-0.1, 0.05] of len period
            # super(CandlePower, self).__init__()
            self.l.perc_of_range = bt.If(self.data.close >= self.data.open, bt.DivByZero((self.data.high - self.data.close), (self.data.high - self.data.low), zero=0.0),
                                         bt.DivByZero((self.data.close - self.data.low), (self.data.high - self.data.low), zero=0.0))
    
            xs = np.array(list(range(1, self.p.period + 1)), dtype=np.float64)  # converts [1,2,3] to array and this is a constant
            candle_size = self.data.close - self.data.open  # lineOperation obj, even if I change this to a line, ys is still empty.
            ys = candle_size.get(size=self.p.period)  # get the last 3 periods, returns an array.
            ys = np.array(ys, dtype=np.float64)  # convert to np array like xs
            self.l.slope = ((mean(xs) * mean(ys)) - mean(xs * ys)) / ((mean(xs) * mean(xs)) - mean(xs * xs)) * 100000  # returns slope of sizes of candles to see if inc or dec
    
        def next(self):
            # Any operation involving lines objects during next yields regular Python types like floats and bools
    
            if 0 <= self.l.perc_of_range[0] >= 0.25 and self.l.slope[0] > 5:  # 0 - 0.25
                self.l.candle_power[0] = 2
    
            elif 0.76 < self.l.perc_of_range[0] <= 1.00 and self.l.slope[0] < - 5:  # 0.76 - 1.00
                self.l.candle_power[0] = -2
            else:
                self.l.candle_power[0] = float('nan')
    

    And since I am here, I like to take the chance to ask one more question.
    Becasue my oop is weak, I like to ask what does super(CandlePower, self).init do? When would I need this line?

    Thanks in advance!



  • This

    ys = candle_size.get(size=self.p.period)
    

    will work in the next(), not in the init().


Log in to reply
 

});