Source code for backtrader.indicators.lrsi
#!/usr/bin/env python
"""Laguerre RSI Module - Laguerre filter-based RSI.
This module provides the LaguerreRSI indicator defined by John F. Ehlers
for faster reaction to price changes using Laguerre filters.
Classes:
LaguerreRSI: Laguerre RSI indicator (alias: LRSI).
LaguerreFilter: Laguerre filter (alias: LAGF).
Example:
class MyStrategy(bt.Strategy):
def __init__(self):
self.lrsi = bt.indicators.LRSI(self.data, gamma=0.5)
self.lfilter = bt.indicators.LAGF(self.data, gamma=0.5)
def next(self):
if self.lrsi.lrsi[0] > 0.8:
self.sell()
elif self.lrsi.lrsi[0] < 0.2:
self.buy()
"""
from . import PeriodN
__all__ = ["LaguerreRSI", "LRSI", "LaguerreFilter", "LAGF"]
[docs]
class LaguerreRSI(PeriodN):
"""
Defined by John F. Ehlers in `Cybernetic Analysis for Stock and Futures`,
2004, published by Wiley. `ISBN: 978-0-471-46307-8`
The Laguerre RSI tries to implement a better RSI by providing a sort of
*Time Warp without Time Travel* using a Laguerre filter. This provides for
faster reactions to price changes
``gamma`` is meant to have values between ``0.2`` and ``0.8``, with the
best balance found theoretically at the default of ``0.5``
"""
alias = ("LRSI",)
lines = ("lrsi",)
params = (
("gamma", 0.5),
("period", 6),
)
plotinfo = {"plotymargin": 0.15, "plotyticks": [0.0, 0.2, 0.5, 0.8, 1.0]}
l0, l1, l2, l3 = 0.0, 0.0, 0.0, 0.0
[docs]
def next(self):
"""Calculate Laguerre RSI for the current bar.
Calculates L0-L3 Laguerre filter values and computes the
RSI-style ratio of upward changes to total changes.
"""
l0_1 = self.l0 # cache previous intermediate values
l1_1 = self.l1
l2_1 = self.l2
g = self.p.gamma # avoid more lookups
self.l0 = l0 = (1.0 - g) * self.data + g * l0_1
self.l1 = l1 = -g * l0 + l0_1 + g * l1_1
self.l2 = l2 = -g * l1 + l1_1 + g * l2_1
self.l3 = l3 = -g * l2 + l2_1 + g * self.l3
cu = 0.0
cd = 0.0
if l0 >= l1:
cu = l0 - l1
else:
cd = l1 - l0
if l1 >= l2:
cu += l1 - l2
else:
cd += l2 - l1
if l2 >= l3:
cu += l2 - l3
else:
cd += l3 - l2
den = cu + cd
self.lines.lrsi[0] = 1.0 if not den else cu / den
[docs]
class LaguerreFilter(PeriodN):
"""
Defined by John F. Ehlers in `Cybernetic Analysis for Stock and Futures`,
2004, published by Wiley. `ISBN: 978-0-471-46307-8`
``gamma`` is meant to have values between ``0.2`` and ``0.8``, with the
best balance found theoretically at the default of ``0.5``
"""
alias = ("LAGF",)
lines = ("lfilter",)
params = (("gamma", 0.5),)
plotinfo = {"subplot": False}
l0, l1, l2, l3 = 0.0, 0.0, 0.0, 0.0
[docs]
def next(self):
"""Calculate Laguerre filter for the current bar.
Computes L0-L3 Laguerre filter values and outputs the
weighted average (l0 + 2*l1 + 2*l2 + l3) / 6.
"""
l0_1 = self.l0 # cache previous intermediate values
l1_1 = self.l1
l2_1 = self.l2
g = self.p.gamma # avoid more lookups
self.l0 = l0 = (1.0 - g) * self.data + g * l0_1
self.l1 = l1 = -g * l0 + l0_1 + g * l1_1
self.l2 = l2 = -g * l1 + l1_1 + g * l2_1
self.l3 = l3 = -g * l2 + l2_1 + g * self.l3
self.lines.lfilter[0] = (l0 + (2 * l1) + (2 * l2) + l3) / 6
LRSI = LaguerreRSI
LAGF = LaguerreFilter