mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-09-11 12:30:30 +08:00
@@ -6,7 +6,7 @@
|
||||
# Technical Analysis Library in Python 3.7
|
||||

|
||||
|
||||
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.
|
||||
Technical Analysis (TA) is an easy to use library that is built upon Python's Pandas library with more than 100 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 & 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'].
|
||||
@@ -119,7 +119,7 @@ print(prehl2.columns) # "pre_HL2"
|
||||
endhl2 = df.ta.hl2(suffix="end")
|
||||
print(endhl2.columns) # "HL2_end"
|
||||
|
||||
bothhl2 = df.ta.hl2(suffix="end")
|
||||
bothhl2 = df.ta.hl2(prefix="pre", suffix="end")
|
||||
print(bothhl2.columns) # "pre_HL2_end"
|
||||
```
|
||||
|
||||
|
||||
@@ -951,6 +951,15 @@ class AnalysisIndicators(BasePandasObject):
|
||||
result = cross(series_a=a, series_b=b, above=above, asint=asint, offset=offset, **kwargs)
|
||||
return result
|
||||
|
||||
def cross_value(self, a=None, value=None, above=True, asint=True, offset=None, **kwargs):
|
||||
if a is None and value is None: return self._df
|
||||
else:
|
||||
a = self._get_column(a, f"{a}")
|
||||
result = cross_value(series_a=a, value=value, above=above, asint=asint, offset=offset, **kwargs)
|
||||
self._add_prefix_suffix(result, **kwargs)
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
# Volatility Indicators
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from pandas import DataFrame
|
||||
from pandas import DataFrame, concat
|
||||
from ..overlap.ema import ema
|
||||
from ..utils import get_offset, verify_series
|
||||
from ..utils import get_offset, verify_series, generate_signal_indicators
|
||||
|
||||
def macd(close, fast=None, slow=None, signal=None, offset=None, **kwargs):
|
||||
"""Indicator: Moving Average, Convergence/Divergence (MACD)"""
|
||||
@@ -51,7 +51,40 @@ def macd(close, fast=None, slow=None, signal=None, offset=None, **kwargs):
|
||||
macddf.name = f"MACD_{fast}_{slow}_{signal}"
|
||||
macddf.category = 'momentum'
|
||||
|
||||
return macddf
|
||||
signal_indicators = kwargs.pop('signal_indicators', False)
|
||||
if signal_indicators:
|
||||
signalsdf = concat(
|
||||
[
|
||||
macddf,
|
||||
generate_signal_indicators(
|
||||
indicator=histogram,
|
||||
xa=kwargs.pop('xa', 0),
|
||||
xb=kwargs.pop('xb', None),
|
||||
xserie=kwargs.pop('xserie', None),
|
||||
xserie_a=kwargs.pop('xserie_a', None),
|
||||
xserie_b=kwargs.pop('xserie_b', None),
|
||||
cross_values=kwargs.pop('cross_values', True),
|
||||
cross_series=kwargs.pop('cross_series', True),
|
||||
offset=offset,
|
||||
),
|
||||
generate_signal_indicators(
|
||||
indicator=macd,
|
||||
xa=kwargs.pop('xa', 0),
|
||||
xb=kwargs.pop('xb', None),
|
||||
xserie=kwargs.pop('xserie', None),
|
||||
xserie_a=kwargs.pop('xserie_a', None),
|
||||
xserie_b=kwargs.pop('xserie_b', None),
|
||||
cross_values=kwargs.pop('cross_values', False),
|
||||
cross_series=kwargs.pop('cross_series', True),
|
||||
offset=offset,
|
||||
),
|
||||
],
|
||||
axis=1
|
||||
)
|
||||
|
||||
return signalsdf
|
||||
else:
|
||||
return macddf
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from ..utils import get_drift, get_offset, verify_series
|
||||
from pandas import DataFrame, concat
|
||||
from ..utils import get_drift, get_offset, verify_series, generate_signal_indicators
|
||||
|
||||
def rsi(close, length=None, scalar=None, drift=None, offset=None, **kwargs):
|
||||
"""Indicator: Relative Strength Index (RSI)"""
|
||||
@@ -36,7 +37,31 @@ def rsi(close, length=None, scalar=None, drift=None, offset=None, **kwargs):
|
||||
rsi.name = f"RSI_{length}"
|
||||
rsi.category = 'momentum'
|
||||
|
||||
return rsi
|
||||
signal_indicators = kwargs.pop('signal_indicators', False)
|
||||
if signal_indicators:
|
||||
signalsdf = concat(
|
||||
[
|
||||
DataFrame(
|
||||
{rsi.name: rsi}
|
||||
),
|
||||
generate_signal_indicators(
|
||||
indicator=rsi,
|
||||
xa=kwargs.pop('xa', 80),
|
||||
xb=kwargs.pop('xb', 20),
|
||||
xserie=kwargs.pop('xserie', None),
|
||||
xserie_a=kwargs.pop('xserie_a', None),
|
||||
xserie_b=kwargs.pop('xserie_b', None),
|
||||
cross_values=kwargs.pop('cross_values', False),
|
||||
cross_series=kwargs.pop('cross_series', True),
|
||||
offset=offset,
|
||||
),
|
||||
],
|
||||
axis=1
|
||||
)
|
||||
|
||||
return signalsdf
|
||||
else:
|
||||
return rsi
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -82,6 +82,10 @@ def combination(**kwargs):
|
||||
return numerator // denominator
|
||||
|
||||
|
||||
def cross_value(series_a:pd.Series, value:float, above:bool =True, asint:bool =True, offset:int =None, **kwargs):
|
||||
series_b = pd.Series(value, index=series_a.index, name=f"{value}".replace('.','_'))
|
||||
return cross(series_a, series_b, above, asint, offset, **kwargs)
|
||||
|
||||
def cross(series_a:pd.Series, series_b:pd.Series, above:bool =True, asint:bool =True, offset:int =None, **kwargs):
|
||||
series_a = verify_series(series_a)
|
||||
series_b = verify_series(series_b)
|
||||
@@ -109,7 +113,53 @@ def cross(series_a:pd.Series, series_b:pd.Series, above:bool =True, asint:bool =
|
||||
|
||||
return cross
|
||||
|
||||
def signals(indicator, xa, xb, cross_values, xserie, xserie_a, xserie_b, cross_series, offset):
|
||||
signalsdf = pd.DataFrame()
|
||||
if xa is not None and isinstance(xa, (int, float)):
|
||||
if cross_values:
|
||||
crossed_above_start = cross_value(indicator, xa, above=True, offset=offset)
|
||||
crossed_above_end = cross_value(indicator, xa, above=False, offset=offset)
|
||||
signalsdf[crossed_above_start.name] = crossed_above_start
|
||||
signalsdf[crossed_above_end.name] = crossed_above_end
|
||||
else:
|
||||
crossed_above = above_value(indicator, xa, offset=offset)
|
||||
signalsdf[crossed_above.name] = crossed_above
|
||||
|
||||
if xb is not None and isinstance(xb, (int, float)):
|
||||
if cross_values:
|
||||
crossed_below_start = cross_value(indicator, xb, above=True, offset=offset)
|
||||
crossed_below_end = cross_value(indicator, xb, above=False, offset=offset)
|
||||
signalsdf[crossed_below_start.name] = crossed_below_start
|
||||
signalsdf[crossed_below_end.name] = crossed_below_end
|
||||
else:
|
||||
crossed_below = below_value(indicator, xb, offset=offset)
|
||||
signalsdf[crossed_below.name] = crossed_below
|
||||
|
||||
# xseries is the default value for both xserie_a and xserie_b
|
||||
if xserie_a is None:
|
||||
xserie_a = xserie
|
||||
if xserie_b is None:
|
||||
xserie_b = xserie
|
||||
|
||||
if xserie_a is not None and verify_series(xserie_a):
|
||||
if cross_series:
|
||||
cross_serie_above = cross(indicator, xserie_a, above=True, offset=offset)
|
||||
else:
|
||||
cross_serie_above = above(indicator, xserie_a, offset=offset)
|
||||
|
||||
signalsdf[cross_serie_above.name] = cross_serie_above
|
||||
|
||||
if xserie_b is not None and verify_series(xserie_b):
|
||||
if cross_series:
|
||||
cross_serie_below = cross(indicator, xserie_b, above=False, offset=offset)
|
||||
else:
|
||||
cross_serie_below = below(indicator, xserie_b, offset=offset)
|
||||
|
||||
signalsdf[cross_serie_below.name] = cross_serie_below
|
||||
|
||||
return signalsdf
|
||||
|
||||
|
||||
def df_error_analysis(dfA:pd.DataFrame, dfB:pd.DataFrame, **kwargs):
|
||||
""" """
|
||||
col = kwargs.pop('col', None)
|
||||
|
||||
Reference in New Issue
Block a user