pythonindieindie-v4

Cannot Apply + Operator Between Series[float] and float


I'm developing an indicator in Indie. I’m trying to calculate Bollinger Bands and Keltner Channels, but I’m running into an error when adding a Series[float] to a float value.

Here’s the error message:

Error: 20:20 cannot apply operator + to operands of types: <class 'indie.Series[float]'> and <class 'float'>

Here’s the relevant code snippet:

sDev = StdDev.new(self.close, length)
mid_line_bb = Sma.new(self.close, length)
lower_band_bb = mid_line_bb + num_dev_dn * sDev[0]  # <-- ERROR HERE
upper_band_bb = mid_line_bb + num_dev_up * sDev[0]  # <-- ERROR HERE

What I’ve Tried:

  1. Wrapping sDev[0] with MutSeriesF.new(), but that caused another issue.
  2. Using sDev.value_or(0) (which doesn’t seem to exist in Indie v4).
  3. Looking for an explicit type conversion function in Indie’s documentation.

I assume the issue is that mid_line_bb is a Series[float], while sDev[0] is a single float. How should I properly handle this type of mismatch in Indie?


Solution

  • The problem is that you cannot add a Series container with a float number, you must extract a specific value from the Series and perform an arithmetic operation with it.

    You can extract the value from the Series using square brackets mid_line_bb[0] or using the get method mid_line_bb.get(offset=0, default=0).

    The source code of the BB algorithm on Indie may also help you:

    # indie:lang_version = 5
    from indie import algorithm, SeriesF, MutSeriesF
    from indie.algorithms import Sma, StdDev
    
    
    @algorithm
    def Bb(self, src: SeriesF, length: int, mult: float) -> tuple[SeriesF, SeriesF, SeriesF]:
        '''Bollinger Bands'''
        middle = Sma.new(src, length)[0]
        dev = mult * StdDev.new(src, length)[0]
        lower = middle - dev
        upper = middle + dev
        return MutSeriesF.new(lower), MutSeriesF.new(middle), MutSeriesF.new(upper)
    

    If we adapt this to your example, we will get the following indicator code:

    # indie:lang_version = 5
    from indie import indicator, param
    from indie.algorithms import StdDev, Sma
    
    @indicator('Std dev', overlay_main_pane=True)
    @param.int('length', default=5)
    @param.float('num_dev_dn', default=1.0)
    @param.float('num_dev_up', default=1.0)
    def Main(self, length, num_dev_dn, num_dev_up):
        sDev = StdDev.new(self.close, length)
        mid_line_bb = Sma.new(self.close, length)
        lower_band_bb = mid_line_bb[0] + num_dev_dn * sDev[0]
        upper_band_bb = mid_line_bb[0] + num_dev_up * sDev[0]
        return mid_line_bb[0], lower_band_bb, upper_band_bb
    

    This code on Indie v4 would have looked the same, switching to v5 did not affect working with Series type.