mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-09-13 12:50:58 +08:00
pvi indicator and tests added and nvi fix
This commit is contained in:
@@ -188,7 +188,7 @@ Use parameter: cumulative=**True** for cumulative results.
|
||||
|:--------:|
|
||||
|  |
|
||||
|
||||
## _Volume_ (11)
|
||||
## _Volume_ (12)
|
||||
|
||||
* _Accumulation/Distribution Index_: **ad**
|
||||
* _Accumulation/Distribution Oscillator_: **adosc**
|
||||
@@ -198,6 +198,7 @@ Use parameter: cumulative=**True** for cumulative results.
|
||||
* _Money Flow Index_: **mfi**
|
||||
* _Negative Volume Index_: **nvi**
|
||||
* _On-Balance Volume_: **obv**
|
||||
* _Positive Volume Index_: **pvi**
|
||||
* _Price-Volume_: **pvol**
|
||||
* _Price Volume Trend_: **pvt**
|
||||
* _Volume Profile_: **vp**
|
||||
|
||||
@@ -748,6 +748,13 @@ class AnalysisIndicators(BasePandasObject):
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
def pvi(self, close=None, volume=None, length=None, initial=None, signed=True, offset=None, **kwargs):
|
||||
close = self._get_column(close, 'close')
|
||||
volume = self._get_column(volume, 'volume')
|
||||
result = pvi(close=close, volume=volume, length=length, initial=initial, signed=signed, offset=offset, **kwargs)
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
def pvol(self, close=None, volume=None, signed=True, offset=None, **kwargs):
|
||||
close = self._get_column(close, 'close')
|
||||
volume = self._get_column(volume, 'volume')
|
||||
|
||||
+74
-2
@@ -249,7 +249,7 @@ def nvi(close, volume, length=None, initial=None, offset=None, **kwargs):
|
||||
offset = get_offset(offset)
|
||||
|
||||
# Calculate Result
|
||||
roc_ = roc(close=close)
|
||||
roc_ = roc(close=close, length=length)
|
||||
signed_volume = signed_series(volume, initial=1)
|
||||
nvi = signed_volume[signed_volume < 0].abs() * roc_
|
||||
nvi.fillna(0, inplace=True)
|
||||
@@ -301,6 +301,41 @@ def obv(close, volume, offset=None, **kwargs):
|
||||
return obv
|
||||
|
||||
|
||||
def pvi(close, volume, length=None, initial=None, offset=None, **kwargs):
|
||||
"""Indicator: Positive Volume Index (PVI)"""
|
||||
# Validate arguments
|
||||
close = verify_series(close)
|
||||
volume = verify_series(volume)
|
||||
length = int(length) if length and length > 0 else 1
|
||||
min_periods = int(kwargs['min_periods']) if 'min_periods' in kwargs and kwargs['min_periods'] is not None else length
|
||||
initial = int(initial) if initial and initial > 0 else 1000
|
||||
offset = get_offset(offset)
|
||||
|
||||
# Calculate Result
|
||||
roc_ = roc(close=close, length=length)
|
||||
signed_volume = signed_series(volume, initial=1)
|
||||
pvi = signed_volume[signed_volume > 0].abs() * roc_
|
||||
pvi.fillna(0, inplace=True)
|
||||
pvi.iloc[0]= initial
|
||||
pvi = pvi.cumsum()
|
||||
|
||||
# Offset
|
||||
if offset != 0:
|
||||
pvi = pvi.shift(offset)
|
||||
|
||||
# Handle fills
|
||||
if 'fillna' in kwargs:
|
||||
pvi.fillna(kwargs['fillna'], inplace=True)
|
||||
if 'fill_method' in kwargs:
|
||||
pvi.fillna(method=kwargs['fill_method'], inplace=True)
|
||||
|
||||
# Name and Categorize it
|
||||
pvi.name = f"PVI_{length}"
|
||||
pvi.category = 'volume'
|
||||
|
||||
return pvi
|
||||
|
||||
|
||||
def pvol(close, volume, signed=True, offset=None, **kwargs):
|
||||
"""Indicator: Price-Volume (PVOL)"""
|
||||
# Validate arguments
|
||||
@@ -662,7 +697,7 @@ Sources:
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
length=20, initial=1000
|
||||
length=1, initial=1000
|
||||
ROC = Rate of Change
|
||||
|
||||
roc = ROC(close, length)
|
||||
@@ -717,6 +752,43 @@ Returns:
|
||||
"""
|
||||
|
||||
|
||||
pvi.__doc__ = \
|
||||
"""Positive Volume Index (PVI)
|
||||
|
||||
The Positive Volume Index is a cumulative indicator that uses volume change in
|
||||
an attempt to identify where smart money is active. Used in conjunction with NVI.
|
||||
|
||||
Sources:
|
||||
https://www.investopedia.com/terms/p/pvi.asp
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
length=1, initial=1000
|
||||
ROC = Rate of Change
|
||||
|
||||
roc = ROC(close, length)
|
||||
signed_volume = signed_series(volume, initial=1)
|
||||
pvi = signed_volume[signed_volume > 0].abs() * roc_
|
||||
pvi.fillna(0, inplace=True)
|
||||
pvi.iloc[0]= initial
|
||||
pvi = pvi.cumsum()
|
||||
|
||||
Args:
|
||||
close (pd.Series): Series of 'close's
|
||||
volume (pd.Series): Series of 'volume's
|
||||
length (int): The short period. Default: 13
|
||||
initial (int): The short period. Default: 1000
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
pvol.__doc__ = \
|
||||
"""Price-Volume (PVOL)
|
||||
|
||||
|
||||
@@ -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.5a",
|
||||
version = "0.1.6a",
|
||||
description=long_description,
|
||||
long_description=long_description,
|
||||
author = "Kevin Johnson",
|
||||
|
||||
@@ -116,6 +116,11 @@ class TestVolume(TestCase):
|
||||
except Exception as ex:
|
||||
error_analysis(result, CORRELATION, ex)
|
||||
|
||||
def test_pvi(self):
|
||||
result = self.volume.pvi(self.close, self.volume_)
|
||||
self.assertIsInstance(result, Series)
|
||||
self.assertEqual(result.name, 'PVI_1')
|
||||
|
||||
def test_pvol(self):
|
||||
result = self.volume.pvol(self.close, self.volume_)
|
||||
self.assertIsInstance(result, Series)
|
||||
|
||||
@@ -63,6 +63,11 @@ class TestVolumeExtension(TestCase):
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'OBV')
|
||||
|
||||
def test_pvi_ext(self):
|
||||
self.data.ta.pvi(append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'PVI_1')
|
||||
|
||||
def test_pvol_ext(self):
|
||||
self.data.ta.pvol(append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
|
||||
Reference in New Issue
Block a user