Source code for backtrader.indicators.contrib.blau_ergodic

#!/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.
"""

import backtrader.functions as btfunc

from .. import (
    EMA,
    Indicator,
)

__all__ = [
    "BlauErgodic",
]


[docs] class BlauErgodic(Indicator): """Blau Ergodic oscillator: triple-smoothed normalised momentum. Price momentum and its absolute value are each triple-smoothed with EMAs; the main line is 100 times their ratio (guarded against division by zero). The signal line is an EMA of the main line, and spread is their difference. """ lines = ("main", "signal", "spread") params = ( ("xlength", 2), ("xlength1", 20), ("xlength2", 5), ("xlength3", 3), ("xlength4", 3), ) def __init__(self): """Build the triple-EMA momentum chain for main, signal and spread.""" shift = max(int(self.p.xlength) - 1, 1) momentum = self.data.close - self.data.close(-shift) abs_momentum = abs(momentum) xmom = EMA(momentum, period=int(self.p.xlength1)) xxmom = EMA(xmom, period=int(self.p.xlength2)) xxxmom = EMA(xxmom, period=int(self.p.xlength3)) xabsmom = EMA(abs_momentum, period=int(self.p.xlength1)) xxabsmom = EMA(xabsmom, period=int(self.p.xlength2)) xxxabsmom = EMA(xxabsmom, period=int(self.p.xlength3)) self.l.main = btfunc.DivByZero(100.0 * xxxmom, xxxabsmom, zero=0.0) self.l.signal = EMA(self.l.main, period=int(self.p.xlength4)) self.l.spread = self.l.main - self.l.signal