From 99ebb86fb7af12beadcb1f9e453b22c3635721b2 Mon Sep 17 00:00:00 2001 From: Kevin Johnson Date: Fri, 15 Mar 2019 09:43:30 -0700 Subject: [PATCH] added Q Stick indicator and tests --- README.md | 5 ++- pandas_ta/core.py | 7 ++++ pandas_ta/trend.py | 68 ++++++++++++++++++++++++++++++- setup.py | 2 +- tests/test_indicator_trend.py | 5 +++ tests/test_indicator_trend_ext.py | 5 +++ 6 files changed, 88 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0f409e..00712a8 100644 --- a/README.md +++ b/README.md @@ -153,14 +153,15 @@ Use parameter: cumulative=**True** for cumulative results. |:--------:| | ![Example Z Score](/images/SPY_ZScore.png) | -## _Trend_ (6) +## _Trend_ (7) * _Average Directional Movement Index_: **adx** * _Aroon Oscillator_: **aroon** * _Decreasing_: **decreasing** * _Detrended Price Oscillator_: **dpo** * _Increasing_: **increasing** -* _Vortex Indicator_: **vortex** +* _Q Stick_: **qstick** +* _Vortex_: **vortex** | _Average Directional Movement Index_ (ADX) | |:--------:| diff --git a/pandas_ta/core.py b/pandas_ta/core.py index d0f9906..7b33cfc 100644 --- a/pandas_ta/core.py +++ b/pandas_ta/core.py @@ -591,6 +591,13 @@ class AnalysisIndicators(BasePandasObject): self._append(result, **kwargs) return result + def qstick(self, open_=None, close=None, length=None, offset=None, **kwargs): + open_ = self._get_column(open_, 'open') + close = self._get_column(close, 'close') + result = qstick(open_=open_, close=close, length=length, offset=offset, **kwargs) + self._append(result, **kwargs) + return result + def vortex(self, high=None, low=None, close=None, drift=None, offset=None, **kwargs): high = self._get_column(high, 'high') low = self._get_column(low, 'low') diff --git a/pandas_ta/trend.py b/pandas_ta/trend.py index 75fb8cc..6a3cdb3 100644 --- a/pandas_ta/trend.py +++ b/pandas_ta/trend.py @@ -3,7 +3,7 @@ import numpy as np import pandas as pd from .momentum import roc -from .overlap import ema, midprice, rma +from .overlap import dema, ema, hma, midprice, rma, sma from .utils import get_drift, get_offset, verify_series, zero from .volatility import atr, true_range @@ -206,6 +206,41 @@ def increasing(close, length=None, asint=True, offset=None, **kwargs): return increasing +def qstick(open_, close, length=None, offset=None, **kwargs): + """Indicator: Q Stick""" + # Validate Arguments + open_ = verify_series(open_) + close = verify_series(close) + length = int(length) if length and length > 0 else 10 + offset = get_offset(offset) + ma = kwargs.pop('ma', 'sma') if 'ma' in kwargs else 'sma' + + # Calculate Result + diff = close - open_ + + if ma in [None, 'sma']: qstick = sma(diff, length=length) + if ma == 'dema': qstick = dema(diff, length=length) + if ma == 'ema': qstick = ema(diff, length=length) + if ma == 'hma': qstick = hma(diff, length=length) + if ma == 'rma': qstick = rma(diff, length=length) + + # Offset + if offset != 0: + qstick = qstick.shift(offset) + + # Handle fills + if 'fillna' in kwargs: + qstick.fillna(kwargs['fillna'], inplace=True) + if 'fill_method' in kwargs: + qstick.fillna(method=kwargs['fill_method'], inplace=True) + + # Name and Categorize it + qstick.name = f"QS_{length}" + qstick.category = 'trend' + + return qstick + + def vortex(high, low, close, length=None, drift=None, offset=None, **kwargs): """Indicator: Vortex""" # Validate arguments @@ -458,6 +493,37 @@ Returns: """ +qstick.__doc__ = \ +"""Q Stick + +The Q Stick indicator, developed by Tushar Chande, attempts to quantify and identify +trends in candlestick charts. + +Sources: + https://library.tradingtechnologies.com/trade/chrt-ti-qstick.html + +Calculation: + Default Inputs: + length=10 + xMA is one of: sma (default), dema, ema, hma, rma + qstick = xMA(close - open, length) + +Args: + open (pd.Series): Series of 'open's + close (pd.Series): Series of 'close's + length (int): It's period. Default: 1 + ma (str): The type of moving average to use. Default: None, which is 'sma' + 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. +""" + + vortex.__doc__ = \ """Vortex diff --git a/setup.py b/setup.py index 6561844..509fde6 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ long_description = "An easy to use Python 3 Pandas Extension of Technical Analys setup( name = "pandas_ta", packages = ["pandas_ta"], - version = "0.1.2a", + version = "0.1.3a", description=long_description, long_description=long_description, author = "Kevin Johnson", diff --git a/tests/test_indicator_trend.py b/tests/test_indicator_trend.py index f3244ed..fd4a833 100644 --- a/tests/test_indicator_trend.py +++ b/tests/test_indicator_trend.py @@ -88,6 +88,11 @@ class TestTrend(TestCase): self.assertIsInstance(result, Series) self.assertEqual(result.name, 'INC_1') + def test_qstick(self): + result = self.trend.qstick(self.open, self.close) + self.assertIsInstance(result, Series) + self.assertEqual(result.name, 'QS_10') + def test_vortex(self): result = self.trend.vortex(self.high, self.low, self.close) self.assertIsInstance(result, DataFrame) diff --git a/tests/test_indicator_trend_ext.py b/tests/test_indicator_trend_ext.py index 3c36fe5..1cbc25e 100644 --- a/tests/test_indicator_trend_ext.py +++ b/tests/test_indicator_trend_ext.py @@ -48,6 +48,11 @@ class TestTrendExtension(TestCase): self.assertIsInstance(self.data, DataFrame) self.assertEqual(self.data.columns[-1], 'INC_1') + def test_qstick_ext(self): + self.data.ta.qstick(append=True) + self.assertIsInstance(self.data, DataFrame) + self.assertEqual(self.data.columns[-1], 'QS_10') + def test_vortext_ext(self): self.data.ta.vortex(append=True) self.assertIsInstance(self.data, DataFrame)