DOC candles and cycles category doc refactor

This commit is contained in:
Kevin Johnson
2021-10-01 11:04:17 -07:00
parent 921ad5ef86
commit c0e98ea9f6
7 changed files with 258 additions and 294 deletions
+39 -43
View File
@@ -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.
"""
+34 -38
View File
@@ -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
"""
+33 -45
View File
@@ -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
cdl = cdl_pattern # Alias
+33 -37
View File
@@ -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.
"""
+47 -51
View File
@@ -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[i1] + HA_CLOSE[i1]) / 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[i1] + HA_CLOSE[i1]) / 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.
"""
+41 -45
View File
@@ -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.
"""
+31 -35
View File
@@ -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.
"""