Source code for backtrader.indicators.contrib.xma_ishimoku_channel_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 (
EMA,
SMA,
Highest,
Indicator,
Lowest,
SmoothedMovingAverage,
WeightedMovingAverage,
)
__all__ = [
"XMAIshimokuChannelIndicator",
]
def resolve_ma_class(name):
"""Resolve a moving-average identifier into a Backtrader indicator class."""
mode = str(name).lower()
if mode in {"sma", "mode_sma"}:
return SMA
if mode in {"ema", "mode_ema"}:
return EMA
if mode in {"smma", "mode_smma"}:
return SmoothedMovingAverage
return WeightedMovingAverage
[docs]
class XMAIshimokuChannelIndicator(Indicator):
"""Compute XMA-smoothed midpoint channel lines."""
lines = (
"mid",
"upper",
"lower",
)
params = (
("up_period", 3),
("dn_period", 3),
("up_mode", "high"),
("dn_mode", "low"),
("xma_method", "sma"),
("xlength", 100),
("xphase", 15),
("up_percent", 1.0),
("dn_percent", 1.0),
("price_shift", 0),
)
def __init__(self):
"""Prepare indicator buffers and min-period for channel outputs."""
ma_cls = resolve_ma_class(self.p.xma_method)
highest = Highest(self.data.high, period=self.p.up_period)
lowest = Lowest(self.data.low, period=self.p.dn_period)
midpoint = (highest + lowest) / 2.0
self.lines.mid = ma_cls(midpoint, period=self.p.xlength) + self.p.price_shift
self.lines.upper = self.lines.mid * (1.0 + self.p.up_percent / 100.0)
self.lines.lower = self.lines.mid * (1.0 - self.p.dn_percent / 100.0)
self.addminperiod(max(self.p.up_period, self.p.dn_period, self.p.xlength) + 3)