Source code for backtrader.indicators.contrib.jma_slope_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 (
ExponentialMovingAverage,
If,
Indicator,
)
__all__ = [
"JMASlopeIndicator",
]
def resolve_price_line(data, mode):
"""Return the applied-price line for a data feed given a price mode.
Args:
data: The data feed providing OHLC lines.
mode: Applied-price selector (e.g. ``price_close``, ``price_median``,
``price_typical`` or their short forms).
Returns:
A line expression for the selected applied price, defaulting to the
close for unrecognized modes.
"""
price_mode = str(mode).lower()
if price_mode in {"price_open", "open"}:
return data.open
if price_mode in {"price_high", "high"}:
return data.high
if price_mode in {"price_low", "low"}:
return data.low
if price_mode in {"price_median", "median"}:
return (data.high + data.low) / 2.0
if price_mode in {"price_typical", "typical"}:
return (data.high + data.low + data.close) / 3.0
if price_mode in {"price_weighted", "weighted"}:
return (2.0 * data.close + data.high + data.low) / 4.0
if price_mode in {"price_simpl", "simpl"}:
return (data.open + data.close) / 2.0
if price_mode in {"price_quarter", "quarter"}:
return (data.high + data.low + data.open + data.close) / 4.0
return data.close
[docs]
class JMASlopeIndicator(Indicator):
"""Slope of a Jurik-style moving average with a rising/falling color.
Approximates the JMA with an EMA of the applied price, then exposes its
bar-over-bar change on the ``value`` line and a ``color`` line marking
whether the slope is positive (4), negative (0) or flat (2).
"""
lines = ("value", "color")
params = (
("jlength", 14),
("jphase", 0),
("ipc", "price_close"),
)
def __init__(self):
"""Build the JMA proxy and its slope/color lines; set the min period."""
price_line = resolve_price_line(self.data, self.p.ipc)
self._jma = ExponentialMovingAverage(price_line, period=max(1, int(self.p.jlength)))
delta = self._jma - self._jma(-1)
self.lines.value = delta
self.lines.color = If(delta > 0.0, 4.0, If(delta < 0.0, 0.0, 2.0))
self.addminperiod(32 + int(self.p.jlength))