ENH rsx indicator added

This commit is contained in:
Kevin Johnson
2021-01-18 09:25:54 -08:00
parent 3b4ef93d57
commit 2f86d47cb1
7 changed files with 50 additions and 59 deletions
+11 -9
View File
@@ -162,7 +162,7 @@ Thanks for trying **Pandas TA**!
_Thank you for your contributions!_
[alexonab](https://github.com/alexonab) | [allahyarzadeh](https://github.com/allahyarzadeh) | [codesutras](https://github.com/codesutras) | [daikts](https://github.com/daikts) | [DrPaprikaa](https://github.com/DrPaprikaa) | [FGU1](https://github.com/FGU1) | [lluissalord](https://github.com/lluissalord) | [maxdignan](https://github.com/maxdignan) | [NkosenhleDuma](https://github.com/NkosenhleDuma) | [pbrumblay](https://github.com/pbrumblay) | [RajeshDhalange](https://github.com/RajeshDhalange) | [rluong003](https://github.com/rluong003) | [SoftDevDanial](https://github.com/SoftDevDanial) | [tg12](https://github.com/tg12) | [twrobel](https://github.com/twrobel) | [YuvalWein](https://github.com/YuvalWein)
[alexonab](https://github.com/alexonab) | [allahyarzadeh](https://github.com/allahyarzadeh) | [codesutras](https://github.com/codesutras) | [daikts](https://github.com/daikts) | [DrPaprikaa](https://github.com/DrPaprikaa) | [FGU1](https://github.com/FGU1) | [lluissalord](https://github.com/lluissalord) | [maxdignan](https://github.com/maxdignan) | [NkosenhleDuma](https://github.com/NkosenhleDuma) | [pbrumblay](https://github.com/pbrumblay) | [RajeshDhalange](https://github.com/RajeshDhalange) | [rengel8](https://github.com/rengel8) | [rluong003](https://github.com/rluong003) | [SoftDevDanial](https://github.com/SoftDevDanial) | [tg12](https://github.com/tg12) | [twrobel](https://github.com/twrobel) | [YuvalWein](https://github.com/YuvalWein)
<br/>
@@ -426,7 +426,7 @@ print(bothhl2.name) # "pre_HL2_post"
* _Inside Bar_: **cdl_inside**
* _Heikin-Ashi_: **ha**
### **Momentum** (35)
### **Momentum** (36)
* _Awesome Oscillator_: **ao**
* _Absolute Price Oscillator_: **apo**
@@ -453,6 +453,7 @@ print(bothhl2.name) # "pre_HL2_post"
* _Quantitative Qualitative Estimation_: **qqe**
* _Rate of Change_: **roc**
* _Relative Strength Index_: **rsi**
* _Relative Strength Xtra_: **rsx**
* _Relative Vigor Index_: **rvgi**
* _Slope_: **slope**
* _SMI Ergodic_ **smi**
@@ -652,16 +653,17 @@ result = ta.cagr(df.close)
## **New Indicators**
* _Drawdown_ (**drawdown**) It is a peak-to-trough decline during a specific period for an investment,
* _Drawdown_ (**drawdown**) shows the peak-to-trough decline during a specific period for an investment,
trading account, or fund. See: ```help(ta.drawdown)```
* _Gann High-Low Activator_ (**hilo**) The Gann High Low Activator Indicator was created by Robert Krausz in a 1998. See: ```help(ta.hilo)```
* _Quantitative Qualitative Estimation_ (**qqe**) The Quantitative Qualitative Estimation (QQE) is like SuperTrend for a Smoothed RSI. See: ```help(ta.qqe)```
* _Price Volume Rank_ (**pvr**) Price Volume Rank (PVR) was created by Anthony J. Macek and is described in his
* _Gann High-Low Activator_ (**hilo**) was created by Robert Krausz in a 1998. See: ```help(ta.hilo)```
* _Quantitative Qualitative Estimation_ (**qqe**) is like SuperTrend for a Smoothed RSI. See: ```help(ta.qqe)```
* _Price Volume Rank_ (**pvr**) was created by Anthony J. Macek and is described in his
article in the June, 1994 issue of Technical Analysis of Stocks & Commodities Magazine. See: ```help(ta.pvr)```
* _Relative Strength Xtra_ (**rsx**) is based on the popular RSI indicator and inspired by the work Jurik Research. See: ```help(ta.rsx)```
* _Ehler's Super Smoother Filter_ (**ssf**). Ehler's solution to reduce lag and remove aliasing noise compared to other common moving average indicators. See: ```help(ta.ssf)```
* _Elder's Thermometer_ (**thermo**) Elder's Thermometer measures price volatility. See: ```help(ta.thermo)```
* _TTM Trend_ (**ttm_trend**). A trend indicator inspired from John Carter's book "Mastering the Trade" issue of Stocks & Commodities Magazine. It is a moving average based trend indicator consisting of two different simple moving averages. See: ```help(ta.ttm_trend)```
* _Variable Index Dynamic Average_ (**vidya**) A popular Dynamic Moving Average created by Tushar Chande. See: ```help(ta.vidya)```
* _Elder's Thermometer_ (**thermo**) measures price volatility. See: ```help(ta.thermo)```
* _TTM Trend_ (**ttm_trend**) is a trend indicator inspired from John Carter's book "Mastering the Trade" issue of Stocks & Commodities Magazine. It is a moving average based trend indicator consisting of two different simple moving averages. See: ```help(ta.ttm_trend)```
* _Variable Index Dynamic Average_ (**vidya**) is a popular Dynamic Moving Average created by Tushar Chande. See: ```help(ta.vidya)```
## **Updated Indicators**
* _Average True Range_ (**atr**): The default ```mamode``` is now "**RMA**" and with the same ```mamode``` options as TradingView. See ```help(ta.atr)```.
+3 -2
View File
@@ -43,8 +43,9 @@ Category = {
"momentum": [
"ao", "apo", "bias", "bop", "brar", "cci", "cfo", "cg", "cmo",
"coppock", "er", "eri", "fisher", "inertia", "kdj", "kst", "macd",
"mom", "pgo", "ppo", "psl", "pvo", "qqe", "roc", "rsi", "rsx", "rvgi", "slope",
"smi", "squeeze", "stoch", "stochrsi", "trix", "tsi", "uo", "willr"
"mom", "pgo", "ppo", "psl", "pvo", "qqe", "roc", "rsi", "rsx", "rvgi",
"slope", "smi", "squeeze", "stoch", "stochrsi", "trix", "tsi", "uo",
"willr"
],
# Overlap
"overlap": [
+1 -1
View File
@@ -880,7 +880,7 @@ class AnalysisIndicators(BasePandasObject):
close = self._get_column(kwargs.pop("close", "close"))
result = rsi(close=close, length=length, scalar=scalar, drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def rsx(self, length=None, drift=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = rsx(close=close, length=length, drift=drift, offset=offset, **kwargs)
+24 -46
View File
@@ -2,7 +2,7 @@
from numpy import NaN as npNaN
from pandas import DataFrame, Series, concat
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
def rsx(close, length=None, drift=None, offset=None, **kwargs):
"""Indicator: Relative Strength Xtra (inspired by Jurik RSX)"""
# Validate arguments
@@ -10,38 +10,15 @@ def rsx(close, length=None, drift=None, offset=None, **kwargs):
length = int(length) if length and length > 0 else 14
drift = get_drift(drift)
offset = get_offset(offset)
# variables
f0 = 0
f8 = 0
f10 = 0
f18 = 0
f20 = 0
f28 = 0
f30 = 0
f38 = 0
f40 = 0
f48 = 0
f50 = 0
f58 = 0
f60 = 0
f68 = 0
f70 = 0
f78 = 0
f80 = 0
f88 = 0
f90 = 0
vC, v1C = 0, 0
v4, v8, v10, v14, v18, v20 = 0, 0, 0, 0, 0, 0
v4 = 0
v8 = 0
v10 = 0
v14 = 0
v18 = 0
v20 = 0
f0, f8, f10, f18, f20, f28, f30, f38 = 0, 0, 0, 0, 0, 0, 0, 0
f40, f48, f50, f58, f60, f68, f70, f78 = 0, 0, 0, 0, 0, 0, 0, 0
f80, f88, f90 = 0, 0, 0
vC = 0
v1C = 0
# Calculate Result
m = close.size
result = [npNaN for _ in range(0, length - 1)] + [0]
@@ -66,26 +43,28 @@ def rsx(close, length=None, drift=None, offset=None, **kwargs):
v8 = f8 - f10
f28 = f20 * f28 + f18 * v8
f30 = f18 * f28 + f20 * f30
vC = f28 * 1.5 - f30 * 0.5
vC = 1.5 * f28 - 0.5 * f30
f38 = f20 * f38 + f18 * vC
f40 = f18 * f38 + f20 * f40
v10 = f38 * 1.5 - f40 * 0.5
v10 = 1.5 * f38 - 0.5 * f40
f48 = f20 * f48 + f18 * v10
f50 = f18 * f48 + f20 * f50
v14 = f48 * 1.5 - f50 * 0.5
v14 = 1.5 * f48 - 0.5 * f50
f58 = f20 * f58 + f18 * abs(v8)
f60 = f18 * f58 + f20 * f60
v18 = f58 * 1.5 - f60 * 0.5
v18 = 1.5 * f58 - 0.5 * f60
f68 = f20 * f68 + f18 * v18
f70 = f18 * f68 + f20 * f70
v1C = f68 * 1.5 - f70 * 0.5
v1C = 1.5 * f68 - 0.5 * f70
f78 = f20 * f78 + f18 * v1C
f80 = f18 * f78 + f20 * f80
v20 = f78 * 1.5 - f80 * 0.5
v20 = 1.5 * f78 - 0.5 * f80
if f88 >= f90 and f8 != f10:
f0 = 1.0
if f88 == f90 and f0 == 0.0:
f90 = 0.0
if f88 < f90 and v20 > 0.0000000001:
v4 = (v14 / v20 + 1.0) * 50.0
if v4 > 100.0:
@@ -95,7 +74,6 @@ def rsx(close, length=None, drift=None, offset=None, **kwargs):
else:
v4 = 50.0
result.append(v4)
# print('v4', v4)
rsx = Series(result, index=close.index)
# Offset
@@ -109,8 +87,6 @@ def rsx(close, length=None, drift=None, offset=None, **kwargs):
rsx.fillna(method=kwargs["fill_method"], inplace=True)
# Name and Categorize it
# print(rsx)
# print(length)
rsx.name = f"RSX_{length}"
rsx.category = "momentum"
@@ -142,9 +118,11 @@ def rsx(close, length=None, drift=None, offset=None, **kwargs):
rsx.__doc__ = \
"""Relative Strength Xtra (rsx)
The Relative Strength Xtra is based on the popular RSI indicator and inspired by the work Jurik Research.
The code implemented is based on published code found at 'prorealcode.com'. This enhanced version of the rsi
reduces noise and provides a clearer, only slightly delayed insight on momentum and velocity of price movements.
The Relative Strength Xtra is based on the popular RSI indicator and inspired
by the work Jurik Research. The code implemented is based on published code
found at 'prorealcode.com'. This enhanced version of the rsi reduces noise and
provides a clearer, only slightly delayed insight on momentum and velocity of
price movements.
Sources:
http://www.jurikres.com/catalog1/ms_rsx.htm
@@ -152,12 +130,12 @@ Sources:
Calculation:
Refer to the sources above for information as well as code example.
Args:
close (pd.Series): Series of 'close's
length (int): It's period. Default: 14
drift (int): The difference period. Default: 1
offset (int): How many periods to offset the result. Default: 0
length (int): It's period. Default: 14
drift (int): The difference period. Default: 1
offset (int): How many periods to offset the result. Default: 0
Kwargs:
fillna (value, optional): pd.DataFrame.fillna(value)
+1 -1
View File
@@ -17,7 +17,7 @@ setup(
"pandas_ta.volatility",
"pandas_ta.volume"
],
version=".".join(("0", "2", "34b")),
version=".".join(("0", "2", "35b")),
description=long_description,
long_description=long_description,
author="Kevin Johnson",
+5
View File
@@ -153,6 +153,11 @@ class TestMomentumExtension(TestCase):
self.assertIsInstance(self.data, DataFrame)
self.assertEqual(self.data.columns[-1], "RSI_14")
def test_rsx_ext(self):
self.data.ta.rsx(append=True)
self.assertIsInstance(self.data, DataFrame)
self.assertEqual(self.data.columns[-1], "RSX_14")
def test_rvgi_ext(self):
self.data.ta.rvgi(append=True)
self.assertIsInstance(self.data, DataFrame)
+5
View File
@@ -295,6 +295,11 @@ class TestMomentum(TestCase):
except Exception as ex:
error_analysis(result, CORRELATION, ex)
def test_rsx(self):
result = pandas_ta.rsx(self.close)
self.assertIsInstance(result, Series)
self.assertEqual(result.name, "RSX_14")
def test_rvgi(self):
result = pandas_ta.rvgi(self.open, self.high, self.low, self.close)
self.assertIsInstance(result, DataFrame)