Skip to content

Commit

Permalink
Merge pull request #330 from bukosabino/develop-linter-vpt
Browse files Browse the repository at this point in the history
Fixing linter details
  • Loading branch information
bukosabino authored Nov 2, 2023
2 parents 663d16a + 9c70287 commit 5654782
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 25 deletions.
30 changes: 24 additions & 6 deletions ta/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"""

import typing as tp

import numpy as np
import pandas as pd

Expand Down Expand Up @@ -269,7 +271,14 @@ class VolumePriceTrendIndicator(IndicatorMixin):
dropnans(bool)=False: drop nans after indicator calculated.
"""

def __init__(self, close: pd.Series, volume: pd.Series, fillna: bool = False, smoothing_factor: int = None, dropnans:bool = False):
def __init__(
self,
close: pd.Series,
volume: pd.Series,
fillna: bool = False,
smoothing_factor: tp.Optional[int] = None,
dropnans: bool = False,
):
self._close = close
self._volume = volume
self._fillna = fillna
Expand All @@ -280,9 +289,12 @@ def __init__(self, close: pd.Series, volume: pd.Series, fillna: bool = False, sm
def _run(self):
self._vpt = (self._close.pct_change() * self._volume).cumsum()
if self._smoothing_factor:
min_periods = 0 if self._fillna else self._smoothing_factor
self._vpt = self._vpt.rolling(self._smoothing_factor, min_periods=min_periods).mean()
if self._dropnans: self._vpt = self._vpt.dropna()
min_periods = 0 if self._fillna else self._smoothing_factor
self._vpt = self._vpt.rolling(
self._smoothing_factor, min_periods=min_periods
).mean()
if self._dropnans:
self._vpt = self._vpt.dropna()

def volume_price_trend(self) -> pd.Series:
"""Volume-price trend (VPT)
Expand Down Expand Up @@ -612,7 +624,9 @@ def sma_ease_of_movement(high, low, volume, window=14, fillna=False):
).sma_ease_of_movement()


def volume_price_trend(close, volume, fillna=False, smoothing_factor: int=None, dropnans: bool=False):
def volume_price_trend(
close, volume, fillna=False, smoothing_factor: tp.Optional[int] = None, dropnans: bool = False
):
"""Volume-price trend (VPT)
Is based on a running cumulative volume that adds or substracts a multiple
Expand All @@ -632,7 +646,11 @@ def volume_price_trend(close, volume, fillna=False, smoothing_factor: int=None,
pandas.Series: New feature generated.
"""
return VolumePriceTrendIndicator(
close=close, volume=volume, fillna=fillna, smoothing_factor=smoothing_factor, dropnans=dropnans
close=close,
volume=volume,
fillna=fillna,
smoothing_factor=smoothing_factor,
dropnans=dropnans,
).volume_price_trend()


Expand Down
2 changes: 1 addition & 1 deletion test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
TestForceIndexIndicator,
TestMFIIndicator,
TestOnBalanceVolumeIndicator,
TestVolumeWeightedAveragePrice,
TestVolumePriceTrendIndicator,
TestVolumeWeightedAveragePrice,
)

__all__ = [
Expand Down
43 changes: 25 additions & 18 deletions test/unit/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
ForceIndexIndicator,
MFIIndicator,
OnBalanceVolumeIndicator,
VolumeWeightedAveragePrice,
VolumePriceTrendIndicator,
VolumeWeightedAveragePrice,
acc_dist_index,
ease_of_movement,
force_index,
money_flow_index,
on_balance_volume,
sma_ease_of_movement,
volume_price_trend,
volume_weighted_average_price,
volume_price_trend
)


Expand Down Expand Up @@ -260,14 +260,16 @@ def test_vwap2(self):
self._df[target].tail(), result.tail(), check_names=False
)


class TestVolumePriceTrendIndicator(unittest.TestCase):
"""
Original VPT: https://en.wikipedia.org/wiki/Volume%E2%80%93price_trend
One more: https://www.barchart.com/education/technical-indicators/price_volume_trend
According to TradingView: PVT = [((CurrentClose - PreviousClose) / PreviousClose) x Volume] + PreviousPVT
Smoothed version (by Alex Orekhov (everget)): https://ru.tradingview.com/script/3Ah2ALck-Price-Volume-Trend/
His script is using `pvt` (TradingView built-in variable) as described in TradingView documentation of PVT and just smoothing it with ema or sma by choice.
His script is using `pvt` (TradingView built-in variable) as described in TradingView documentation of PVT and
just smoothing it with ema or sma by choice.
You can find smoothing here (13 row of script):
`signal = signalType == "EMA" ? ema(pvt, signalLength) : sma(pvt, signalLength)`
"""
Expand All @@ -277,20 +279,24 @@ class TestVolumePriceTrendIndicator(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._df = pd.read_csv(cls._filename, sep=",")
cls._params = dict( # default VPT params, unsmoothed
close=cls._df["Close"],
volume=cls._df["Volume"],
fillna=False,
smoothing_factor=None,
dropnans=False
)
cls._params_smoothed = dict( # smoothed VPT params
close=cls._df["Close"],
volume=cls._df["Volume"],
fillna=False,
smoothing_factor=14,
dropnans=False
)

# default VPT params, unsmoothed
cls._params = {
"close": cls._df['Close'],
"volume": cls._df['Volume'],
"fillna": False,
"smoothing_factor": None,
"dropnans": False,
}

# smoothed VPT params
cls._params_smoothed = {
"close": cls._df['Close'],
"volume": cls._df['Volume'],
"fillna": False,
"smoothing_factor": 14,
"dropnans": False,
}
cls._indicator_default = VolumePriceTrendIndicator(**cls._params)
cls._indicator_smoothed = VolumePriceTrendIndicator(**cls._params_smoothed)

Expand Down Expand Up @@ -326,5 +332,6 @@ def test_vpt4(self):
self._df[target].tail(), result.tail(), check_names=False
)


if __name__ == "__main__":
unittest.main()

0 comments on commit 5654782

Please sign in to comment.