From fc20b0c7df753e968927b1ff14af55f4647cd7e2 Mon Sep 17 00:00:00 2001 From: Kevin Johnson Date: Tue, 12 May 2020 12:24:58 -0700 Subject: [PATCH] ENH reverse and datetime_ordered properties --- .gitignore | 1 - LICENSE | 2 +- README.md | 27 +++++++++++++++++++++------ pandas_ta/core.py | 14 +++++++++++++- setup.py | 2 +- tests/config.py | 9 +++++++-- tests/test_indicator_momentum.py | 25 +++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 1e26ff0..4e18958 100644 --- a/.gitignore +++ b/.gitignore @@ -116,7 +116,6 @@ env/** pandas_ta/_wrapper.py # twopirllc stuff -IBclient/ data/datas.csv data/SPY_5min.csv data/SPY_1min.csv diff --git a/LICENSE b/LICENSE index 5ae193c..14e5543 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) Microsoft Corporation +Copyright (c) 2020 pandas-ta Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 92a34cc..6e09c61 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Technical Analysis Library in Python 3.7 ![Example Chart](/images/TA_Chart.png) -Technical Analysis (TA) is an easy to use library that is built upon Python's Pandas library with more than 80 Indicators. These indicators are comminly used for financial time series datasets with columns or labels similar to: datetime, open, high, low, close, volume, et al. Many commonly used indicators are included, such as: _Moving Average Convergence Divergence_ (*MACD*), _Hull Exponential Moving Average_ (*HMA*), _Bollinger Bands_ (*BBANDS*), _On-Balance Volume_ (*OBV*), _Aroon Oscillator_ (*AROON*) and more. +Technical Analysis (TA) is an easy to use library that is built upon Python's Pandas library with more than 85 Indicators. These indicators are comminly used for financial time series datasets with columns or labels similar to: datetime, open, high, low, close, volume, et al. Many commonly used indicators are included, such as: _Moving Average Convergence Divergence_ (*MACD*), _Hull Exponential Moving Average_ (*HMA*), _Bollinger Bands_ (*BBANDS*), _On-Balance Volume_ (*OBV*), _Aroon Oscillator_ (*AROON*) and more. This version contains both the orignal code branch as well as a newly refactored branch with the option to use [Pandas DataFrame Extension](https://pandas.pydata.org/pandas-docs/stable/extending.html) mode. All the indicators return a named Series or a DataFrame in uppercase underscore parameter format. For example, MACD(fast=12, slow=26, signal=9) will return a DataFrame with columns: ['MACD_12_26_9', 'MACDH_12_26_9', 'MACDS_12_26_9']. @@ -9,12 +9,11 @@ All the indicators return a named Series or a DataFrame in uppercase underscore ## Features -* Over 80 indicators. +* Has 89+ indicators. * Example Jupyter Notebook under the examples directory. * Abbreviated Indicator names as listed below. * *Extended Pandas DataFrame* as 'ta'. See examples below. -* Parameter names are more consistent. -* Refactoring indicators into categories similar to [TA-lib](https://github.com/mrjbq7/ta-lib/tree/master/docs/func_groups). +* Categories similar to [TA-lib](https://github.com/mrjbq7/ta-lib/tree/master/docs/func_groups). ## Recent Changes @@ -86,7 +85,20 @@ help(pd.DataFrame().ta.log_return) ``` -## New ta DataFrame Property: *adjusted* +## New DataFrame Properties: *reverse* & *datetime_ordered* + +```python +# The 'reverse' is a helper property that returns the DataFrame +# in reverse order +df = df.ta.reverse + +# The 'datetime_ordered' property returns True if the DataFrame +# index is of Pandas datetime64 and df.index[0] < df.index[-1] +# Otherwise it return False +time_series_in_order = df.ta.datetime_ordered +``` + +## DataFrame Property: *adjusted* ```python # Set ta to default to an adjusted column, 'adj_close', overriding default 'close' @@ -153,7 +165,7 @@ df.ta.adjusted = None * _T3 Moving Average_: **t3** * _Triple Exponential Moving Average_: **tema** * _Triangular Moving Average_: **trima** -* _Volume Weighted Average Price_: **vwap** +* _Volume Weighted Average Price_: **vwap** * _Volume Weighted Moving Average_: **vwma** * _Weighted Moving Average_: **wma** * _Zero Lag Moving Average_: **zlma** @@ -248,6 +260,9 @@ Use parameter: cumulative=**True** for cumulative results. | ![Example OBV](/images/SPY_OBV.png) | +# Contributors +* [allahyarzadeh](https://github.com/allahyarzadeh) + # Inspiration * TradingView: http://www.tradingview.com diff --git a/pandas_ta/core.py b/pandas_ta/core.py index 41b42a8..cf05a5b 100644 --- a/pandas_ta/core.py +++ b/pandas_ta/core.py @@ -140,6 +140,18 @@ class AnalysisIndicators(BasePandasObject): else: self._adjusted = None + @property + def datetime_ordered(self) -> bool: + """Returns true if the index is a datetime and ordered else False.""" + index_is_datetime = pd.api.types.is_datetime64_any_dtype(self._df.index) + ordered = self._df.index[0] < self._df.index[-1] + return True if index_is_datetime and ordered else False + + @property + def reverse(self) -> pd.DataFrame: + """Reverses the DataFrame""" + return self._df.iloc[::-1] + def _append(self, result=None, **kwargs): """Appends a Pandas Series or DataFrame columns to self._df.""" if 'append' in kwargs and kwargs['append']: @@ -219,7 +231,7 @@ class AnalysisIndicators(BasePandasObject): """Indicator list""" header = f"pandas.ta - Technical Analysis Indicators" helper_methods = ['indicators', 'constants'] # Public non-indicator methods - ta_properties = ['adjusted'] + ta_properties = ['adjusted', 'datetime_ordered', 'reverse'] exclude_methods = kwargs.pop('exclude', None) as_list = kwargs.pop('as_list', False) ta_indicators = list((x for x in dir(pd.DataFrame().ta) if not x.startswith('_') and not x.endswith('_'))) diff --git a/setup.py b/setup.py index 6f7ec7a..752fc1c 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ long_description = "An easy to use Python 3 Pandas Extension with 80+ Technical setup( name ="pandas_ta", packages =['pandas_ta', 'pandas_ta.momentum', 'pandas_ta.overlap', 'pandas_ta.performance', 'pandas_ta.statistics', 'pandas_ta.trend', 'pandas_ta.volatility', 'pandas_ta.volume'], - version ="0.1.40b", + version ="0.1.41b", description =long_description, long_description =long_description, author ="Kevin Johnson", diff --git a/tests/config.py b/tests/config.py index 9fc9b88..3c4534f 100644 --- a/tests/config.py +++ b/tests/config.py @@ -1,5 +1,4 @@ import os -from random import choice from pandas import read_csv VERBOSE = True @@ -10,7 +9,13 @@ INFO = f"[i]" CORRELATION = 'corr' #'sem' CORRELATION_THRESHOLD = 0.99 # Less than 0.99 is undesirable -sample_data = read_csv(f"data/SPY_D.csv", index_col=0, parse_dates=True, infer_datetime_format=False, keep_date_col=True) +sample_data = read_csv( + f"data/SPY_D.csv", + index_col=0, + parse_dates=True, + infer_datetime_format=False, + keep_date_col=True + ) def error_analysis(df, kind, msg, icon=INFO, newline=True): if VERBOSE: diff --git a/tests/test_indicator_momentum.py b/tests/test_indicator_momentum.py index 8b5c006..0580b84 100644 --- a/tests/test_indicator_momentum.py +++ b/tests/test_indicator_momentum.py @@ -34,6 +34,31 @@ class TestMomentum(TestCase): def tearDown(self): pass + def test_datetime_ordered(self): + # Test if datetime64 index and ordered + result = self.data.ta.datetime_ordered + self.assertTrue(result) + + # Test if not ordered + original = self.data.copy() + reversal = original.ta.reverse + result = reversal.ta.datetime_ordered + self.assertFalse(result) + + # Test a non-datetime64 index + original = self.data.copy() + original.reset_index(inplace=True) + result = original.ta.datetime_ordered + self.assertFalse(result) + + def test_reverse(self): + original = self.data.copy() + result = original.ta.reverse + + # Check if first and last time are reversed + self.assertEqual(result.index[-1], original.index[0]) + self.assertEqual(result.index[0], original.index[-1]) + def test_ao(self): result = pandas_ta.ao(self.high, self.low) self.assertIsInstance(result, Series)