BUG #311 ENH #311 DOC update MAINT numpy nan refactor

This commit is contained in:
Kevin Johnson
2021-06-17 18:35:16 -07:00
parent c671f9fab3
commit 618e37dca7
20 changed files with 153 additions and 73 deletions
+16 -12
View File
@@ -14,7 +14,7 @@ Pandas TA - A Technical Analysis Library in Python 3
[![Downloads](https://img.shields.io/pypi/dm/pandas_ta?style=flat)](https://pypistats.org/packages/pandas_ta)
[![Stars](https://img.shields.io/github/stars/twopirllc/pandas-ta?style=flat)](#stars)
[![Forks](https://img.shields.io/github/forks/twopirllc/pandas-ta?style=flat)](#forks)
[![Used By](https://img.shields.io/badge/used_by-136-orange.svg?style=flat)](#usedby)
[![Used By](https://img.shields.io/badge/used_by-138-orange.svg?style=flat)](#usedby)
[![Contributors](https://img.shields.io/github/contributors/twopirllc/pandas-ta?style=flat)](#contributors)
[![Issues](https://img.shields.io/github/issues-raw/twopirllc/pandas-ta?style=flat)](#issues)
[![Closed Issues](https://img.shields.io/github/issues-closed-raw/twopirllc/pandas-ta?style=flat)](#closed-issues)
@@ -43,6 +43,9 @@ _Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that lever
* [Help](#help)
* [Issues and Contributions](#issues-and-contributions)
* [Programming Conventions](#programming-conventions)
* [Standard](#standard)
* [Pandas TA DataFrame Extension](#pandas-ta-dataframe-extension)
* [Pandas TA Strategy](#pandas-ta-strategy)
* [Pandas TA Strategies](#pandas-ta-strategies)
* [Types of Strategies](#types-of-strategies)
* [DataFrame Properties](#dataframe-properties)
@@ -50,7 +53,7 @@ _Pandas Technical Analysis_ (**Pandas TA**) is an easy to use library that lever
* [Indicators by Category](#indicators-by-category)
* [Candles](#candles-64)
* [Cycles](#cycles-1)
* [Momentum](#momentum-39)
* [Momentum](#momentum-40)
* [Overlap](#overlap-32)
* [Performance](#performance-3)
* [Statistics](#statistics-9)
@@ -107,7 +110,7 @@ $ pip install pandas_ta
Latest Version
--------------
Best choice! Version: *0.2.88b*
Best choice! Version: *0.2.89b*
```sh
$ pip install -U git+https://github.com/twopirllc/pandas-ta
```
@@ -195,7 +198,7 @@ Thanks for using **Pandas TA**!
* The indicator does not match another website, library, broker platform, language, et al.
* Do you have correlation analysis to back your claim?
* Can you contribute?
* You will be asked to fill out an Issue even if you email my personal email address.
* You **will** be asked to fill out an Issue even if you email my personally.
<br/>
@@ -203,9 +206,9 @@ Thanks for using **Pandas TA**!
**Contributors**
================
_Thank you for your contributions!_
_Thank you for your contributions!_
[alexonab](https://github.com/alexonab) | [allahyarzadeh](https://github.com/allahyarzadeh) | [CMobley7](https://github.com/CMobley7) | [codesutras](https://github.com/codesutras) | [DrPaprikaa](https://github.com/DrPaprikaa) | [daikts](https://github.com/daikts) | [dorren](https://github.com/dorren) | [edwardwang1](https://github.com/edwardwang1) | [ffhirata](https://github.com/ffhirata) | [FGU1](https://github.com/FGU1) | [floatinghotpot](https://github.com/floatinghotpot) | [GSlinger](https://github.com/gslinger) | [JoeSchr](https://github.com/JoeSchr) | [lluissalord](https://github.com/lluissalord) | [luisbarrancos](https://github.com/luisbarrancos) | [M6stafa](https://github.com/M6stafa) | [maxdignan](https://github.com/maxdignan) | [mchant](https://github.com/mchant) | [moritzgun](https://github.com/moritzgun) | [nicoloridulfo](https://github.com/nicoloridulfo) [NkosenhleDuma](https://github.com/NkosenhleDuma) | [pbrumblay](https://github.com/pbrumblay) | [RajeshDhalange](https://github.com/RajeshDhalange) | [rengel8](https://github.com/rengel8) | [rluong003](https://github.com/rluong003) | [SoftDevDanial](https://github.com/SoftDevDanial) | [tg12](https://github.com/tg12) | [twrobel](https://github.com/twrobel) | [WellMaybeItIs](https://github.com/WellMaybeItIs) | [whubsch](https://github.com/whubsch) | [witokondoria](https://github.com/witokondoria) | [wouldayajustlookatit](https://github.com/wouldayajustlookatit) | [YuvalWein](https://github.com/YuvalWein)
[AbyssAlora](https://github.com/AbyssAlora) | [alexonab](https://github.com/alexonab) | [allahyarzadeh](https://github.com/allahyarzadeh) | [CMobley7](https://github.com/CMobley7) | [codesutras](https://github.com/codesutras) | [DrPaprikaa](https://github.com/DrPaprikaa) | [daikts](https://github.com/daikts) | [dorren](https://github.com/dorren) | [edwardwang1](https://github.com/edwardwang1) | [ffhirata](https://github.com/ffhirata) | [FGU1](https://github.com/FGU1) | [floatinghotpot](https://github.com/floatinghotpot) | [GSlinger](https://github.com/gslinger) | [JoeSchr](https://github.com/JoeSchr) | [lluissalord](https://github.com/lluissalord) | [luisbarrancos](https://github.com/luisbarrancos) | [M6stafa](https://github.com/M6stafa) | [maxdignan](https://github.com/maxdignan) | [mchant](https://github.com/mchant) | [moritzgun](https://github.com/moritzgun) | [nicoloridulfo](https://github.com/nicoloridulfo) [NkosenhleDuma](https://github.com/NkosenhleDuma) | [pbrumblay](https://github.com/pbrumblay) | [RajeshDhalange](https://github.com/RajeshDhalange) | [rengel8](https://github.com/rengel8) | [rluong003](https://github.com/rluong003) | [SoftDevDanial](https://github.com/SoftDevDanial) | [tg12](https://github.com/tg12) | [twrobel](https://github.com/twrobel) | [WellMaybeItIs](https://github.com/WellMaybeItIs) | [whubsch](https://github.com/whubsch) | [witokondoria](https://github.com/witokondoria) | [wouldayajustlookatit](https://github.com/wouldayajustlookatit) | [YuvalWein](https://github.com/YuvalWein)
<br/>
@@ -661,7 +664,7 @@ df = df.ta.cdl_pattern(name=["doji", "inside"])
<br/>
### **Momentum** (39)
### **Momentum** (40)
* _Awesome Oscillator_: **ao**
* _Absolute Price Oscillator_: **apo**
* _Bias_: **bias**
@@ -674,6 +677,7 @@ df = df.ta.cdl_pattern(name=["doji", "inside"])
* _Coppock Curve_: **coppock**
* _Correlation Trend Indicator_: **cti**
* A wrapper for ```ta.linreg(series, r=True)```
* _Directional Movement_: **dm**
* _Efficiency Ratio_: **er**
* _Elder Ray Index_: **eri**
* _Fisher Transform_: **fisher**
@@ -725,7 +729,7 @@ df = df.ta.cdl_pattern(name=["doji", "inside"])
* _Hull Exponential Moving Average_: **hma**
* _Holt-Winter Moving Average_: **hwma**
* _Ichimoku Kinkō Hyō_: **ichimoku**
* Use: help(ta.ichimoku). Returns two DataFrames.
* Returns two DataFrames. For more information: ```help(ta.ichimoku)```.
* Drop the Chikou Span Column, the final column of the first resultant DataFrame, remove potential data leak.
* _Kaufman's Adaptive Moving Average_: **kama**
* _Linear Regression_: **linreg**
@@ -942,7 +946,7 @@ print(pf.returns_stats())
<br />
## **Breaking Indicators**
## **Breaking / Depreciated Indicators**
* _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)```
<br/>
@@ -954,10 +958,10 @@ trading account, or fund. See: ```help(ta.drawdown)```
* _Candle Z Score_ (**cdl_z**) normalizes OHLC Candles with a rolling Z Score. See: ```help(ta.cdl_z)```
* _Correlation Trend Indicator_ (**cti**) is an oscillator created by John Ehler in 2020. See: ```help(ta.cti)```
* _Cross Signals_ (**xsignals**) was created by Kevin Johnson. It is a wrapper of Trade Signals that returns Trends, Trades, Entries and Exits. Cross Signals are commonly used for **bbands**, **rsi**, **zscore** crossing some value either above or below two values at different times. See: ```help(ta.xsignals)```
* _Directional Movement_ (**dm**) developed by J. Welles Wilder in 1978 attempts to determine which direction the price of an asset is moving. See: ```help(ta.dm)```
* _Even Better Sinewave_ (**ebsw**) measures market cycles and uses a low pass filter to remove noise. See: ```help(ta.ebsw)```
* _Klinger Volume Oscillator_ (**kvo**) was developed by Stephen J. Klinger. It is designed to predict price reversals in a market by comparing volume to price.. See: ```help(ta.kvo)```
* _Schaff Trend Cycle_ (**stc**) is an evolution of the popular MACD incorportating two
cascaded stochastic calculations with additional smoothing. See: ```help(ta.stc)```
* _Schaff Trend Cycle_ (**stc**) is an evolution of the popular MACD incorportating two cascaded stochastic calculations with additional smoothing. See: ```help(ta.stc)```
* _Tom DeMark's Sequential_ (**td_seq**) attempts to identify a price point where an uptrend or a downtrend exhausts itself and reverses. Currently exlcuded from ```df.ta.strategy()``` for performance reasons. See: ```help(ta.td_seq)```
* _Vertical Horizontal Filter_ (**vhf**) was created by Adam White to identify trending and ranging markets.. See: ```help(ta.vhf)```
@@ -972,7 +976,7 @@ cascaded stochastic calculations with additional smoothing. See: ```help(ta.stc)
* _Chande Kroll Stop_ (**cksp**): Added ```tvmode``` with default ```True```. When ```tvmode=False```, **cksp** implements “The New Technical Trader” with default values. See ```help(ta.cksp)```.
* _Decreasing_ (**decreasing**): New argument ```strict``` checks if the series is continuously decreasing over period ```length``` with a faster calculation. Default: ```False```. The ```percent``` argument has also been added with default None. See ```help(ta.decreasing)```.
* _Increasing_ (**increasing**): New argument ```strict``` checks if the series is continuously increasing over period ```length``` with a faster calculation. Default: ```False```. The ```percent``` argument has also been added with default None. See ```help(ta.increasing)```.
* _Parabolic Stop and Reverse_ (**psar**): New argument ```af0``` to initialize the Acceleration Factor. ```help(ta.psar)```.
* _Parabolic Stop and Reverse_ (**psar**): Bug fix and adjustment to match TradingView's ```sar```. New argument ```af0``` to initialize the Acceleration Factor. ```help(ta.psar)```.
* _Volume Weighted Average Price_ (**vwap**): Added a new parameter called ```anchor```. Default: "D" for "Daily". See [Timeseries Offset Aliases](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases) for additional options. **Requires** the DataFrame index to be a DatetimeIndex
* _Z Score_ (**zscore**): Changed return column name from ```Z_length``` to ```ZS_length```.
+1 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from numpy import cos as npCos
from numpy import exp as npExp
from numpy import NaN as npNaN
from numpy import nan as npNaN
from numpy import pi as npPi
from numpy import sin as npSin
from numpy import sqrt as npSqrt
+50 -14
View File
@@ -1,12 +1,16 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame
from pandas_ta import Imports
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, verify_series, get_drift, zero
def dm(high, low, drift=None, offset=None, **kwargs):
def dm(high, low, length=None, mamode=None, drift=None, offset=None, **kwargs):
"""Indicator: DM"""
# Validate Arguments
length = int(length) if length and length > 0 else 14
mamode = mamode.lower() if mamode and isinstance(mamode, str) else "rma"
high = verify_series(high)
low = verify_series(low)
drift = get_drift(drift)
@@ -15,27 +19,37 @@ def dm(high, low, drift=None, offset=None, **kwargs):
if high is None or low is None:
return
up = high - high.shift(drift)
dn = low.shift(drift) - low
if Imports["talib"]:
from talib import MINUS_DM, PLUS_DM
pos, neg = PLUS_DM(high, low), MINUS_DM(high, low)
else:
up = high - high.shift(drift)
dn = low.shift(drift) - low
pos = ((up > dn) & (up > 0)) * up
neg = ((dn > up) & (dn > 0)) * dn
pos_ = ((up > dn) & (up > 0)) * up
neg_ = ((dn > up) & (dn > 0)) * dn
pos = pos.apply(zero)
neg = neg.apply(zero)
pos_ = pos_.apply(zero)
neg_ = neg_.apply(zero)
# Not the same values as TA Lib's -+DM (Good First Issue)
pos = ma(mamode, pos_, length=length)
neg = ma(mamode, neg_, length=length)
# Offset
if offset != 0:
pos = pos.shift(offset)
neg = neg.shift(offset)
_params = f"_{drift}"
_params = f"_{length}"
data = {
f"+DM{_params}": pos,
f"-DM{_params}": neg,
f"DMP{_params}": pos,
f"DMN{_params}": neg,
}
dmdf = DataFrame(data)
# print(dmdf.head(20))
# print()
dmdf.name = f"DM{_params}"
dmdf.category = "trend"
@@ -43,9 +57,31 @@ def dm(high, low, drift=None, offset=None, **kwargs):
dm.__doc__ = \
"""Directional Movement (DM)
"""Directional Movement (DM)
Directional Movement
The Directional Movement was developed by J. Welles Wilder in 1978 attempts to
determine which direction the price of an asset is moving. It compares prior
highs and lows to yield to two series +DM and -DM.
Sources:
https://www.tradingview.com/pine-script-reference/#fun_dmi
https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=24&Name=Directional_Movement_Index
Calculation:
Default Inputs:
length=14, mamode="rma", drift=1
up = high - high.shift(drift)
dn = low.shift(drift) - low
pos_ = ((up > dn) & (up > 0)) * up
neg_ = ((dn > up) & (dn > 0)) * dn
pos_ = pos_.apply(zero)
neg_ = neg_.apply(zero)
# Not the same values as TA Lib's -+DM
pos = ma(mamode, pos_, length=length)
neg = ma(mamode, neg_, length=length)
Args:
high (pd.Series): Series of 'high's
@@ -54,5 +90,5 @@ Args:
offset (int): How many periods to offset the result. Default: 0
Returns:
pd.DataFrame: +DM and -DM columns.
pd.DataFrame: DMP (+DM) and DMN (-DM) columns.
"""
+1 -1
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from numpy import log as nplog
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame, Series
from pandas_ta.overlap import ema, hl2
from pandas_ta.utils import get_offset, high_low_range, verify_series, zero
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import concat, DataFrame, Series
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame
from pandas_ta.momentum import mom
from pandas_ta.overlap import ema, linreg, sma
+1 -1
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from numpy import exp as npExp
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import Series
from pandas_ta.utils import get_offset, verify_series
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame, Series
from .ma import ma
from pandas_ta.utils import get_offset, verify_series
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import Series
from pandas_ta.utils import get_drift, get_offset, non_zero_range, verify_series
+1 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from numpy import array as npArray
from numpy import arctan as npAtan
from numpy import NaN as npNaN
from numpy import nan as npNaN
from numpy import pi as npPi
from numpy.lib.stride_tricks import sliding_window_view
from pandas import Series
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame
from pandas_ta.overlap import hl2
from pandas_ta.volatility import atr
+48 -31
View File
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, verify_series
from pandas_ta.momentum import dm
from pandas_ta.utils import get_offset, verify_series, zero
def psar(high, low, close=None, af0=None, af=None, max_af=None, offset=None, **kwargs):
@@ -15,9 +15,16 @@ def psar(high, low, close=None, af0=None, af=None, max_af=None, offset=None, **k
max_af = float(max_af) if max_af and max_af > 0 else 0.2
offset = get_offset(offset)
_dm = dm(high, low, close)
def _falling(high, low, drift:int=1):
"""Returns the last -DM value"""
# Not to be confused with ta.falling()
up = high - high.shift(drift)
dn = low.shift(drift) - low
_dmn = (((dn > up) & (dn > 0)) * dn).apply(zero)[-1]
return _dmn > 0
falling = _dm["-DM_1"].iloc[1] > 0
# Falling if the first NaN -DM is positive
falling = _falling(high.iloc[:2], low.iloc[:2])
if falling:
sar = high.iloc[0]
ep = low.iloc[0]
@@ -33,50 +40,46 @@ def psar(high, low, close=None, af0=None, af=None, max_af=None, offset=None, **k
short = long.copy()
reversal = Series(False, index=high.index)
_af = long.copy()
_af.iloc[0:1] = af0
m = high.shape[0]
_af.iloc[0:2] = af0
# Calculate Result
m = high.shape[0]
for row in range(1, m):
HIGH = high.iloc[row]
LOW = low.iloc[row]
high_ = high.iloc[row]
low_ = low.iloc[row]
if falling:
new_sar = sar + af * (ep - sar)
reverse = HIGH > new_sar
_sar = sar + af * (ep - sar)
reverse = high_ > _sar
if LOW < ep:
ep = LOW
if low_ < ep:
ep = low_
af = min(af + af0, max_af)
new_sar = max(high.iloc[row - 1], high.iloc[row - 2], new_sar)
_sar = max(high.iloc[row - 1], high.iloc[row - 2], _sar)
else:
new_sar = sar + af * (ep - sar)
reverse = LOW < new_sar
_sar = sar + af * (ep - sar)
reverse = low_ < _sar
if HIGH > ep:
ep = HIGH
if high_ > ep:
ep = high_
af = min(af + af0, max_af)
new_sar = min(low.iloc[row - 1], low.iloc[row - 2], new_sar)
_sar = min(low.iloc[row - 1], low.iloc[row - 2], _sar)
if reverse:
new_sar = ep
_sar = ep
af = af0
falling = not falling
falling = not falling # Must come before next line
ep = low_ if falling else high_
if falling:
ep = LOW
else:
ep = HIGH
sar = _sar # Update SAR
sar = new_sar
if not falling:
long.iloc[row] = sar
else:
# Seperate long/short sar based on falling
if falling:
short.iloc[row] = sar
else:
long.iloc[row] = sar
_af.iloc[row] = af
reversal.iloc[row] = reverse
@@ -118,12 +121,26 @@ def psar(high, low, close=None, af0=None, af=None, max_af=None, offset=None, **k
psar.__doc__ = \
"""Parabolic Stop and Reverse (psar)
Parabolic Stop and Reverse
Parabolic Stop and Reverse (PSAR) was developed by J. Wells Wilder, that is used
to determine trend direction and it's potential reversals in price. PSAR uses a
trailing stop and reverse method called "SAR," or stop and reverse, to identify
possible entries and exits. It is also known as SAR.
PSAR indicator typically appears on a chart as a series of dots, either above or
below an asset's price, depending on the direction the price is moving. A dot is
placed below the price when it is trending upward, and above the price when it
is trending downward.
Sources:
https://www.tradingview.com/pine-script-reference/#fun_sar
https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=66&Name=Parabolic
Calculation:
Default Inputs:
af0=0.02, af=0.02, max_af=0.2
See Source links
Args:
high (pd.Series): Series of 'high's
low (pd.Series): Series of 'low's
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame
from .tsignals import tsignals
from pandas_ta.utils._signals import cross_value
+1 -1
View File
@@ -4,7 +4,7 @@ from pathlib import Path
from sys import float_info as sflt
from numpy import argmax, argmin
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import DataFrame, Series
from pandas.api.types import is_datetime64_any_dtype
+1 -1
View File
@@ -15,7 +15,7 @@ from numpy import fabs as npFabs
from numpy import floor as npFloor
from numpy import exp as npExp
from numpy import log as npLog
from numpy import NaN as npNaN
from numpy import nan as npNaN
from numpy import ndarray as npNdArray
from numpy import seterr
from numpy import sqrt as npSqrt
+1 -1
View File
@@ -2,7 +2,7 @@
from typing import Tuple
from numpy import log as npLog
from numpy import NaN as npNaN
from numpy import nan as npNaN
from numpy import sqrt as npSqrt
from pandas import Series, Timedelta
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from numpy import NaN as npNaN
from numpy import nan as npNaN
from pandas import concat
from pandas_ta import Imports
from pandas_ta.utils import get_drift, get_offset, non_zero_range, verify_series
+1 -1
View File
@@ -18,7 +18,7 @@ setup(
"pandas_ta.volatility",
"pandas_ta.volume"
],
version=".".join(("0", "2", "88b")),
version=".".join(("0", "2", "89b")),
description=long_description,
long_description=long_description,
author="Kevin Johnson",
+23
View File
@@ -159,6 +159,29 @@ class TestMomentum(TestCase):
self.assertIsInstance(result, Series)
self.assertEqual(result.name, "ER_10")
def test_dm(self):
result = pandas_ta.dm(self.high, self.low)
self.assertIsInstance(result, DataFrame)
self.assertEqual(result.name, "DM_14")
try:
expected_pos = tal.PLUS_DM(self.high, self.low)
expected_neg = tal.MINUS_DM(self.high, self.low)
expecteddf = DataFrame({"DMP_14": expected_pos, "DMN_14": expected_neg})
pdt.assert_frame_equal(result, expecteddf)
except AssertionError as ae:
try:
dmp = pandas_ta.utils.df_error_analysis(result.iloc[:,0], expecteddf.iloc[:,0], col=CORRELATION)
self.assertGreater(dmp, CORRELATION_THRESHOLD)
except Exception as ex:
error_analysis(result, CORRELATION, ex)
try:
dmn = pandas_ta.utils.df_error_analysis(result.iloc[:,1], expecteddf.iloc[:,1], col=CORRELATION)
self.assertGreater(dmn, CORRELATION_THRESHOLD)
except Exception as ex:
error_analysis(result, CORRELATION, ex)
def test_eri(self):
result = pandas_ta.eri(self.high, self.low, self.close)
self.assertIsInstance(result, DataFrame)