From e8c9509d4d2da0b36d3b63e745926d667810bebe Mon Sep 17 00:00:00 2001 From: Lluis Date: Fri, 22 May 2020 10:41:41 +0200 Subject: [PATCH] Add crossing signals and change naming convention --- pandas_ta/signals/rsi_signals.py | 43 ++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/pandas_ta/signals/rsi_signals.py b/pandas_ta/signals/rsi_signals.py index ab67417..be4c51d 100644 --- a/pandas_ta/signals/rsi_signals.py +++ b/pandas_ta/signals/rsi_signals.py @@ -1,25 +1,54 @@ # -*- coding: utf-8 -*- from pandas import DataFrame from ..momentum.rsi import rsi -from ..utils import above_value, below_value +from ..utils import above_value, below_value, cross_value -def rsi_signals(close, above_val=None, below_val=None, length=None, drift=None, offset=None, **kwargs): - """Indicator: Overbought or Oversold based on Relative Strength Index (RSI)""" +def rsi_signals(close, above_val=None, below_val=None, length=None, drift=None, offset=None, crossing=False, **kwargs): + """Indicator: Signals based on Relative Strength Index (RSI)""" rsi_series = rsi(close, length=None, drift=None, offset=None, **kwargs) above_val = int(above_val) if above_val and above_val > 0 else 80 below_val = int(below_val) if below_val and below_val > 0 else 20 + # Mark the all the ticks when the security is overbought/oversold above = above_value(rsi_series, above_val, asint=True, **kwargs) below = below_value(rsi_series, below_val, asint=True, **kwargs) + if crossing: + # Mark only the crossing ticks when the security starts to be overbought/oversold + cross_start_above = cross_value(rsi_series, above_val, above=True, asint=True, **kwargs) + cross_start_below = cross_value(rsi_series, below_val, above=False, asint=True, **kwargs) + + # Mark only the crossing ticks when the security ends to be overbought/oversold + cross_end_above = cross_value(rsi_series, above_val, above=False, asint=True, **kwargs) + cross_end_below = cross_value(rsi_series, below_val, above=True, asint=True, **kwargs) + # Name and Categorize it # Not needed because above_value/below_value is already naming - # above.name = f"RSI_{length}_A_{above_val}" - # below.name = f"RSI_{length}_B_{below_val}" + above.name = f"RSI_{length}_OB_{above_val}" + below.name = f"RSI_{length}_OS_{below_val}" above.category = below.category = 'signals' + if crossing: + cross_start_above.name = f"RSI_{length}_XS_OB_{above_val}" + cross_start_below.name = f"RSI_{length}_XS_OS_{below_val}" + cross_end_above.name = f"RSI_{length}_XE_OB_{above_val}" + cross_end_below.name = f"RSI_{length}_XE_OS_{below_val}" + cross_start_above.category = cross_start_below.category = cross_end_above.category = cross_end_below.category = 'signals' # Prepare DataFrame to return - data = {above.name: above, below.name: below} + data = { + above.name: above, + below.name: below, + } + if crossing: + data.update( + { + cross_start_above.name: cross_start_above, + cross_start_below.name: cross_start_below, + cross_end_above.name: cross_end_above, + cross_end_below.name: cross_end_below + } + ) + rsidf = DataFrame(data) rsidf.name = f"RSI_signals" rsidf.category = 'signals' @@ -29,7 +58,7 @@ def rsi_signals(close, above_val=None, below_val=None, length=None, drift=None, rsi.__doc__ = \ -"""Overbought or Oversold based on Relative Strength Index (RSI) +"""Signals based on Relative Strength Index (RSI) The Relative Strength Index is popular momentum oscillator used to measure the velocity as well as the magnitude of directional price movements. RSI reading