Source code for backtrader.indicators.contrib.roc2_vg_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 Indicator
__all__ = [
"ROC2VGIndicator",
]
def _calc_roc(price, prev_price, roc_type):
if prev_price == 0:
return 0.0
if roc_type == 1: # MOM
return price - prev_price
if roc_type == 2: # ROC
return ((price / prev_price) - 1) * 100
if roc_type == 3: # ROCP
return (price - prev_price) / prev_price
if roc_type == 4: # ROCR
return price / prev_price
if roc_type == 5: # ROCR100
return (price / prev_price) * 100
return (price - prev_price) / prev_price
[docs]
class ROC2VGIndicator(Indicator):
"""Reconstructs ROC2_VG indicator.
DRAW_FILLING between ROC1 and ROC2.
Buffer 0 = ROC1 (period1, type1), Buffer 1 = ROC2 (period2, type2).
"""
lines = ("roc1", "roc2")
params = (
("roc_period1", 8),
("roc_type1", 1),
("roc_period2", 14),
("roc_type2", 1),
)
def __init__(self):
"""Initialize ROC periods and required minimum history window."""
self._p1 = int(self.p.roc_period1)
self._p2 = int(self.p.roc_period2)
self._t1 = int(self.p.roc_type1)
self._t2 = int(self.p.roc_type2)
self.addminperiod(max(self._p1, self._p2) + 2)
[docs]
def next(self):
"""Populate ``roc1`` and ``roc2`` for the current bar."""
price = float(self.data.close[0])
if self._p1 < len(self.data):
prev1 = float(self.data.close[-self._p1])
else:
prev1 = price
self.lines.roc1[0] = _calc_roc(price, prev1, self._t1)
if self._p2 < len(self.data):
prev2 = float(self.data.close[-self._p2])
else:
prev2 = price
self.lines.roc2[0] = _calc_roc(price, prev2, self._t2)