diff --git a/README.md b/README.md
index 0a32abb..0c4dfc9 100644
--- a/README.md
+++ b/README.md
@@ -554,11 +554,82 @@ help(ta.yf)
# **Indicators** (_by Category_)
-### **Candles** (3)
+### **Candles** (63)
-* _Doji_: **cdl_doji**
-* _Inside Bar_: **cdl_inside**
+* _Patterns_: cdl_pattern (Patterns that aren't bold, need TA-Lib to be installed: "```pip install TA-Lib```")
+ * 2crows
+ * 3blackcrows
+ * 3inside
+ * 3linestrike
+ * 3outside
+ * 3starsinsouth
+ * 3whitesoldiers
+ * abandonedbaby
+ * advanceblock
+ * belthold
+ * breakaway
+ * closingmarubozu
+ * concealbabyswall
+ * counterattack
+ * darkcloudcover
+ * **doji**
+ * dojistar
+ * dragonflydoji
+ * engulfing
+ * eveningdojistar
+ * eveningstar
+ * gapsidesidewhite
+ * gravestonedoji
+ * hammer
+ * hangingman
+ * harami
+ * haramicross
+ * highwave
+ * hikkake
+ * hikkakemod
+ * homingpigeon
+ * identical3crows
+ * inneck
+ * **inside**
+ * invertedhammer
+ * kicking
+ * kickingbylength
+ * ladderbottom
+ * longleggeddoji
+ * longline
+ * marubozu
+ * matchinglow
+ * mathold
+ * morningdojistar
+ * morningstar
+ * onneck
+ * piercing
+ * rickshawman
+ * risefall3methods
+ * separatinglines
+ * shootingstar
+ * shortline
+ * spinningtop
+ * stalledpattern
+ * sticksandwich
+ * takuri
+ * tasukigap
+ * thrusting
+ * tristar
+ * unique3river
+ * upsidegap2crows
+ * xsidegap3methods
* _Heikin-Ashi_: **ha**
+```python
+# 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"])
+```
diff --git a/pandas_ta/__init__.py b/pandas_ta/__init__.py
index f816e4e..52cf265 100644
--- a/pandas_ta/__init__.py
+++ b/pandas_ta/__init__.py
@@ -40,7 +40,7 @@ Imports = {
Category = {
# Candles
"candles": [
- "cdl_doji", "cdl_inside", "ha"
+ "cdl_pattern", "ha"
],
# Cycles
"cycles": ["ebsw"],
diff --git a/pandas_ta/candles/__init__.py b/pandas_ta/candles/__init__.py
index a94f3f7..b0444e2 100644
--- a/pandas_ta/candles/__init__.py
+++ b/pandas_ta/candles/__init__.py
@@ -2,3 +2,4 @@
from .ha import ha
from .cdl_doji import cdl_doji
from .cdl_inside import cdl_inside
+from .cdl_pattern import cdl_pattern, ALL_PATTERNS as CDL_PATTERN_NAMES
diff --git a/pandas_ta/candles/cdl_pattern.py b/pandas_ta/candles/cdl_pattern.py
new file mode 100644
index 0000000..3a2cb0f
--- /dev/null
+++ b/pandas_ta/candles/cdl_pattern.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+from typing import Sequence, Union
+from pandas import Series, DataFrame
+
+from . import cdl_doji, cdl_inside
+from pandas_ta.utils import get_offset, verify_series
+from pandas_ta import Imports
+if Imports["talib"]:
+ import talib.abstract as tala
+
+
+ALL_PATTERNS = [
+ "2crows", "3blackcrows", "3inside", "3linestrike", "3outside", "3starsinsouth",
+ "3whitesoldiers", "abandonedbaby", "advanceblock", "belthold", "breakaway",
+ "closingmarubozu", "concealbabyswall", "counterattack", "darkcloudcover", "doji",
+ "dojistar", "dragonflydoji", "engulfing", "eveningdojistar", "eveningstar",
+ "gapsidesidewhite", "gravestonedoji", "hammer", "hangingman", "harami",
+ "haramicross", "highwave", "hikkake", "hikkakemod", "homingpigeon",
+ "identical3crows", "inneck", "inside", "invertedhammer", "kicking", "kickingbylength",
+ "ladderbottom", "longleggeddoji", "longline", "marubozu", "matchinglow", "mathold",
+ "morningdojistar", "morningstar", "onneck", "piercing", "rickshawman",
+ "risefall3methods", "separatinglines", "shootingstar", "shortline", "spinningtop",
+ "stalledpattern", "sticksandwich", "takuri", "tasukigap", "thrusting", "tristar",
+ "unique3river", "upsidegap2crows", "xsidegap3methods"
+]
+
+
+def cdl_pattern(open_, high, low, close, name: Union[str, Sequence[str]]="all", scalar=None, offset=None, **kwargs) -> DataFrame:
+ """Candle Pattern"""
+ # Validate Arguments
+ open_ = verify_series(open_)
+ high = verify_series(high)
+ low = verify_series(low)
+ close = verify_series(close)
+ offset = get_offset(offset)
+ scalar = float(scalar) if scalar else 100
+
+ # Patterns that implemented in pandas-ta
+ pta_patterns = {
+ "doji": cdl_doji, "inside": cdl_inside,
+ }
+
+ if name == "all":
+ name = ALL_PATTERNS
+ if type(name) is str:
+ name = [name]
+
+ result = {}
+ for n in name:
+ if n not in ALL_PATTERNS:
+ print(f"[X] There is no candle pattern named {n} available!")
+ continue
+ if n in pta_patterns:
+ pattern_result = pta_patterns[n](open_, high, low, close, offset=offset, scalar=scalar, **kwargs)
+ result[pattern_result.name] = pattern_result
+ else:
+ if not Imports["talib"]:
+ print(f"[X] Please install TA-Lib to use {n}. (pip install TA-Lib)")
+ continue
+
+ pattern_func = tala.Function("CDL" + n.upper())
+ pattern_result = Series(pattern_func(open_, high, low, close, **kwargs) / 100 * scalar)
+ pattern_result.index = close.index
+
+ # Offset
+ if offset != 0:
+ pattern_result = pattern_result.shift(offset)
+
+ # Handle fills
+ if "fillna" in kwargs:
+ pattern_result.fillna(kwargs["fillna"], inplace=True)
+ if "fill_method" in kwargs:
+ pattern_result.fillna(method=kwargs["fill_method"], inplace=True)
+
+ result["CDL_" + n.upper()] = pattern_result
+
+ if len(result) == 0:
+ return
+
+ # Prepare DataFrame to return
+ df = DataFrame(result)
+ df.name = "CDL_PATTERN"
+ df.category = "candles"
+ return df
+
+
+cdl_pattern.__doc__ = \
+"""Candle Pattern
+
+A wrapper around all candle patterns.
+
+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.
+"""
diff --git a/pandas_ta/core.py b/pandas_ta/core.py
index 3862b61..5f8696b 100644
--- a/pandas_ta/core.py
+++ b/pandas_ta/core.py
@@ -832,20 +832,12 @@ class AnalysisIndicators(BasePandasObject):
# Public DataFrame Methods: Indicators and Utilities
# Candles
- def cdl_doji(self, offset=None, **kwargs):
+ def cdl_pattern(self, name="all", offset=None, **kwargs):
open_ = self._get_column(kwargs.pop("open", "open"))
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
- result = cdl_doji(open_=open_, high=high, low=low, close=close, offset=offset, **kwargs)
- return self._post_process(result, **kwargs)
-
- def cdl_inside(self, offset=None, **kwargs):
- open_ = self._get_column(kwargs.pop("open", "open"))
- high = self._get_column(kwargs.pop("high", "high"))
- low = self._get_column(kwargs.pop("low", "low"))
- close = self._get_column(kwargs.pop("close", "close"))
- result = cdl_inside(open_=open_, high=high, low=low, close=close, offset=offset, **kwargs)
+ result = cdl_pattern(open_=open_, high=high, low=low, close=close, name=name, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def ha(self, offset=None, **kwargs):
diff --git a/tests/test_indicator_candle.py b/tests/test_indicator_candle.py
index beba7f9..81a1345 100644
--- a/tests/test_indicator_candle.py
+++ b/tests/test_indicator_candle.py
@@ -39,6 +39,17 @@ class TestCandle(TestCase):
self.assertIsInstance(result, DataFrame)
self.assertEqual(result.name, "Heikin-Ashi")
+ def test_cdl_pattern(self):
+ result = pandas_ta.cdl_pattern(self.open, self.high, self.low, self.close, name="all")
+ self.assertIsInstance(result, DataFrame)
+ self.assertEqual(len(result.columns), len(pandas_ta.CDL_PATTERN_NAMES))
+
+ result = pandas_ta.cdl_pattern(self.open, self.high, self.low, self.close, name="doji")
+ self.assertIsInstance(result, DataFrame)
+
+ result = pandas_ta.cdl_pattern(self.open, self.high, self.low, self.close, name=["doji", "inside"])
+ self.assertIsInstance(result, DataFrame)
+
def test_cdl_doji(self):
result = pandas_ta.cdl_doji(self.open, self.high, self.low, self.close)
self.assertIsInstance(result, Series)