Skip to content

Commit

Permalink
DEV numpy prenan fn TST new numba file MAINT minor refactor BUG #690
Browse files Browse the repository at this point in the history
…pivots
  • Loading branch information
twopirllc committed Jun 9, 2023
1 parent fcfeac0 commit 8785dc2
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 36 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ init:
test_metrics:
pytest -vv -s -l --cache-clear tests/test_metrics.py

test_numba:
pytest -vv -s -l --cache-clear tests/test_numba.py

test_studies:
pytest -vv -s -l --cache-clear tests/test_studies.py

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ $ pip install pandas_ta[full]

Development Version
-------------------
The _development_ version, _0.3.95b_, includes _numerous_ bug fixes, speed improvements and better documentation since release, _0.3.14b_.
The _development_ version, _0.3.96b_, includes _numerous_ bug fixes, speed improvements and better documentation since release, _0.3.14b_.
```sh
$ pip install -U git+https://github.com/twopirllc/pandas-ta.git@development
```
Expand Down Expand Up @@ -538,7 +538,7 @@ df.ta.cores
df.ta.ds

# Set the Data Source (ds) so that df.ta.ticker() can download ohlcv data.
# Available Data Sources: "yf", "polgon"
# Available Data Sources: "yf", "polygon"
df.ta.ds = "yf"
```

Expand Down
5 changes: 1 addition & 4 deletions pandas_ta/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1260,10 +1260,7 @@ def pivots(self, method=None, anchor=None, **kwargs: DictLike):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = pivots(
open_=open_, high=high, low=low, close=close,
method=method, anchor=anchor, **kwargs,
)
result = pivots(open_=open_, high=high, low=low, close=close, method=method, anchor=anchor, **kwargs)
return self._post_process(result, **kwargs)

def pwma(self, length=None, offset=None, **kwargs: DictLike):
Expand Down
8 changes: 5 additions & 3 deletions pandas_ta/overlap/pivots.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,14 @@ def pivots(
]
method = v_str(method, methods[0])

dt_index = close.index
if dt_index.size < 3:
if close.index.size < 3:
return # Emergency Break

if not v_datetime_ordered(close):
dt_index = to_datetime(close.index, unit="ms")
print("[!] Pivots requires a datetime ordered index.")
return

dt_index = close.index
freq = infer_freq(dt_index)

if anchor and isinstance(anchor, str) and len(anchor) >= 1:
Expand All @@ -189,6 +190,7 @@ def pivots(
"close": close.resample(anchor).last()
}
)
df.dropna(inplace=True)
else:
df = DataFrame(
data={"open": open_, "high": high, "low": low, "close": close},
Expand Down
2 changes: 1 addition & 1 deletion pandas_ta/overlap/sma.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import convolve, ndarray, ones
from numpy import convolve, ones
from numba import njit
from pandas import Series
from pandas_ta._typing import Array, DictLike, Int
Expand Down
3 changes: 3 additions & 0 deletions pandas_ta/utils/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ def _speed_group(
result = []
for i in group:
r = df.ta(i, talib=talib, timed=True)
if r is None:
print(f"[S] {i} skipped due to returning None")
continue # ta.pivots() sometimes returns None
ms = float(r.timed.split(" ")[0].split(" ")[0])
result.append({index_name: i, "ms": ms, "secs": ms2secs(ms, p)})
return result
Expand Down
11 changes: 10 additions & 1 deletion pandas_ta/utils/_numba.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@
from pandas_ta._typing import Array, Int, IntFloat

__all__ = [
"np_prenan",
"np_prepend",
"np_rolling",
"np_shift",
]


# Utilities
@njit(cache=True)
def np_prenan(x: Array, n: Int, value: IntFloat = nan) -> Array:
"""Prepend n values, typically np.nan, to array x."""
if n > 0:
x[:n - 1] = value
return x
return x


@njit(cache=True)
def np_prepend(x: Array, n: Int, value: IntFloat = nan) -> Array:
"""Prepend n values, typically np.nan, to array x."""
Expand Down
4 changes: 2 additions & 2 deletions pandas_ta/volatility/natr.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ def natr(
from talib import NATR
natr = NATR(high, low, close, length)
else:
natr = scalar / close
natr *= atr(
natr = (scalar / close) * \
atr(
high=high, low=low, close=close, length=length,
mamode=mamode, drift=drift, talib=mode_tal,
offset=offset, **kwargs
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"pandas_ta.volatility",
"pandas_ta.volume"
],
version=".".join(("0", "3", "95b")),
version=".".join(("0", "3", "96b")),
description=long_description,
long_description=long_description,
author="Kevin Johnson",
Expand Down
34 changes: 34 additions & 0 deletions tests/test_numba.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
import numpy as np
import pandas_ta as ta

from pytest import mark


@mark.parametrize("array,n,result", [
(np.ones(5), 2, np.array([np.nan, 1.0, 1.0, 1.0, 1.0])),
(np.ones(5), -2, np.ones(5))
])
def test_np_prenan(array, n, result):
np.testing.assert_array_equal(ta.np_prenan(array, n), result)


@mark.parametrize("array,n,result", [
(np.ones(5), 2, np.array([np.nan, np.nan, 1.0, 1.0, 1.0, 1.0, 1.0])),
(np.ones(5), -2, np.ones(5))
])
def test_np_prepend(array, n, result):
np.testing.assert_array_equal(ta.np_prepend(array, n), result)


@mark.parametrize("array,n,fn,result", [(np.ones(5), 2, None, np.ones(5))])
def test_np_rolling(array, n, fn, result):
np.testing.assert_array_equal(ta.np_rolling(array, n, fn), result)


@mark.parametrize("array,n,result", [
(np.ones(5), 2, np.array([np.nan, np.nan, 1.0, 1.0, 1.0])),
(np.ones(5), -2, np.array([1.0, 1.0, 1.0, np.nan, np.nan]))
])
def test_np_shift(array, n, result):
np.testing.assert_array_equal(ta.np_shift(array, n), result)
23 changes: 1 addition & 22 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,27 +277,6 @@ def test_inv_norm_value(value, result):
assert ta.utils.inv_norm(value) == result


@mark.parametrize("array,window,result", [
(np.ones(5), 2, np.array([np.nan, np.nan, 1.0, 1.0, 1.0, 1.0, 1.0])),
(np.ones(5), -2, np.ones(5))
])
def test_np_prepend(array, window, result):
np.testing.assert_array_equal(ta.np_prepend(array, window), result)


@mark.parametrize("array,window,fn,result", [(np.ones(5), 2, None, np.ones(5))])
def test_np_rolling(array, window, fn, result):
np.testing.assert_array_equal(ta.np_rolling(array, window, fn), result)


@mark.parametrize("array,window,result", [
(np.ones(5), 2, np.array([np.nan, np.nan, 1.0, 1.0, 1.0])),
(np.ones(5), -2, np.array([1.0, 1.0, 1.0, np.nan, np.nan]))
])
def test_np_shift(array, window, result):
np.testing.assert_array_equal(ta.np_shift(array, window), result)


def test_symmetric_triangle():
np.testing.assert_array_equal(ta.utils.symmetric_triangle(), np.array([1,1]))
np.testing.assert_array_equal(ta.utils.symmetric_triangle(weighted=True), np.array([0.5, 0.5]))
Expand Down Expand Up @@ -399,5 +378,5 @@ def test_zero(value, result):
@mark.parametrize("talib", [False, True])
@mark.parametrize("verbose", [False, True])
def test_indicator_speed_talib_verbose(df, talib, verbose):
resultdf =ta.speed_test(df, talib=talib, verbose=verbose)
resultdf = ta.speed_test(df, talib=talib, verbose=verbose)
assert isinstance(resultdf, DataFrame)

0 comments on commit 8785dc2

Please sign in to comment.