mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-06-27 16:10:07 +08:00
ENH BUG #38 vwap anchor argument fix
This commit is contained in:
@@ -28,5 +28,4 @@ test_ta:
|
|||||||
python -m unittest -v -f tests/test_indicator_*.py
|
python -m unittest -v -f tests/test_indicator_*.py
|
||||||
|
|
||||||
test_utils:
|
test_utils:
|
||||||
python -m unittest -v -f tests/test_utils.py
|
python -m unittest -v -f tests/test_utils.py
|
||||||
python -m unittest -v -f tests/test_utils_metrics.py
|
|
||||||
@@ -672,6 +672,7 @@ article in the June, 1994 issue of Technical Analysis of Stocks & Commodities Ma
|
|||||||
* _Decreasing_ (**decreasing**): New argument ```strict``` checks if the series is continuously decreasing over period ```length```. Default: ```False```. See ```help(ta.decreasing)```.
|
* _Decreasing_ (**decreasing**): New argument ```strict``` checks if the series is continuously decreasing over period ```length```. Default: ```False```. See ```help(ta.decreasing)```.
|
||||||
* _Increasing_ (**increasing**): New argument ```strict``` checks if the series is continuously increasing over period ```length```. Default: ```False```. See ```help(ta.increasing)```.
|
* _Increasing_ (**increasing**): New argument ```strict``` checks if the series is continuously increasing over period ```length```. Default: ```False```. See ```help(ta.increasing)```.
|
||||||
* _Trend Return_ (**trend_return**): Returns a DataFrame now instead of Series with pertinenet trade info for a _trend_. An example can be found in the [AI Example Notebook](https://github.com/twopirllc/pandas-ta/tree/master/examples/AIExample.ipynb). The notebook is still a work in progress and open to colloboration.
|
* _Trend Return_ (**trend_return**): Returns a DataFrame now instead of Series with pertinenet trade info for a _trend_. An example can be found in the [AI Example Notebook](https://github.com/twopirllc/pandas-ta/tree/master/examples/AIExample.ipynb). The notebook is still a work in progress and open to colloboration.
|
||||||
|
* _Volume Weighted Average Price_ (**vwap**) Added a new parameter called ```anchor```. Default: "D" for "Daily". See [Timeseries Offset Aliases](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases) for additional options.
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1104,7 +1104,7 @@ class AnalysisIndicators(BasePandasObject):
|
|||||||
result = vidya(close=close, length=length, offset=offset, **kwargs)
|
result = vidya(close=close, length=length, offset=offset, **kwargs)
|
||||||
return self._post_process(result, **kwargs)
|
return self._post_process(result, **kwargs)
|
||||||
|
|
||||||
def vwap(self, offset=None, **kwargs):
|
def vwap(self, anchor=None, offset=None, **kwargs):
|
||||||
high = self._get_column(kwargs.pop("high", "high"))
|
high = self._get_column(kwargs.pop("high", "high"))
|
||||||
low = self._get_column(kwargs.pop("low", "low"))
|
low = self._get_column(kwargs.pop("low", "low"))
|
||||||
close = self._get_column(kwargs.pop("close", "close"))
|
close = self._get_column(kwargs.pop("close", "close"))
|
||||||
@@ -1113,7 +1113,7 @@ class AnalysisIndicators(BasePandasObject):
|
|||||||
if not self.datetime_ordered:
|
if not self.datetime_ordered:
|
||||||
volume.index = self._df.index
|
volume.index = self._df.index
|
||||||
|
|
||||||
result = vwap(high=high, low=low, close=close, volume=volume, offset=offset, **kwargs)
|
result = vwap(high=high, low=low, close=close, volume=volume, anchor=anchor, offset=offset, **kwargs)
|
||||||
return self._post_process(result, **kwargs)
|
return self._post_process(result, **kwargs)
|
||||||
|
|
||||||
def vwma(self, volume=None, length=None, offset=None, **kwargs):
|
def vwma(self, volume=None, length=None, offset=None, **kwargs):
|
||||||
|
|||||||
@@ -2,33 +2,33 @@
|
|||||||
from .hlc3 import hlc3
|
from .hlc3 import hlc3
|
||||||
from pandas_ta.utils import get_offset, is_datetime_ordered, verify_series
|
from pandas_ta.utils import get_offset, is_datetime_ordered, verify_series
|
||||||
|
|
||||||
def vwap(high, low, close, volume, offset=None, **kwargs):
|
def vwap(high, low, close, volume, anchor=None, offset=None, **kwargs):
|
||||||
"""Indicator: Volume Weighted Average Price (VWAP)"""
|
"""Indicator: Volume Weighted Average Price (VWAP)"""
|
||||||
# Validate Arguments
|
# Validate Arguments
|
||||||
high = verify_series(high)
|
high = verify_series(high)
|
||||||
low = verify_series(low)
|
low = verify_series(low)
|
||||||
close = verify_series(close)
|
close = verify_series(close)
|
||||||
volume = verify_series(volume)
|
volume = verify_series(volume)
|
||||||
|
anchor = anchor.upper() if anchor and isinstance(anchor, str) and len(anchor) >= 1 else "D"
|
||||||
offset = get_offset(offset)
|
offset = get_offset(offset)
|
||||||
|
|
||||||
typical_price = hlc3(high=high, low=low, close=close)
|
typical_price = hlc3(high=high, low=low, close=close)
|
||||||
|
|
||||||
if not is_datetime_ordered(volume):
|
if not is_datetime_ordered(volume):
|
||||||
print(f"[!] VWAP volume series is not datetime ordered. Results may not be as expected.")
|
print(f"[!] VWAP volume series is not datetime ordered. Results may not be as expected.")
|
||||||
if not is_datetime_ordered(typical_price):
|
if not is_datetime_ordered(typical_price):
|
||||||
print(f"[!] VWAP price series is not datetime ordered. Results may not be as expected.")
|
print(f"[!] VWAP price series is not datetime ordered. Results may not be as expected.")
|
||||||
|
|
||||||
# Calculate Result
|
# Calculate Result
|
||||||
weighted_price = typical_price * volume
|
wp = typical_price * volume
|
||||||
vwap = weighted_price.groupby(weighted_price.index.to_period("d")).cumsum()
|
vwap = wp.groupby(wp.index.to_period(anchor)).cumsum()
|
||||||
vwap /= volume.groupby(volume.index.to_period("d")).cumsum()
|
vwap /= volume.groupby(volume.index.to_period(anchor)).cumsum()
|
||||||
|
|
||||||
# Offset
|
# Offset
|
||||||
if offset != 0:
|
if offset != 0:
|
||||||
vwap = vwap.shift(offset)
|
vwap = vwap.shift(offset)
|
||||||
|
|
||||||
# Name & Category
|
# Name & Category
|
||||||
vwap.name = "VWAP"
|
vwap.name = f"VWAP_{anchor}"
|
||||||
vwap.category = "overlap"
|
vwap.category = "overlap"
|
||||||
|
|
||||||
return vwap
|
return vwap
|
||||||
@@ -56,7 +56,11 @@ Args:
|
|||||||
low (pd.Series): Series of 'low's
|
low (pd.Series): Series of 'low's
|
||||||
close (pd.Series): Series of 'close's
|
close (pd.Series): Series of 'close's
|
||||||
volume (pd.Series): Series of 'volume's
|
volume (pd.Series): Series of 'volume's
|
||||||
offset (int): How many periods to offset the result. Default: 0
|
anchor (str): How to anchor VWAP. Depending on the index values, it will
|
||||||
|
implement various Timeseries Offset Aliases as listed here:
|
||||||
|
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases
|
||||||
|
Default: "D".
|
||||||
|
offset (int): How many periods to offset the result. Default: 0
|
||||||
|
|
||||||
Kwargs:
|
Kwargs:
|
||||||
fillna (value, optional): pd.DataFrame.fillna(value)
|
fillna (value, optional): pd.DataFrame.fillna(value)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ setup(
|
|||||||
"pandas_ta.volatility",
|
"pandas_ta.volatility",
|
||||||
"pandas_ta.volume"
|
"pandas_ta.volume"
|
||||||
],
|
],
|
||||||
version=".".join(("0", "2", "37b")),
|
version=".".join(("0", "2", "38b")),
|
||||||
description=long_description,
|
description=long_description,
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
author="Kevin Johnson",
|
author="Kevin Johnson",
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class TestOverlapExtension(TestCase):
|
|||||||
def test_vwap_ext(self):
|
def test_vwap_ext(self):
|
||||||
self.data.ta.vwap(append=True)
|
self.data.ta.vwap(append=True)
|
||||||
self.assertIsInstance(self.data, DataFrame)
|
self.assertIsInstance(self.data, DataFrame)
|
||||||
self.assertEqual(self.data.columns[-1], "VWAP")
|
self.assertEqual(self.data.columns[-1], "VWAP_D")
|
||||||
|
|
||||||
def test_vwma_ext(self):
|
def test_vwma_ext(self):
|
||||||
self.data.ta.vwma(append=True)
|
self.data.ta.vwma(append=True)
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ class TestOverlap(TestCase):
|
|||||||
def test_vwap(self):
|
def test_vwap(self):
|
||||||
result = pandas_ta.vwap(self.high, self.low, self.close, self.volume)
|
result = pandas_ta.vwap(self.high, self.low, self.close, self.volume)
|
||||||
self.assertIsInstance(result, Series)
|
self.assertIsInstance(result, Series)
|
||||||
self.assertEqual(result.name, "VWAP")
|
self.assertEqual(result.name, "VWAP_D")
|
||||||
|
|
||||||
def test_vwma(self):
|
def test_vwma(self):
|
||||||
result = pandas_ta.vwma(self.close, self.volume)
|
result = pandas_ta.vwma(self.close, self.volume)
|
||||||
|
|||||||
Reference in New Issue
Block a user