Source code for backtrader.indicators.contrib.smoothed_adx_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 (
    ADX,
    ExponentialMovingAverage,
    Indicator,
    MinusDirectionalIndicator,
    PlusDirectionalIndicator,
    SimpleMovingAverage,
    SmoothedMovingAverage,
    WeightedMovingAverage,
)

__all__ = [
    "SmoothedADXIndicator",
]


def resolve_ma_class(name):
    """Map a moving-average name to its backtrader indicator class.

    Args:
        name: MA type name (e.g. ``t3``, ``ema``, ``sma``, ``smma`` or MT5-style
            ``mode_*`` variants); several smoothing variants map to EMA.

    Returns:
        The matching backtrader moving-average indicator class, defaulting to
        the weighted moving average for unrecognized names.
    """
    mode = str(name).lower()
    if mode in {
        "mode_t3",
        "t3",
        "mode_ema",
        "ema",
        "mode_ama",
        "ama",
        "mode_jjma",
        "jjma",
        "mode_jurx",
        "jurx",
        "mode_vidya",
        "vidya",
        "mode_parma",
        "parma",
    }:
        return ExponentialMovingAverage
    if mode in {"mode_sma", "sma"}:
        return SimpleMovingAverage
    if mode in {"mode_smma", "smma"}:
        return SmoothedMovingAverage
    return WeightedMovingAverage


[docs] class SmoothedADXIndicator(Indicator): """ADX/DI system with each line smoothed by a configurable moving average. Computes raw +DI, -DI and ADX over ``adx_period`` and exposes moving-average smoothed versions on the ``plus_di``, ``minus_di`` and ``adx`` lines. """ lines = ("plus_di", "minus_di", "adx") params = ( ("xma_method", "t3"), ("adx_period", 14), ("adx_phase", 100), ) def __init__(self): """Build the raw +DI/-DI/ADX indicators and their smoothed lines.""" ma_cls = resolve_ma_class(self.p.xma_method) self._plus = PlusDirectionalIndicator(self.data, period=max(1, int(self.p.adx_period))) self._minus = MinusDirectionalIndicator(self.data, period=max(1, int(self.p.adx_period))) self._adx_raw = ADX(self.data, period=max(1, int(self.p.adx_period))) self._plus_smooth = ma_cls(self._plus, period=max(1, int(self.p.adx_period))) self._minus_smooth = ma_cls(self._minus, period=max(1, int(self.p.adx_period))) self._adx_smooth = ma_cls(self._adx_raw, period=max(1, int(self.p.adx_period))) self.lines.plus_di = self._plus_smooth self.lines.minus_di = self._minus_smooth self.lines.adx = self._adx_smooth self.addminperiod(int(self.p.adx_period) * 3)