Source code for backtrader.indicators.contrib.cci_woodies_indicator

#!/usr/bin/env python
"""Functional-test indicators migrated to contrib.

Generated from a single functional strategy module to preserve file-local
helper functions and constants without cross-test name collisions.
"""

from .. import Indicator

__all__ = [
    "CCIWoodiesIndicator",
]


def _applied_price(data, price_type, ago=0):
    """Get price based on ENUM_APPLIED_PRICE."""
    o = float(data.open[-ago])
    h = float(data.high[-ago])
    low_price = float(data.low[-ago])
    c = float(data.close[-ago])
    if price_type == 0:
        return c  # PRICE_CLOSE
    if price_type == 1:
        return o  # PRICE_OPEN
    if price_type == 2:
        return h  # PRICE_HIGH
    if price_type == 3:
        return low_price  # PRICE_LOW
    if price_type == 4:
        return (h + low_price) / 2  # PRICE_MEDIAN
    if price_type == 5:
        return (h + low_price + c) / 3  # PRICE_TYPICAL
    if price_type == 6:
        return (h + low_price + c + c) / 4  # PRICE_WEIGHTED
    return c


[docs] class CCIWoodiesIndicator(Indicator): """Reconstructs CCI_Woodies indicator. DRAW_FILLING between FastCCI and SlowCCI. Buffer 0 = FastCCI, Buffer 1 = SlowCCI. When Fast > Slow → bullish (Lime fill); when Fast < Slow → bearish (Plum fill). """ lines = ("fast_cci", "slow_cci") params = ( ("fast_period", 6), ("fast_price", 4), ("slow_period", 14), ("slow_price", 4), ) def __init__(self): """Build internal period and price type state for fast and slow CCI.""" self._fp = int(self.p.fast_period) self._sp = int(self.p.slow_period) self._fpr = int(self.p.fast_price) self._spr = int(self.p.slow_price) self.addminperiod(max(self._fp, self._sp) + 2) def _calc_cci(self, period, price_type): prices = [] for i in range(period): if i >= len(self.data): break prices.append(_applied_price(self.data, price_type, i)) if not prices: return 0.0 mean = sum(prices) / len(prices) mad = sum(abs(p - mean) for p in prices) / len(prices) tp = prices[0] # current bar if mad == 0: return 0.0 return (tp - mean) / (0.015 * mad)
[docs] def next(self): """Compute and store current fast and slow CCI values for each bar.""" self.lines.fast_cci[0] = self._calc_cci(self._fp, self._fpr) self.lines.slow_cci[0] = self._calc_cci(self._sp, self._spr)