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


[docs] class AnchoredMomentumLine(Indicator): """Anchored Momentum line: EMA-vs-SMA percentage plus a zone classifier.""" lines = ("momentum", "zone") params = ( ("mom_period", 8), ("smooth_period", 6), ("up_level", 0.025), ("dn_level", -0.025), ) def __init__(self): """Create the SMA/EMA sub-indicators and set the minimum period.""" self.sma = SimpleMovingAverage(self.data, period=int(self.p.mom_period)) self.ema = ExponentialMovingAverage(self.data, period=int(self.p.mom_period)) self.addminperiod(int(self.p.mom_period) + 2)
[docs] def next(self): """Compute the percentage momentum and assign its up/neutral/down zone.""" sma = float(self.sma[0]) if sma == 0: momentum = 0.0 else: momentum = 100.0 * (float(self.ema[0]) / sma - 1.0) self.lines.momentum[0] = momentum if momentum > float(self.p.up_level): zone = 2 elif momentum < float(self.p.dn_level): zone = 0 else: zone = 1 self.lines.zone[0] = zone
[docs] class AnchoredMomentumCandleIndicator(Indicator): """Synthetic candle from Anchored Momentum on each OHLC price plus colour.""" lines = ("a_open", "a_high", "a_low", "a_close", "color") params = ( ("mom_period", 8), ("smooth_period", 6), ("up_level", 0.025), ("dn_level", -0.025), ) def __init__(self): """Create the four per-price Anchored Momentum lines and set min period.""" self.mom_open = AnchoredMomentumLine( self.data.open, mom_period=self.p.mom_period, smooth_period=self.p.smooth_period, up_level=self.p.up_level, dn_level=self.p.dn_level, ) self.mom_high = AnchoredMomentumLine( self.data.high, mom_period=self.p.mom_period, smooth_period=self.p.smooth_period, up_level=self.p.up_level, dn_level=self.p.dn_level, ) self.mom_low = AnchoredMomentumLine( self.data.low, mom_period=self.p.mom_period, smooth_period=self.p.smooth_period, up_level=self.p.up_level, dn_level=self.p.dn_level, ) self.mom_close = AnchoredMomentumLine( self.data.close, mom_period=self.p.mom_period, smooth_period=self.p.smooth_period, up_level=self.p.up_level, dn_level=self.p.dn_level, ) self.addminperiod(int(self.p.mom_period) + 2)
[docs] def next(self): """Assemble the momentum candle OHLC and colour for the current bar.""" o = float(self.mom_open.momentum[0]) h = max(float(self.mom_high.momentum[0]), o) low_price = min(float(self.mom_low.momentum[0]), o) c = float(self.mom_close.momentum[0]) h = max(h, c) low_price = min(low_price, c) self.lines.a_open[0] = o self.lines.a_high[0] = h self.lines.a_low[0] = low_price self.lines.a_close[0] = c if o < c: color = 2 elif o > c: color = 0 else: color = 1 self.lines.color[0] = color