Source code for backtrader.indicators.contrib.macd_candle_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 (
MACD,
Indicator,
)
__all__ = [
"MacdCandleIndicator",
]
[docs]
class MacdCandleIndicator(Indicator):
"""MACD-based candle indicator returning open/high/low/close values."""
lines = ("macd_open", "macd_high", "macd_low", "macd_close", "color")
params = (
("fast_ema_period", 12),
("slow_ema_period", 26),
("signal_period", 9),
("mode", "signal"),
)
def __init__(self):
"""Create MACD lines and register warmup period."""
self.addminperiod(
max(int(self.p.fast_ema_period), int(self.p.slow_ema_period))
+ int(self.p.signal_period)
+ 3
)
self.macd_open = MACD(
self.data.open,
period_me1=int(self.p.fast_ema_period),
period_me2=int(self.p.slow_ema_period),
period_signal=int(self.p.signal_period),
)
self.macd_high = MACD(
self.data.high,
period_me1=int(self.p.fast_ema_period),
period_me2=int(self.p.slow_ema_period),
period_signal=int(self.p.signal_period),
)
self.macd_low = MACD(
self.data.low,
period_me1=int(self.p.fast_ema_period),
period_me2=int(self.p.slow_ema_period),
period_signal=int(self.p.signal_period),
)
self.macd_close = MACD(
self.data.close,
period_me1=int(self.p.fast_ema_period),
period_me2=int(self.p.slow_ema_period),
period_signal=int(self.p.signal_period),
)
def _value(self, macd_obj):
return float(macd_obj.signal[0]) if self.p.mode == "signal" else float(macd_obj.macd[0])
[docs]
def next(self):
"""Populate output candle components and derive color state per bar."""
open_value = self._value(self.macd_open)
high_value = self._value(self.macd_high)
low_value = self._value(self.macd_low)
close_value = self._value(self.macd_close)
self.lines.macd_open[0] = open_value
self.lines.macd_high[0] = high_value
self.lines.macd_low[0] = low_value
self.lines.macd_close[0] = close_value
if open_value < close_value:
color = 2
elif open_value > close_value:
color = 0
else:
color = 1
self.lines.color[0] = color