From c0e98ea9f612270aaa6a6783e9ea7b681ac3b132 Mon Sep 17 00:00:00 2001 From: Kevin Johnson Date: Fri, 1 Oct 2021 11:04:17 -0700 Subject: [PATCH] DOC candles and cycles category doc refactor --- pandas_ta/candles/cdl_doji.py | 82 +++++++++++++------------- pandas_ta/candles/cdl_inside.py | 72 +++++++++++------------ pandas_ta/candles/cdl_pattern.py | 78 +++++++++++-------------- pandas_ta/candles/cdl_z.py | 70 +++++++++++------------ pandas_ta/candles/ha.py | 98 +++++++++++++++----------------- pandas_ta/cycles/ebsw.py | 86 +++++++++++++--------------- pandas_ta/cycles/reflex.py | 66 ++++++++++----------- 7 files changed, 258 insertions(+), 294 deletions(-) diff --git a/pandas_ta/candles/cdl_doji.py b/pandas_ta/candles/cdl_doji.py index 591d92d..9c053c3 100644 --- a/pandas_ta/candles/cdl_doji.py +++ b/pandas_ta/candles/cdl_doji.py @@ -5,7 +5,45 @@ from pandas_ta.utils import real_body, verify_series def cdl_doji(open_, high, low, close, length=None, factor=None, scalar=None, asint=True, offset=None, **kwargs): - """Candle Type: Doji""" + """Candle Type: Doji + + A candle body is Doji, when it's shorter than 10% of the + average of the 10 previous candles' high-low range. + + Sources: + TA-Lib: 96.56% Correlation + + Calculation: + Default values: + length=10, percent=10 (0.1), scalar=100 + ABS = Absolute Value + SMA = Simple Moving Average + + BODY = ABS(close - open) + HL_RANGE = ABS(high - low) + + DOJI = scalar IF BODY < 0.01 * percent * SMA(HL_RANGE, length) ELSE 0 + + Args: + open_ (pd.Series): Series of 'open's + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + length (int): The period. Default: 10 + factor (float): Doji value. Default: 100 + scalar (float): How much to magnify. Default: 100 + asint (bool): Keep results numerical instead of boolean. Default: True + + Kwargs: + naive (bool, optional): If True, prefills potential Doji less than + the length if less than a percentage of it's high-low range. + Default: False + fillna (value, optional): pd.DataFrame.fillna(value) + fill_method (value, optional): Type of fill method + + Returns: + pd.Series: CDL_DOJI column. + """ # Validate Arguments length = int(length) if length and length > 0 else 10 factor = float(factor) if is_percent(factor) else 10 @@ -45,45 +83,3 @@ def cdl_doji(open_, high, low, close, length=None, factor=None, scalar=None, asi doji.category = "candles" return doji - - -cdl_doji.__doc__ = \ -"""Candle Type: Doji - -A candle body is Doji, when it's shorter than 10% of the -average of the 10 previous candles' high-low range. - -Sources: - TA-Lib: 96.56% Correlation - -Calculation: - Default values: - length=10, percent=10 (0.1), scalar=100 - ABS = Absolute Value - SMA = Simple Moving Average - - BODY = ABS(close - open) - HL_RANGE = ABS(high - low) - - DOJI = scalar IF BODY < 0.01 * percent * SMA(HL_RANGE, length) ELSE 0 - -Args: - open_ (pd.Series): Series of 'open's - high (pd.Series): Series of 'high's - low (pd.Series): Series of 'low's - close (pd.Series): Series of 'close's - length (int): The period. Default: 10 - factor (float): Doji value. Default: 100 - scalar (float): How much to magnify. Default: 100 - asint (bool): Keep results numerical instead of boolean. Default: True - -Kwargs: - naive (bool, optional): If True, prefills potential Doji less than - the length if less than a percentage of it's high-low range. - Default: False - fillna (value, optional): pd.DataFrame.fillna(value) - fill_method (value, optional): Type of fill method - -Returns: - pd.Series: CDL_DOJI column. -""" diff --git a/pandas_ta/candles/cdl_inside.py b/pandas_ta/candles/cdl_inside.py index fe9ae24..272e85e 100644 --- a/pandas_ta/candles/cdl_inside.py +++ b/pandas_ta/candles/cdl_inside.py @@ -4,7 +4,40 @@ from pandas_ta.utils import verify_series def cdl_inside(open_, high, low, close, asbool=False, offset=None, **kwargs): - """Candle Type: Inside Bar""" + """Candle Type: Inside Bar + + An Inside Bar is a bar that is engulfed by the prior highs and lows of it's + previous bar. In other words, the current bar is smaller than it's previous bar. + Set asbool=True if you want to know if it is an Inside Bar. Note by default + asbool=False so this returns a 0 if it is not an Inside Bar, 1 if it is an + Inside Bar and close > open, and -1 if it is an Inside Bar but close < open. + + Sources: + https://www.tradingview.com/script/IyIGN1WO-Inside-Bar/ + + Calculation: + Default Inputs: + asbool=False + inside = (high.diff() < 0) & (low.diff() > 0) + + if not asbool: + inside *= candle_color(open_, close) + + Args: + open_ (pd.Series): Series of 'open's + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + asbool (bool): Returns the boolean result. Default: False + 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 + """ # Validate arguments open_ = verify_series(open_) high = verify_series(high) @@ -33,40 +66,3 @@ def cdl_inside(open_, high, low, close, asbool=False, offset=None, **kwargs): inside.category = "candles" return inside - - -cdl_inside.__doc__ = \ -"""Candle Type: Inside Bar - -An Inside Bar is a bar that is engulfed by the prior highs and lows of it's -previous bar. In other words, the current bar is smaller than it's previous bar. -Set asbool=True if you want to know if it is an Inside Bar. Note by default -asbool=False so this returns a 0 if it is not an Inside Bar, 1 if it is an -Inside Bar and close > open, and -1 if it is an Inside Bar but close < open. - -Sources: - https://www.tradingview.com/script/IyIGN1WO-Inside-Bar/ - -Calculation: - Default Inputs: - asbool=False - inside = (high.diff() < 0) & (low.diff() > 0) - - if not asbool: - inside *= candle_color(open_, close) - -Args: - open_ (pd.Series): Series of 'open's - high (pd.Series): Series of 'high's - low (pd.Series): Series of 'low's - close (pd.Series): Series of 'close's - asbool (bool): Returns the boolean result. Default: False - 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 -""" diff --git a/pandas_ta/candles/cdl_pattern.py b/pandas_ta/candles/cdl_pattern.py index 568294f..954d831 100644 --- a/pandas_ta/candles/cdl_pattern.py +++ b/pandas_ta/candles/cdl_pattern.py @@ -24,7 +24,37 @@ ALL_PATTERNS = [ def cdl_pattern(open_, high, low, close, name: Union[str, Sequence[str]]="all", scalar=None, offset=None, **kwargs) -> DataFrame: - """Candle Pattern""" + """TA Lib Candle Patterns + + A wrapper around all TA Lib's candle patterns. + + Examples: + + Get all candle patterns (This is the default behaviour) + >>> df = df.ta.cdl_pattern(name="all") + + Get only one pattern + >>> df = df.ta.cdl_pattern(name="doji") + + Get some patterns + >>> df = df.ta.cdl_pattern(name=["doji", "inside"]) + + Args: + open_ (pd.Series): Series of 'open's + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + name: (Union[str, Sequence[str]]): name of the patterns + scalar (float): How much to magnify. Default: 100 + 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.DataFrame: one column for each pattern. + """ # Validate Arguments open_ = verify_series(open_) high = verify_series(high) @@ -34,9 +64,7 @@ def cdl_pattern(open_, high, low, close, name: Union[str, Sequence[str]]="all", scalar = float(scalar) if scalar else 100 # Patterns that implemented in pandas-ta - pta_patterns = { - "doji": cdl_doji, "inside": cdl_inside, - } + pta_patterns = {"doji": cdl_doji, "inside": cdl_inside} if name == "all": name = ALL_PATTERNS @@ -84,44 +112,4 @@ def cdl_pattern(open_, high, low, close, name: Union[str, Sequence[str]]="all", df.category = "candles" return df - -cdl_pattern.__doc__ = \ -"""Candle Pattern - -A wrapper around all candle patterns. - -Examples: - -Get all candle patterns (This is the default behaviour) ->>> df = df.ta.cdl_pattern(name="all") -Or ->>> df.ta.cdl("all", append=True) # = df.ta.cdl_pattern("all", append=True) - -Get only one pattern ->>> df = df.ta.cdl_pattern(name="doji") -Or ->>> df.ta.cdl("doji", append=True) - -Get some patterns ->>> df = df.ta.cdl_pattern(name=["doji", "inside"]) -Or ->>> df.ta.cdl(["doji", "inside"], append=True) - -Args: - open_ (pd.Series): Series of 'open's - high (pd.Series): Series of 'high's - low (pd.Series): Series of 'low's - close (pd.Series): Series of 'close's - name: (Union[str, Sequence[str]]): name of the patterns - scalar (float): How much to magnify. Default: 100 - 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.DataFrame: one column for each pattern. -""" - -cdl = cdl_pattern \ No newline at end of file +cdl = cdl_pattern # Alias \ No newline at end of file diff --git a/pandas_ta/candles/cdl_z.py b/pandas_ta/candles/cdl_z.py index 6f96707..a003f2b 100644 --- a/pandas_ta/candles/cdl_z.py +++ b/pandas_ta/candles/cdl_z.py @@ -5,7 +5,39 @@ from pandas_ta.utils import get_offset, verify_series def cdl_z(open_, high, low, close, length=None, full=None, ddof=None, offset=None, **kwargs): - """Candle Type: Z Score""" + """Candle Type: Z + + Normalizes OHLC Candles with a rolling Z Score. + + Source: Kevin Johnson + + Calculation: + Default values: + length=30, full=False, ddof=1 + Z = ZSCORE + + open = Z( open, length, ddof) + high = Z( high, length, ddof) + low = Z( low, length, ddof) + close = Z(close, length, ddof) + + Args: + open_ (pd.Series): Series of 'open's + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + length (int): The period. Default: 10 + + Kwargs: + naive (bool, optional): If True, prefills potential Doji less than + the length if less than a percentage of it's high-low range. + Default: False + fillna (value, optional): pd.DataFrame.fillna(value) + fill_method (value, optional): Type of fill method + + Returns: + pd.Series: CDL_DOJI column. + """ # Validate Arguments length = int(length) if length and length > 0 else 30 ddof = int(ddof) if ddof and ddof >= 0 and ddof < length else 1 @@ -54,39 +86,3 @@ def cdl_z(open_, high, low, close, length=None, full=None, ddof=None, offset=Non df.category = "candles" return df - - -cdl_z.__doc__ = \ -"""Candle Type: Z - -Normalizes OHLC Candles with a rolling Z Score. - -Source: Kevin Johnson - -Calculation: - Default values: - length=30, full=False, ddof=1 - Z = ZSCORE - - open = Z( open, length, ddof) - high = Z( high, length, ddof) - low = Z( low, length, ddof) - close = Z(close, length, ddof) - -Args: - open_ (pd.Series): Series of 'open's - high (pd.Series): Series of 'high's - low (pd.Series): Series of 'low's - close (pd.Series): Series of 'close's - length (int): The period. Default: 10 - -Kwargs: - naive (bool, optional): If True, prefills potential Doji less than - the length if less than a percentage of it's high-low range. - Default: False - fillna (value, optional): pd.DataFrame.fillna(value) - fill_method (value, optional): Type of fill method - -Returns: - pd.Series: CDL_DOJI column. -""" diff --git a/pandas_ta/candles/ha.py b/pandas_ta/candles/ha.py index 1e0f53f..f6b2532 100644 --- a/pandas_ta/candles/ha.py +++ b/pandas_ta/candles/ha.py @@ -4,7 +4,53 @@ from pandas_ta.utils import get_offset, verify_series def ha(open_, high, low, close, offset=None, **kwargs): - """Candle Type: Heikin Ashi""" + """Heikin Ashi Candles (HA) + + The Heikin-Ashi technique averages price data to create a Japanese + candlestick chart that filters out market noise. Heikin-Ashi charts, + developed by Munehisa Homma in the 1700s, share some characteristics + with standard candlestick charts but differ based on the values used + to create each candle. Instead of using the open, high, low, and close + like standard candlestick charts, the Heikin-Ashi technique uses a + modified formula based on two-period averages. This gives the chart a + smoother appearance, making it easier to spots trends and reversals, + but also obscures gaps and some price data. + + Sources: + https://www.investopedia.com/terms/h/heikinashi.asp + + Calculation: + HA_OPEN[0] = (open[0] + close[0]) / 2 + HA_CLOSE = (open[0] + high[0] + low[0] + close[0]) / 4 + + for i > 1 in df.index: + HA_OPEN = (HA_OPEN[i−1] + HA_CLOSE[i−1]) / 2 + + HA_HIGH = MAX(HA_OPEN, HA_HIGH, HA_CLOSE) + HA_LOW = MIN(HA_OPEN, HA_LOW, HA_CLOSE) + + How to Calculate Heikin-Ashi + + Use one period to create the first Heikin-Ashi (HA) candle, using + the formulas. For example use the high, low, open, and close to + create the first HA close price. Use the open and close to create + the first HA open. The high of the period will be the first HA high, + and the low will be the first HA low. With the first HA calculated, + it is now possible to continue computing the HA candles per the formulas. + ​​ + Args: + open_ (pd.Series): Series of 'open's + high (pd.Series): Series of 'high's + low (pd.Series): Series of 'low's + close (pd.Series): Series of 'close's + + Kwargs: + fillna (value, optional): pd.DataFrame.fillna(value) + fill_method (value, optional): Type of fill method + + Returns: + pd.DataFrame: ha_open, ha_high,ha_low, ha_close columns. + """ # Validate Arguments open_ = verify_series(open_) high = verify_series(high) @@ -42,53 +88,3 @@ def ha(open_, high, low, close, offset=None, **kwargs): df.category = "candles" return df - - -ha.__doc__ = \ -"""Heikin Ashi Candles (HA) - -The Heikin-Ashi technique averages price data to create a Japanese -candlestick chart that filters out market noise. Heikin-Ashi charts, -developed by Munehisa Homma in the 1700s, share some characteristics -with standard candlestick charts but differ based on the values used -to create each candle. Instead of using the open, high, low, and close -like standard candlestick charts, the Heikin-Ashi technique uses a -modified formula based on two-period averages. This gives the chart a -smoother appearance, making it easier to spots trends and reversals, -but also obscures gaps and some price data. - -Sources: - https://www.investopedia.com/terms/h/heikinashi.asp - -Calculation: - HA_OPEN[0] = (open[0] + close[0]) / 2 - HA_CLOSE = (open[0] + high[0] + low[0] + close[0]) / 4 - - for i > 1 in df.index: - HA_OPEN = (HA_OPEN[i−1] + HA_CLOSE[i−1]) / 2 - - HA_HIGH = MAX(HA_OPEN, HA_HIGH, HA_CLOSE) - HA_LOW = MIN(HA_OPEN, HA_LOW, HA_CLOSE) - - How to Calculate Heikin-Ashi - - Use one period to create the first Heikin-Ashi (HA) candle, using - the formulas. For example use the high, low, open, and close to - create the first HA close price. Use the open and close to create - the first HA open. The high of the period will be the first HA high, - and the low will be the first HA low. With the first HA calculated, - it is now possible to continue computing the HA candles per the formulas. -​​ -Args: - open_ (pd.Series): Series of 'open's - high (pd.Series): Series of 'high's - low (pd.Series): Series of 'low's - close (pd.Series): Series of 'close's - -Kwargs: - fillna (value, optional): pd.DataFrame.fillna(value) - fill_method (value, optional): Type of fill method - -Returns: - pd.DataFrame: ha_open, ha_high,ha_low, ha_close columns. -""" diff --git a/pandas_ta/cycles/ebsw.py b/pandas_ta/cycles/ebsw.py index a8a2ceb..5cad4b7 100644 --- a/pandas_ta/cycles/ebsw.py +++ b/pandas_ta/cycles/ebsw.py @@ -13,7 +13,47 @@ from pandas_ta.utils import get_offset, verify_series def ebsw(close, length=None, bars=None, offset=None, initial_version=False, **kwargs): - """Indicator: Even Better SineWave (EBSW)""" + """Even Better SineWave (EBSW) + + This indicator measures market cycles and uses a low pass filter to remove noise. + Its output is bound signal between -1 and 1 and the maximum length of a detected + trend is limited by its length input. + + Written by rengel8 for Pandas TA based on a publication at 'prorealcode.com' and + a book by J.F.Ehlers. According to the suggestion by Squigglez2* and major differences between + the initial version's output close to the implementation from Ehler's, the default version is now + more closely related to the code from pro-realcode. + + Remark: + The default version is now more cycle oriented and tends to be less whipsaw-prune. Thus the older version + might offer earlier signals at medium and stronger reversals. + A test against the version at TradingView showed very close results with the advantage to be one bar/candle + faster, than the corresponding reference value. This might be pre-roll related and was not further investigated. + * https://github.com/twopirllc/pandas-ta/issues/350 + + + Sources: + - https://www.prorealcode.com/prorealtime-indicators/even-better-sinewave/ + - J.F.Ehlers 'Cycle Analytics for Traders', 2014 + + Calculation: + refer to 'sources' or implementation + + Args: + close (pd.Series): Series of 'close's + length (int): It's max cycle/trend period. Values between 40-48 work like + expected with minimum value: 39. Default: 40. + bars (int): Period of low pass filtering. Default: 10 + 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) + fill_method (value, optional): Type of fill method + + Returns: + pd.Series: New feature generated. + """ # Validate arguments length = int(length) if isinstance(length, int) and length > 10 else 40 bars = int(bars) if isinstance(bars, int) and bars > 0 else 10 @@ -113,47 +153,3 @@ def ebsw(close, length=None, bars=None, offset=None, initial_version=False, **kw ebsw.category = "cycles" return ebsw - - -ebsw.__doc__ = \ -"""Even Better SineWave (EBSW) - -This indicator measures market cycles and uses a low pass filter to remove noise. -Its output is bound signal between -1 and 1 and the maximum length of a detected -trend is limited by its length input. - -Written by rengel8 for Pandas TA based on a publication at 'prorealcode.com' and -a book by J.F.Ehlers. According to the suggestion by Squigglez2* and major differences between -the initial version's output close to the implementation from Ehler's, the default version is now -more closely related to the code from pro-realcode. - -Remark: -The default version is now more cycle oriented and tends to be less whipsaw-prune. Thus the older version -might offer earlier signals at medium and stronger reversals. -A test against the version at TradingView showed very close results with the advantage to be one bar/candle -faster, than the corresponding reference value. This might be pre-roll related and was not further investigated. -* https://github.com/twopirllc/pandas-ta/issues/350 - - -Sources: - - https://www.prorealcode.com/prorealtime-indicators/even-better-sinewave/ - - J.F.Ehlers 'Cycle Analytics for Traders', 2014 - -Calculation: - refer to 'sources' or implementation - -Args: - close (pd.Series): Series of 'close's - length (int): It's max cycle/trend period. Values between 40-48 work like - expected with minimum value: 39. Default: 40. - bars (int): Period of low pass filtering. Default: 10 - 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) - fill_method (value, optional): Type of fill method - -Returns: - pd.Series: New feature generated. -""" diff --git a/pandas_ta/cycles/reflex.py b/pandas_ta/cycles/reflex.py index 9615a83..63a79c1 100644 --- a/pandas_ta/cycles/reflex.py +++ b/pandas_ta/cycles/reflex.py @@ -10,7 +10,37 @@ from pandas_ta.utils import get_offset, verify_series def reflex(close, length=None, smooth=None, alpha=None, offset=None, **kwargs): - """Indicator: Reflex""" + """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 (see Sources). 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 (int): Period of internal SuperSmoother. Default: 20 + alpha (float: Alpha weight of Difference Sums. Default: 0.04 + 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. + """ # Validate arguments close = verify_series(close, length) length = int(length) if isinstance(length, int) and length > 0 else 20 @@ -71,37 +101,3 @@ def reflex(close, length=None, smooth=None, alpha=None, offset=None, **kwargs): 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 (see Sources). 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 (int): Period of internal SuperSmoother. Default: 20 - alpha (float: Alpha weight of Difference Sums. Default: 0.04 - 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. -"""