Source code for backtrader.indicators.contrib.accumulation_distribution_line

#!/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,
    SimpleMovingAverage,
)

__all__ = [
    "AccumulationDistributionLine",
    "ChaikinOscillator",
    "LineCCI",
    "CCIDualOnMA",
]


[docs] class AccumulationDistributionLine(Indicator): """Accumulate the ADL indicator from price and volume progression.""" lines = ("adl",)
[docs] def next(self): """Compute one bar's accumulation/distribution line value.""" high = float(self.data.high[0]) low = float(self.data.low[0]) close = float(self.data.close[0]) volume = float(self.data.volume[0]) if high == low: money_flow_multiplier = 0.0 else: money_flow_multiplier = ((close - low) - (high - close)) / (high - low) previous = float(self.lines.adl[-1]) if len(self) > 1 else 0.0 self.lines.adl[0] = previous + money_flow_multiplier * volume
[docs] class ChaikinOscillator(Indicator): """Chaikin oscillator as EMA(short) minus EMA(long) of ADL.""" lines = ("cho",) params = ( ("fast_period", 3), ("slow_period", 10), ) def __init__(self): """Initialize fast/slow ADL EMAs.""" self.adl = AccumulationDistributionLine(self.data) fast = ExponentialMovingAverage(self.adl, period=self.p.fast_period) slow = ExponentialMovingAverage(self.adl, period=self.p.slow_period) self.lines.cho = fast - slow
[docs] class LineCCI(Indicator): """Custom CCI computation on the selected input data.""" lines = ("cci",) params = (("period", 14),)
[docs] def next(self): """Calculate a bar's CCI value with zero-handling for degenerate windows.""" if len(self.data) < self.p.period: self.lines.cci[0] = 0.0 return values = [float(self.data[-i]) for i in range(self.p.period)] mean_value = sum(values) / self.p.period mean_dev = sum(abs(v - mean_value) for v in values) / self.p.period if mean_dev == 0: self.lines.cci[0] = 0.0 return self.lines.cci[0] = (float(self.data[0]) - mean_value) / (0.015 * mean_dev)
[docs] class CCIDualOnMA(Indicator): """Provide fast/slow CCI values computed on a smoothing moving average.""" lines = ("fast", "slow") params = ( ("ma_period", 12), ("fast_period", 14), ("slow_period", 50), ) def __init__(self): """Initialize smoothed MA and dual CCI lines.""" self.ma = SimpleMovingAverage(self.data.close, period=self.p.ma_period) self.lines.fast = LineCCI(self.ma, period=self.p.fast_period) self.lines.slow = LineCCI(self.ma, period=self.p.slow_period)