Merge branch 'pr/457' into development

This commit is contained in:
Kevin Johnson
2022-01-23 09:41:31 -08:00
160 changed files with 731 additions and 578 deletions
+3 -1
View File
@@ -2,9 +2,11 @@
from pandas_ta.overlap import sma
from pandas_ta.utils import get_offset, high_low_range, is_percent
from pandas_ta.utils import real_body, verify_series
from pandas import Series
def cdl_doji(open_, high, low, close, length=None, factor=None, scalar=None, asint=True, offset=None, **kwargs):
def cdl_doji(open_: Series, high: Series, low: Series, close: Series, length: int = None, factor: float = None,
scalar: float = None, asint: bool = True, offset: int = None, **kwargs) -> Series:
"""Candle Type: Doji
A candle body is Doji, when it's shorter than 10% of the
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import candle_color, get_offset
from pandas_ta.utils import verify_series
from pandas import Series
def cdl_inside(open_, high, low, close, asbool=False, offset=None, **kwargs):
def cdl_inside(open_: Series, high: Series, low: Series, close: Series, asbool: bool = False,
offset: int = None, **kwargs) -> Series:
"""Candle Type: Inside Bar
An Inside Bar is a bar that is engulfed by the prior highs and lows of it's
+9 -8
View File
@@ -24,13 +24,13 @@ ALL_PATTERNS = [
def cdl_pattern(
open_,
high,
low,
close,
name: Union[str, Sequence[str]]="all",
scalar=None,
offset=None,
open_: Series,
high: Series,
low: Series,
close: Series,
name: Union[str, Sequence[str]] = "all",
scalar: float = None,
offset: int = None,
**kwargs
) -> DataFrame:
"""TA Lib Candle Patterns
@@ -121,4 +121,5 @@ def cdl_pattern(
df.category = "candles"
return df
cdl = cdl_pattern # Alias
cdl = cdl_pattern # Alias
+3 -2
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.statistics import zscore
from pandas_ta.utils import get_offset, verify_series
def cdl_z(open_, high, low, close, length=None, full=None, ddof=None, offset=None, **kwargs):
def cdl_z(open_: Series, high: Series, low: Series, close: Series, length: int = None, full: bool = None,
ddof=None, offset: int = None, **kwargs) -> DataFrame:
"""Candle Type: Z
Normalizes OHLC Candles with a rolling Z Score.
+2 -2
View File
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, verify_series
def ha(open_, high, low, close, offset=None, **kwargs):
def ha(open_: Series, high: Series, low: Series, close: Series, offset: int = None, **kwargs) -> DataFrame:
"""Heikin Ashi Candles (HA)
The Heikin-Ashi technique averages price data to create a Japanese
+109 -158
View File
@@ -1,113 +1,22 @@
# -*- coding: utf-8 -*-
from dataclasses import dataclass, field
# from dataclasses import dataclass, field
from email.policy import default
from multiprocessing import cpu_count, Pool
from time import perf_counter
from typing import List, Tuple
from typing import Union
from warnings import simplefilter
from numpy import log10, ndarray
from pandas.api.extensions import register_dataframe_accessor
from pandas.core.base import PandasObject
from pandas.errors import PerformanceWarning
from pandas import DataFrame, Series
from pandas_ta import Category, Imports, np, pd, version
from pandas_ta.candles.cdl_pattern import ALL_PATTERNS
from pandas_ta.candles import *
from pandas_ta.cycles import *
from pandas_ta.momentum import *
from pandas_ta.overlap import *
from pandas_ta.performance import *
from pandas_ta.statistics import *
from pandas_ta.trend import *
from pandas_ta.volatility import *
from pandas_ta.volume import *
from pandas_ta import *
from pandas_ta.utils import *
df = pd.DataFrame()
# Study DataClass
@dataclass
class Study:
"""Study DataClass
Class to name and group indicators for processing
Args:
name (str): Some short memorable string. Note: Case-insensitive "All" is reserved.
ta (list of dicts): A list of dicts containing keyword arguments where "kind" is the indicator.
description (str): A more detailed description of what the Study tries to capture. Default: None
created (str): At datetime string of when it was created. Default: Automatically generated. *Subject to change*
Example TA:
ta = [
{"kind": "sma", "length": 200},
{"kind": "sma", "close": "volume", "length": 50},
{"kind": "bbands", "length": 20},
{"kind": "rsi"},
{"kind": "macd", "fast": 8, "slow": 21},
{"kind": "sma", "close": "volume", "length": 20, "prefix": "VOLUME"},
]
"""
name: str # = None # Required.
ta: List = field(default_factory=list) # Required.
description: str = "" # Helpful. More descriptive version or notes or w/e.
created: str = get_time(to_string=True) # Optional. Gets Exchange Time and Local Time execution time
def __post_init__(self):
req_args = ["[X] Study requires the following argument(s):"]
if self._is_name():
req_args.append(' - name. Must be a string. Example: "My TA". Note: "all" is reserved.')
if self.ta is None:
self.ta = None
elif not self._is_ta():
s = " - ta. Format is a list of dicts. Example: [{'kind': 'sma', 'length': 10}]"
s += "\n Check the indicator for the correct arguments if you receive this error."
req_args.append(s)
if len(req_args) > 1:
[print(_) for _ in req_args]
return None
def _is_name(self):
return self.name is None or not isinstance(self.name, str)
def _is_ta(self):
if isinstance(self.ta, list) and self.total_ta() > 0:
# Check that all elements of the list are dicts.
# Does not check if the dicts values are valid indicator kwargs
# User must check indicator documentation for all indicators args.
return all([isinstance(_, dict) and len(_.keys()) > 0 for _ in self.ta])
return False
def total_ta(self):
return len(self.ta) if self.ta is not None else 0
# All Study
AllStudy = Study(
name="All",
description="All the indicators with their default settings. Pandas TA default.",
ta=None,
)
# Default (Example) Study.
CommonStudy = Study(
name="Common Price and Volume SMAs",
description="Common Price SMAs: 10, 20, 50, 200 and Volume SMA: 20.",
ta=[
{"kind": "sma", "length": 10},
{"kind": "sma", "length": 20},
{"kind": "sma", "length": 50},
{"kind": "sma", "length": 200},
{"kind": "sma", "close": "volume", "length": 20, "prefix": "VOL"}
]
)
# Temporary Strategy DataClass Alias
Strategy = Study
AllStrategy = AllStudy
CommonStrategy = CommonStudy
# Base Class for extending a Pandas DataFrame
class BasePandasObject(PandasObject):
"""Simple PandasObject Extension
@@ -119,7 +28,7 @@ class BasePandasObject(PandasObject):
df (pd.DataFrame): Extends Pandas DataFrame
"""
def __init__(self, df, **kwargs):
def __init__(self, df: DataFrame, **kwargs):
if df.empty: return
print(f"\n[!] kwargs: {kwargs}\n")
if len(df.columns) > 0:
@@ -158,7 +67,7 @@ class BasePandasObject(PandasObject):
# Pandas TA - DataFrame Analysis Indicators
@pd.api.extensions.register_dataframe_accessor("ta")
@register_dataframe_accessor("ta")
class AnalysisIndicators(BasePandasObject):
"""
This Pandas Extension is named 'ta' for Technical Analysis. In other words,
@@ -251,14 +160,14 @@ class AnalysisIndicators(BasePandasObject):
_time_range = "years"
_last_run = get_time(_exchange, to_string=True)
def __init__(self, pandas_obj):
def __init__(self, pandas_obj: Union[DataFrame, Series]):
self._validate(pandas_obj)
self._df = pandas_obj
self._last_run = get_time(self._exchange, to_string=True)
@staticmethod
def _validate(obj: Tuple[pd.DataFrame, pd.Series]):
if not isinstance(obj, pd.DataFrame) and not isinstance(obj, pd.Series):
def _validate(obj: Union[DataFrame, Series]):
if not isinstance(obj, DataFrame) and not isinstance(obj, Series):
raise AttributeError("[X] Must be either a Pandas Series or DataFrame.")
# DataFrame Behavioral Methods
@@ -305,8 +214,8 @@ class AnalysisIndicators(BasePandasObject):
self._adjusted = None
@property
def cores(self) -> str:
"""Returns the categories."""
def cores(self) -> int:
"""Returns the number of CPU cores."""
return self._cores
@cores.setter
@@ -347,7 +256,7 @@ class AnalysisIndicators(BasePandasObject):
# Public Get DataFrame Properties
@property
def categories(self) -> str:
def categories(self) -> list:
"""Returns the categories."""
return list(Category.keys())
@@ -360,7 +269,7 @@ class AnalysisIndicators(BasePandasObject):
return hasdf
@property
def reverse(self) -> pd.DataFrame:
def reverse(self) -> DataFrame:
"""Reverses the DataFrame. Simply: df.iloc[::-1]"""
return self._df.iloc[::-1]
@@ -401,7 +310,7 @@ class AnalysisIndicators(BasePandasObject):
if "suffix" in kwargs:
suffix = f"{delimiter}{kwargs['suffix']}"
if isinstance(result, pd.Series):
if isinstance(result, Series):
result.name = prefix + result.name + suffix
else:
result.columns = [prefix + column + suffix for column in result.columns]
@@ -412,11 +321,11 @@ class AnalysisIndicators(BasePandasObject):
df = self._df
if df is None or result is None: return
else:
simplefilter(action="ignore", category=pd.errors.PerformanceWarning)
simplefilter(action="ignore", category=PerformanceWarning)
if "col_names" in kwargs and not isinstance(kwargs["col_names"], tuple):
kwargs["col_names"] = (kwargs["col_names"],) # Note: tuple(kwargs["col_names"]) doesn't work
if isinstance(result, pd.DataFrame):
if isinstance(result, DataFrame):
# If specified in kwargs, rename the columns.
# If not, use the default names.
if "col_names" in kwargs and isinstance(kwargs["col_names"], tuple):
@@ -440,13 +349,13 @@ class AnalysisIndicators(BasePandasObject):
"""Returns the columns in which all it's values are na."""
return [x for x in self._df.columns if all(self._df[x].isna())]
def _get_column(self, series):
def _get_column(self, series: Union[Series, str, None]):
"""Attempts to get the correct series or 'column' and return it."""
df = self._df
if df is None: return
# Explicitly passing a pd.Series to override default.
if isinstance(series, pd.Series):
if isinstance(series, Series):
return series
# Apply default if no series nor a default.
elif series is None:
@@ -463,7 +372,7 @@ class AnalysisIndicators(BasePandasObject):
match = [i for i, x in enumerate(matches) if x]
# If found, awesome. Return it or return the 'series'.
cols = ", ".join(list(df.columns))
NOT_FOUND = f"[X] Ooops!!! It's {series not in df.columns}, the column named '{series}' was not found in {cols}"
NOT_FOUND = f"[X] Ooops!!! It's {series not in df.columns}, the column '{series}' was not found in {cols}"
return df.iloc[:, match[0]] if len(match) else print(NOT_FOUND)
def _indicators_by_category(self, name: str) -> list:
@@ -479,13 +388,13 @@ class AnalysisIndicators(BasePandasObject):
else:
return getattr(self, method)(*args, **kwargs)[0]
def _post_process(self, result, **kwargs) -> Tuple[pd.Series, pd.DataFrame]:
def _post_process(self, result: Union[Series, DataFrame], **kwargs) -> Union[Series, DataFrame]:
"""Applies any additional modifications to the DataFrame
* Applies prefixes and/or suffixes
* Appends the result to main DataFrame
"""
verbose = kwargs.pop("verbose", False)
if not isinstance(result, (pd.Series, pd.DataFrame)):
if not isinstance(result, (Series, DataFrame)):
if verbose:
print(f"[X] Oops! The result was not a Series or DataFrame.")
return self._df
@@ -493,7 +402,7 @@ class AnalysisIndicators(BasePandasObject):
# Append only specific columns to the dataframe (via
# 'col_numbers':(0,1,3) for example)
result = (result.iloc[:, [int(n) for n in kwargs["col_numbers"]]]
if isinstance(result, pd.DataFrame) and
if isinstance(result, DataFrame) and
"col_numbers" in kwargs and
kwargs["col_numbers"] is not None else result)
# Add prefix/suffix and append to the dataframe
@@ -501,8 +410,9 @@ class AnalysisIndicators(BasePandasObject):
self._append(result=result, **kwargs)
return result
def _strategy_mode(self, *args) -> tuple:
"""Helper method to determine the mode and name of the study. Returns tuple: (name:str, mode:dict)"""
def _study_mode(self, *args) -> tuple:
"""Helper method to determine the mode and name of the study.
Returns tuple: (name:str, mode:dict)"""
name = "All"
mode = {"all": False, "category": False, "custom": False}
@@ -556,7 +466,7 @@ class AnalysisIndicators(BasePandasObject):
Returns nothing to the user. Either adds or removes constant ranges
from the working DataFrame.
"""
if isinstance(values, np.ndarray) or isinstance(values, list):
if isinstance(values, ndarray) or isinstance(values, list):
if append:
for x in values:
self._df[f"{x}"] = x
@@ -598,7 +508,7 @@ class AnalysisIndicators(BasePandasObject):
]
# Public non-indicator methods
ta_indicators = list((x for x in dir(pd.DataFrame().ta) if not x.startswith("_") and not x.endswith("_")))
ta_indicators = list((x for x in dir(DataFrame().ta) if not x.startswith("_") and not x.endswith("_")))
# Add Pandas TA methods and properties to be removed
removed = helper_methods + ta_properties
@@ -620,6 +530,7 @@ class AnalysisIndicators(BasePandasObject):
s, _count = f"{header}\n", 0
if indicator_count > 0:
from pandas_ta.candles.cdl_pattern import ALL_PATTERNS
s += f"\nIndicators and Utilities [{indicator_count}]:\n {', '.join(ta_indicators)}\n"
_count += indicator_count
if Imports["talib"]:
@@ -628,14 +539,12 @@ class AnalysisIndicators(BasePandasObject):
s += f"\nTotal Candles, Indicators and Utilities: {_count}"
print(s)
def sample(self, **kwargs):
"""sample
See help(ta.sample) for parameters.
"""
return sample(**kwargs)
def strategy(self, *args, **kwargs):
"""Strategy Method
@@ -664,13 +573,13 @@ class AnalysisIndicators(BasePandasObject):
"""
# If True, it returns the resultant DataFrame. Default: False
returns = kwargs.pop("returns", False)
# cpus = cpu_count()
# Ensure indicators are appended to the DataFrame
kwargs["append"] = True
all_ordered = kwargs.pop("ordered", True)
mp_chunksize = kwargs.pop("chunksize", self.cores)
_depwarning = kwargs.pop("warning", True)
if _depwarning:
print(f"\n[!] DEPRECIATION WARNING:\n Use study() instead of strategy().\n")
@@ -692,7 +601,7 @@ class AnalysisIndicators(BasePandasObject):
]
# Get the Study Name and mode
name, mode = self._strategy_mode(*args)
name, mode = self._study_mode(*args)
# If All or a Category, exclude user list if any
user_excluded = kwargs.pop("exclude", [])
@@ -755,7 +664,7 @@ class AnalysisIndicators(BasePandasObject):
_total_ta = len(ta)
with Pool(self.cores) as pool:
# Some magic to optimize chunksize for speed based on total ta indicators
_chunksize = mp_chunksize - 1 if mp_chunksize > _total_ta else int(np.log10(_total_ta)) + 1
_chunksize = mp_chunksize - 1 if mp_chunksize > _total_ta else int(log10(_total_ta)) + 1
if verbose:
print(f"[i] Multiprocessing {_total_ta} indicators with {_chunksize} chunks and {self.cores}/{cpu_count()} cpus.")
@@ -909,16 +818,27 @@ class AnalysisIndicators(BasePandasObject):
ds = ds.lower() if isinstance(ds, str) else self.ds
strategy = kwargs.pop("strategy", None)
study = kwargs.pop("study", strategy)
timed = kwargs.setdefault("timed", False)
if isinstance(ticker, str):
tickers = [ticker]
if isinstance(ticker, list):
ticker = ticker.pop()
# Fetch Data
if ds == "polygon":
if timed: stime = perf_counter()
df = polygon_api(ticker, **kwargs)
elif ds in ["yahoo", "yf"]:
if timed: stime = perf_counter()
df = yf(ticker, **kwargs)
else: return
if timed:
df.timed = final_time(stime)
print(f"[+] {ds} | {ticker}: {df.timed}")
if df is None: return
elif df.empty:
print(f"[X] DataFrame is empty: {df.shape}")
@@ -932,10 +852,9 @@ class AnalysisIndicators(BasePandasObject):
if study is not None: return self.study(study, returns=True, **kwargs)
return df
# Public DataFrame Methods: Indicators and Utilities
# Candles
def cdl_pattern(self, name="all", offset=None, **kwargs):
def cdl_pattern(self, name: str = "all", offset=None, **kwargs):
open_ = self._get_column(kwargs.pop("open", "open"))
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
@@ -1064,9 +983,11 @@ class AnalysisIndicators(BasePandasObject):
if refined is not None or thirds is not None:
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
result = inertia(close=close, high=high, low=low, length=length, rvi_length=rvi_length, scalar=scalar, refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs)
result = inertia(close=close, high=high, low=low, length=length, rvi_length=rvi_length, scalar=scalar,
refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs)
else:
result = inertia(close=close, length=length, rvi_length=rvi_length, scalar=scalar, refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs)
result = inertia(close=close, length=length, rvi_length=rvi_length, scalar=scalar, refined=refined,
thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
@@ -1079,7 +1000,8 @@ class AnalysisIndicators(BasePandasObject):
def kst(self, roc1=None, roc2=None, roc3=None, roc4=None, sma1=None, sma2=None, sma3=None, sma4=None, signal=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = kst(close=close, roc1=roc1, roc2=roc2, roc3=roc3, roc4=roc4, sma1=sma1, sma2=sma2, sma3=sma3, sma4=sma4, signal=signal, offset=offset, **kwargs)
result = kst(close=close, roc1=roc1, roc2=roc2, roc3=roc3, roc4=roc4, sma1=sma1, sma2=sma2, sma3=sma3,
sma4=sma4, signal=signal, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def macd(self, fast=None, slow=None, signal=None, offset=None, **kwargs):
@@ -1142,7 +1064,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = rvgi(open_=open_, high=high, low=low, close=close, length=length, swma_length=swma_length, offset=offset, **kwargs)
result = rvgi(open_=open_, high=high, low=low, close=close, length=length, swma_length=swma_length,
offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def slope(self, length=None, offset=None, **kwargs):
@@ -1159,19 +1082,25 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = squeeze(high=high, low=low, close=close, bb_length=bb_length, bb_std=bb_std, kc_length=kc_length, kc_scalar=kc_scalar, mom_length=mom_length, mom_smooth=mom_smooth, use_tr=use_tr, mamode=mamode, offset=offset, **kwargs)
result = squeeze(high=high, low=low, close=close, bb_length=bb_length, bb_std=bb_std, kc_length=kc_length,
kc_scalar=kc_scalar, mom_length=mom_length, mom_smooth=mom_smooth, use_tr=use_tr,
mamode=mamode, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def squeeze_pro(self, bb_length=None, bb_std=None, kc_length=None, kc_scalar_wide=None, kc_scalar_normal=None, kc_scalar_narrow=None, mom_length=None, mom_smooth=None, use_tr=None, mamode=None, offset=None, **kwargs):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = squeeze_pro(high=high, low=low, close=close, bb_length=bb_length, bb_std=bb_std, kc_length=kc_length, kc_scalar_wide=kc_scalar_wide, kc_scalar_normal=kc_scalar_normal, kc_scalar_narrow=kc_scalar_narrow, mom_length=mom_length, mom_smooth=mom_smooth, use_tr=use_tr, mamode=mamode, offset=offset, **kwargs)
result = squeeze_pro(high=high, low=low, close=close, bb_length=bb_length, bb_std=bb_std, kc_length=kc_length,
kc_scalar_wide=kc_scalar_wide, kc_scalar_normal=kc_scalar_normal,
kc_scalar_narrow=kc_scalar_narrow, mom_length=mom_length, mom_smooth=mom_smooth,
use_tr=use_tr, mamode=mamode, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def stc(self, ma1=None, ma2=None, osc=None, tclength=None, fast=None, slow=None, factor=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = stc(close=close, ma1=ma1, ma2=ma2, osc=osc, tclength=tclength, fast=fast, slow=slow, factor=factor, offset=offset, **kwargs)
result = stc(close=close, ma1=ma1, ma2=ma2, osc=osc, tclength=tclength, fast=fast, slow=slow, factor=factor,
offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def stoch(self, k=None, d=None, smooth_k=None, mamode=None, talib=None, offset=None, **kwargs):
@@ -1192,7 +1121,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = stochrsi(high=high, low=low, close=close, length=length, rsi_length=rsi_length, k=k, d=d, mamode=mamode, offset=offset, **kwargs)
result = stochrsi(high=high, low=low, close=close, length=length, rsi_length=rsi_length, k=k, d=d,
mamode=mamode, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def td_seq(self, asint=None, offset=None, show_all=None, **kwargs):
@@ -1214,7 +1144,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = uo(high=high, low=low, close=close, fast=fast, medium=medium, slow=slow, fast_w=fast_w, medium_w=medium_w, slow_w=slow_w, drift=drift, offset=offset, **kwargs)
result = uo(high=high, low=low, close=close, fast=fast, medium=medium, slow=slow, fast_w=fast_w,
medium_w=medium_w, slow_w=slow_w, drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def willr(self, length=None, percentage=True, offset=None, **kwargs):
@@ -1232,7 +1163,8 @@ class AnalysisIndicators(BasePandasObject):
def alma(self, length=None, sigma=None, distribution_offset=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = alma(close=close, length=length, sigma=sigma, distribution_offset=distribution_offset, offset=offset, **kwargs)
result = alma(close=close, length=length, sigma=sigma, distribution_offset=distribution_offset, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def dema(self, length=None, offset=None, **kwargs):
@@ -1294,7 +1226,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result, span = ichimoku(high=high, low=low, close=close, tenkan=tenkan, kijun=kijun, senkou=senkou, include_chikou=include_chikou, offset=offset, **kwargs)
result, span = ichimoku(high=high, low=low, close=close, tenkan=tenkan, kijun=kijun, senkou=senkou,
include_chikou=include_chikou, offset=offset, **kwargs)
self._add_prefix_suffix(result, **kwargs)
self._add_prefix_suffix(span, **kwargs)
self._append(result, **kwargs)
@@ -1369,7 +1302,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = supertrend(high=high, low=low, close=close, length=length, multiplier=multiplier, offset=offset, **kwargs)
result = supertrend(high=high, low=low, close=close, length=length, multiplier=multiplier, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def swma(self, length=None, offset=None, **kwargs):
@@ -1440,7 +1374,8 @@ class AnalysisIndicators(BasePandasObject):
def percent_return(self, length=None, cumulative=False, percent=False, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
result = percent_return(close=close, length=length, cumulative=cumulative, percent=percent, offset=offset, **kwargs)
result = percent_return(close=close, length=length, cumulative=cumulative, percent=percent, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
# Statistics
@@ -1499,7 +1434,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = adx(high=high, low=low, close=close, length=length, lensig=lensig, mamode=mamode, scalar=scalar, drift=drift, offset=offset, **kwargs)
result = adx(high=high, low=low, close=close, length=length, lensig=lensig, mamode=mamode, scalar=scalar,
drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def amat(self, fast=None, slow=None, mamode=None, lookback=None, offset=None, **kwargs):
@@ -1517,7 +1453,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = chop(high=high, low=low, close=close, length=length, atr_length=atr_length, scalar=scalar, drift=drift, offset=offset, **kwargs)
result = chop(high=high, low=low, close=close, length=length, atr_length=atr_length, scalar=scalar,
drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def cksp(self, p=None, x=None, q=None, mamode=None, offset=None, **kwargs):
@@ -1578,7 +1515,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = supertrend(high=high, low=low, close=close, period=period, multiplier=multiplier, mamode=mamode, drift=drift, offset=offset, **kwargs)
result = supertrend(high=high, low=low, close=close, period=period, multiplier=multiplier, mamode=mamode,
drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def trendflex(self, close=None, length=None, smooth=None, alpha=None, pi=None, sqrt2=None, offset=None, **kwargs):
@@ -1616,7 +1554,8 @@ class AnalysisIndicators(BasePandasObject):
if signal is None:
return self._df
else:
result = xsignals(signal=signal, xa=xa, xb=xb, above=above, long=long, asbool=asbool, trend_offset=trend_offset, trend_reset=trend_reset, offset=offset, **kwargs)
result = xsignals(signal=signal, xa=xa, xb=xb, above=above, long=long, asbool=asbool,
trend_offset=trend_offset, trend_reset=trend_reset, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
# Utility
@@ -1658,7 +1597,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = aberration(high=high, low=low, close=close, length=length, atr_length=atr_length, offset=offset, **kwargs)
result = aberration(high=high, low=low, close=close, length=length, atr_length=atr_length, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def accbands(self, length=None, c=None, mamode=None, offset=None, **kwargs):
@@ -1683,7 +1623,8 @@ class AnalysisIndicators(BasePandasObject):
def donchian(self, lower_length=None, upper_length=None, offset=None, **kwargs):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
result = donchian(high=high, low=low, lower_length=lower_length, upper_length=upper_length, offset=offset, **kwargs)
result = donchian(high=high, low=low, lower_length=lower_length, upper_length=upper_length, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def hwc(self, na=None, nb=None, nc=None, nd=None, scalar=None, offset=None, **kwargs):
@@ -1695,7 +1636,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = kc(high=high, low=low, close=close, length=length, scalar=scalar, mamode=mamode, offset=offset, **kwargs)
result = kc(high=high, low=low, close=close, length=length, scalar=scalar, mamode=mamode, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def massi(self, fast=None, slow=None, offset=None, **kwargs):
@@ -1708,7 +1650,8 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = natr(high=high, low=low, close=close, length=length, mamode=mamode, scalar=scalar, offset=offset, **kwargs)
result = natr(high=high, low=low, close=close, length=length, mamode=mamode, scalar=scalar, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def pdist(self, drift=None, offset=None, **kwargs):
@@ -1723,13 +1666,15 @@ class AnalysisIndicators(BasePandasObject):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
result = rvi(high=high, low=low, close=close, length=length, scalar=scalar, refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs)
result = rvi(high=high, low=low, close=close, length=length, scalar=scalar, refined=refined, thirds=thirds,
mamode=mamode, drift=drift, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def thermo(self, long=None, short= None, length=None, mamode=None, drift=None, offset=None, **kwargs):
high = self._get_column(kwargs.pop("high", "high"))
low = self._get_column(kwargs.pop("low", "low"))
result = thermo(high=high, low=low, long=long, short=short, length=length, mamode=mamode, drift=drift, offset=offset, **kwargs)
result = thermo(high=high, low=low, long=long, short=short, length=length, mamode=mamode, drift=drift,
offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def true_range(self, drift=None, offset=None, **kwargs):
@@ -1762,13 +1707,15 @@ class AnalysisIndicators(BasePandasObject):
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
volume = self._get_column(kwargs.pop("volume", "volume"))
result = adosc(high=high, low=low, close=close, volume=volume, open_=open_, fast=fast, slow=slow, signed=signed, offset=offset, **kwargs)
result = adosc(high=high, low=low, close=close, volume=volume, open_=open_, fast=fast, slow=slow,
signed=signed, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def aobv(self, fast=None, slow=None, mamode=None, max_lookback=None, min_lookback=None, offset=None, **kwargs):
close = self._get_column(kwargs.pop("close", "close"))
volume = self._get_column(kwargs.pop("volume", "volume"))
result = aobv(close=close, volume=volume, fast=fast, slow=slow, mamode=mamode, max_lookback=max_lookback, min_lookback=min_lookback, offset=offset, **kwargs)
result = aobv(close=close, volume=volume, fast=fast, slow=slow, mamode=mamode, max_lookback=max_lookback,
min_lookback=min_lookback, offset=offset, **kwargs)
return self._post_process(result, **kwargs)
def cmf(self, open_=None, length=None, offset=None, **kwargs):
@@ -1778,7 +1725,8 @@ class AnalysisIndicators(BasePandasObject):
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
volume = self._get_column(kwargs.pop("volume", "volume"))
result = cmf(high=high, low=low, close=close, volume=volume, open_=open_, length=length, offset=offset, **kwargs)
result = cmf(high=high, low=low, close=close, volume=volume, open_=open_, length=length, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def efi(self, length=None, mamode=None, offset=None, drift=None, **kwargs):
@@ -1792,7 +1740,8 @@ class AnalysisIndicators(BasePandasObject):
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
volume = self._get_column(kwargs.pop("volume", "volume"))
result = eom(high=high, low=low, close=close, volume=volume, length=length, divisor=divisor, offset=offset, drift=drift, **kwargs)
result = eom(high=high, low=low, close=close, volume=volume, length=length, divisor=divisor, offset=offset,
drift=drift, **kwargs)
return self._post_process(result, **kwargs)
def kvo(self, fast=None, slow=None, length_sig=None, mamode=None, offset=None, drift=None, **kwargs):
@@ -1800,7 +1749,8 @@ class AnalysisIndicators(BasePandasObject):
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
volume = self._get_column(kwargs.pop("volume", "volume"))
result = kvo(high=high, low=low, close=close, volume=volume, fast=fast, slow=slow, length_sig=length_sig, mamode=mamode, offset=offset, drift=drift, **kwargs)
result = kvo(high=high, low=low, close=close, volume=volume, fast=fast, slow=slow, length_sig=length_sig,
mamode=mamode, offset=offset, drift=drift, **kwargs)
return self._post_process(result, **kwargs)
def mfi(self, length=None, drift=None, offset=None, **kwargs):
@@ -1808,7 +1758,8 @@ class AnalysisIndicators(BasePandasObject):
low = self._get_column(kwargs.pop("low", "low"))
close = self._get_column(kwargs.pop("close", "close"))
volume = self._get_column(kwargs.pop("volume", "volume"))
result = mfi(high=high, low=low, close=close, volume=volume, length=length, drift=drift, offset=offset, **kwargs)
result = mfi(high=high, low=low, close=close, volume=volume, length=length, drift=drift, offset=offset,
**kwargs)
return self._post_process(result, **kwargs)
def nvi(self, length=None, initial=None, signed=True, offset=None, **kwargs):
+5 -5
View File
@@ -11,7 +11,7 @@ import pandas_ta
from pandas_ta import AnalysisIndicators
def bind(function_name, function, method):
def bind(function_name: str, function: types.FunctionType, method: types.MethodType):
"""
Helper function to bind the function and class method defined in a custom
indicator module to the active pandas_ta instance.
@@ -25,7 +25,7 @@ def bind(function_name, function, method):
setattr(AnalysisIndicators, function_name, method)
def create_dir(path, create_categories=True, verbose=True):
def create_dir(path: str, create_categories: bool = True, verbose: bool = True):
"""
Helper function to setup a suitable folder structure for working with
custom indicators. You only need to call this once whenever you want to
@@ -57,7 +57,7 @@ def create_dir(path, create_categories=True, verbose=True):
print(f"[i] Created an empty sub-directory '{dirname}'.")
def get_module_functions(module):
def get_module_functions(module: types.ModuleType) -> dict:
"""
Helper function to get the functions of an imported module as a dictionary.
@@ -80,7 +80,7 @@ def get_module_functions(module):
return module_functions
def import_dir(path, verbose=True):
def import_dir(path: str, verbose: bool = True):
# ensure that the passed directory exists / is readable
if not exists(path):
print(f"[X] Unable to read the directory '{path}'.")
@@ -202,7 +202,7 @@ like all other native indicators in pandas_ta, including help functions.
"""
def load_indicator_module(name):
def load_indicator_module(name: str) -> dict:
"""
Helper function to (re)load an indicator module.
+2 -1
View File
@@ -3,7 +3,8 @@ from pandas_ta import np, pd
from pandas_ta.utils import get_offset, verify_series
def ebsw(close, length=None, bars=None, offset=None, initial_version=False, **kwargs):
def ebsw(close: Series, length: int = None, bars: int = None, offset: int = None, initial_version: bool = False,
**kwargs) -> Series:
"""Even Better SineWave (EBSW)
This indicator measures market cycles and uses a low pass filter to remove noise.
+22 -16
View File
@@ -1,23 +1,24 @@
# -*- coding: utf-8 -*-
from pandas_ta import np, pd
from numpy import cos, exp, nan, ndarray, sqrt, zeros_like
from pandas import Series
from pandas_ta.utils import get_offset, verify_series
try:
from numba import njit
except ImportError:
njit = lambda _: _
@njit
def np_reflex(x: np.ndarray, n: int, k: int, alpha: float, pi: float, sqrt2: float):
def np_reflex(x: ndarray, n: int, k: int, alpha: float, pi: float, sqrt2: float):
m, ratio = x.size, 2 * sqrt2 / k
a = np.exp(-pi * ratio)
b = 2 * a * np.cos(180 * ratio)
a = exp(-pi * ratio)
b = 2 * a * cos(180 * ratio)
c = a * a - b + 1
_f = np.zeros_like(x)
_ms = np.zeros_like(x)
result = np.zeros_like(x)
_f = zeros_like(x)
_ms = zeros_like(x)
result = zeros_like(x)
for i in range(2, m):
_f[i] = 0.5 * c * (x[i] + x[i - 1]) + b * _f[i - 1] - a * a * _f[i - 2]
@@ -32,12 +33,17 @@ def np_reflex(x: np.ndarray, n: int, k: int, alpha: float, pi: float, sqrt2: flo
_ms[i] = alpha * _sum * _sum + (1 - alpha) * _ms[i - 1]
if _ms[i] != 0.0:
result[i] = _sum / np.sqrt(_ms[i])
result[i] = _sum / sqrt(_ms[i])
return result
def reflex(close, length=None, smooth=None, alpha=None, pi=None, sqrt2=None, offset=None, **kwargs):
def reflex(
close: Series, length: int = None,
smooth: int = None, alpha: float = None,
pi: float = None, sqrt2: float = None,
offset: int = None, **kwargs
) -> Series:
"""Reflex (reflex)
John F. Ehlers introduced two indicators within the article
@@ -73,7 +79,7 @@ def reflex(close, length=None, smooth=None, alpha=None, pi=None, sqrt2=None, off
Returns:
pd.Series: New feature generated.
"""
# Validate arguments
# Validate
length = int(length) if isinstance(length, int) and length > 0 else 20
smooth = int(smooth) if isinstance(smooth, int) and smooth > 0 else 20
alpha = float(alpha) if isinstance(alpha, float) and alpha > 0 else 0.04
@@ -82,23 +88,23 @@ def reflex(close, length=None, smooth=None, alpha=None, pi=None, sqrt2=None, off
close = verify_series(close, max(length, smooth))
offset = get_offset(offset)
# Calculate Result
# Calculate
np_close = close.values
result = np_reflex(np_close, length, smooth, alpha, pi, sqrt2)
result[:length] = np.nan
result = pd.Series(result, index=close.index)
result[:length] = nan
result = Series(result, index=close.index)
# Offset
if offset != 0:
result = result.shift(offset)
# Handle fills
# Fill
if "fillna" in kwargs:
result.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
result.fillna(method=kwargs["fill_method"], inplace=True)
# Name and Categorize it
# Name and Category
result.name = f"REFLEX_{length}_{smooth}_{alpha}"
result.category = "cycles"
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta.overlap import sma
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def ao(high, low, fast=None, slow=None, offset=None, **kwargs):
def ao(high: Series, low: Series, fast: int = None, slow: int = None, offset: int = None, **kwargs) -> Series:
"""Awesome Oscillator (AO)
The Awesome Oscillator is an indicator used to measure a security's momentum.
+3 -1
View File
@@ -2,9 +2,11 @@
from pandas_ta import Imports
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, tal_ma, verify_series
from pandas import Series
def apo(close, fast=None, slow=None, mamode=None, talib=None, offset=None, **kwargs):
def apo(close: Series, fast: int = None, slow: int = None, mamode: str = None, talib: bool = None,
offset: int = None, **kwargs) -> Series:
"""Absolute Price Oscillator (APO)
The Absolute Price Oscillator is an indicator used to measure a security's
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def bias(close, length=None, mamode=None, offset=None, **kwargs):
def bias(close: Series, length: int = None, mamode: str = None, offset: int = None, **kwargs) -> Series:
"""Bias (BIAS)
Rate of change between the source and a moving average.
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, non_zero_range, verify_series
from pandas import Series
def bop(open_, high, low, close, scalar=None, talib=None, offset=None, **kwargs):
def bop(open_: Series, high: Series, low: Series, close: Series, scalar: float = None, talib: bool = None,
offset: int = None, **kwargs) -> Series:
"""Balance of Power (BOP)
Balance of Power measure the market strength of buyers against sellers.
+3 -2
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.utils import get_drift, get_offset, non_zero_range, verify_series
def brar(open_, high, low, close, length=None, scalar=None, drift=None, offset=None, **kwargs):
def brar(open_: Series, high: Series, low: Series, close: Series, length: int = None, scalar: float = None,
drift: int = None, offset: int = None, **kwargs) -> DataFrame:
"""BRAR (BRAR)
BR and AR
+3 -1
View File
@@ -3,9 +3,11 @@ from pandas_ta import Imports
from pandas_ta.overlap import hlc3, sma
from pandas_ta.statistics.mad import mad
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def cci(high, low, close, length=None, c=None, talib=None, offset=None, **kwargs):
def cci(high: Series, low: Series, close: Series, length: int = None, c: float = None,
talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Commodity Channel Index (CCI)
Commodity Channel Index is a momentum oscillator used to primarily identify
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pandas_ta.overlap import linreg
from pandas_ta.utils import get_drift, get_offset, verify_series
from pandas import Series
def cfo(close, length=None, scalar=None, drift=None, offset=None, **kwargs):
def cfo(close: Series, length: int = None, scalar: float = None, drift: int = None, offset: int = None,
**kwargs) -> Series:
"""Chande Forcast Oscillator (CFO)
The Forecast Oscillator calculates the percentage difference between the actual
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series, weights
from pandas import Series
def cg(close, length=None, offset=None, **kwargs):
def cg(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Center of Gravity (CG)
The Center of Gravity Indicator by John Ehlers attempts to identify turning
+3 -1
View File
@@ -2,9 +2,11 @@
from pandas_ta import Imports
from pandas_ta.overlap import rma
from pandas_ta.utils import get_drift, get_offset, verify_series
from pandas import Series
def cmo(close, length=None, scalar=None, talib=None, drift=None, offset=None, **kwargs):
def cmo(close: Series, length: int = None, scalar: float = None, talib: bool = None, drift: int = None,
offset: int = None, **kwargs) -> Series:
"""Chande Momentum Oscillator (CMO)
Attempts to capture the momentum of an asset with overbought at 50 and
+3 -1
View File
@@ -2,9 +2,11 @@
from .roc import roc
from pandas_ta.overlap import wma
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def coppock(close, length=None, fast=None, slow=None, offset=None, **kwargs):
def coppock(close: Series, length: int = None, fast: int = None, slow: int = None, offset: int = None,
**kwargs) -> Series:
"""Coppock Curve (COPC)
Coppock Curve (originally called the "Trendex Model") is a momentum indicator
+1 -1
View File
@@ -4,7 +4,7 @@ from pandas_ta.overlap import linreg
from pandas_ta.utils import get_offset, verify_series
def cti(close, length=None, offset=None, **kwargs) -> Series:
def cti(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Correlation Trend Indicator (CTI)
The Correlation Trend Indicator is an oscillator created by John Ehler in 2020.
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
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, length=None, mamode=None, talib=None, drift=None, offset=None, **kwargs):
def dm(high: Series, low: Series, length: int = None, mamode: str = None, talib: bool = None, drift: int = None,
offset: int = None, **kwargs) -> DataFrame:
"""Directional Movement (DM)
The Directional Movement was developed by J. Welles Wilder in 1978 attempts to
+2 -2
View File
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame, concat
from pandas import DataFrame, concat, Series
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
def er(close, length=None, drift=None, offset=None, **kwargs):
def er(close: Series, length: int = None, drift: int = None, offset: int = None, **kwargs) -> Series:
"""Efficiency Ratio (ER)
The Efficiency Ratio was invented by Perry J. Kaufman and presented in his book "New Trading Systems and Methods". It is designed to account for market noise or volatility.
+2 -2
View File
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.overlap import ema
from pandas_ta.utils import get_offset, verify_series
def eri(high, low, close, length=None, offset=None, **kwargs):
def eri(high: Series, low: Series, close: Series, length: int = None, offset: int = None, **kwargs) -> DataFrame:
"""Elder Ray Index (ERI)
Elder's Bulls Ray Index contains his Bull and Bear Powers. Which are useful ways
+2 -1
View File
@@ -6,7 +6,8 @@ from pandas_ta.overlap import hl2
from pandas_ta.utils import get_offset, high_low_range, verify_series
def fisher(high, low, length=None, signal=None, offset=None, **kwargs):
def fisher(high: Series, low: Series, length: int = None, signal: int = None, offset: int = None,
**kwargs) -> Series:
"""Fisher Transform (FISHT)
Attempts to identify significant price reversals by normalizing prices over a
+4 -1
View File
@@ -2,9 +2,12 @@
from pandas_ta.overlap import linreg
from pandas_ta.volatility import rvi
from pandas_ta.utils import get_drift, get_offset, verify_series
from pandas import Series
def inertia(close=None, high=None, low=None, length=None, rvi_length=None, scalar=None, refined=None, thirds=None, mamode=None, drift=None, offset=None, **kwargs):
def inertia(close: Series, high: Series, low: Series, length: int = None, rvi_length: int = None, scalar: float = None,
refined: bool = None, thirds: bool = None, mamode: str = None, drift: int = None, offset: int = None,
**kwargs) -> Series:
"""Inertia (INERTIA)
Inertia was developed by Donald Dorsey and was introduced his article
+3 -2
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, non_zero_range, rma_pandas, verify_series
def kdj(high=None, low=None, close=None, length=None, signal=None, offset=None, **kwargs):
def kdj(high: Series, low: Series, close: Series, length: int = None, signal: int = None, offset: int = None,
**kwargs) -> Series:
"""KDJ (KDJ)
The KDJ indicator is actually a derived form of the Slow
+4 -2
View File
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from .roc import roc
from pandas_ta.utils import get_drift, get_offset, verify_series
def kst(close, roc1=None, roc2=None, roc3=None, roc4=None, sma1=None, sma2=None, sma3=None, sma4=None, signal=None, drift=None, offset=None, **kwargs):
def kst(close: Series, roc1: int = None, roc2: int = None, roc3: int = None, roc4: int = None, sma1: int = None,
sma2: int = None, sma3: int = None, sma4: int = None, signal: int = None, drift: int = None,
offset: int = None, **kwargs) -> DataFrame:
"""'Know Sure Thing' (KST)
The 'Know Sure Thing' is a momentum based oscillator and based on ROC.
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import concat, DataFrame
from pandas import concat, DataFrame, Series
from pandas_ta import Imports
from pandas_ta.overlap import ema
from pandas_ta.utils import get_offset, verify_series, signals
def macd(close, fast=None, slow=None, signal=None, talib=None, offset=None, **kwargs):
def macd(close: Series, fast: int = None, slow: int = None, signal: int = None, talib: bool = None,
offset: int = None, **kwargs) -> DataFrame:
"""Moving Average Convergence Divergence (MACD)
The MACD is a popular indicator to that is used to identify a security's trend.
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def mom(close, length=None, talib=None, offset=None, **kwargs):
def mom(close: Series, length: int = None, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Momentum (MOM)
Momentum is an indicator used to measure a security's speed (or strength) of
+2 -1
View File
@@ -2,9 +2,10 @@
from pandas_ta.overlap import ema, sma
from pandas_ta.volatility import atr
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def pgo(high, low, close, length=None, offset=None, **kwargs):
def pgo(high: Series, low: Series, close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Pretty Good Oscillator (PGO)
The Pretty Good Oscillator indicator was created by Mark Johnson to measure the distance of the current close from its N-day Simple Moving Average, expressed in terms of an average true range over a similar period. Johnson's approach was to
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta import Imports
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, tal_ma, verify_series
def ppo(close, fast=None, slow=None, signal=None, scalar=None, mamode=None, talib=None, offset=None, **kwargs):
def ppo(close: Series, fast: int = None, slow: int = None, signal: int = None, scalar: float = None,
mamode: str = None, talib: bool = None, offset: int = None, **kwargs) -> DataFrame:
"""Percentage Price Oscillator (PPO)
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from numpy import sign as npSign
from pandas_ta.utils import get_drift, get_offset, verify_series
from pandas import Series
def psl(close, open_=None, length=None, scalar=None, drift=None, offset=None, **kwargs):
def psl(close: Series, open_: Series = None, length: int = None, scalar: float = None, drift: int = None,
offset: int = None, **kwargs) -> Series:
"""Psychological Line (PSL)
The Psychological Line is an oscillator-type indicator that compares the
+3 -2
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.overlap import ema
from pandas_ta.utils import get_offset, verify_series
def pvo(volume, fast=None, slow=None, signal=None, scalar=None, offset=None, **kwargs):
def pvo(volume: Series, fast: int = None, slow: int = None, signal: int = None, scalar: float = None,
offset: int = None, **kwargs) -> DataFrame:
"""Percentage Volume Oscillator (PVO)
Percentage Volume Oscillator is a Momentum Oscillator for Volume.
+2 -1
View File
@@ -9,7 +9,8 @@ from pandas_ta.overlap import ma
from pandas_ta.utils import get_drift, get_offset, verify_series
def qqe(close, length=None, smooth=None, factor=None, mamode=None, drift=None, offset=None, **kwargs):
def qqe(close: Series, length: int = None, smooth: int = None, factor: float = None, mamode: str = None,
drift: int = None, offset: int = None, **kwargs) -> DataFrame:
"""Quantitative Qualitative Estimation (QQE)
The Quantitative Qualitative Estimation (QQE) is similar to SuperTrend but uses a Smoothed RSI with an upper and lower bands. The band width is a combination of a one period True Range of the Smoothed RSI which is double smoothed using Wilder's smoothing length (2 * rsiLength - 1) and multiplied by the default factor of 4.236. A Long trend is determined when the Smoothed RSI crosses the previous upperband and a Short trend when the Smoothed RSI crosses the previous lowerband.
+3 -1
View File
@@ -2,9 +2,11 @@
from .mom import mom
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def roc(close, length=None, scalar=None, talib=None, offset=None, **kwargs):
def roc(close: Series, length: int = None, scalar: float = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""Rate of Change (ROC)
Rate of Change is an indicator is also referred to as Momentum (yeah, confusingly).
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame, concat
from pandas import DataFrame, concat, Series
from pandas_ta import Imports
from pandas_ta.overlap import rma
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
def rsi(close, length=None, scalar=None, talib=None, drift=None, offset=None, **kwargs):
def rsi(close: Series, length: int = None, scalar: float = None, talib: bool = None, drift: int = None,
offset: int = None, **kwargs) -> Series:
"""Relative Strength Index (RSI)
The Relative Strength Index is popular momentum oscillator used to measure the
+1 -1
View File
@@ -4,7 +4,7 @@ from pandas import concat, DataFrame, Series
from pandas_ta.utils import get_drift, get_offset, verify_series, signals
def rsx(close, length=None, drift=None, offset=None, **kwargs):
def rsx(close: Series, length: int = None, drift: int = None, offset: int = None, **kwargs) -> Series:
"""Relative Strength Xtra (rsx)
The Relative Strength Xtra is based on the popular RSI indicator and inspired
+3 -2
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.overlap import swma
from pandas_ta.utils import get_offset, non_zero_range, verify_series
def rvgi(open_, high, low, close, length=None, swma_length=None, offset=None, **kwargs):
def rvgi(open_: Series, high: Series, low: Series, close: Series, length: int = None, swma_length: int = None,
offset: int = None, **kwargs) -> Series:
"""Relative Vigor Index (RVGI)
The Relative Vigor Index attempts to measure the strength of a trend relative to
+3 -1
View File
@@ -2,9 +2,11 @@
from numpy import arctan as npAtan
from numpy import pi as npPi
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def slope( close, length=None, as_angle=None, to_degrees=None, vertical=None, offset=None, **kwargs):
def slope( close: Series, length: int = None, as_angle=None, to_degrees=None, vertical=None,
offset: int = None, **kwargs) -> Series:
"""Slope
Returns the slope of a series of length n. Can convert the slope to angle.
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from .tsi import tsi
from pandas_ta.overlap import ema
from pandas_ta.utils import get_offset, verify_series
def smi(close, fast=None, slow=None, signal=None, scalar=None, offset=None, **kwargs):
def smi(close: Series, fast: int = None, slow: int = None, signal: int = None, scalar: float = None,
offset: int = None, **kwargs) -> DataFrame:
"""SMI Ergodic Indicator (SMI)
The SMI Ergodic Indicator is the same as the True Strength Index (TSI) developed
+4 -2
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from numpy import nan as npNaN
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.momentum import mom
from pandas_ta.overlap import ema, linreg, sma
from pandas_ta.trend import decreasing, increasing
@@ -9,7 +9,9 @@ from pandas_ta.utils import get_offset
from pandas_ta.utils import unsigned_differences, verify_series
def squeeze(high, low, close, bb_length=None, bb_std=None, kc_length=None, kc_scalar=None, mom_length=None, mom_smooth=None, use_tr=None, mamode=None, offset=None, **kwargs):
def squeeze(high: Series, low: Series, close: Series, bb_length: int = None, bb_std: float = None,
kc_length: int = None, kc_scalar: float = None, mom_length: int = None, mom_smooth: int = None,
use_tr=None, mamode: str = None, offset: int = None, **kwargs) -> DataFrame:
"""Squeeze (SQZ)
The default is based on John Carter's "TTM Squeeze" indicator, as discussed
+26 -17
View File
@@ -1,14 +1,22 @@
# -*- coding: utf-8 -*-
from pandas_ta import np, pd
from numpy import nan
from pandas import DataFrame, Series
from pandas_ta.momentum import mom
from pandas_ta.overlap import ema, sma
from pandas_ta.trend import decreasing, increasing
from pandas_ta.volatility import bbands, kc
from pandas_ta.utils import get_offset
from pandas_ta.utils import unsigned_differences, verify_series
from pandas_ta.utils import get_offset, unsigned_differences, verify_series
def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, kc_scalar_wide=None, kc_scalar_normal=None, kc_scalar_narrow=None, mom_length=None, mom_smooth=None, use_tr=None, mamode=None, offset=None, **kwargs):
def squeeze_pro(
high: Series, low: Series, close: Series,
bb_length: int = None, bb_std: float = None,
kc_length: int = None, kc_scalar_wide: float = None,
kc_scalar_normal: float = None, kc_scalar_narrow: float = None,
mom_length: int = None, mom_smooth: int = None,
use_tr=None, mamode: str = None,
offset: int = None, **kwargs
) -> DataFrame:
"""Squeeze PRO(SQZPRO)
This indicator is an extended version of "TTM Squeeze" from John Carter.
@@ -51,7 +59,7 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
pd.DataFrame: SQZPRO, SQZPRO_ON_WIDE, SQZPRO_ON_NORMAL, SQZPRO_ON_NARROW, SQZPRO_OFF_WIDE, SQZPRO_NO columns by default. More
detailed columns if 'detailed' kwarg is True.
"""
# Validate arguments
# Validate
bb_length = int(bb_length) if bb_length and bb_length > 0 else 20
bb_std = float(bb_std) if bb_std and bb_std > 0 else 2.0
kc_length = int(kc_length) if kc_length and kc_length > 0 else 20
@@ -81,7 +89,7 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
df.columns = df.columns.str.lower()
return [c.split("_")[0][n - 1:n] for c in df.columns]
# Calculate Result
# Calculate
bbd = bbands(close, length=bb_length, std=bb_std, mamode=mamode)
kch_wide = kc(high, low, close, length=kc_length, scalar=kc_scalar_wide, mamode=mamode, tr=use_tr)
kch_normal = kc(high, low, close, length=kc_length, scalar=kc_scalar_normal, mamode=mamode, tr=use_tr)
@@ -115,7 +123,7 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
squeeze_off_wide = squeeze_off_wide.shift(offset)
no_squeeze = no_squeeze.shift(offset)
# Handle fills
# Fill
if "fillna" in kwargs:
squeeze.fillna(kwargs["fillna"], inplace=True)
squeeze_on_wide.fillna(kwargs["fillna"], inplace=True)
@@ -131,7 +139,7 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
squeeze_off_wide.fillna(method=kwargs["fill_method"], inplace=True)
no_squeeze.fillna(method=kwargs["fill_method"], inplace=True)
# Name and Categorize it
# Name and Category
_props = "" if use_tr else "hlr"
_props += f"_{bb_length}_{bb_std}_{kc_length}_{kc_scalar_wide}_{kc_scalar_normal}_{kc_scalar_narrow}"
squeeze.name = f"SQZPRO{_props}"
@@ -144,11 +152,11 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
f"SQZPRO_OFF": squeeze_off_wide.astype(int) if asint else squeeze_off_wide,
f"SQZPRO_NO": no_squeeze.astype(int) if asint else no_squeeze,
}
df = pd.DataFrame(data)
df = DataFrame(data)
df.name = squeeze.name
df.category = squeeze.category = "momentum"
# Detailed Squeeze Series
# More Detail
if detailed:
pos_squeeze = squeeze[squeeze >= 0]
neg_squeeze = squeeze[squeeze < 0]
@@ -161,17 +169,17 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
neg_dec *= squeeze
neg_inc *= squeeze
pos_inc.replace(0, np.nan, inplace=True)
pos_dec.replace(0, np.nan, inplace=True)
neg_dec.replace(0, np.nan, inplace=True)
neg_inc.replace(0, np.nan, inplace=True)
pos_inc.replace(0, nan, inplace=True)
pos_dec.replace(0, nan, inplace=True)
neg_dec.replace(0, nan, inplace=True)
neg_inc.replace(0, nan, inplace=True)
sqz_inc = squeeze * increasing(squeeze)
sqz_dec = squeeze * decreasing(squeeze)
sqz_inc.replace(0, np.nan, inplace=True)
sqz_dec.replace(0, np.nan, inplace=True)
sqz_inc.replace(0, nan, inplace=True)
sqz_dec.replace(0, nan, inplace=True)
# Handle fills
# Fill
if "fillna" in kwargs:
sqz_inc.fillna(kwargs["fillna"], inplace=True)
sqz_dec.fillna(kwargs["fillna"], inplace=True)
@@ -179,6 +187,7 @@ def squeeze_pro(high, low, close, bb_length=None, bb_std=None, kc_length=None, k
pos_dec.fillna(kwargs["fillna"], inplace=True)
neg_dec.fillna(kwargs["fillna"], inplace=True)
neg_inc.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
sqz_inc.fillna(method=kwargs["fill_method"], inplace=True)
sqz_dec.fillna(method=kwargs["fill_method"], inplace=True)
+2 -1
View File
@@ -4,7 +4,8 @@ from pandas_ta.overlap import ema
from pandas_ta.utils import get_offset, non_zero_range, verify_series
def stc(close, tclength=None, fast=None, slow=None, factor=None, offset=None, **kwargs):
def stc(close: Series, tclength: int = None, fast: int = None, slow: int = None, factor: float = None,
offset: int = None, **kwargs) -> DataFrame:
"""Schaff Trend Cycle (STC)
The Schaff Trend Cycle is an evolution of the popular MACD incorportating two
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta import Imports
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, non_zero_range, tal_ma, verify_series
def stoch(high, low, close, k=None, d=None, smooth_k=None, mamode=None, talib=None, offset=None, **kwargs):
def stoch(high: Series, low: Series, close: Series, k: int = None, d: int = None, smooth_k: int = None,
mamode: str = None, talib: bool = None, offset: int = None, **kwargs) -> DataFrame:
"""Stochastic (STOCH)
The Stochastic Oscillator (STOCH) was developed by George Lane in the 1950's.
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta import Imports
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, non_zero_range, tal_ma, verify_series
def stochf(high, low, close, k=None, d=None, mamode=None, talib=None, offset=None, **kwargs):
def stochf(high: Series, low: Series, close: Series, k: int = None, d: int = None, mamode: str = None,
talib: bool = None, offset: int = None, **kwargs) -> DataFrame:
"""Fast Stochastic (STOCHF)
The Fast Stochastic Oscillator (STOCHF) was developed by George Lane in the
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from .rsi import rsi
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, non_zero_range, verify_series
def stochrsi(close, length=None, rsi_length=None, k=None, d=None, mamode=None, offset=None, **kwargs):
def stochrsi(close: Series, length: int = None, rsi_length: int = None, k: int = None, d: int = None,
mamode: str = None, offset: int = None, **kwargs) -> DataFrame:
"""Stochastic (STOCHRSI)
"Stochastic RSI and Dynamic Momentum Index" was created by Tushar Chande and Stanley Kroll and published in Stock & Commodities V.11:5 (189-199)
+1 -1
View File
@@ -5,7 +5,7 @@ from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, verify_series
def td_seq(close, asint=None, offset=None, **kwargs):
def td_seq(close: Series, asint: bool = None, offset: int = None, **kwargs) -> DataFrame:
"""TD Sequential (TD_SEQ)
Tom DeMark's Sequential indicator attempts to identify a price point where an
+3 -2
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.overlap.ema import ema
from pandas_ta.utils import get_drift, get_offset, verify_series
def trix(close, length=None, signal=None, scalar=None, drift=None, offset=None, **kwargs):
def trix(close: Series, length: int = None, signal: int = None, scalar: float = None, drift: int = None,
offset: int = None, **kwargs) -> Series:
"""Trix (TRIX)
TRIX is a momentum oscillator to identify divergences.
+3 -2
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.overlap import ema, ma
from pandas_ta.utils import get_drift, get_offset, verify_series
def tsi(close, fast=None, slow=None, signal=None, scalar=None, mamode=None, drift=None, offset=None, **kwargs):
def tsi(close: Series, fast: int = None, slow: int = None, signal: int = None, scalar: float = None,
mamode: str = None, drift: int = None, offset: int = None, **kwargs) -> DataFrame:
"""True Strength Index (TSI)
The True Strength Index is a momentum indicator used to identify short-term
+4 -2
View File
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta import Imports
from pandas_ta.utils import get_drift, get_offset, verify_series
def uo(high, low, close, fast=None, medium=None, slow=None, fast_w=None, medium_w=None, slow_w=None, talib=None, drift=None, offset=None, **kwargs):
def uo(high: Series, low: Series, close: Series, fast: int = None, medium: int = None, slow: int = None,
fast_w: float = None, medium_w: float = None, slow_w: float = None, talib: bool = None, drift: int = None,
offset: int = None, **kwargs) -> Series:
"""Ultimate Oscillator (UO)
The Ultimate Oscillator is a momentum indicator over three different
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def willr(high, low, close, length=None, talib=None, offset=None, **kwargs):
def willr(high: Series, low: Series, close: Series, length: int = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""William's Percent R (WILLR)
William's Percent R is a momentum oscillator similar to the RSI that
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
# from numpy import nan as npNaN
from pandas import DataFrame
from pandas import DataFrame, Series
from .smma import smma
from pandas_ta.utils import get_offset, verify_series
def alligator(close, jaw=None, teeth=None, lips=None, talib=None, offset=None, **kwargs):
def alligator(close: Series, jaw: int = None, teeth: int = None, lips: int = None, talib: bool = None,
offset: int = None, **kwargs) -> DataFrame:
"""Bill Williams Alligator (ALLIGATOR)
The Alligator Indicator was developed by Bill Williams and combines moving
+2 -1
View File
@@ -11,7 +11,8 @@ from pandas import Series
from pandas_ta.utils import get_offset, strided_window, verify_series
def alma(close, length=None, sigma=None, dist_offset=None, offset=None, **kwargs):
def alma(close: Series, length: int = None, sigma: float = None, dist_offset: float = None, offset: int = None,
**kwargs) -> Series:
"""Arnaud Legoux Moving Average (ALMA)
The ALMA moving average uses the curve of the Normal (Gauss) distribution, which
+2 -1
View File
@@ -2,9 +2,10 @@
from .ema import ema
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def dema(close, length=None, talib=None, offset=None, **kwargs):
def dema(close: Series, length: int = None, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Double Exponential Moving Average (DEMA)
The Double Exponential Moving Average attempts to a smoother average with less
+13 -8
View File
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports, np
from numpy import nan
from pandas import Series
from pandas_ta.maps import Imports
from pandas_ta.utils import get_offset, verify_series
try:
@@ -7,7 +9,6 @@ try:
except ImportError:
njit = lambda _: _
# Almost there
# @njit
# def np_ema(x: np.ndarray, n: int):
@@ -21,7 +22,11 @@ except ImportError:
# # return np_prepend(result, n - 1)
def ema(close, length=None, talib=None, presma=None, offset=None, **kwargs):
def ema(
close: Series, length: int = None,
talib: bool = None, presma: bool = None,
offset: int = None, **kwargs
) -> Series:
"""Exponential Moving Average (EMA)
The Exponential Moving Average is more responsive moving average compared to the
@@ -51,7 +56,7 @@ def ema(close, length=None, talib=None, presma=None, offset=None, **kwargs):
Returns:
pd.Series: New feature generated.
"""
# Validate Arguments
# Validate
length = int(length) if length and length > 0 else 10
presma = bool(presma) if isinstance(presma, bool) else True
mode_tal = bool(talib) if isinstance(talib, bool) else True
@@ -61,7 +66,7 @@ def ema(close, length=None, talib=None, presma=None, offset=None, **kwargs):
if close is None: return
# Calculate Result
# Calculate
if Imports["talib"] and mode_tal:
from talib import EMA
ema = EMA(close, length)
@@ -69,7 +74,7 @@ def ema(close, length=None, talib=None, presma=None, offset=None, **kwargs):
if presma: # TA Lib implementation
close = close.copy()
sma_nth = close[0:length].mean()
close[:length - 1] = np.nan
close[:length - 1] = nan
close.iloc[length - 1] = sma_nth
ema = close.ewm(span=length, adjust=adjust).mean()
@@ -77,13 +82,13 @@ def ema(close, length=None, talib=None, presma=None, offset=None, **kwargs):
if offset != 0:
ema = ema.shift(offset)
# Handle fills
# Fill
if "fillna" in kwargs:
ema.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
ema.fillna(method=kwargs["fill_method"], inplace=True)
# Name & Category
# Name and Category
ema.name = f"EMA_{length}"
ema.category = "overlap"
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import fibonacci, get_offset, verify_series, weights
from pandas import Series
def fwma(close, length=None, asc=None, offset=None, **kwargs):
def fwma(close: Series, length: int = None, asc: bool = None, offset: int = None, **kwargs) -> Series:
"""Fibonacci's Weighted Moving Average (FWMA)
Fibonacci's Weighted Moving Average is similar to a Weighted Moving Average
+2 -1
View File
@@ -5,7 +5,8 @@ from .ma import ma
from pandas_ta.utils import get_offset, verify_series
def hilo(high, low, close, high_length=None, low_length=None, mamode=None, offset=None, **kwargs):
def hilo(high: Series, low: Series, close: Series, high_length: int = None, low_length: int = None,
mamode: str = None, offset: int = None, **kwargs) -> DataFrame:
"""Gann HiLo Activator(HiLo)
The Gann High Low Activator Indicator was created by Robert Krausz in a 1998
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def hl2(high, low, offset=None, **kwargs):
def hl2(high: Series, low: Series, offset: int = None, **kwargs) -> Series:
"""HL2
HL2 is the midpoint/average of high and low.
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def hlc3(high, low, close, talib=None, offset=None, **kwargs):
def hlc3(high: Series, low: Series, close: Series, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""HLC3
HLC3 is the average of high, low and close.
+2 -1
View File
@@ -2,9 +2,10 @@
from numpy import sqrt as npSqrt
from .wma import wma
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def hma(close, length=None, offset=None, **kwargs):
def hma(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Hull Moving Average (HMA)
The Hull Exponential Moving Average attempts to reduce or remove lag in moving
+1 -1
View File
@@ -3,7 +3,7 @@ from pandas import Series
from pandas_ta.utils import get_offset, verify_series
def hwma(close, na=None, nb=None, nc=None, offset=None, **kwargs):
def hwma(close: Series, na: float = None, nb: float = None, nc: float = None, offset: int = None, **kwargs) -> Series:
"""HWMA (Holt-Winter Moving Average)
Indicator HWMA (Holt-Winter Moving Average) is a three-parameter moving average
+3 -2
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from pandas import date_range, DataFrame, RangeIndex, Timedelta
from pandas import date_range, DataFrame, RangeIndex, Timedelta, Series
from .midprice import midprice
from pandas_ta.utils import get_offset, verify_series
def ichimoku(high, low, close, tenkan=None, kijun=None, senkou=None, include_chikou=True, offset=None, **kwargs):
def ichimoku(high: Series, low: Series, close: Series, tenkan: int = None, kijun: int = None, senkou: int = None,
include_chikou: bool = True, offset: int = None, **kwargs) -> DataFrame:
"""Ichimoku Kinkō Hyō (ichimoku)
Developed Pre WWII as a forecasting model for financial markets.
+1 -1
View File
@@ -9,7 +9,7 @@ from pandas import Series
from pandas_ta.utils import get_offset, verify_series
def jma(close, length=None, phase=None, offset=None, **kwargs):
def jma(close: Series, length: int = None, phase: float = None, offset: int = None, **kwargs) -> Series:
"""Jurik Moving Average Average (JMA)
Mark Jurik's Moving Average (JMA) attempts to eliminate noise to see the "true"
+2 -1
View File
@@ -5,7 +5,8 @@ from pandas_ta.overlap.ma import ma
from pandas_ta.utils import get_drift, get_offset, non_zero_range, verify_series
def kama(close, length=None, fast=None, slow=None, mamode=None, drift=None, offset=None, **kwargs):
def kama(close: Series, length: int = None, fast: int = None, slow: int = None, mamode: str = None,
drift: int = None, offset: int = None, **kwargs) -> Series:
"""Kaufman's Adaptive Moving Average (KAMA)
Developed by Perry Kaufman, Kaufman's Adaptive Moving Average (KAMA) is a moving average
+1 -1
View File
@@ -9,7 +9,7 @@ from pandas_ta import Imports
from pandas_ta.utils import get_offset, strided_window, verify_series
def linreg(close, length=None, talib=None, offset=None, **kwargs):
def linreg(close: Series, length: int = None, talib: int = None, offset: int = None, **kwargs) -> Series:
"""Linear Regression Moving Average (linreg)
Linear Regression Moving Average (LINREG). This is a simplified version of a
+2 -2
View File
@@ -19,7 +19,7 @@ from .vidya import vidya
from .wma import wma
def ma(name:str = None, source:Series = None, **kwargs) -> Series:
def ma(name: str = None, source: Series = None, **kwargs) -> Series:
"""Simple MA Utility for easier MA selection
Available MAs:
@@ -50,7 +50,7 @@ def ma(name:str = None, source:Series = None, **kwargs) -> Series:
return _mas
elif isinstance(name, str) and name.lower() in _mas:
name = name.lower()
else: # "ema"
else: # "ema"
name = _mas[1]
if name == "dema": return dema(source, **kwargs)
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def mcgd(close, length=None, offset=None, c=None, **kwargs):
def mcgd(close: Series, length: int = None, offset: int = None, c: float = None, **kwargs) -> Series:
"""McGinley Dynamic Indicator
The McGinley Dynamic looks like a moving average line, yet it is actually a
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def midpoint(close, length=None, talib=None, offset=None, **kwargs):
def midpoint(close: Series, length: int = None, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Midpoint
The Midpoint is the average of the rolling high and low of period length.
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def midprice(high, low, length=None, talib=None, offset=None, **kwargs):
def midprice(high: Series, low: Series, length: int = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""Midprice
The Midprice is the average of the rolling high and low of period length.
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def ohlc4(open_, high, low, close, offset=None, **kwargs):
def ohlc4(open_: Series, high: Series, low: Series, close: Series, offset: int = None, **kwargs) -> Series:
"""OHLC4
OHLC4 is the average of open, high, low and close.
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, pascals_triangle, verify_series, weights
from pandas import Series
def pwma(close, length=None, asc=None, offset=None, **kwargs):
def pwma(close: Series, length: int = None, asc: bool = None, offset: bool = None, **kwargs) -> Series:
"""Pascal's Weighted Moving Average (PWMA)
Pascal's Weighted Moving Average is similar to a symmetric triangular window
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def rma(close, length=None, offset=None, **kwargs):
def rma(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""wildeR's Moving Average (RMA)
The WildeR's Moving Average is simply an Exponential Moving Average (EMA) with
+1 -1
View File
@@ -5,7 +5,7 @@ from pandas import Series
from pandas_ta.utils import get_offset, verify_series, weights
def sinwma(close, length=None, offset=None, **kwargs):
def sinwma(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Sine Weighted Moving Average (SWMA)
A weighted average using sine cycles. The middle term(s) of the average have the
+16 -11
View File
@@ -1,17 +1,19 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports, np, pd
from numpy import convolve, ndarray, ones
from pandas import Series
from pandas_ta.maps import Imports
from pandas_ta.utils import get_offset, np_prepend, verify_series
try:
from numba import njit
except ImportError:
njit = lambda _: _
@njit
def np_sma(x: np.ndarray, n: int):
def np_sma(x: ndarray, n: int):
"""https://github.com/numba/numba/issues/4119"""
result = np.convolve(np.ones(n) / n, x)[n - 1:1 - n]
result = convolve(ones(n) / n, x)[n - 1:1 - n]
return np_prepend(result, n - 1)
## SMA: Alternative Implementations
@@ -20,7 +22,6 @@ def np_sma(x: np.ndarray, n: int):
# result = np.convolve(x, np.ones(n), mode="valid") / n
# return np_prepend(result, n - 1)
# @njit
# def np_sma(x: np.ndarray, n: int):
# csum = np.cumsum(x, dtype=float)
@@ -29,7 +30,11 @@ def np_sma(x: np.ndarray, n: int):
# return np_prepend(result, n - 1)
def sma(close, length=None, talib=None, offset=None, **kwargs):
def sma(
close: Series, length: int = None,
talib: bool = None,
offset: int = None, **kwargs
) -> Series:
"""Simple Moving Average (SMA)
The Simple Moving Average is the classic moving average that is the equally
@@ -54,7 +59,7 @@ def sma(close, length=None, talib=None, offset=None, **kwargs):
Returns:
pd.Series: New feature generated.
"""
# Validate Arguments
# Validate
length = int(length) if length and length > 0 else 10
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))
@@ -63,26 +68,26 @@ def sma(close, length=None, talib=None, offset=None, **kwargs):
if close is None: return
# Calculate Result
# Calculate
if Imports["talib"] and mode_tal:
from talib import SMA
sma = SMA(close, length)
else:
np_close = close.values
sma = np_sma(np_close, length)
sma = pd.Series(sma, index=close.index)
sma = Series(sma, index=close.index)
# Offset
if offset != 0:
sma = sma.shift(offset)
# Handle fills
# Fill
if "fillna" in kwargs:
sma.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
sma.fillna(method=kwargs["fill_method"], inplace=True)
# Name & Category
# Name and Category
sma.name = f"SMA_{length}"
sma.category = "overlap"
+3 -1
View File
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
from numpy import nan as npNaN
from pandas_ta.overlap.ma import ma
from pandas import Series
from pandas_ta.utils import get_offset, verify_series
def smma(close, length=None, mamode=None, talib=None, offset=None, **kwargs):
def smma(close: Series, length: int = None, mamode: str = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""SMoothed Moving Average (SMMA)
The SMoothed Moving Average (SMMA) is bootstrapped by default with a Simple
+21 -17
View File
@@ -1,21 +1,22 @@
# -*- coding: utf-8 -*-
from pandas_ta import np, pd
from numpy import copy, cos, exp, ndarray
from pandas import Series
from pandas_ta.utils import get_offset, verify_series
try:
from numba import njit
except ImportError:
njit = lambda _: _
@njit
def np_ssf(x: np.ndarray, n: int, pi: float, sqrt2: float):
def np_ssf(x: ndarray, n: int, pi: float, sqrt2: float):
"""Ehler's Super Smoother Filter
http://traders.com/documentation/feedbk_docs/2014/01/traderstips.html
"""
m, ratio, result = x.size, sqrt2 / n, np.copy(x)
a = np.exp(-pi * ratio)
b = 2 * a * np.cos(180 * ratio)
m, ratio, result = x.size, sqrt2 / n, copy(x)
a = exp(-pi * ratio)
b = 2 * a * cos(180 * ratio)
c = a * a - b + 1
for i in range(2, m):
@@ -24,15 +25,14 @@ def np_ssf(x: np.ndarray, n: int, pi: float, sqrt2: float):
return result
@njit
def np_ssf_everget(x: np.ndarray, n: int, pi: float, sqrt2: float):
def np_ssf_everget(x: ndarray, n: int, pi: float, sqrt2: float):
"""John F. Ehler's Super Smoother Filter by Everget (2 poles), Tradingview
https://www.tradingview.com/script/VdJy0yBJ-Ehlers-Super-Smoother-Filter/
"""
m, arg, result = x.size, pi * sqrt2 / n, np.copy(x)
a = np.exp(-arg)
b = 2 * a * np.cos(arg)
m, arg, result = x.size, pi * sqrt2 / n, copy(x)
a = exp(-arg)
b = 2 * a * cos(arg)
for i in range(2, m):
result[i] = 0.5 * (a * a - b + 1) * (x[i] + x[i - 1]) \
@@ -41,7 +41,11 @@ def np_ssf_everget(x: np.ndarray, n: int, pi: float, sqrt2: float):
return result
def ssf(close, length=None, everget=None, pi=None, sqrt2=None, offset=None, **kwargs):
def ssf(
close: Series, length: int = None,
everget: bool = None, pi: float = None, sqrt2: float = None,
offset: int = None, **kwargs
) -> Series:
"""Ehler's Super Smoother Filter (SSF) © 2013
John F. Ehlers's solution to reduce lag and remove aliasing noise with his
@@ -77,7 +81,7 @@ def ssf(close, length=None, everget=None, pi=None, sqrt2=None, offset=None, **kw
Returns:
pd.Series: New feature generated.
"""
# Validate Arguments
# Validate
length = int(length) if isinstance(length, int) and length > 0 else 20
everget = bool(everget) if isinstance(everget, bool) else False
pi = float(pi) if isinstance(pi, float) and pi > 0 else 3.14159
@@ -87,25 +91,25 @@ def ssf(close, length=None, everget=None, pi=None, sqrt2=None, offset=None, **kw
if close is None: return
# Calculate Result
# Calculate
np_close = close.values
if everget:
ssf = np_ssf_everget(np_close, length, pi, sqrt2)
else:
ssf = np_ssf(np_close, length, pi, sqrt2)
ssf = pd.Series(ssf, index=close.index)
ssf = Series(ssf, index=close.index)
# Offset
if offset != 0:
ssf = ssf.shift(offset)
# Handle fills
# Fill
if "fillna" in kwargs:
ssf.fillna(kwargs["fillna"], inplace=True)
if "fill_method" in kwargs:
ssf.fillna(method=kwargs["fill_method"], inplace=True)
# Name & Category
# Name and Category
ssf.name = f"SSF{'e' if everget else ''}_{length}"
ssf.category = "overlap"
+3 -2
View File
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
from numpy import nan as npNaN
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.overlap import hl2
from pandas_ta.volatility import atr
from pandas_ta.utils import get_offset, verify_series
def supertrend(high, low, close, length=None, multiplier=None, offset=None, **kwargs):
def supertrend(high: Series, low: Series, close: Series, length: int = None, multiplier: float = None,
offset: int = None, **kwargs) -> DataFrame:
"""Supertrend (supertrend)
Supertrend is an overlap indicator. It is used to help identify trend
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, symmetric_triangle, verify_series, weights
from pandas import Series
def swma(close, length=None, asc=None, offset=None, **kwargs):
def swma(close: Series, length: int = None, asc: bool = None, offset: int = None, **kwargs) -> Series:
"""Symmetric Weighted Moving Average (SWMA)
Symmetric Weighted Moving Average where weights are based on a symmetric
+2 -1
View File
@@ -2,9 +2,10 @@
from .ema import ema
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def t3(close, length=None, a=None, talib=None, offset=None, **kwargs):
def t3(close: Series, length: int = None, a: float = None, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Tim Tillson's T3 Moving Average (T3)
Tim Tillson's T3 Moving Average is considered a smoother and more responsive
+2 -1
View File
@@ -2,9 +2,10 @@
from .ema import ema
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def tema(close, length=None, talib=None, offset=None, **kwargs):
def tema(close: Series, length: int = None, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Triple Exponential Moving Average (TEMA)
A less laggy Exponential Moving Average.
+2 -1
View File
@@ -2,9 +2,10 @@
from .sma import sma
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def trima(close, length=None, talib=None, offset=None, **kwargs):
def trima(close: Series, length: int = None, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Triangular Moving Average (TRIMA)
A weighted moving average where the shape of the weights are triangular and the
+1 -1
View File
@@ -4,7 +4,7 @@ from pandas import Series
from pandas_ta.utils import get_drift, get_offset, verify_series
def vidya(close, length=None, drift=None, offset=None, **kwargs):
def vidya(close: Series, length: int = None, drift: int = None, offset: int = None, **kwargs) -> Series:
"""Variable Index Dynamic Average (VIDYA)
Variable Index Dynamic Average (VIDYA) was developed by Tushar Chande. It is
+4 -1
View File
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
from .hlc3 import hlc3
from pandas_ta.utils import get_offset, is_datetime_ordered, verify_series
from pandas import Series
def vwap(high, low, close, volume, anchor=None, offset=None, **kwargs):
def vwap(high: Series, low: Series, close: Series, volume: Series, anchor: str = None, offset: int = None,
**kwargs) -> Series:
"""Volume Weighted Average Price (VWAP)
The Volume Weighted Average Price that measures the average typical price
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from .sma import sma
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def vwma(close, volume, length=None, offset=None, **kwargs):
def vwma(close: Series, volume: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Volume Weighted Moving Average (VWMA)
Volume Weighted Moving Average.
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def wcp(high, low, close, talib=None, offset=None, **kwargs):
def wcp(high: Series, low: Series, close: Series, talib: bool = None, offset: int = None, **kwargs) -> Series:
"""Weighted Closing Price (WCP)
Weighted Closing Price is the weighted price given: high, low
+2 -1
View File
@@ -4,7 +4,8 @@ from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
def wma(close, length=None, asc=None, talib=None, offset=None, **kwargs):
def wma(close: Series, length: int = None, asc: bool = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""Weighted Moving Average (WMA)
The Weighted Moving Average where the weights are linearly increasing and
+2 -1
View File
@@ -4,9 +4,10 @@
# )
from pandas_ta.overlap import ma
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def zlma(close, length=None, mamode=None, offset=None, **kwargs):
def zlma(close: Series, length: int = None, mamode: str = None, offset: int = None, **kwargs) -> Series:
"""Zero Lag Moving Average (ZLMA)
The Zero Lag Moving Average attempts to eliminate the lag associated
+2 -2
View File
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from numpy import log as nplog
from numpy import seterr
from pandas import DataFrame
from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, verify_series
def drawdown(close, offset=None, **kwargs) -> DataFrame:
def drawdown(close: Series, offset: int = None, **kwargs) -> DataFrame:
"""Drawdown (DD)
Drawdown is a peak-to-trough decline during a specific period for an investment,
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from numpy import log as nplog
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def log_return(close, length=None, cumulative=None, offset=None, **kwargs):
def log_return(close: Series, length: int = None, cumulative: bool = None, offset: int = None, **kwargs) -> Series:
"""Log Return
Calculates the logarithmic return of a Series.
+3 -1
View File
@@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def percent_return(close, length=None, cumulative=None, offset=None, **kwargs):
def percent_return(close: Series, length: int = None, cumulative: bool = None, offset: int = None,
**kwargs) -> Series:
"""Percent Return
Calculates the percent return of a Series.
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from numpy import log as npLog
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def entropy(close, length=None, base=None, offset=None, **kwargs):
def entropy(close: Series, length: int = None, base: float = None, offset: int = None, **kwargs) -> Series:
"""Entropy (ENTP)
Introduced by Claude Shannon in 1948, entropy measures the unpredictability
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def kurtosis(close, length=None, offset=None, **kwargs):
def kurtosis(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Rolling Kurtosis
Calculates the Kurtosis over a rolling period.
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from numpy import fabs as npfabs
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def mad(close, length=None, offset=None, **kwargs):
def mad(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Rolling Mean Absolute Deviation
Calculates the Mean Absolute Deviation over a rolling period.
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def median(close, length=None, offset=None, **kwargs):
def median(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Rolling Median
Calculates the Median over a rolling period. Sibling of a Simple Moving Average.
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def quantile(close, length=None, q=None, offset=None, **kwargs):
def quantile(close: Series, length: int = None, q: float = None, offset: int = None, **kwargs) -> Series:
"""Rolling Quantile
Calculates the Quantile over a rolling period.
+2 -1
View File
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def skew(close, length=None, offset=None, **kwargs):
def skew(close: Series, length: int = None, offset: int = None, **kwargs) -> Series:
"""Rolling Skew
Calculates the Skew over a rolling period.
+3 -1
View File
@@ -3,9 +3,11 @@ from numpy import sqrt as npsqrt
from .variance import variance
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def stdev(close, length=None, ddof=None, talib=None, offset=None, **kwargs):
def stdev(close: Series, length: int = None, ddof: int = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""Rolling Standard Deviation
Calculates the Standard Deviation over a rolling period.
+3 -1
View File
@@ -7,7 +7,9 @@ from pandas import DataFrame, DatetimeIndex, Series
from .stdev import stdev as stdev
from pandas_ta.utils import get_offset, verify_series
def tos_stdevall(close, length=None, stds=None, ddof=None, offset=None, **kwargs):
def tos_stdevall(close: Series, length: int = None, stds: list = None, ddof: int = None, offset: int = None,
**kwargs) -> DataFrame:
"""TD Ameritrade's Think or Swim Standard Deviation All (TOS_STDEV)
A port of TD Ameritrade's Think or Swim Standard Deviation All indicator which
+3 -1
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from pandas_ta import Imports
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def variance(close, length=None, ddof=None, talib=None, offset=None, **kwargs):
def variance(close: Series, length: int = None, ddof: int = None, talib: bool = None, offset: int = None,
**kwargs) -> Series:
"""Rolling Variance
Calculates the Variance over a rolling period.
+2 -1
View File
@@ -2,9 +2,10 @@
from pandas_ta.overlap import sma
from .stdev import stdev
from pandas_ta.utils import get_offset, verify_series
from pandas import Series
def zscore(close, length=None, std=None, offset=None, **kwargs):
def zscore(close: Series, length: int = None, std: float = None, offset: int = None, **kwargs) -> Series:
"""Rolling Z Score
Calculates the Z Score over a rolling period.

Some files were not shown because too many files have changed in this diff Show More