ENH #283 vhf indicator TST vhf

This commit is contained in:
Kevin Johnson
2021-05-11 14:24:24 -07:00
parent ac9f48f1e7
commit f30fe232af
7 changed files with 61 additions and 46 deletions
+4 -2
View File
@@ -45,7 +45,7 @@ _Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that lever
* [Overlap](#overlap-32)
* [Performance](#performance-3)
* [Statistics](#statistics-9)
* [Trend](#trend-16)
* [Trend](#trend-17)
* [Utility](#utility-5)
* [Volatility](#volatility-14)
* [Volume](#volume-15)
@@ -778,7 +778,7 @@ Use parameter: cumulative=**True** for cumulative results.
| ![Example Z Score](/images/SPY_ZScore.png) |
<br/>
### **Trend** (16)
### **Trend** (17)
* _Average Directional Movement Index_: **adx**
* Also includes **dmp** and **dmn** in the resultant DataFrame.
@@ -798,6 +798,7 @@ Use parameter: cumulative=**True** for cumulative results.
* _Short Run_: **short_run**
* _Trend Signals_: **tsignals**
* _TTM Trend_: **ttm_trend**
* _Vertical Horizontal Filter_: **vhf**
* _Vortex_: **vortex**
| _Average Directional Movement Index_ (ADX) |
@@ -947,6 +948,7 @@ trading account, or fund. See: ```help(ta.drawdown)```
* _Schaff Trend Cycle_ (**stc**) is an evolution of the popular MACD incorportating two
cascaded stochastic calculations with additional smoothing. See: ```help(ta.stc)```
* _Tom DeMark's Sequential_ (**td_seq**) attempts to identify a price point where an uptrend or a downtrend exhausts itself and reverses. Currently exlcuded from ```df.ta.strategy()``` for performance reasons. See: ```help(ta.td_seq)```
* _Vertical Horizontal Filter_ (**vhf**) was created by Adam White to identify trending and ranging markets.. See: ```help(ta.vhf)```
<br/>
+1 -1
View File
@@ -71,7 +71,7 @@ Category = {
"trend": [
"adx", "amat", "aroon", "chop", "cksp", "decay", "decreasing", "dpo",
"increasing", "long_run", "psar", "qstick", "short_run", "tsignals",
"ttm_trend", "vortex"
"ttm_trend", "vhf", "vortex"
],
# Volatility
"volatility": [
+6 -1
View File
@@ -599,7 +599,7 @@ class AnalysisIndicators(BasePandasObject):
total_indicators = len(ta_indicators)
header = f"Pandas TA - Technical Analysis Indicators - v{self.version}"
s = f"{header}\nTotal Indicators: {total_indicators + len(ALL_PATTERNS)}\n"
s = f"{header}\nTotal Indicators & Utilities: {total_indicators + len(ALL_PATTERNS)}\n"
if total_indicators > 0:
print(f"{s}Abbreviations:\n {', '.join(ta_indicators)}\n\nCandle Patterns:\n {', '.join(ALL_PATTERNS)}")
else:
@@ -1464,6 +1464,11 @@ class AnalysisIndicators(BasePandasObject):
result = ttm_trend(high=high, low=low, close=close, length=length, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def vhf(self, length=None, drift=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = vhf(close=close, length=length, drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def vortex(self, drift=None, offset=None, **kwargs):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
+43 -41
View File
@@ -1,64 +1,66 @@
# -*- coding: utf-8 -*-
from numpy import fabs as npFabs
from pandas_ta.utils import get_offset, verify_series
from pandas_ta.utils import get_drift, get_offset, verify_series
def vhf(source, length=None, offset=None, **kwargs):
def vhf(close, length=None, drift=None, offset=None, **kwargs):
"""Indicator: Vertical Horizontal Filter (VHF)"""
# Validate arguments
length = int(length ) if length and length > 0 else 28
source = verify_series(source, length) # usually close price
close = verify_series(close, length)
drift = get_offset(drift)
offset = get_offset(offset)
if source is None: return
if close is None: return
# Calculate Result
hcp = source.rolling(length).max()
lcp = source.rolling(length).min()
diff = npFabs(source - source.shift(1))
vhf_ = npFabs(hcp - lcp) / diff.rolling(length).sum()
hcp = close.rolling(length).max()
lcp = close.rolling(length).min()
diff = npFabs(close - close.shift(drift))
vhf = npFabs(hcp - lcp) / diff.rolling(length).sum()
# Offset
if offset != 0:
vhf_ = vhf_.shift(offset)
vhf = vhf_.shift(offset)
# Handle fills
if "fillna" in kwargs:
vhf_.fillna(kwargs["fillna"], inplace=True)
vhf.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
vhf_.fillna(method=kwargs["fill_method"], inplace=True)
vhf.fillna(method=kwargs["fill_method"], inplace=True)
# Name and Categorize it
vhf_.name = f"VHF_{length}"
vhf_.category = "trend"
vhf.name = f"VHF_{length}"
vhf.category = "trend"
return vhf_
return vhf
vhf.__doc__ = """Vertical Horizontal Filter (VHF)
VHF was created by Adam White to identify trending and ranging markets.
Sources:
https://www.incrediblecharts.com/indicators/vertical_horizontal_filter.php
Calculation:
Default Inputs:
source = Close, length = 28
HCP = Highest Close Price in Period
LCP = Lowest Close Price in Period
Change = abs(Ct - Ct-1)
VHF = (HCP - LCP) / RollingSum[length] of Change
Args:
source (pd.Series): Series of prices (usually close).
length (int): The period length. Default: 28
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.
"""
vhf.__doc__ = \
"""Vertical Horizontal Filter (VHF)
VHF was created by Adam White to identify trending and ranging markets.
Sources:
https://www.incrediblecharts.com/indicators/vertical_horizontal_filter.php
Calculation:
Default Inputs:
length = 28
HCP = Highest Close Price in Period
LCP = Lowest Close Price in Period
Change = abs(Ct - Ct-1)
VHF = (HCP - LCP) / RollingSum[length] of Change
Args:
source (pd.Series): Series of prices (usually close).
length (int): The period length. Default: 28
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.
"""
+1
View File
@@ -5,6 +5,7 @@ from .aobv import aobv
from .cmf import cmf
from .efi import efi
from .eom import eom
from .kvo import kvo
from .mfi import mfi
from .nvi import nvi
from .obv import obv
+1 -1
View File
@@ -18,7 +18,7 @@ setup(
"pandas_ta.volatility",
"pandas_ta.volume"
],
version=".".join(("0", "2", "78")),
version=".".join(("0", "2", "78b")),
description=long_description,
long_description=long_description,
author="Kevin Johnson",
+5
View File
@@ -180,6 +180,11 @@ class TestTrend(TestCase):
self.assertIsInstance(result, DataFrame)
self.assertEqual(result.name, "TTMTREND_6")
def test_vhf(self):
result = pandas_ta.vhf(self.close)
self.assertIsInstance(result, Series)
self.assertEqual(result.name, "VHF_28")
def test_vortex(self):
result = pandas_ta.vortex(self.high, self.low, self.close)
self.assertIsInstance(result, DataFrame)