Source code for backtrader.indicators.contrib.bulls_bears_eyes

#!/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 (
    ExponentialMovingAverage,
    Indicator,
)

__all__ = [
    "BullsBearsEyes",
]


[docs] class BullsBearsEyes(Indicator): """Rebuild a signal oscillator from recursive smoothed directional momentum.""" lines = ("value",) params = ( ("period", 13), ("gamma", 0.6), ) def __init__(self): """Initialize EMA and recursive helper state used by the indicator.""" self.ema = ExponentialMovingAverage(self.data.close, period=int(self.p.period)) self.addminperiod(int(self.p.period) + 5) self._l0 = 0.0 self._l1 = 0.0 self._l2 = 0.0 self._l3 = 0.0
[docs] def next(self): """Compute the next recursive signal value and write it to ``lines.value``.""" bulls = float(self.data.high[0] - self.ema[0]) bears = float(self.data.low[0] - self.ema[0]) gamma = float(self.p.gamma) l0a = self._l0 l1a = self._l1 l2a = self._l2 l3a = self._l3 l0 = (1.0 - gamma) * (bears + bulls) + gamma * l0a l1 = -gamma * l0 + l0a + gamma * l1a l2 = -gamma * l1 + l1a + gamma * l2a l3 = -gamma * l2 + l2a + gamma * l3a cu = 0.0 cd = 0.0 if l0 >= l1: cu += l0 - l1 else: cd += l1 - l0 if l1 >= l2: cu += l1 - l2 else: cd += l2 - l1 if l2 >= l3: cu += l2 - l3 else: cd += l3 - l2 self.lines.value[0] = cu / (cu + cd) if (cu + cd) != 0.0 else 0.0 self._l0 = l0 self._l1 = l1 self._l2 = l2 self._l3 = l3