diff --git a/pandas_ta/candles/cdl_inside.py b/pandas_ta/candles/cdl_inside.py index 9b2bbe6d..43ff7852 100644 --- a/pandas_ta/candles/cdl_inside.py +++ b/pandas_ta/candles/cdl_inside.py @@ -62,7 +62,7 @@ def cdl_inside( offset = v_offset(offset) # Calculate - np_high, np_low = high.values, low.values + np_high, np_low = high.to_numpy(), low.to_numpy() np_inside = np_cdl_inside(np_high, np_low) inside = Series(np_inside, index=close.index, dtype=bool) diff --git a/pandas_ta/candles/ha.py b/pandas_ta/candles/ha.py index 993c7e3b..2d10b1fb 100644 --- a/pandas_ta/candles/ha.py +++ b/pandas_ta/candles/ha.py @@ -65,8 +65,8 @@ def ha( return # Calculate - np_open, np_high = open_.values, high.values - np_low, np_close = low.values, close.values + np_open, np_high = open_.to_numpy(), high.to_numpy() + np_low, np_close = low.to_numpy(), close.to_numpy() ha_open, ha_high, ha_low, ha_close = np_ha(np_open, np_high, np_low, np_close) df = DataFrame({ "HA_open": ha_open, diff --git a/pandas_ta/core.py b/pandas_ta/core.py index b2be5634..adbe0abf 100644 --- a/pandas_ta/core.py +++ b/pandas_ta/core.py @@ -1806,10 +1806,10 @@ def obv(self, offset=None, **kwargs: DictLike): result = obv(close=close, volume=volume, offset=offset, **kwargs) return self._post_process(result, **kwargs) - def pvi(self, length=None, initial=None, mamode=None, offset=None, **kwargs: DictLike): + def pvi(self, length=None, initial=None, mamode=None, overlay=None, offset=None, **kwargs: DictLike): close = self._get_column(kwargs.pop("close", "close")) volume = self._get_column(kwargs.pop("volume", "volume")) - result = pvi(close=close, volume=volume, length=length, initial=initial, mamode=mamode, offset=offset, **kwargs) + result = pvi(close=close, volume=volume, length=length, initial=initial, mamode=mamode, overlay=overlay, offset=offset, **kwargs) return self._post_process(result, **kwargs) def pvo(self, fast=None, slow=None, signal=None, scalar=None, offset=None, **kwargs: DictLike): diff --git a/pandas_ta/cycles/reflex.py b/pandas_ta/cycles/reflex.py index ccdaa2d7..9313d8a3 100644 --- a/pandas_ta/cycles/reflex.py +++ b/pandas_ta/cycles/reflex.py @@ -93,7 +93,7 @@ def reflex( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() result = np_reflex(np_close, length, smooth, alpha, pi, sqrt2) result[:length] = nan result = Series(result, index=close.index) diff --git a/pandas_ta/momentum/crsi.py b/pandas_ta/momentum/crsi.py index 46bfcaf9..7dd64c11 100644 --- a/pandas_ta/momentum/crsi.py +++ b/pandas_ta/momentum/crsi.py @@ -145,7 +145,7 @@ def crsi( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() streak = Series(consecutive_streak(np_close), index=close.index) if Imports["talib"] and mode_tal: diff --git a/pandas_ta/momentum/rvgi.py b/pandas_ta/momentum/rvgi.py index ded6ad52..d027427f 100644 --- a/pandas_ta/momentum/rvgi.py +++ b/pandas_ta/momentum/rvgi.py @@ -63,7 +63,7 @@ def rvgi( rvgi = numerator / denominator signal = swma(rvgi, length=swma_length) - if all(isnan(signal.values)): + if all(isnan(signal.to_numpy())): return # Emergency Break # Offset diff --git a/pandas_ta/overlap/alma.py b/pandas_ta/overlap/alma.py index b0667f34..15a89c24 100644 --- a/pandas_ta/overlap/alma.py +++ b/pandas_ta/overlap/alma.py @@ -55,7 +55,7 @@ def alma( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() x = arange(length) k = floor(offset_ * (length - 1)) weights = exp(-0.5 * ((sigma / length) * (x - k)) ** 2) diff --git a/pandas_ta/overlap/dema.py b/pandas_ta/overlap/dema.py index 4315d1c6..b0892a9e 100644 --- a/pandas_ta/overlap/dema.py +++ b/pandas_ta/overlap/dema.py @@ -52,7 +52,7 @@ def dema( ema2 = ema(close=ema1, length=length, talib=mode_tal) dema = 2 * ema1 - ema2 - if all(isnan(dema.values)): + if all(isnan(dema.to_numpy())): return # Emergency Break # Offset diff --git a/pandas_ta/overlap/hl2.py b/pandas_ta/overlap/hl2.py index c0ef8336..57f04c06 100644 --- a/pandas_ta/overlap/hl2.py +++ b/pandas_ta/overlap/hl2.py @@ -35,7 +35,7 @@ def hl2( return # Calculate - avg = 0.5 * (high.values + low.values) + avg = 0.5 * (high.to_numpy() + low.to_numpy()) hl2 = Series(avg, index=high.index) # Offset diff --git a/pandas_ta/overlap/hlc3.py b/pandas_ta/overlap/hlc3.py index 185cc735..219d1c54 100644 --- a/pandas_ta/overlap/hlc3.py +++ b/pandas_ta/overlap/hlc3.py @@ -43,7 +43,7 @@ def hlc3( from talib import TYPPRICE hlc3 = TYPPRICE(high, low, close) else: - avg = (high.values + low.values + close.values) / 3.0 + avg = (high.to_numpy() + low.to_numpy() + close.to_numpy()) / 3.0 hlc3 = Series(avg, index=close.index) # Offset diff --git a/pandas_ta/overlap/linreg.py b/pandas_ta/overlap/linreg.py index bb5db7e7..ad7e324f 100644 --- a/pandas_ta/overlap/linreg.py +++ b/pandas_ta/overlap/linreg.py @@ -70,7 +70,7 @@ def linreg( tsf = kwargs.pop("tsf", False) # Calculate - np_close = close.values + np_close = close.to_numpy() if Imports["talib"] and mode_tal and not r: from talib import LINEARREG, LINEARREG_ANGLE, LINEARREG_INTERCEPT, LINEARREG_SLOPE, TSF diff --git a/pandas_ta/overlap/mama.py b/pandas_ta/overlap/mama.py index 97b5160e..035c006b 100644 --- a/pandas_ta/overlap/mama.py +++ b/pandas_ta/overlap/mama.py @@ -143,7 +143,7 @@ def mama( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() if Imports["talib"] and mode_tal: from talib import MAMA mama, fama = MAMA(np_close, fastlimit, slowlimit) diff --git a/pandas_ta/overlap/ohlc4.py b/pandas_ta/overlap/ohlc4.py index f89c4abb..0b4dc6a1 100644 --- a/pandas_ta/overlap/ohlc4.py +++ b/pandas_ta/overlap/ohlc4.py @@ -36,7 +36,7 @@ def ohlc4( offset = v_offset(offset) # Calculate - avg = 0.25 * (open_.values + high.values + low.values + close.values) + avg = 0.25 * (open_.to_numpy() + high.to_numpy() + low.to_numpy() + close.to_numpy()) ohlc4 = Series(avg, index=close.index) # Offset diff --git a/pandas_ta/overlap/pivots.py b/pandas_ta/overlap/pivots.py index 30ab778c..41db0443 100644 --- a/pandas_ta/overlap/pivots.py +++ b/pandas_ta/overlap/pivots.py @@ -190,10 +190,10 @@ def pivots( index=dt_index ) - np_open = df.open.values - np_high = df.high.values - np_low = df.low.values - np_close = df.close.values + np_open = df.open.to_numpy() + np_high = df.high.to_numpy() + np_low = df.low.to_numpy() + np_close = df.close.to_numpy() # Create nan arrays for "demark" and "fibonacci" pivots _nan_array = zeros_like(np_close) diff --git a/pandas_ta/overlap/sma.py b/pandas_ta/overlap/sma.py index afe15209..eefa3294 100644 --- a/pandas_ta/overlap/sma.py +++ b/pandas_ta/overlap/sma.py @@ -80,7 +80,7 @@ def sma( from talib import SMA sma = SMA(close, length) else: - np_close = close.values + np_close = close.to_numpy() sma = np_sma(np_close, length) sma = Series(sma, index=close.index) diff --git a/pandas_ta/overlap/ssf.py b/pandas_ta/overlap/ssf.py index ea01c5cc..4cc79378 100644 --- a/pandas_ta/overlap/ssf.py +++ b/pandas_ta/overlap/ssf.py @@ -95,7 +95,7 @@ def ssf( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() if everget: ssf = np_ssf_everget(np_close, length, pi, sqrt2) else: diff --git a/pandas_ta/overlap/ssf3.py b/pandas_ta/overlap/ssf3.py index 1a596dc7..36121dd0 100644 --- a/pandas_ta/overlap/ssf3.py +++ b/pandas_ta/overlap/ssf3.py @@ -77,7 +77,7 @@ def ssf3( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() ssf = np_ssf3(np_close, length, pi, sqrt3) ssf = Series(ssf, index=close.index) diff --git a/pandas_ta/overlap/wcp.py b/pandas_ta/overlap/wcp.py index 30d8dd1c..07d09955 100644 --- a/pandas_ta/overlap/wcp.py +++ b/pandas_ta/overlap/wcp.py @@ -49,7 +49,7 @@ def wcp( from talib import WCLPRICE wcp = WCLPRICE(high, low, close) else: - weight = high.values + low.values + 2 * close.values + weight = high.to_numpy() + low.to_numpy() + 2 * close.to_numpy() wcp = Series(weight, index=close.index) # Offset diff --git a/pandas_ta/overlap/wma.py b/pandas_ta/overlap/wma.py index c98d448c..fb1be19b 100644 --- a/pandas_ta/overlap/wma.py +++ b/pandas_ta/overlap/wma.py @@ -76,7 +76,7 @@ def wma( from talib import WMA wma = WMA(close, length) else: - np_close = close.values + np_close = close.to_numpy() wma_ = np_wma(np_close, length, asc, True) wma = Series(wma_, index=close.index) diff --git a/pandas_ta/performance/log_return.py b/pandas_ta/performance/log_return.py index 872fe393..e4076026 100644 --- a/pandas_ta/performance/log_return.py +++ b/pandas_ta/performance/log_return.py @@ -42,7 +42,7 @@ def log_return( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() if cumulative: r = np_close / np_close[0] else: diff --git a/pandas_ta/performance/percent_return.py b/pandas_ta/performance/percent_return.py index d5750c70..c7d222f2 100644 --- a/pandas_ta/performance/percent_return.py +++ b/pandas_ta/performance/percent_return.py @@ -42,7 +42,7 @@ def percent_return( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() if cumulative: pr = (np_close / np_close[0]) - 1 else: diff --git a/pandas_ta/transform/ifisher.py b/pandas_ta/transform/ifisher.py index 3e752ff4..cad5e569 100644 --- a/pandas_ta/transform/ifisher.py +++ b/pandas_ta/transform/ifisher.py @@ -55,14 +55,14 @@ def ifisher( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() is_remapped = logical_and(np_close >= -1, np_close <= 1) if not all(is_remapped): np_max, np_min = max(np_close), min(np_close) close_map = remap(close, from_min=np_min, from_max=np_max, to_min=-1, to_max=1) - if close_map is None or all(isnan(close_map.values)): + if close_map is None or all(isnan(close_map.to_numpy())): return # Emergency Break - np_close = close_map.values + np_close = close_map.to_numpy() amped = exp(amp * np_close) result = (amped - 1) / (amped + 1) diff --git a/pandas_ta/transform/remap.py b/pandas_ta/transform/remap.py index ae4e7f50..d3b0dd69 100644 --- a/pandas_ta/transform/remap.py +++ b/pandas_ta/transform/remap.py @@ -50,7 +50,7 @@ def remap( frange, trange = from_max - from_min, to_max - to_min if frange <= 0 or trange <= 0: return - result = to_min + (trange / frange) * (close.values - from_min) + result = to_min + (trange / frange) * (close.to_numpy() - from_min) result = Series(result, index=close.index) # Offset diff --git a/pandas_ta/trend/alphatrend.py b/pandas_ta/trend/alphatrend.py index f4a39252..d36496a0 100644 --- a/pandas_ta/trend/alphatrend.py +++ b/pandas_ta/trend/alphatrend.py @@ -126,9 +126,9 @@ def alphatrend( if momo is None: return - np_upper_atr, np_lower_atr = upper_atr.values, lower_atr.values + np_upper_atr, np_lower_atr = upper_atr.to_numpy(), lower_atr.to_numpy() - at = np_alpha(np_lower_atr, np_upper_atr, momo.values >= threshold) + at = np_alpha(np_lower_atr, np_upper_atr, momo.to_numpy() >= threshold) at = Series(at, index=close.index) atl = at.shift(lag) diff --git a/pandas_ta/trend/decay.py b/pandas_ta/trend/decay.py index 03590a8b..5316aca0 100644 --- a/pandas_ta/trend/decay.py +++ b/pandas_ta/trend/decay.py @@ -71,7 +71,7 @@ def decay( offset = v_offset(offset) # Calculate - _mode, np_close = "L", close.values + _mode, np_close = "L", close.to_numpy() if mode in ["exp", "exponential"]: _mode = "EXP" diff --git a/pandas_ta/trend/ht_trendline.py b/pandas_ta/trend/ht_trendline.py index 4e626713..efdbaa1a 100644 --- a/pandas_ta/trend/ht_trendline.py +++ b/pandas_ta/trend/ht_trendline.py @@ -123,7 +123,7 @@ def ht_trendline( from talib import HT_TRENDLINE tl = HT_TRENDLINE(close) else: - np_close = close.values + np_close = close.to_numpy() np_tl = np_ht_trendline(np_close) if prenan > 0: diff --git a/pandas_ta/trend/trendflex.py b/pandas_ta/trend/trendflex.py index b5bab922..ffee5ba4 100644 --- a/pandas_ta/trend/trendflex.py +++ b/pandas_ta/trend/trendflex.py @@ -92,7 +92,7 @@ def trendflex( offset = v_offset(offset) # Calculate - np_close = close.values + np_close = close.to_numpy() result = np_trendflex(np_close, length, smooth, alpha, pi, sqrt2) result[:length] = nan result = Series(result, index=close.index) diff --git a/pandas_ta/trend/xsignals.py b/pandas_ta/trend/xsignals.py index 19933c8f..96897dbd 100644 --- a/pandas_ta/trend/xsignals.py +++ b/pandas_ta/trend/xsignals.py @@ -93,7 +93,7 @@ def xsignals( # Modify trades to fill gaps for trends trades.replace({0: nan}, inplace=True) - trades.interpolate(method="pad", inplace=True) + trades.ffill(limit_area="inside", inplace=True) # or trades.bfill(limit_area="inside", inplace=True) trades.fillna(0, inplace=True) trends = (trades > 0).astype(int) diff --git a/pandas_ta/trend/zigzag.py b/pandas_ta/trend/zigzag.py index eb6a4176..6f010f0f 100644 --- a/pandas_ta/trend/zigzag.py +++ b/pandas_ta/trend/zigzag.py @@ -60,7 +60,7 @@ def zigzag( if close is not None: close = v_series(close, _length + 1) - np_close = close.values + np_close = close.to_numpy() if close is None: return @@ -70,7 +70,7 @@ def zigzag( offset = v_offset(offset) # Calculation - np_high, np_low = high.values, low.values + np_high, np_low = high.to_numpy(), low.to_numpy() highest_high = high.rolling(window=pivot_leg, center=True, min_periods=0).max() lowest_low = low.rolling(window=pivot_leg, center=True, min_periods=0).min() diff --git a/pandas_ta/utils/_math.py b/pandas_ta/utils/_math.py index c2f174cb..9ca844ba 100644 --- a/pandas_ta/utils/_math.py +++ b/pandas_ta/utils/_math.py @@ -104,7 +104,7 @@ def geometric_mean(series: Series) -> Float: if n < 1: return series.iloc[0] - has_zeros = 0 in series.values + has_zeros = 0 in series.to_numpy() if has_zeros: series = series.fillna(0) + 1 if all(series > 0): diff --git a/pandas_ta/volatility/atrts.py b/pandas_ta/volatility/atrts.py index 18965805..d6d102ca 100644 --- a/pandas_ta/volatility/atrts.py +++ b/pandas_ta/volatility/atrts.py @@ -122,7 +122,7 @@ def atrts( atr_ *= multiplier ma_ = _ma(mamode, close, length=ma_length, talib=mode_tal) - np_close, np_ma, np_atr = close.values, ma_.values, atr_.values + np_close, np_ma, np_atr = close.to_numpy(), ma_.to_numpy(), atr_.to_numpy() np_atrts_, _, _ = np_atrts(np_close, np_ma, np_atr, length, ma_length) percent = kwargs.pop("percent", False) diff --git a/pandas_ta/volume/kvo.py b/pandas_ta/volume/kvo.py index f6089595..685d046e 100644 --- a/pandas_ta/volume/kvo.py +++ b/pandas_ta/volume/kvo.py @@ -69,11 +69,11 @@ def kvo( sv = signed_volume.loc[signed_volume.first_valid_index():, ] kvo = ma(mamode, sv, length=fast) - ma(mamode, sv, length=slow) - if kvo is None or all(isnan(kvo.values)): + if kvo is None or all(isnan(kvo.to_numpy())): return # Emergency Break kvo_signal = ma(mamode, kvo.loc[kvo.first_valid_index():, ], length=signal) - if kvo_signal is None or all(isnan(kvo_signal.values)): + if kvo_signal is None or all(isnan(kvo_signal.to_numpy())): return # Emergency Break # Offset diff --git a/pandas_ta/volume/mfi.py b/pandas_ta/volume/mfi.py index f5a4c546..89f1fc84 100644 --- a/pandas_ta/volume/mfi.py +++ b/pandas_ta/volume/mfi.py @@ -68,8 +68,8 @@ def mfi( else: m, _ones = close.size, ones(length) - tp = (high.values + low.values + close.values) / 3.0 - smf = tp * volume.values * where(tp > roll(tp, shift=drift), 1, -1) + tp = (high.to_numpy() + low.to_numpy() + close.to_numpy()) / 3.0 + smf = tp * volume.to_numpy() * where(tp > roll(tp, shift=drift), 1, -1) pos, neg = maximum(smf, 0), maximum(-smf, 0) avg_gain, avg_loss = convolve(pos, _ones)[:m], convolve(neg, _ones)[:m] diff --git a/pandas_ta/volume/pvi.py b/pandas_ta/volume/pvi.py index f3bf046a..509d86ce 100644 --- a/pandas_ta/volume/pvi.py +++ b/pandas_ta/volume/pvi.py @@ -1,15 +1,38 @@ # -*- coding: utf-8 -*- -import pandas as pd -import numpy as np -from pandas import Series +from numba import njit +from numpy import empty, float64, zeros_like +from pandas import DataFrame, Series from pandas_ta._typing import DictLike, Int from pandas_ta.ma import ma -from pandas_ta.utils import v_offset, v_mamode, v_pos_default, v_series +from pandas_ta.utils import ( + v_bool, + v_mamode, + v_offset, + v_pos_default, + v_series +) + + +@njit(cache=True) +def np_pvi(np_close, np_volume, initial): + result = zeros_like(np_close, dtype=float64) + result[0] = initial + + m = np_close.size + for i in range(1, m): + if np_volume[i] > np_volume[i - 1]: + result[i] = result[i - i] * (np_close[i] / np_close[i - 1]) + else: + result[i] = result[i - i] + + return result + def pvi( close: Series, volume: Series, length: Int = None, initial: Int = None, - mamode: str = None, offset: Int = None, **kwargs: DictLike -) -> pd.DataFrame: + mamode: str = None, overlay: bool = None, offset: Int = None, + **kwargs: DictLike +) -> DataFrame: """Positive Volume Index (PVI) The Positive Volume Index is a cumulative indicator that uses volume @@ -17,6 +40,7 @@ def pvi( conjunction with NVI. Sources: + https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=101 https://www.investopedia.com/terms/p/pvi.asp Args: @@ -25,6 +49,8 @@ def pvi( length (int): The short period. Default: 255 initial (int): The short period. Default: 100 mamode (str): See ``help(ta.ma)``. Default: 'ema' + overlay (bool): Sets the initial value to initial close so PVI + can be overlaid the price chart. Default: False offset (int): How many periods to offset the result. Default: 0 Kwargs: @@ -32,52 +58,55 @@ def pvi( fill_method (value, optional): Type of fill method Returns: - pd.DataFrame: New DataFrame with ['PVI_1', 'PVIs_'] + pd.DataFrame: DataFrame with PVI and PVI Signal columns """ - # Validate - mamode = v_mamode(mamode, "ema") length = v_pos_default(length, 255) close = v_series(close, length + 1) volume = v_series(volume, length + 1) - initial = v_pos_default(initial, 100) - offset = v_offset(offset) if close is None or volume is None: return - # Get numpy arrays of the data - close_prices = close.to_numpy() - volumes = volume.to_numpy() - pvis = np.empty(len(close_prices)) - - # Set the first value from from initial - pvis[0] = initial + mamode = v_mamode(mamode, "ema") + overlay = v_bool(overlay, False) + if overlay: + initial = close.iloc[0] + initial = v_pos_default(initial, 100) + offset = v_offset(offset) # Calculate - for i in range(1, len(close_prices)): - if volumes[i] > volumes[i-1]: - # PVI = Yesterday’s PVI + [[(Close – Yesterday’s Close) / Yesterday’s Close] * Yesterday’s PVI - pvis[i] = pvis[i-1] + (((close_prices[i] - close_prices[i-1]) / close_prices[i-1]) * pvis[i-1]) - else: - # PVI = Yesterday’s PVI - pvis[i] = pvis[i-1] + np_close, np_volume = close.to_numpy(), volume.to_numpy() + _pvi = np_pvi(np_close, np_volume, initial) - data = { - 'PVI_1': pvis, - } - df = pd.DataFrame(data, index=close.index) + pvi = Series(_pvi, index=close.index) + pvi_ma = ma(mamode, pvi, length=length) + # Offset if offset != 0: - df['PVI_1'] = df['PVI_1'].shift(offset) - - sig_series = ma(mamode, df['PVI_1'], length=length) - df[f'PVIs_{length}'] = sig_series + pvi = pvi.shift(offset) + pvi_ma = pvi_ma.shift(offset) # Fill if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) + pvi.fillna(kwargs["fillna"], inplace=True) + pvi_ma.fillna(kwargs["fillna"], inplace=True) if "fill_method" in kwargs: - df.fillna(method=kwargs["fill_method"], inplace=True) + pvi.fillna(method=kwargs["fill_method"], inplace=True) + pvi_ma.fillna(method=kwargs["fill_method"], inplace=True) + + # Name and Category + _mode = mamode.lower()[0] if len(mamode) else "" + _props = f"{_mode}_{length}" + pvi.name = f"PVI" + pvi_ma.name = f"PVI{_props}" + pvi.category = pvi_ma.category = "volume" + + data = { pvi.name: pvi, pvi_ma.name: pvi_ma } + df = DataFrame(data, index=close.index) + + # Name and Category + df.name = pvi.name + df.category = pvi.category return df diff --git a/tests/conftest.py b/tests/conftest.py index 67829934..301fe42e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,7 +9,7 @@ from pandas import read_csv -TEST_ROWS = 200 +TEST_ROWS = 300 TEST_CSV = f"data/SPY_D.csv" BEEP = False diff --git a/tests/test_indicator_volume.py b/tests/test_indicator_volume.py index 88307bb5..15ccb39a 100644 --- a/tests/test_indicator_volume.py +++ b/tests/test_indicator_volume.py @@ -137,9 +137,13 @@ def test_obv(df): def test_pvi(df): - result = ta.pvi(df.close, df.volume) + result = ta.pvi(df.close, df.volume, length=10) assert isinstance(result, DataFrame) - assert result.name == "PVI_1" + assert result.name == "PVI" + + result = ta.pvi(df.close, df.volume, length=10, overlay=True) + assert isinstance(result, DataFrame) + assert df.close.iloc[0] == result.iloc[0,0] def test_pvol(df): @@ -251,9 +255,9 @@ def test_ext_nvi(df): assert df.columns[-1] == "NVI_1" -def test_ext_pvi(df): - df.ta.pvi(append=True) - assert list(df.columns[-2:]) == ["PVI_1", "PVIs_255"] +# def test_ext_pvi(df): + df.ta.pvi(length=10, append=True) + assert list(df.columns[-2:]) == ["PVI", "PVIe_10"] def test_ext_pvol(df): diff --git a/tests/test_studies.py b/tests/test_studies.py index e57b1781..0256acde 100644 --- a/tests/test_studies.py +++ b/tests/test_studies.py @@ -9,7 +9,7 @@ [pytest.param(ta.CommonStudy, id="common"), pytest.param(ta.AllStudy, id="all")] # +/- when adding/removing indicators -ALL_COLUMNS = 324 +ALL_COLUMNS = 325 def test_all_study_props(all_study): @@ -33,7 +33,7 @@ def test_common_study_props(common_study): @pytest.mark.parametrize("category,columns", [ ("candles", 70), ("cycles", 2), ("momentum", 78), ("overlap", 56), ("performance", 2), ("statistics", 16), ("transform", 5), ("trend", 31), - ("volatility", 36), ("volume", 28), + ("volatility", 36), ("volume", 29), pytest.param(ta.AllStudy, ALL_COLUMNS, id=f"all-{ALL_COLUMNS}"), pytest.param(ta.CommonStudy, 5, id="common-5"), ]) @@ -89,7 +89,7 @@ def test_study_custom_e_talib(df, custom_study_e, talib): @pytest.mark.parametrize("talib", [False, True]) def test_study_all_multirun_talib(df, all_study, talib): - new_columns = 613 # +/- when adding/removing indicators + new_columns = 619 # +/- when adding/removing indicators initial_columns = df.shape[1] df.ta.study(all_study, length=10, cores=0, talib=talib) df.ta.study(all_study, length=50, cores=0, talib=talib)