From cbeef9104702ccbe57907df29d570746d4c78c3e Mon Sep 17 00:00:00 2001 From: Kevin Johnson Date: Fri, 19 Feb 2021 11:44:46 -0800 Subject: [PATCH] ENH #215 hwma indicator TST added DOC readme --- README.md | 4 +++- pandas_ta/overlap/hwma.py | 22 ++++++++++------------ tests/test_ext_indicator_overlap_ext.py | 5 +++++ tests/test_indicator_overlap.py | 7 +++++++ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index cd33b0d..d02e3ba 100644 --- a/README.md +++ b/README.md @@ -496,7 +496,7 @@ print(bothhl2.name) # "pre_HL2_post" |:--------:| | ![Example MACD](/images/SPY_MACD.png) | -### **Overlap** (30) +### **Overlap** (31) * _Double Exponential Moving Average_: **dema** * _Exponential Moving Average_: **ema** @@ -506,6 +506,7 @@ print(bothhl2.name) # "pre_HL2_post" * _High-Low-Close Average_: **hlc3** * Commonly known as 'Typical Price' in Technical Analysis literature * _Hull Exponential Moving Average_: **hma** +* _Holt-Winter Moving Average_: **hwma** * _Ichimoku Kinkō Hyō_: **ichimoku** * Use: help(ta.ichimoku). Returns two DataFrames. * Drop the Chikou Span Column, the final column of the first resultant DataFrame, remove potential data leak. @@ -686,6 +687,7 @@ result = ta.cagr(df.close) * _Drawdown_ (**drawdown**) shows the peak-to-trough decline during a specific period for an investment, trading account, or fund. See: ```help(ta.drawdown)``` * _Gann High-Low Activator_ (**hilo**) was created by Robert Krausz in a 1998. See: ```help(ta.hilo)``` +* _Holt-Winter Moving Average_ (**hwma**) is a three-parameter moving average by the Holt-Winter method. * _McGinley Dynamic_ (**mcgd**) is an overlap indicator developed by John R. McGinley, a Certified Market Technician. See: ```help(ta.mcgd)``` * _Price Volume Rank_ (**pvr**) was created by Anthony J. Macek. See: ```help(ta.pvr)``` * _Quantitative Qualitative Estimation_ (**qqe**) is like SuperTrend for a Smoothed RSI. See: ```help(ta.qqe)``` diff --git a/pandas_ta/overlap/hwma.py b/pandas_ta/overlap/hwma.py index 02e36ef..142fa60 100644 --- a/pandas_ta/overlap/hwma.py +++ b/pandas_ta/overlap/hwma.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# import numpy as np from pandas import Series from pandas_ta.utils import get_offset, verify_series @@ -16,8 +15,8 @@ def hwma(close, na=None, nb=None, nc=None, offset=None, **kwargs): # Initialize .. m = close.size last_f = close[0] - last_v = 0 - last_a = 0 + # last_a, last_v = 0, 0 + last_a = last_v = 0 result = [] # Calculate .. @@ -25,14 +24,10 @@ def hwma(close, na=None, nb=None, nc=None, offset=None, **kwargs): F = (1.0 - na) * (last_f + last_v + 0.5 * last_a) + na * close[i] V = (1.0 - nb) * (last_v + last_a) + nb * (F - last_f) A = (1.0 - nc) * last_a + nc * (V - last_v) - # print('F|V|A:', F, V, A) result.append((F + V + 0.5 * A)) # update values - last_a = A - last_f = F - last_v = V + last_a, last_f, last_v = A, F, V - # Serialize .. hwma = Series(result, index=close.index) # Offset @@ -45,8 +40,8 @@ def hwma(close, na=None, nb=None, nc=None, offset=None, **kwargs): if "fill_method" in kwargs: hwma.fillna(method=kwargs["fill_method"], inplace=True) - # Name & Category - suffix = f'{na}_{nb}_{nc}' + # Name & Category + suffix = f"{na}_{nb}_{nc}" hwma.name = f"HWMA_{suffix}" hwma.category = "overlap" @@ -58,8 +53,11 @@ hwma.__doc__ = \ """HWMA (Holt-Winter Moving Average) Indicator HWMA (Holt-Winter Moving Average) is a three-parameter moving average -by the Holt-Winter method; the three parameters should be selected to obtain a forecast. -This version has been implemented for Pandas TA by rengel8 based on a publication for MetaTrader 5. +by the Holt-Winter method; the three parameters should be selected to obtain a +forecast. + +This version has been implemented for Pandas TA by rengel8 based +on a publication for MetaTrader 5. Sources: https://www.mql5.com/en/code/20856 diff --git a/tests/test_ext_indicator_overlap_ext.py b/tests/test_ext_indicator_overlap_ext.py index 9744621..fc1a8a7 100644 --- a/tests/test_ext_indicator_overlap_ext.py +++ b/tests/test_ext_indicator_overlap_ext.py @@ -53,6 +53,11 @@ class TestOverlapExtension(TestCase): self.assertIsInstance(self.data, DataFrame) self.assertEqual(self.data.columns[-1], "HMA_10") + def test_hwma_ext(self): + self.data.ta.hwma(append=True) + self.assertIsInstance(self.data, DataFrame) + self.assertEqual(self.data.columns[-1], "HWMA_0.2_0.1_0.1") + def test_kama_ext(self): self.data.ta.kama(append=True) self.assertIsInstance(self.data, DataFrame) diff --git a/tests/test_indicator_overlap.py b/tests/test_indicator_overlap.py index 971aea6..6562a6d 100644 --- a/tests/test_indicator_overlap.py +++ b/tests/test_indicator_overlap.py @@ -99,6 +99,13 @@ class TestOverlap(TestCase): self.assertIsInstance(result, Series) self.assertEqual(result.name, "HMA_10") + def test_hwma(self): + result = pandas_ta.hwma(self.close) + self.assertIsInstance(result, Series) + self.assertEqual(result.name, "HWMA_0.2_0.1_0.1") + print(f"\n{result.head(30)}") + print(f"\n{result.tail(30)}") + def test_kama(self): result = pandas_ta.kama(self.close) self.assertIsInstance(result, Series)