mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-06-27 16:10:07 +08:00
@@ -14,7 +14,7 @@ Pandas TA - A Technical Analysis Library in Python 3
|
||||
[](https://pypistats.org/packages/pandas_ta)
|
||||
[](#stars)
|
||||
[](#forks)
|
||||
[](#usedby)
|
||||
[](#usedby)
|
||||
[](#contributors)
|
||||
[](#issues)
|
||||
[](#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,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
@@ -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,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,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,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,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,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,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,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,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,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
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user