Skip to content

Bug Report: key error in bbands calculatiuon using Candles feature #67

@smatiush

Description

@smatiush

Describe the bug

hi all,
i'm currently trying to calculate volatility using the Candles features,
my code looks like that:

INTERVALS = ["30m"]
VOLATILITY_WINDOW = 100

Image
Volatility(VolatilityConfig(window=VOLATILITY_WINDOW)).calculate(all_candles[INTERVALS[0]][0].data)

and get this:

Cell In[14], line 1
----> 1 all_candles[INTERVALS[0]][0].add_features([Volatility(VolatilityConfig(window=VOLATILITY_WINDOW)), Volume(VolumeConfig(short_term_window=VOLUME_SHORT_WINDOW, long_term_window=VOLUME_LONG_WINDOW))])

File ~/quants-lab/core/data_structures/data_structure_base.py:16, in DataStructureBase.add_features(self, features)
     14 def add_features(self, features: List[FeatureBase]):
     15     for feature in features:
---> 16         self.data = feature.calculate(self.data)
     17     return self

File ~/quants-lab/core/features/candles/volatility.py:41, in Volatility.calculate(self, data)
     39 # Bollinger Bands width
     40 bbands = ta.bbands(df["close"], length=window)
---> 41 df["bb_width"] = bbands[f"BBB_{window}_2.0"]
     43 return df

File ~/miniconda3/envs/quants-lab/lib/python3.12/site-packages/pandas/core/frame.py:4113, in DataFrame.__getitem__(self, key)
   4111 if self.columns.nlevels > 1:
   4112     return self._getitem_multilevel(key)
-> 4113 indexer = self.columns.get_loc(key)
   4114 if is_integer(indexer):
   4115     indexer = [indexer]

File ~/miniconda3/envs/quants-lab/lib/python3.12/site-packages/pandas/core/indexes/base.py:3819, in Index.get_loc(self, key)
   3814     if isinstance(casted_key, slice) or (
   3815         isinstance(casted_key, abc.Iterable)
   3816         and any(isinstance(x, slice) for x in casted_key)
   3817     ):
   3818         raise InvalidIndexError(key)
-> 3819     raise KeyError(key) from err
   3820 except TypeError:
   3821     # If we have a listlike key, _check_indexing_error will raise
   3822     #  InvalidIndexError. Otherwise we fall through and re-raise
   3823     #  the TypeError.
   3824     self._check_indexing_error(key)

KeyError: 'BBB_100_2.0'

after a simple investigation on what pandas ta give us back i found this:

Image

the code for calculating the volatility is in the quants-labs/core/features/candles/volatility.py
the culprit is Volatility.calculate() method:

def calculate(self, data):
        """Calculate volatility indicators on data."""
        window = self.config.window
        df = data.copy()

        # Standard deviation of returns
        df["volatility"] = df["close"].pct_change().rolling(window=window).std()

        # Normalized ATR
        df["natr"] = ta.natr(df["high"], df["low"], df["close"], length=window) / 100

        # Bollinger Bands width
        bbands = ta.bbands(df["close"], length=window)
        df["bb_width"] = bbands[f"BBB_{window}_2.0"]  #<--- here the culprit line

        return df

we can see from the screen that our df have double "_2.0" in the name.
the real problem is that pandas ta build the df name for bb calculation method, adding the "_x.x" to df name based on 2 parameter of the method "lower_std" and "upper_std"(Ref. /pandas_ta/volatility/bbands.py)

looking at the fact that in the volatility.py we can omit these param, in this way we use the defaults that are always 2.0. standardizing the name and adding just a "_2.0" to the culprit line inside of volatility.py should be enogh.

Steps to reproduce bug

  1. try calculate the volatility using the Candles feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions