Source code for backtrader.indicators.contrib.aroon_horn_sign_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__ = [
    "AroonHornSignIndicator",
]


[docs] class AroonHornSignIndicator(Indicator): """Reconstructs AroonHornSign indicator. BULLS = 100 - (bars_since_highest_high + 0.5) * 100 / AroonPeriod BEARS = 100 - (bars_since_lowest_low + 0.5) * 100 / AroonPeriod trend = +1 if BULLS > BEARS and BULLS >= 50 trend = -1 if BULLS < BEARS and BEARS >= 50 BullsAroon (buy arrow) when trend flips from -1 to +1: low - ATR*3/8 BearsAroon (sell arrow) when trend flips from +1 to -1: high + ATR*3/8 Buffers: 0=BearsAroon(sell), 1=BullsAroon(buy). """ lines = ("bears_aroon", "bulls_aroon") params = ( ("aroon_period", 9), ("atr_period", 10), ) def __init__(self): """Initialize Aroon window, ATR window, and trend tracking state.""" self._ap = int(self.p.aroon_period) self._atr_p = int(self.p.atr_period) self._trend_prev = 0 self.addminperiod(max(self._ap, self._atr_p) + 3) def _calc_atr(self): period = self._atr_p total = 0.0 for i in range(period): h = float(self.data.high[-i]) low_price = float(self.data.low[-i]) if i + 1 < len(self.data): pc = float(self.data.close[-(i + 1)]) tr = max(h - low_price, abs(h - pc), abs(low_price - pc)) else: tr = h - low_price total += tr return total / period
[docs] def next(self): """Compute bear/bull arrow levels based on trend flips and ATR displacement.""" ap = self._ap # Find bars since highest high and lowest low within AroonPeriod max_idx = 0 max_val = float(self.data.high[0]) min_idx = 0 min_val = float(self.data.low[0]) for i in range(ap): h = float(self.data.high[-i]) low_price = float(self.data.low[-i]) if h > max_val: max_val = h max_idx = i if low_price < min_val: min_val = low_price min_idx = i bulls = 100.0 - (max_idx + 0.5) * 100.0 / ap bears = 100.0 - (min_idx + 0.5) * 100.0 / ap trend = self._trend_prev if bulls > bears and bulls >= 50: trend = 1 if bulls < bears and bears >= 50: trend = -1 bu = 0.0 be = 0.0 if self._trend_prev < 0 and trend > 0: atr = self._calc_atr() bu = float(self.data.low[0]) - atr * 3.0 / 8.0 if self._trend_prev > 0 and trend < 0: atr = self._calc_atr() be = float(self.data.high[0]) + atr * 3.0 / 8.0 self._trend_prev = trend self.lines.bears_aroon[0] = be self.lines.bulls_aroon[0] = bu