ENH added Reflex and Trendflex indicators

Reflex and Trendflex indicators by Ehlers.
This commit is contained in:
rengel
2021-08-11 22:42:38 +02:00
parent d2a4c2ee08
commit 3ebd362b1e
7 changed files with 220 additions and 3 deletions
+2
View File
@@ -667,6 +667,7 @@ df = df.ta.cdl_pattern(name=["doji", "inside"])
### **Cycles** (1)
* _Even Better Sinewave_: **ebsw**
* _Reflex_ (companion of trendflex): **reflex**
<br/>
@@ -818,6 +819,7 @@ Use parameter: cumulative=**True** for cumulative results.
* _Parabolic Stop and Reverse_: **psar**
* _Q Stick_: **qstick**
* _Short Run_: **short_run**
* _Trendflex_ (companion of reflex): **trendflex**
* _Trend Signals_: **tsignals**
* _TTM Trend_: **ttm_trend**
* _Vertical Horizontal Filter_: **vhf**
+2 -2
View File
@@ -43,7 +43,7 @@ Category = {
"cdl_pattern", "cdl_z", "ha"
],
# Cycles
"cycles": ["ebsw"],
"cycles": ["ebsw", "reflex"],
# Momentum
"momentum": [
"ao", "apo", "bias", "bop", "brar", "cci", "cfo", "cg", "cmo",
@@ -69,7 +69,7 @@ Category = {
# Trend
"trend": [
"adx", "amat", "aroon", "chop", "cksp", "decay", "decreasing", "dpo",
"increasing", "long_run", "psar", "qstick", "short_run", "tsignals",
"increasing", "long_run", "psar", "qstick", "short_run", "trendflex", "tsignals",
"ttm_trend", "vhf", "vortex", "xsignals"
],
# Volatility
+11 -1
View File
@@ -895,6 +895,11 @@ class AnalysisIndicators(BasePandasObject):
close = self._get_column(kwargs.pop("close", "close"))
result = ebsw(close=close, length=length, bars=bars, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def reflex(self, close=None, length=None, smooth_bars=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = reflex(close=close, length=length, smooth_bars=bars, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
# Momentum
def ao(self, fast=None, slow=None, offset=None, **kwargs):
@@ -1484,7 +1489,12 @@ class AnalysisIndicators(BasePandasObject):
close = self._get_column(kwargs.pop("close", "close"))
result = supertrend(high=high, low=low, close=close, period=period, multiplier=multiplier, mamode=mamode, drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def trendflex(self, close=None, length=None, smooth_bars=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = trendflex(close=close, length=length, smooth_bars=bars, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def tsignals(self, trend=None, asbool=None, trend_reset=None, trend_offset=None, offset=None, **kwargs):
if trend is None:
return self._df
+1
View File
@@ -1,2 +1,3 @@
# -*- coding: utf-8 -*-
from .ebsw import ebsw
from .reflex import reflex
+104
View File
@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import cos as npCos
from numpy import exp as npExp
from numpy import full as npFull
from numpy import sqrt as npSqrt
from pandas import DataFrame, Series, concat
from pandas_ta.overlap import rma
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
def reflex(close, length=None, smooth_bars=None, offset=None, **kwargs):
"""Indicator: Reflex"""
# Validate arguments
close = verify_series(close, length)
length = int(length) if length and length > 0 else 20
smooth_bars = int(smooth_bars) if smooth_bars and smooth_bars > 0 else 20
offset = get_offset(offset)
# Precalculations
a1 = npExp(-1.414 * 3.14159 / smooth_bars)
b1 = 2 * a1 * npCos(1.414 * 180 / smooth_bars)
c2 = b1
c3 = -a1 * a1
c1 = 1 - c2 - c3
Filt = npFull(close.size, 0)
MS = npFull(close.size, 0)
# Reflex = list(Filt)
Reflex = npFull(close.size, npNaN)
# Calculation
for i in range(1, close.size):
# Gently smooth the data in a SuperSmoother
Filt[i] = c1 * (close[i] + close[i - 1]) / 2 + c2 * Filt[i - 1] + c3 * Filt[i - 2]
# Length is assumed cycle period
Slope = (Filt[i - length] - Filt[i]) / length
# Sum the differences
Sum = 0
for count in range(1, length):
Sum = Sum + (Filt[i] + count * Slope) - Filt[i - count]
Sum = Sum / length
# Normalize in terms of Standard Deviations
MS[i] = .04 * Sum * Sum + .96 * MS[i - 1]
if MS[i] != 0:
Reflex[i] = Sum / npSqrt(MS[i])
else:
Reflex[i] = Sum / 0.00001
result = Series(Reflex, index=close.index)
# Neutralize pre-roll phase
result.iloc[0:length] = npNaN
# Offset
if offset != 0:
result = result.shift(offset)
# Handle fills
if "fillna" in kwargs:
result.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
result.fillna(method=kwargs["fill_method"], inplace=True)
# Name and Categorize it
result.name = f"REFLEX_{length}_{smooth_bars}"
result.category = "cycles"
return result
reflex.__doc__ = \
"""Reflex (reflex)
John F. Ehlers introduced two indicators within the article "Reflex: A New Zero-Lag Indicator”
in February 2020, TASC magazine. One of which is the Reflex, a lag reduced cycle indicator.
Both indicators (Reflex/Trendflex) are oscillators and complement each other with the focus for
cycle and trend.
Written for Pandas TA by rengel8 (2021-08-11) based on the implementation on prorealcode (refer to source).
Beyond the mentioned source, this implementation has a separate control parameter for the internal
applied SuperSmoother.
Sources:
https://www.prorealcode.com/prorealtime-indicators/reflex-and-trendflex-indicators-john-f-ehlers/
Calculation:
Refer to provided source or the code above.
Args:
close (pd.Series): Series of 'close's
length (int): It's period. Default: 20
smooth_bars (int): Period of internal SuperSmoother (default: asmooth_bars = length). Default: 20
offset (int): How many periods to offset the result. Default: 0
Kwargs:
fillna (value, optional): pd.DataFrame.fillna(value)
fill_method (value, optional): Type of fill method
Returns:
pd.Series: New feature generated.
"""
+1
View File
@@ -12,6 +12,7 @@ from .long_run import long_run
from .psar import psar
from .qstick import qstick
from .short_run import short_run
from .trendflex import trendflex
from .tsignals import tsignals
from .ttm_trend import ttm_trend
from .vhf import vhf
+99
View File
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import cos as npCos
from numpy import exp as npExp
from numpy import full as npFull
from numpy import sqrt as npSqrt
from pandas import DataFrame, Series, concat
from pandas_ta.overlap import rma
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
def trendflex(close, length=None, smooth_bars=None, offset=None, **kwargs):
"""Indicator: Reflex"""
# Validate arguments
close = verify_series(close, length)
length = int(length) if length and length > 0 else 20
smooth_bars = int(smooth_bars) if smooth_bars and smooth_bars > 0 else 20
offset = get_offset(offset)
# Precalculations
a1 = npExp(-1.414 * 3.14159 / smooth_bars)
b1 = 2 * a1 * npCos(1.414 * 180 / smooth_bars)
c2 = b1
c3 = -a1 * a1
c1 = 1 - c2 - c3
Filt = npFull(close.size, 0)
MS = npFull(close.size, 0)
Trendflex = list(Filt)
# Calculation
for i in range(1, close.size):
# Gently smooth the data in a SuperSmoother
Filt[i] = c1 * (close[i] + close[i - 1]) / 2 + c2 * Filt[i - 1] + c3 * Filt[i - 2]
# Sum the differences
Sum = 0
for count in range(1, length):
Sum = Sum + Filt[i] - Filt[i - count]
Sum = Sum / length
# Normalize in terms of Standard Deviations
MS[i] = .04 * Sum * Sum + .96 * MS[i - 1]
if MS[i] != 0:
Trendflex[i] = Sum / npSqrt(MS[i])
else:
Trendflex[i] = Sum / 0.00001
result = Series(Trendflex, index=close.index)
# Neutralize pre-roll phase
result.iloc[0:length] = npNaN
# Offset
if offset != 0:
result = result.shift(offset)
# Handle fills
if "fillna" in kwargs:
result.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
result.fillna(method=kwargs["fill_method"], inplace=True)
# Name and Categorize it
result.name = f"TRENDFLEX_{length}_{smooth_bars}"
result.category = "trend"
return result
trendflex.__doc__ = \
"""Trendflex (trendflex)
John F. Ehlers introduced two indicators within the article "Reflex: A New Zero-Lag Indicator”
in February 2020, TASC magazine. One of which is the Trendflex, a lag reduced trend indicator.
Both indicators (Reflex/Trendflex) are oscillators and complement each other with the focus for
cycle and trend.
Written for Pandas TA by rengel8 (2021-08-11) based on the implementation on prorealcode (refer to source).
Beyond the mentioned source, this implementation has a separate control parameter for the internal
applied SuperSmoother.
Sources:
https://www.prorealcode.com/prorealtime-indicators/reflex-and-trendflex-indicators-john-f-ehlers/
Calculation:
Refer to provided source or the code above.
Args:
close (pd.Series): Series of 'close's
length (int): It's period. Default: 20
smooth_bars (int): Period of internal SuperSmoother (default: asmooth_bars = length). Default: 20
offset (int): How many periods to offset the result. Default: 0
Kwargs:
fillna (value, optional): pd.DataFrame.fillna(value)
fill_method (value, optional): Type of fill method
Returns:
pd.Series: New feature generated.
"""