diff --git a/.gitignore b/.gitignore index dc05d78..db9fdb3 100644 --- a/.gitignore +++ b/.gitignore @@ -143,4 +143,7 @@ data/TV_5min.csv data/tulip.csv examples/*.csv jnb/*.ipynb -jnb/*.txt \ No newline at end of file +jnb/*.txt + +*.txt +reza_ohlcv \ No newline at end of file diff --git a/README.md b/README.md index 419321e..97beaa2 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ $ pip install pandas_ta Latest Version -------------- -Best choice! Version: *0.3.19b* +Best choice! Version: *0.3.20b* * Includes all fixes and updates between **pypi** and what is covered in this README. ```sh $ pip install -U git+https://github.com/twopirllc/pandas-ta @@ -958,6 +958,7 @@ print(pf.returns_stats())
## **Breaking / Depreciated Indicators** +* _Arnaud Legoux Moving Average_ (**alma**) New default ```length=9```. See ```help(ta.alma)```. * _Trend Return_ (**trend_return**) has been removed and replaced with **tsignals**. When given a trend Series like ```close > sma(close, 50)``` it returns the Trend, Trade Entries and Trade Exits of that trend to make it compatible with [**vectorbt**](https://github.com/polakowo/vectorbt) by setting ```asbool=True``` to get boolean Trade Entries and Exits. See ```help(ta.tsignals)``` * _Zero Lag Moving Average_ (**zlma**) now using available Moving Averages from ```ta.ma```. See ```help(ta.zlma)``` and ```help(ta.ma)```. diff --git a/pandas_ta/overlap/alma.py b/pandas_ta/overlap/alma.py index 2107831..c6dfd04 100644 --- a/pandas_ta/overlap/alma.py +++ b/pandas_ta/overlap/alma.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from math import floor from numpy import exp as npExp from numpy import nan as npNaN from pandas import Series @@ -8,8 +9,8 @@ from pandas_ta.utils import get_offset, verify_series def alma(close, length=None, sigma=None, distribution_offset=None, offset=None, **kwargs): """Indicator: Arnaud Legoux Moving Average (ALMA)""" # Validate Arguments - length = int(length) if length and length > 0 else 10 - sigma = float(sigma) if sigma and sigma > 0 else 6.0 + length = int(length) if isinstance(length, int) and length > 0 else 9 + sigma = float(sigma) if isinstance(sigma, float) and sigma > 0 else 6.0 distribution_offset = float(distribution_offset) if distribution_offset and distribution_offset > 0 else 0.85 close = verify_series(close, length) offset = get_offset(offset) @@ -67,6 +68,7 @@ in conjunction with smoothing to reduce noise. Implemented for Pandas TA by rengel8 based on the source provided below. Sources: + https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=475&Name=Moving_Average_-_Arnaud_Legoux https://www.prorealcode.com/prorealtime-indicators/alma-arnaud-legoux-moving-average/ Calculation: @@ -74,7 +76,7 @@ Calculation: Args: close (pd.Series): Series of 'close's - length (int): It's period, window size. Default: 10 + length (int): It's period, window size. Default: 9 sigma (float): Smoothing value. Default 6.0 distribution_offset (float): Value to offset the distribution min 0 (smoother), max 1 (more responsive). Default 0.85 diff --git a/pandas_ta/overlap/ssf.py b/pandas_ta/overlap/ssf.py index 88742d7..692f65b 100644 --- a/pandas_ta/overlap/ssf.py +++ b/pandas_ta/overlap/ssf.py @@ -10,8 +10,8 @@ from pandas_ta.utils import get_offset, verify_series def ssf(close, length=None, poles=None, offset=None, **kwargs): """Indicator: Ehler's Super Smoother Filter (SSF)""" # Validate Arguments - length = int(length) if length and length > 0 else 10 - poles = int(poles) if poles in [2, 3] else 2 + length = int(length) if isinstance(length, int) and length > 0 else 10 + poles = int(poles) if isinstance(poles, int) and poles in [2, 3] else 2 close = verify_series(close, length) offset = get_offset(offset) @@ -32,11 +32,9 @@ def ssf(close, length=None, poles=None, offset=None, **kwargs): c2 = c0 + b0 # e^(-2x) + 2e^(-x)*cos(3^(.5) * x) c1 = 1 - c2 - c3 - c4 - for i in range(0, m): + for i in range(poles, m): ssf.iloc[i] = c1 * close.iloc[i] + c2 * ssf.iloc[i - 1] + c3 * ssf.iloc[i - 2] + c4 * ssf.iloc[i - 3] - ssf.iloc[:3] = npNaN - else: # poles == 2 x = npPi * npSqrt(2) / length # x = PI * 2^(.5) / n a0 = npExp(-x) # e^(-x) @@ -44,10 +42,10 @@ def ssf(close, length=None, poles=None, offset=None, **kwargs): b1 = 2 * a0 * npCos(x) # 2e^(-x)*cos(x) c1 = 1 - a1 - b1 # e^(-2x) - 2e^(-x)*cos(x) + 1 - for i in range(0, m): + for i in range(poles, m): ssf.iloc[i] = c1 * close.iloc[i] + b1 * ssf.iloc[i - 1] + a1 * ssf.iloc[i - 2] - ssf.iloc[:2] = npNaN + ssf.iloc[:length] = npNaN # Offset if offset != 0: diff --git a/pandas_ta/statistics/stdev.py b/pandas_ta/statistics/stdev.py index 6047101..f0e6780 100644 --- a/pandas_ta/statistics/stdev.py +++ b/pandas_ta/statistics/stdev.py @@ -8,7 +8,7 @@ from pandas_ta.utils import get_offset, verify_series def stdev(close, length=None, ddof=None, talib=None, offset=None, **kwargs): """Indicator: Standard Deviation""" # Validate Arguments - length = int(length) if length and length > 0 else 30 + length = int(length) if isinstance(length, int) and length > 0 else 30 ddof = int(ddof) if isinstance(ddof, int) and ddof >= 0 and ddof < length else 1 close = verify_series(close, length) offset = get_offset(offset) diff --git a/pandas_ta/statistics/variance.py b/pandas_ta/statistics/variance.py index 60f54f4..c964c9f 100644 --- a/pandas_ta/statistics/variance.py +++ b/pandas_ta/statistics/variance.py @@ -6,7 +6,7 @@ from pandas_ta.utils import get_offset, verify_series def variance(close, length=None, ddof=None, talib=None, offset=None, **kwargs): """Indicator: Variance""" # Validate Arguments - length = int(length) if length and length > 1 else 30 + length = int(length) if isinstance(length, int) and length > 1 else 30 ddof = int(ddof) if isinstance(ddof, int) and ddof >= 0 and ddof < length else 1 min_periods = int(kwargs["min_periods"]) if "min_periods" in kwargs and kwargs["min_periods"] is not None else length close = verify_series(close, max(length, min_periods)) diff --git a/setup.py b/setup.py index fbaf0a6..ddfb6c3 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ setup( "pandas_ta.volatility", "pandas_ta.volume" ], - version=".".join(("0", "3", "19b")), + version=".".join(("0", "3", "20b")), description=long_description, long_description=long_description, author="Kevin Johnson", diff --git a/tests/test_ext_indicator_overlap_ext.py b/tests/test_ext_indicator_overlap_ext.py index 514af45..80990d5 100644 --- a/tests/test_ext_indicator_overlap_ext.py +++ b/tests/test_ext_indicator_overlap_ext.py @@ -26,7 +26,7 @@ class TestOverlapExtension(TestCase): def test_alma_ext(self): self.data.ta.alma(append=True) self.assertIsInstance(self.data, DataFrame) - self.assertEqual(self.data.columns[-1], "ALMA_10_6.0_0.85") + self.assertEqual(self.data.columns[-1], "ALMA_9_6.0_0.85") def test_dema_ext(self): self.data.ta.dema(append=True) diff --git a/tests/test_indicator_overlap.py b/tests/test_indicator_overlap.py index 4ec0cb0..f2d7592 100644 --- a/tests/test_indicator_overlap.py +++ b/tests/test_indicator_overlap.py @@ -42,7 +42,7 @@ class TestOverlap(TestCase): def test_alma(self): result = pandas_ta.alma(self.close)# , length=None, sigma=None, distribution_offset=) self.assertIsInstance(result, Series) - self.assertEqual(result.name, "ALMA_10_6.0_0.85") + self.assertEqual(result.name, "ALMA_9_6.0_0.85") def test_dema(self): result = pandas_ta.dema(self.close, talib=False)