Source code for backtrader.indicators.contrib.the20s_v020_signal

#!/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 (
    ATR,
    Indicator,
)

__all__ = [
    "The20sV020Signal",
]


[docs] class The20sV020Signal(Indicator): """Reversal signal from prior-bar 20% zones with an ATR-offset entry.""" lines = ("sell", "buy") params = ( ("alg", "MODE_1"), ("level", 100), ("ratio", 0.2), ("direct", False), ("atr_period", 15), ("point", 0.01), ) def __init__(self): """Build the ATR sub-indicator and set the warm-up minimum period.""" self.atr = ATR(self.data, period=max(int(self.p.atr_period), 1)) self.addminperiod(max(int(self.p.atr_period), 5) + 6)
[docs] def next(self): """Emit buy/sell signal levels from the prior-bar 20% zone logic. Resets both lines to zero, and once enough bars exist computes the prior-bar range, its upper/lower 20% zones, and the ATR. Under MODE_1 it flags a reversal when the previous bar spans the band and the current bar breaks beyond it by the level threshold; under MODE_2 it uses a three-bar expansion-then-inside pattern. The ``direct`` flag optionally swaps the buy and sell outputs. """ self.lines.buy[0] = 0.0 self.lines.sell[0] = 0.0 if len(self.data) < 6: return dlevel = float(self.p.level) * float(self.p.point) last_range = float(self.data.high[-1]) - float(self.data.low[-1]) top20 = float(self.data.high[-1]) - last_range * float(self.p.ratio) bottom20 = float(self.data.low[-1]) + last_range * float(self.p.ratio) atr = float(self.atr[0]) raw_buy = 0.0 raw_sell = 0.0 if str(self.p.alg) == "MODE_1": if ( float(self.data.open[-1]) >= top20 and float(self.data.close[-1]) <= bottom20 and float(self.data.low[0]) <= float(self.data.low[-1]) - dlevel ): raw_buy = float(self.data.low[0]) - atr * 3.0 / 8.0 elif ( float(self.data.open[-1]) <= bottom20 and float(self.data.close[-1]) >= top20 and float(self.data.high[0]) >= float(self.data.high[-1]) + dlevel ): raw_sell = float(self.data.high[0]) + atr * 3.0 / 8.0 else: cond = ( (float(self.data.high[-4]) - float(self.data.low[-4]) > last_range) and (float(self.data.high[-3]) - float(self.data.low[-3]) > last_range) and (float(self.data.high[-2]) - float(self.data.low[-2]) > last_range) and float(self.data.high[-2]) > float(self.data.high[-1]) and float(self.data.low[-2]) < float(self.data.low[-1]) ) if cond: if float(self.data.open[0]) <= bottom20: raw_buy = float(self.data.low[0]) - atr * 3.0 / 8.0 if float(self.data.open[0]) >= top20: raw_sell = float(self.data.high[0]) + atr * 3.0 / 8.0 if bool(self.p.direct): self.lines.buy[0] = raw_buy self.lines.sell[0] = raw_sell else: self.lines.buy[0] = raw_sell self.lines.sell[0] = raw_buy