918 lines
51 KiB
Python
918 lines
51 KiB
Python
"""
|
|
Cross-library wrapper registry — comprehensive indicator coverage.
|
|
|
|
Unified interface: execute_indicator(library, indicator, data, df=None, **kwargs)
|
|
Supported libraries: ferro_ta, talib, pandas_ta, ta, tulipy, finta
|
|
50+ indicators across all categories.
|
|
"""
|
|
from __future__ import annotations
|
|
from typing import Any
|
|
import numpy as np
|
|
|
|
def _try_import(name):
|
|
try:
|
|
import importlib; return importlib.import_module(name)
|
|
except ImportError: return None
|
|
|
|
_talib = _try_import("talib")
|
|
_pta = _try_import("pandas_ta")
|
|
_ta = _try_import("ta")
|
|
_tl = _try_import("tulipy")
|
|
_fi_m = _try_import("finta")
|
|
_fi = getattr(_fi_m, "TA", None) if _fi_m else None
|
|
|
|
def available_libraries():
|
|
libs = ["ferro_ta"]
|
|
if _talib: libs.append("talib")
|
|
if _pta: libs.append("pandas_ta")
|
|
if _ta: libs.append("ta")
|
|
if _tl: libs.append("tulipy")
|
|
if _fi: libs.append("finta")
|
|
return libs
|
|
|
|
def is_supported(library: str, indicator: str) -> bool:
|
|
"""Return True if a wrapper exists for the given (library, indicator) pair."""
|
|
if library not in available_libraries():
|
|
return False
|
|
return (library, indicator) in REGISTRY
|
|
|
|
def _strip_nan(arr):
|
|
a = np.asarray(arr, dtype=np.float64).ravel()
|
|
return a[np.isfinite(a)]
|
|
|
|
def _c64(a):
|
|
return np.ascontiguousarray(a, dtype=np.float64)
|
|
|
|
def _empty():
|
|
return np.array([], dtype=np.float64)
|
|
|
|
def _first_col(df, prefix):
|
|
col = next((c for c in df.columns if c.startswith(prefix)), None)
|
|
return _strip_nan(df[col].values) if col is not None else _empty()
|
|
|
|
# ============================================================
|
|
# OVERLAP
|
|
# ============================================================
|
|
def _sma_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.SMA(d["close"],timeperiod=timeperiod))
|
|
def _sma_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.SMA(d["close"],timeperiod=timeperiod))
|
|
def _sma_pt(d,df,timeperiod=20,**_): return _strip_nan(_pta.sma(df["close"],length=timeperiod).values)
|
|
def _sma_ta(d,df,timeperiod=20,**_):
|
|
from ta.trend import SMAIndicator; return _strip_nan(SMAIndicator(df["close"],window=timeperiod).sma_indicator().values)
|
|
def _sma_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.sma(_c64(d["close"]),period=timeperiod))
|
|
def _sma_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.SMA(df,timeperiod).values)
|
|
|
|
def _ema_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.EMA(d["close"],timeperiod=timeperiod))
|
|
def _ema_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.EMA(d["close"],timeperiod=timeperiod))
|
|
def _ema_pt(d,df,timeperiod=20,**_): return _strip_nan(_pta.ema(df["close"],length=timeperiod).values)
|
|
def _ema_ta(d,df,timeperiod=20,**_):
|
|
from ta.trend import EMAIndicator; return _strip_nan(EMAIndicator(df["close"],window=timeperiod).ema_indicator().values)
|
|
def _ema_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.ema(_c64(d["close"]),period=timeperiod))
|
|
def _ema_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.EMA(df,timeperiod).values)
|
|
|
|
def _wma_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.WMA(d["close"],timeperiod=timeperiod))
|
|
def _wma_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.WMA(d["close"],timeperiod=timeperiod))
|
|
def _wma_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.wma(df["close"],length=timeperiod).values)
|
|
def _wma_ta(d,df,**_): return _empty()
|
|
_wma_ta._stub = True
|
|
def _wma_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.wma(_c64(d["close"]),period=timeperiod))
|
|
def _wma_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.WMA(df,timeperiod).values)
|
|
|
|
def _dema_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.DEMA(d["close"],timeperiod=timeperiod))
|
|
def _dema_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.DEMA(d["close"],timeperiod=timeperiod))
|
|
def _dema_pt(d,df,timeperiod=20,**_): return _strip_nan(_pta.dema(df["close"],length=timeperiod).values)
|
|
def _dema_ta(d,df,**_): return _empty()
|
|
_dema_ta._stub = True
|
|
def _dema_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.dema(_c64(d["close"]),period=timeperiod))
|
|
def _dema_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.DEMA(df,timeperiod).values)
|
|
|
|
def _tema_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.TEMA(d["close"],timeperiod=timeperiod))
|
|
def _tema_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.TEMA(d["close"],timeperiod=timeperiod))
|
|
def _tema_pt(d,df,timeperiod=20,**_): return _strip_nan(_pta.tema(df["close"],length=timeperiod).values)
|
|
def _tema_ta(d,df,**_): return _empty()
|
|
_tema_ta._stub = True
|
|
def _tema_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.tema(_c64(d["close"]),period=timeperiod))
|
|
def _tema_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.TEMA(df,timeperiod).values)
|
|
|
|
def _t3_ft(d,df,timeperiod=5,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.T3(d["close"],timeperiod=timeperiod))
|
|
def _t3_tl(d,df,timeperiod=5,**_): return _strip_nan(_talib.T3(d["close"],timeperiod=timeperiod))
|
|
def _t3_pt(d,df,timeperiod=5,**_): return _strip_nan(_pta.t3(df["close"],length=timeperiod).values)
|
|
def _t3_ta(d,df,**_): return _empty()
|
|
_t3_ta._stub = True
|
|
def _t3_tu(d,df,**_): return _empty()
|
|
_t3_tu._stub = True
|
|
def _t3_fi(d,df,**_): return _empty()
|
|
_t3_fi._stub = True
|
|
|
|
def _trima_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.TRIMA(d["close"],timeperiod=timeperiod))
|
|
def _trima_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.TRIMA(d["close"],timeperiod=timeperiod))
|
|
def _trima_pt(d,df,timeperiod=20,**_): return _strip_nan(_pta.trima(df["close"],length=timeperiod).values)
|
|
def _trima_ta(d,df,**_): return _empty()
|
|
_trima_ta._stub = True
|
|
def _trima_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.trima(_c64(d["close"]),period=timeperiod))
|
|
def _trima_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.TRIMA(df,timeperiod).values)
|
|
|
|
def _kama_ft(d,df,timeperiod=10,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.KAMA(d["close"],timeperiod=timeperiod))
|
|
def _kama_tl(d,df,timeperiod=10,**_): return _strip_nan(_talib.KAMA(d["close"],timeperiod=timeperiod))
|
|
def _kama_pt(d,df,timeperiod=10,**_): return _strip_nan(_pta.kama(df["close"],length=timeperiod).values)
|
|
def _kama_ta(d,df,**_): return _empty()
|
|
_kama_ta._stub = True
|
|
def _kama_tu(d,df,timeperiod=10,**_): return _strip_nan(_tl.kama(_c64(d["close"]),period=timeperiod))
|
|
def _kama_fi(d,df,**_): return _empty()
|
|
_kama_fi._stub = True
|
|
|
|
def _hma_ft(d,df,timeperiod=16,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.HULL_MA(d["close"],timeperiod=timeperiod))
|
|
def _hma_tl(d,df,**_): return _empty()
|
|
_hma_tl._stub = True
|
|
def _hma_pt(d,df,timeperiod=16,**_): return _strip_nan(_pta.hma(df["close"],length=timeperiod).values)
|
|
def _hma_ta(d,df,**_): return _empty()
|
|
_hma_ta._stub = True
|
|
def _hma_tu(d,df,timeperiod=16,**_): return _strip_nan(_tl.hma(_c64(d["close"]),period=timeperiod))
|
|
def _hma_fi(d,df,timeperiod=16,**_): return _strip_nan(_fi.HMA(df,timeperiod).values)
|
|
|
|
def _vwma_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.VWMA(d["close"],d["volume"],timeperiod=timeperiod))
|
|
def _vwma_tl(d,df,**_): return _empty()
|
|
_vwma_tl._stub = True
|
|
def _vwma_pt(d,df,timeperiod=20,**_):
|
|
r=_pta.vwma(df["close"],df["volume"],length=timeperiod); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _vwma_ta(d,df,**_): return _empty()
|
|
_vwma_ta._stub = True
|
|
def _vwma_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.vwma(_c64(d["close"]),_c64(d["volume"]),period=timeperiod))
|
|
def _vwma_fi(d,df,**_): return _empty()
|
|
_vwma_fi._stub = True
|
|
|
|
def _midpoint_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.MIDPOINT(d["close"],timeperiod=timeperiod))
|
|
def _midpoint_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.MIDPOINT(d["close"],timeperiod=timeperiod))
|
|
def _midpoint_pt(d,df,**_): return _empty()
|
|
_midpoint_pt._stub = True
|
|
def _midpoint_ta(d,df,**_): return _empty()
|
|
_midpoint_ta._stub = True
|
|
def _midpoint_tu(d,df,**_): return _empty()
|
|
_midpoint_tu._stub = True
|
|
def _midpoint_fi(d,df,**_): return _empty()
|
|
_midpoint_fi._stub = True
|
|
|
|
def _midprice_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.MIDPRICE(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _midprice_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.MIDPRICE(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _midprice_pt(d,df,**_): return _empty()
|
|
_midprice_pt._stub = True
|
|
def _midprice_ta(d,df,**_): return _empty()
|
|
_midprice_ta._stub = True
|
|
def _midprice_tu(d,df,**_): return _empty()
|
|
_midprice_tu._stub = True
|
|
def _midprice_fi(d,df,**_): return _empty()
|
|
_midprice_fi._stub = True
|
|
|
|
# ============================================================
|
|
# MOMENTUM
|
|
# ============================================================
|
|
def _rsi_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.RSI(d["close"],timeperiod=timeperiod))
|
|
def _rsi_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.RSI(d["close"],timeperiod=timeperiod))
|
|
def _rsi_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.rsi(df["close"],length=timeperiod).values)
|
|
def _rsi_ta(d,df,timeperiod=14,**_):
|
|
from ta.momentum import RSIIndicator; return _strip_nan(RSIIndicator(df["close"],window=timeperiod).rsi().values)
|
|
def _rsi_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.rsi(_c64(d["close"]),period=timeperiod))
|
|
def _rsi_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.RSI(df,timeperiod).values)
|
|
|
|
def _macd_ft(d,df,fastperiod=12,slowperiod=26,signalperiod=9,**_):
|
|
import ferro_ta; m,s,h=ferro_ta.MACD(d["close"],fastperiod=fastperiod,slowperiod=slowperiod,signalperiod=signalperiod); return _strip_nan(m)
|
|
def _macd_tl(d,df,fastperiod=12,slowperiod=26,signalperiod=9,**_):
|
|
m,s,h=_talib.MACD(d["close"],fastperiod=fastperiod,slowperiod=slowperiod,signalperiod=signalperiod); return _strip_nan(m)
|
|
def _macd_pt(d,df,fastperiod=12,slowperiod=26,signalperiod=9,**_):
|
|
r=_pta.macd(df["close"],fast=fastperiod,slow=slowperiod,signal=signalperiod); return _first_col(r,"MACD_")
|
|
def _macd_ta(d,df,fastperiod=12,slowperiod=26,signalperiod=9,**_):
|
|
from ta.trend import MACD; return _strip_nan(MACD(df["close"],window_fast=fastperiod,window_slow=slowperiod,window_sign=signalperiod).macd().values)
|
|
def _macd_tu(d,df,fastperiod=12,slowperiod=26,signalperiod=9,**_):
|
|
m,s,h=_tl.macd(_c64(d["close"]),short_period=fastperiod,long_period=slowperiod,signal_period=signalperiod); return _strip_nan(m)
|
|
def _macd_fi(d,df,fastperiod=12,slowperiod=26,signalperiod=9,**_):
|
|
return _strip_nan(_fi.MACD(df,fastperiod,slowperiod,signalperiod)["MACD"].values)
|
|
|
|
def _stoch_ft(d,df,fastk_period=14,slowk_period=3,slowd_period=3,**_):
|
|
import ferro_ta; k,dd=ferro_ta.STOCH(d["high"],d["low"],d["close"],fastk_period=fastk_period,slowk_period=slowk_period,slowd_period=slowd_period); return _strip_nan(k)
|
|
def _stoch_tl(d,df,fastk_period=14,slowk_period=3,slowd_period=3,**_):
|
|
k,dd=_talib.STOCH(d["high"],d["low"],d["close"],fastk_period=fastk_period,slowk_period=slowk_period,slowd_period=slowd_period); return _strip_nan(k)
|
|
def _stoch_pt(d,df,fastk_period=14,slowk_period=3,slowd_period=3,**_):
|
|
r=_pta.stoch(df["high"],df["low"],df["close"],k=fastk_period,d=slowd_period)
|
|
return _first_col(r,"STOCHk_") if r is not None else _empty()
|
|
def _stoch_ta(d,df,fastk_period=14,**_):
|
|
from ta.momentum import StochasticOscillator; return _strip_nan(StochasticOscillator(df["high"],df["low"],df["close"],window=fastk_period).stoch().values)
|
|
def _stoch_tu(d,df,fastk_period=14,slowk_period=3,slowd_period=3,**_):
|
|
k,dd=_tl.stoch(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),pct_k_period=fastk_period,pct_k_slowing_period=slowk_period,pct_d_period=slowd_period); return _strip_nan(k)
|
|
def _stoch_fi(d,df,fastk_period=14,**_): return _strip_nan(_fi.STOCH(df,fastk_period).values)
|
|
|
|
def _cci_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CCI(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _cci_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.CCI(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _cci_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.cci(df["high"],df["low"],df["close"],length=timeperiod).values)
|
|
def _cci_ta(d,df,timeperiod=14,**_):
|
|
from ta.trend import CCIIndicator; return _strip_nan(CCIIndicator(df["high"],df["low"],df["close"],window=timeperiod).cci().values)
|
|
def _cci_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.cci(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod))
|
|
def _cci_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.CCI(df,timeperiod).values)
|
|
|
|
def _willr_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.WILLR(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _willr_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.WILLR(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _willr_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.willr(df["high"],df["low"],df["close"],length=timeperiod).values)
|
|
def _willr_ta(d,df,timeperiod=14,**_):
|
|
from ta.momentum import WilliamsRIndicator; return _strip_nan(WilliamsRIndicator(df["high"],df["low"],df["close"],lbp=timeperiod).williams_r().values)
|
|
def _willr_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.willr(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod))
|
|
def _willr_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.WILLIAMS(df,timeperiod).values)
|
|
|
|
def _aroon_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; dn,up=ferro_ta.AROON(d["high"],d["low"],timeperiod=timeperiod); return _strip_nan(up)
|
|
def _aroon_tl(d,df,timeperiod=14,**_):
|
|
dn,up=_talib.AROON(d["high"],d["low"],timeperiod=timeperiod); return _strip_nan(up)
|
|
def _aroon_pt(d,df,timeperiod=14,**_):
|
|
r=_pta.aroon(df["high"],df["low"],length=timeperiod); return _first_col(r,"AROONU_") if r is not None else _empty()
|
|
def _aroon_ta(d,df,timeperiod=14,**_):
|
|
from ta.trend import AroonIndicator; return _strip_nan(AroonIndicator(df["high"],df["low"],window=timeperiod).aroon_up().values)
|
|
def _aroon_tu(d,df,timeperiod=14,**_):
|
|
dn,up=_tl.aroon(_c64(d["high"]),_c64(d["low"]),period=timeperiod); return _strip_nan(up)
|
|
def _aroon_fi(d,df,**_): return _empty()
|
|
_aroon_fi._stub = True
|
|
|
|
def _aroonosc_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.AROONOSC(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _aroonosc_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.AROONOSC(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _aroonosc_pt(d,df,**_): return _empty()
|
|
_aroonosc_pt._stub = True
|
|
def _aroonosc_ta(d,df,**_): return _empty()
|
|
_aroonosc_ta._stub = True
|
|
def _aroonosc_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.aroonosc(_c64(d["high"]),_c64(d["low"]),period=timeperiod))
|
|
def _aroonosc_fi(d,df,**_): return _empty()
|
|
_aroonosc_fi._stub = True
|
|
|
|
def _adx_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.ADX(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _adx_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.ADX(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _adx_pt(d,df,timeperiod=14,**_):
|
|
r=_pta.adx(df["high"],df["low"],df["close"],length=timeperiod); return _first_col(r,"ADX_")
|
|
def _adx_ta(d,df,timeperiod=14,**_):
|
|
from ta.trend import ADXIndicator; return _strip_nan(ADXIndicator(df["high"],df["low"],df["close"],window=timeperiod).adx().values)
|
|
def _adx_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.adx(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod))
|
|
def _adx_fi(d,df,**_): return _empty()
|
|
_adx_fi._stub = True
|
|
|
|
def _mom_ft(d,df,timeperiod=10,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.MOM(d["close"],timeperiod=timeperiod))
|
|
def _mom_tl(d,df,timeperiod=10,**_): return _strip_nan(_talib.MOM(d["close"],timeperiod=timeperiod))
|
|
def _mom_pt(d,df,timeperiod=10,**_): return _strip_nan(_pta.mom(df["close"],length=timeperiod).values)
|
|
def _mom_ta(d,df,**_): return _empty()
|
|
_mom_ta._stub = True
|
|
def _mom_tu(d,df,timeperiod=10,**_): return _strip_nan(_tl.mom(_c64(d["close"]),period=timeperiod))
|
|
def _mom_fi(d,df,timeperiod=10,**_): return _strip_nan(_fi.MOM(df,timeperiod).values)
|
|
|
|
def _roc_ft(d,df,timeperiod=10,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.ROC(d["close"],timeperiod=timeperiod))
|
|
def _roc_tl(d,df,timeperiod=10,**_): return _strip_nan(_talib.ROC(d["close"],timeperiod=timeperiod))
|
|
def _roc_pt(d,df,timeperiod=10,**_): return _strip_nan(_pta.roc(df["close"],length=timeperiod).values)
|
|
def _roc_ta(d,df,timeperiod=10,**_):
|
|
from ta.momentum import ROCIndicator; return _strip_nan(ROCIndicator(df["close"],window=timeperiod).roc().values)
|
|
def _roc_tu(d,df,timeperiod=10,**_): return _strip_nan(_tl.roc(_c64(d["close"]),period=timeperiod) * 100.0)
|
|
def _roc_fi(d,df,timeperiod=10,**_): return _strip_nan(_fi.ROC(df,timeperiod).values)
|
|
|
|
def _cmo_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CMO(d["close"],timeperiod=timeperiod))
|
|
def _cmo_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.CMO(d["close"],timeperiod=timeperiod))
|
|
def _cmo_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.cmo(df["close"],length=timeperiod).values)
|
|
def _cmo_ta(d,df,**_): return _empty()
|
|
_cmo_ta._stub = True
|
|
def _cmo_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.cmo(_c64(d["close"]),period=timeperiod))
|
|
def _cmo_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.CMO(df,timeperiod).values)
|
|
|
|
def _ppo_ft(d,df,fastperiod=12,slowperiod=26,**_):
|
|
import ferro_ta; ppo,sig,hist=ferro_ta.PPO(d["close"],fastperiod=fastperiod,slowperiod=slowperiod); return _strip_nan(ppo)
|
|
def _ppo_tl(d,df,fastperiod=12,slowperiod=26,**_): return _strip_nan(_talib.PPO(d["close"],fastperiod=fastperiod,slowperiod=slowperiod))
|
|
def _ppo_pt(d,df,fastperiod=12,slowperiod=26,**_):
|
|
r=_pta.ppo(df["close"],fast=fastperiod,slow=slowperiod)
|
|
return _strip_nan(r.iloc[:,0].values) if r is not None else _empty()
|
|
def _ppo_ta(d,df,**_): return _empty()
|
|
_ppo_ta._stub = True
|
|
def _ppo_tu(d,df,fastperiod=12,slowperiod=26,**_): return _strip_nan(_tl.ppo(_c64(d["close"]),short_period=fastperiod,long_period=slowperiod))
|
|
def _ppo_fi(d,df,fastperiod=12,slowperiod=26,**_): return _strip_nan(_fi.PPO(df,fastperiod,slowperiod).values)
|
|
|
|
def _trix_ft(d,df,timeperiod=18,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.TRIX(d["close"],timeperiod=timeperiod))
|
|
def _trix_tl(d,df,timeperiod=18,**_): return _strip_nan(_talib.TRIX(d["close"],timeperiod=timeperiod))
|
|
def _trix_pt(d,df,timeperiod=18,**_):
|
|
r=_pta.trix(df["close"],length=timeperiod)
|
|
return _strip_nan(r.iloc[:,0].values) if r is not None else _empty()
|
|
def _trix_ta(d,df,timeperiod=18,**_):
|
|
from ta.trend import TRIXIndicator; return _strip_nan(TRIXIndicator(df["close"],window=timeperiod).trix().values)
|
|
def _trix_tu(d,df,timeperiod=18,**_): return _strip_nan(_tl.trix(_c64(d["close"]),period=timeperiod))
|
|
def _trix_fi(d,df,timeperiod=18,**_): return _strip_nan(_fi.TRIX(df,timeperiod).values)
|
|
|
|
def _tsf_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.TSF(d["close"],timeperiod=timeperiod))
|
|
def _tsf_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.TSF(d["close"],timeperiod=timeperiod))
|
|
def _tsf_pt(d,df,**_): return _empty()
|
|
_tsf_pt._stub = True
|
|
def _tsf_ta(d,df,**_): return _empty()
|
|
_tsf_ta._stub = True
|
|
def _tsf_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.tsf(_c64(d["close"]),period=timeperiod))
|
|
def _tsf_fi(d,df,**_): return _empty()
|
|
_tsf_fi._stub = True
|
|
|
|
def _ultosc_ft(d,df,timeperiod1=7,timeperiod2=14,timeperiod3=28,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.ULTOSC(d["high"],d["low"],d["close"],timeperiod1=timeperiod1,timeperiod2=timeperiod2,timeperiod3=timeperiod3))
|
|
def _ultosc_tl(d,df,timeperiod1=7,timeperiod2=14,timeperiod3=28,**_):
|
|
return _strip_nan(_talib.ULTOSC(d["high"],d["low"],d["close"],timeperiod1=timeperiod1,timeperiod2=timeperiod2,timeperiod3=timeperiod3))
|
|
def _ultosc_pt(d,df,**_): return _empty()
|
|
_ultosc_pt._stub = True
|
|
def _ultosc_ta(d,df,timeperiod1=7,timeperiod2=14,timeperiod3=28,**_):
|
|
from ta.momentum import UltimateOscillator
|
|
return _strip_nan(UltimateOscillator(df["high"],df["low"],df["close"],window1=timeperiod1,window2=timeperiod2,window3=timeperiod3).ultimate_oscillator().values)
|
|
def _ultosc_tu(d,df,timeperiod1=7,timeperiod2=14,timeperiod3=28,**_):
|
|
return _strip_nan(_tl.ultosc(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),short_period=timeperiod1,medium_period=timeperiod2,long_period=timeperiod3))
|
|
def _ultosc_fi(d,df,**_): return _empty()
|
|
_ultosc_fi._stub = True
|
|
|
|
def _bop_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.BOP(d["open"],d["high"],d["low"],d["close"]))
|
|
def _bop_tl(d,df,**_): return _strip_nan(_talib.BOP(d["open"],d["high"],d["low"],d["close"]))
|
|
def _bop_pt(d,df,**_):
|
|
r=_pta.bop(df["open"],df["high"],df["low"],df["close"]); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _bop_ta(d,df,**_): return _empty()
|
|
_bop_ta._stub = True
|
|
def _bop_tu(d,df,**_): return _strip_nan(_tl.bop(_c64(d["open"]),_c64(d["high"]),_c64(d["low"]),_c64(d["close"])))
|
|
def _bop_fi(d,df,**_): return _empty()
|
|
_bop_fi._stub = True
|
|
|
|
def _plusdi_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.PLUS_DI(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _plusdi_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.PLUS_DI(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _plusdi_pt(d,df,timeperiod=14,**_):
|
|
r=_pta.adx(df["high"],df["low"],df["close"],length=timeperiod); return _first_col(r,"DMP_") if r is not None else _empty()
|
|
def _plusdi_ta(d,df,**_): return _empty()
|
|
_plusdi_ta._stub = True
|
|
def _plusdi_tu(d,df,timeperiod=14,**_):
|
|
pdi,mdi=_tl.di(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod); return _strip_nan(pdi)
|
|
def _plusdi_fi(d,df,**_): return _empty()
|
|
_plusdi_fi._stub = True
|
|
|
|
def _minusdi_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.MINUS_DI(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _minusdi_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.MINUS_DI(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _minusdi_pt(d,df,**_): return _empty()
|
|
_minusdi_pt._stub = True
|
|
def _minusdi_ta(d,df,**_): return _empty()
|
|
_minusdi_ta._stub = True
|
|
def _minusdi_tu(d,df,timeperiod=14,**_):
|
|
pdi,mdi=_tl.di(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod); return _strip_nan(mdi)
|
|
def _minusdi_fi(d,df,**_): return _empty()
|
|
_minusdi_fi._stub = True
|
|
|
|
# ============================================================
|
|
# VOLATILITY
|
|
# ============================================================
|
|
def _bb_ft(d,df,timeperiod=20,nbdevup=2.0,nbdevdn=2.0,**_):
|
|
import ferro_ta; u,m,l=ferro_ta.BBANDS(d["close"],timeperiod=timeperiod,nbdevup=nbdevup,nbdevdn=nbdevdn); return _strip_nan(u)
|
|
def _bb_tl(d,df,timeperiod=20,nbdevup=2.0,nbdevdn=2.0,**_):
|
|
u,m,l=_talib.BBANDS(d["close"],timeperiod=timeperiod,nbdevup=nbdevup,nbdevdn=nbdevdn); return _strip_nan(u)
|
|
def _bb_pt(d,df,timeperiod=20,nbdevup=2.0,**_):
|
|
r=_pta.bbands(df["close"],length=timeperiod,std=nbdevup); return _first_col(r,"BBU_")
|
|
def _bb_ta(d,df,timeperiod=20,nbdevup=2.0,**_):
|
|
from ta.volatility import BollingerBands; return _strip_nan(BollingerBands(df["close"],window=timeperiod,window_dev=nbdevup).bollinger_hband().values)
|
|
def _bb_tu(d,df,timeperiod=20,nbdevup=2.0,**_):
|
|
lo,mi,up=_tl.bbands(_c64(d["close"]),period=timeperiod,stddev=nbdevup); return _strip_nan(up)
|
|
def _bb_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.BBANDS(df,timeperiod)["BB_UPPER"].values)
|
|
|
|
def _atr_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.ATR(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _atr_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.ATR(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _atr_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.atr(df["high"],df["low"],df["close"],length=timeperiod).values)
|
|
def _atr_ta(d,df,timeperiod=14,**_):
|
|
from ta.volatility import AverageTrueRange; return _strip_nan(AverageTrueRange(df["high"],df["low"],df["close"],window=timeperiod).average_true_range().values)
|
|
def _atr_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.atr(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod))
|
|
def _atr_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.ATR(df,timeperiod).values)
|
|
|
|
def _natr_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.NATR(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _natr_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.NATR(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _natr_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.natr(df["high"],df["low"],df["close"],length=timeperiod).values)
|
|
def _natr_ta(d,df,**_): return _empty()
|
|
_natr_ta._stub = True
|
|
def _natr_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.natr(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),period=timeperiod))
|
|
def _natr_fi(d,df,**_): return _empty()
|
|
_natr_fi._stub = True
|
|
|
|
def _trange_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.TRANGE(d["high"],d["low"],d["close"]))
|
|
def _trange_tl(d,df,**_): return _strip_nan(_talib.TRANGE(d["high"],d["low"],d["close"]))
|
|
def _trange_pt(d,df,**_):
|
|
r=_pta.true_range(df["high"],df["low"],df["close"]); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _trange_ta(d,df,**_): return _empty()
|
|
_trange_ta._stub = True
|
|
def _trange_tu(d,df,**_): return _strip_nan(_tl.tr(_c64(d["high"]),_c64(d["low"]),_c64(d["close"])))
|
|
def _trange_fi(d,df,**_): return _strip_nan(_fi.TR(df).values)
|
|
|
|
def _stddev_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.STDDEV(d["close"],timeperiod=timeperiod))
|
|
def _stddev_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.STDDEV(d["close"],timeperiod=timeperiod))
|
|
def _stddev_pt(d,df,timeperiod=20,**_):
|
|
r=_pta.stdev(df["close"],length=timeperiod); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _stddev_ta(d,df,**_): return _empty()
|
|
_stddev_ta._stub = True
|
|
def _stddev_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.stddev(_c64(d["close"]),period=timeperiod))
|
|
def _stddev_fi(d,df,timeperiod=20,**_): return _strip_nan(_fi.MSD(df,timeperiod).values)
|
|
|
|
def _var_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.VAR(d["close"],timeperiod=timeperiod))
|
|
def _var_tl(d,df,timeperiod=20,**_): return _strip_nan(_talib.VAR(d["close"],timeperiod=timeperiod))
|
|
def _var_pt(d,df,timeperiod=20,**_):
|
|
r=_pta.variance(df["close"],length=timeperiod); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _var_ta(d,df,**_): return _empty()
|
|
_var_ta._stub = True
|
|
def _var_tu(d,df,timeperiod=20,**_): return _strip_nan(_tl.var(_c64(d["close"]),period=timeperiod))
|
|
def _var_fi(d,df,**_): return _empty()
|
|
_var_fi._stub = True
|
|
|
|
def _sar_ft(d,df,acceleration=0.02,maximum=0.2,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.SAR(d["high"],d["low"],acceleration=acceleration,maximum=maximum))
|
|
def _sar_tl(d,df,acceleration=0.02,maximum=0.2,**_): return _strip_nan(_talib.SAR(d["high"],d["low"],acceleration=acceleration,maximum=maximum))
|
|
def _sar_pt(d,df,**_): return _empty()
|
|
_sar_pt._stub = True
|
|
def _sar_ta(d,df,**_): return _empty()
|
|
_sar_ta._stub = True
|
|
def _sar_tu(d,df,acceleration=0.02,maximum=0.2,**_): return _strip_nan(_tl.psar(_c64(d["high"]),_c64(d["low"]),acceleration_factor_step=acceleration,acceleration_factor_maximum=maximum))
|
|
def _sar_fi(d,df,**_): return _empty()
|
|
_sar_fi._stub = True
|
|
|
|
def _kc_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; u,m,l=ferro_ta.KELTNER_CHANNELS(d["high"],d["low"],d["close"],timeperiod=timeperiod); return _strip_nan(u)
|
|
def _kc_tl(d,df,**_): return _empty()
|
|
_kc_tl._stub = True
|
|
def _kc_pt(d,df,timeperiod=20,**_):
|
|
r=_pta.kc(df["high"],df["low"],df["close"],length=timeperiod)
|
|
if r is None: return _empty()
|
|
col=next((c for c in r.columns if "UCe" in c or "UB" in c or c.endswith("U")),None)
|
|
return _strip_nan(r[col].values) if col else _first_col(r,"KC")
|
|
def _kc_ta(d,df,timeperiod=20,**_):
|
|
from ta.volatility import KeltnerChannel; return _strip_nan(KeltnerChannel(df["high"],df["low"],df["close"],window=timeperiod).keltner_channel_hband().values)
|
|
def _kc_tu(d,df,**_): return _empty()
|
|
_kc_tu._stub = True
|
|
def _kc_fi(d,df,**_): return _empty()
|
|
_kc_fi._stub = True
|
|
|
|
def _donchian_ft(d,df,timeperiod=20,**_):
|
|
import ferro_ta; u,m,l=ferro_ta.DONCHIAN(d["high"],d["low"],timeperiod=timeperiod); return _strip_nan(u)
|
|
def _donchian_tl(d,df,**_): return _empty()
|
|
_donchian_tl._stub = True
|
|
def _donchian_pt(d,df,timeperiod=20,**_):
|
|
r=_pta.donchian(df["high"],df["low"],lower_length=timeperiod,upper_length=timeperiod)
|
|
return _first_col(r,"DCU_") if r is not None else _empty()
|
|
def _donchian_ta(d,df,timeperiod=20,**_):
|
|
from ta.volatility import DonchianChannel; return _strip_nan(DonchianChannel(df["high"],df["low"],df["close"],window=timeperiod).donchian_channel_hband().values)
|
|
def _donchian_tu(d,df,**_): return _empty()
|
|
_donchian_tu._stub = True
|
|
def _donchian_fi(d,df,**_): return _empty()
|
|
_donchian_fi._stub = True
|
|
|
|
def _supertrend_ft(d,df,timeperiod=7,**_):
|
|
import ferro_ta; st,dir_=ferro_ta.SUPERTREND(d["high"],d["low"],d["close"],timeperiod=timeperiod); return _strip_nan(st)
|
|
def _supertrend_tl(d,df,**_): return _empty()
|
|
_supertrend_tl._stub = True
|
|
def _supertrend_pt(d,df,timeperiod=7,**_):
|
|
r=_pta.supertrend(df["high"],df["low"],df["close"],length=timeperiod)
|
|
return _first_col(r,"SUPERT_") if r is not None else _empty()
|
|
def _supertrend_ta(d,df,**_): return _empty()
|
|
_supertrend_ta._stub = True
|
|
def _supertrend_tu(d,df,**_): return _empty()
|
|
_supertrend_tu._stub = True
|
|
def _supertrend_fi(d,df,**_): return _empty()
|
|
_supertrend_fi._stub = True
|
|
|
|
def _chop_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CHOPPINESS_INDEX(d["high"],d["low"],d["close"],timeperiod=timeperiod))
|
|
def _chop_tl(d,df,**_): return _empty()
|
|
_chop_tl._stub = True
|
|
def _chop_pt(d,df,timeperiod=14,**_):
|
|
r=_pta.chop(df["high"],df["low"],df["close"],length=timeperiod); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _chop_ta(d,df,**_): return _empty()
|
|
_chop_ta._stub = True
|
|
def _chop_tu(d,df,**_): return _empty()
|
|
_chop_tu._stub = True
|
|
def _chop_fi(d,df,**_): return _empty()
|
|
_chop_fi._stub = True
|
|
|
|
# ============================================================
|
|
# VOLUME
|
|
# ============================================================
|
|
def _obv_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.OBV(d["close"],d["volume"]))
|
|
def _obv_tl(d,df,**_): return _strip_nan(_talib.OBV(d["close"],d["volume"]))
|
|
def _obv_pt(d,df,**_): return _strip_nan(_pta.obv(df["close"],df["volume"]).values)
|
|
def _obv_ta(d,df,**_):
|
|
from ta.volume import OnBalanceVolumeIndicator; return _strip_nan(OnBalanceVolumeIndicator(df["close"],df["volume"]).on_balance_volume().values)
|
|
def _obv_tu(d,df,**_): return _strip_nan(_tl.obv(_c64(d["close"]),_c64(d["volume"])))
|
|
def _obv_fi(d,df,**_): return _strip_nan(_fi.OBV(df).values)
|
|
|
|
def _ad_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.AD(d["high"],d["low"],d["close"],d["volume"]))
|
|
def _ad_tl(d,df,**_): return _strip_nan(_talib.AD(d["high"],d["low"],d["close"],d["volume"]))
|
|
def _ad_pt(d,df,**_): return _strip_nan(_pta.ad(df["high"],df["low"],df["close"],df["volume"]).values)
|
|
def _ad_ta(d,df,**_):
|
|
from ta.volume import AccDistIndexIndicator; return _strip_nan(AccDistIndexIndicator(df["high"],df["low"],df["close"],df["volume"]).acc_dist_index().values)
|
|
def _ad_tu(d,df,**_): return _strip_nan(_tl.ad(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),_c64(d["volume"])))
|
|
def _ad_fi(d,df,**_): return _empty()
|
|
_ad_fi._stub = True
|
|
|
|
def _adosc_ft(d,df,fastperiod=3,slowperiod=10,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.ADOSC(d["high"],d["low"],d["close"],d["volume"],fastperiod=fastperiod,slowperiod=slowperiod))
|
|
def _adosc_tl(d,df,fastperiod=3,slowperiod=10,**_): return _strip_nan(_talib.ADOSC(d["high"],d["low"],d["close"],d["volume"],fastperiod=fastperiod,slowperiod=slowperiod))
|
|
def _adosc_pt(d,df,fastperiod=3,slowperiod=10,**_): return _strip_nan(_pta.adosc(df["high"],df["low"],df["close"],df["volume"],fast=fastperiod,slow=slowperiod).values)
|
|
def _adosc_ta(d,df,**_): return _empty()
|
|
_adosc_ta._stub = True
|
|
def _adosc_tu(d,df,fastperiod=3,slowperiod=10,**_): return _strip_nan(_tl.adosc(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),_c64(d["volume"]),short_period=fastperiod,long_period=slowperiod))
|
|
def _adosc_fi(d,df,**_): return _empty()
|
|
_adosc_fi._stub = True
|
|
|
|
def _mfi_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.MFI(d["high"],d["low"],d["close"],d["volume"],timeperiod=timeperiod))
|
|
def _mfi_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.MFI(d["high"],d["low"],d["close"],d["volume"],timeperiod=timeperiod))
|
|
def _mfi_pt(d,df,timeperiod=14,**_): return _strip_nan(_pta.mfi(df["high"],df["low"],df["close"],df["volume"],length=timeperiod).values)
|
|
def _mfi_ta(d,df,timeperiod=14,**_):
|
|
from ta.volume import MFIIndicator; return _strip_nan(MFIIndicator(df["high"],df["low"],df["close"],df["volume"],window=timeperiod).money_flow_index().values)
|
|
def _mfi_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.mfi(_c64(d["high"]),_c64(d["low"]),_c64(d["close"]),_c64(d["volume"]),period=timeperiod))
|
|
def _mfi_fi(d,df,timeperiod=14,**_): return _strip_nan(_fi.MFI(df,timeperiod).values)
|
|
|
|
def _vwap_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.VWAP(d["high"],d["low"],d["close"],d["volume"]))
|
|
def _vwap_tl(d,df,**_): return _empty()
|
|
_vwap_tl._stub = True
|
|
def _vwap_pt(d,df,**_):
|
|
r=_pta.vwap(df["high"],df["low"],df["close"],df["volume"]); return _strip_nan(r.values) if r is not None else _empty()
|
|
def _vwap_ta(d,df,**_): return _empty()
|
|
_vwap_ta._stub = True
|
|
def _vwap_tu(d,df,**_): return _empty()
|
|
_vwap_tu._stub = True
|
|
def _vwap_fi(d,df,**_):
|
|
return _strip_nan(_fi.VWAP(df).values)
|
|
|
|
# ============================================================
|
|
# PRICE TRANSFORM
|
|
# ============================================================
|
|
def _avgprice_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.AVGPRICE(d["open"],d["high"],d["low"],d["close"]))
|
|
def _avgprice_tl(d,df,**_): return _strip_nan(_talib.AVGPRICE(d["open"],d["high"],d["low"],d["close"]))
|
|
def _avgprice_pt(d,df,**_): return _empty()
|
|
_avgprice_pt._stub = True
|
|
def _avgprice_ta(d,df,**_): return _empty()
|
|
_avgprice_ta._stub = True
|
|
def _avgprice_tu(d,df,**_): return _strip_nan(_tl.avgprice(_c64(d["open"]),_c64(d["high"]),_c64(d["low"]),_c64(d["close"])))
|
|
def _avgprice_fi(d,df,**_): return _empty()
|
|
_avgprice_fi._stub = True
|
|
|
|
def _medprice_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.MEDPRICE(d["high"],d["low"]))
|
|
def _medprice_tl(d,df,**_): return _strip_nan(_talib.MEDPRICE(d["high"],d["low"]))
|
|
def _medprice_pt(d,df,**_): return _empty()
|
|
_medprice_pt._stub = True
|
|
def _medprice_ta(d,df,**_): return _empty()
|
|
_medprice_ta._stub = True
|
|
def _medprice_tu(d,df,**_): return _strip_nan(_tl.medprice(_c64(d["high"]),_c64(d["low"])))
|
|
def _medprice_fi(d,df,**_): return _empty()
|
|
_medprice_fi._stub = True
|
|
|
|
def _typprice_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.TYPPRICE(d["high"],d["low"],d["close"]))
|
|
def _typprice_tl(d,df,**_): return _strip_nan(_talib.TYPPRICE(d["high"],d["low"],d["close"]))
|
|
def _typprice_pt(d,df,**_): return _empty()
|
|
_typprice_pt._stub = True
|
|
def _typprice_ta(d,df,**_): return _empty()
|
|
_typprice_ta._stub = True
|
|
def _typprice_tu(d,df,**_): return _strip_nan(_tl.typprice(_c64(d["high"]),_c64(d["low"]),_c64(d["close"])))
|
|
def _typprice_fi(d,df,**_): return _empty()
|
|
_typprice_fi._stub = True
|
|
|
|
def _wclprice_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.WCLPRICE(d["high"],d["low"],d["close"]))
|
|
def _wclprice_tl(d,df,**_): return _strip_nan(_talib.WCLPRICE(d["high"],d["low"],d["close"]))
|
|
def _wclprice_pt(d,df,**_): return _empty()
|
|
_wclprice_pt._stub = True
|
|
def _wclprice_ta(d,df,**_): return _empty()
|
|
_wclprice_ta._stub = True
|
|
def _wclprice_tu(d,df,**_): return _strip_nan(_tl.wcprice(_c64(d["high"]),_c64(d["low"]),_c64(d["close"])))
|
|
def _wclprice_fi(d,df,**_): return _empty()
|
|
_wclprice_fi._stub = True
|
|
|
|
# ============================================================
|
|
# MATH
|
|
# ============================================================
|
|
def _sqrt_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.SQRT(d["close"]))
|
|
def _sqrt_tl(d,df,**_): return _strip_nan(_talib.SQRT(d["close"]))
|
|
def _sqrt_pt(d,df,**_): return _empty()
|
|
_sqrt_pt._stub = True
|
|
def _sqrt_ta(d,df,**_): return _empty()
|
|
_sqrt_ta._stub = True
|
|
def _sqrt_tu(d,df,**_): return _strip_nan(_tl.sqrt(_c64(d["close"])))
|
|
def _sqrt_fi(d,df,**_): return _empty()
|
|
_sqrt_fi._stub = True
|
|
|
|
def _log10_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.LOG10(d["close"]))
|
|
def _log10_tl(d,df,**_): return _strip_nan(_talib.LOG10(d["close"]))
|
|
def _log10_pt(d,df,**_): return _empty()
|
|
_log10_pt._stub = True
|
|
def _log10_ta(d,df,**_): return _empty()
|
|
_log10_ta._stub = True
|
|
def _log10_tu(d,df,**_): return _strip_nan(_tl.log10(_c64(d["close"])))
|
|
def _log10_fi(d,df,**_): return _empty()
|
|
_log10_fi._stub = True
|
|
|
|
def _add_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.ADD(d["high"],d["low"]))
|
|
def _add_tl(d,df,**_): return _strip_nan(_talib.ADD(d["high"],d["low"]))
|
|
def _add_pt(d,df,**_): return _empty()
|
|
_add_pt._stub = True
|
|
def _add_ta(d,df,**_): return _empty()
|
|
_add_ta._stub = True
|
|
def _add_tu(d,df,**_): return _strip_nan(_tl.add(_c64(d["high"]),_c64(d["low"])))
|
|
def _add_fi(d,df,**_): return _empty()
|
|
_add_fi._stub = True
|
|
|
|
# ============================================================
|
|
# STATISTICS
|
|
# ============================================================
|
|
def _linearreg_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.LINEARREG(d["close"],timeperiod=timeperiod))
|
|
def _linearreg_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.LINEARREG(d["close"],timeperiod=timeperiod))
|
|
def _linearreg_pt(d,df,**_): return _empty()
|
|
_linearreg_pt._stub = True
|
|
def _linearreg_ta(d,df,**_): return _empty()
|
|
_linearreg_ta._stub = True
|
|
def _linearreg_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.linreg(_c64(d["close"]),period=timeperiod))
|
|
def _linearreg_fi(d,df,**_): return _empty()
|
|
_linearreg_fi._stub = True
|
|
|
|
def _linreg_slope_ft(d,df,timeperiod=14,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.LINEARREG_SLOPE(d["close"],timeperiod=timeperiod))
|
|
def _linreg_slope_tl(d,df,timeperiod=14,**_): return _strip_nan(_talib.LINEARREG_SLOPE(d["close"],timeperiod=timeperiod))
|
|
def _linreg_slope_pt(d,df,**_): return _empty()
|
|
_linreg_slope_pt._stub = True
|
|
def _linreg_slope_ta(d,df,**_): return _empty()
|
|
_linreg_slope_ta._stub = True
|
|
def _linreg_slope_tu(d,df,timeperiod=14,**_): return _strip_nan(_tl.linregslope(_c64(d["close"]),period=timeperiod))
|
|
def _linreg_slope_fi(d,df,**_): return _empty()
|
|
_linreg_slope_fi._stub = True
|
|
|
|
def _correl_ft(d,df,timeperiod=30,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CORREL(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _correl_tl(d,df,timeperiod=30,**_): return _strip_nan(_talib.CORREL(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _correl_pt(d,df,**_): return _empty()
|
|
_correl_pt._stub = True
|
|
def _correl_ta(d,df,**_): return _empty()
|
|
_correl_ta._stub = True
|
|
def _correl_tu(d,df,**_): return _empty()
|
|
_correl_tu._stub = True
|
|
def _correl_fi(d,df,**_): return _empty()
|
|
_correl_fi._stub = True
|
|
|
|
def _beta_ft(d,df,timeperiod=5,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.BETA(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _beta_tl(d,df,timeperiod=5,**_): return _strip_nan(_talib.BETA(d["high"],d["low"],timeperiod=timeperiod))
|
|
def _beta_pt(d,df,**_): return _empty()
|
|
_beta_pt._stub = True
|
|
def _beta_ta(d,df,**_): return _empty()
|
|
_beta_ta._stub = True
|
|
def _beta_tu(d,df,**_): return _empty()
|
|
_beta_tu._stub = True
|
|
def _beta_fi(d,df,**_): return _empty()
|
|
_beta_fi._stub = True
|
|
|
|
# ============================================================
|
|
# CYCLE
|
|
# ============================================================
|
|
def _ht_dcperiod_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.HT_DCPERIOD(d["close"]))
|
|
def _ht_dcperiod_tl(d,df,**_): return _strip_nan(_talib.HT_DCPERIOD(d["close"]))
|
|
def _ht_dcperiod_pt(d,df,**_): return _empty()
|
|
_ht_dcperiod_pt._stub = True
|
|
def _ht_dcperiod_ta(d,df,**_): return _empty()
|
|
_ht_dcperiod_ta._stub = True
|
|
def _ht_dcperiod_tu(d,df,**_): return _empty()
|
|
_ht_dcperiod_tu._stub = True
|
|
def _ht_dcperiod_fi(d,df,**_): return _empty()
|
|
_ht_dcperiod_fi._stub = True
|
|
|
|
def _ht_trendmode_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.HT_TRENDMODE(d["close"]).astype(float))
|
|
def _ht_trendmode_tl(d,df,**_): return _strip_nan(_talib.HT_TRENDMODE(d["close"]).astype(float))
|
|
def _ht_trendmode_pt(d,df,**_): return _empty()
|
|
_ht_trendmode_pt._stub = True
|
|
def _ht_trendmode_ta(d,df,**_): return _empty()
|
|
_ht_trendmode_ta._stub = True
|
|
def _ht_trendmode_tu(d,df,**_): return _empty()
|
|
_ht_trendmode_tu._stub = True
|
|
def _ht_trendmode_fi(d,df,**_): return _empty()
|
|
_ht_trendmode_fi._stub = True
|
|
|
|
# ============================================================
|
|
# CANDLESTICK PATTERNS
|
|
# ============================================================
|
|
def _cdlengulfing_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CDLENGULFING(d["open"],d["high"],d["low"],d["close"]).astype(float))
|
|
def _cdlengulfing_tl(d,df,**_): return _strip_nan(_talib.CDLENGULFING(d["open"],d["high"],d["low"],d["close"]).astype(float))
|
|
def _cdlengulfing_pt(d,df,**_): return _empty()
|
|
_cdlengulfing_pt._stub = True
|
|
def _cdlengulfing_ta(d,df,**_): return _empty()
|
|
_cdlengulfing_ta._stub = True
|
|
def _cdlengulfing_tu(d,df,**_): return _empty()
|
|
_cdlengulfing_tu._stub = True
|
|
def _cdlengulfing_fi(d,df,**_): return _empty()
|
|
_cdlengulfing_fi._stub = True
|
|
|
|
def _cdldoji_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CDLDOJI(d["open"],d["high"],d["low"],d["close"]).astype(float))
|
|
def _cdldoji_tl(d,df,**_): return _strip_nan(_talib.CDLDOJI(d["open"],d["high"],d["low"],d["close"]).astype(float))
|
|
def _cdldoji_pt(d,df,**_): return _empty()
|
|
_cdldoji_pt._stub = True
|
|
def _cdldoji_ta(d,df,**_): return _empty()
|
|
_cdldoji_ta._stub = True
|
|
def _cdldoji_tu(d,df,**_): return _empty()
|
|
_cdldoji_tu._stub = True
|
|
def _cdldoji_fi(d,df,**_): return _empty()
|
|
_cdldoji_fi._stub = True
|
|
|
|
def _cdlhammer_ft(d,df,**_):
|
|
import ferro_ta; return _strip_nan(ferro_ta.CDLHAMMER(d["open"],d["high"],d["low"],d["close"]).astype(float))
|
|
def _cdlhammer_tl(d,df,**_): return _strip_nan(_talib.CDLHAMMER(d["open"],d["high"],d["low"],d["close"]).astype(float))
|
|
def _cdlhammer_pt(d,df,**_): return _empty()
|
|
_cdlhammer_pt._stub = True
|
|
def _cdlhammer_ta(d,df,**_): return _empty()
|
|
_cdlhammer_ta._stub = True
|
|
def _cdlhammer_tu(d,df,**_): return _empty()
|
|
_cdlhammer_tu._stub = True
|
|
def _cdlhammer_fi(d,df,**_): return _empty()
|
|
_cdlhammer_fi._stub = True
|
|
|
|
# ============================================================
|
|
# REGISTRY BUILD
|
|
# ============================================================
|
|
REGISTRY: dict[tuple[str,Any], Any] = {}
|
|
|
|
def _reg(ind, ft, tl, pt, ta_, tu, fi):
|
|
"""
|
|
Register wrappers for a given indicator across all libraries.
|
|
|
|
Wrappers marked ._stub = True (no-op return _empty()) are not registered,
|
|
so execute_indicator raises KeyError for unsupported (lib, ind). Speed
|
|
benchmarks then skip those pairs and the table shows N/A.
|
|
"""
|
|
for lib, fn in [
|
|
("ferro_ta", ft),
|
|
("talib", tl),
|
|
("pandas_ta",pt),
|
|
("ta", ta_),
|
|
("tulipy", tu),
|
|
("finta", fi),
|
|
]:
|
|
if getattr(fn, "_stub", False):
|
|
continue
|
|
REGISTRY[(lib, ind)] = fn
|
|
|
|
_reg("SMA",_sma_ft,_sma_tl,_sma_pt,_sma_ta,_sma_tu,_sma_fi)
|
|
_reg("EMA",_ema_ft,_ema_tl,_ema_pt,_ema_ta,_ema_tu,_ema_fi)
|
|
_reg("WMA",_wma_ft,_wma_tl,_wma_pt,_wma_ta,_wma_tu,_wma_fi)
|
|
_reg("DEMA",_dema_ft,_dema_tl,_dema_pt,_dema_ta,_dema_tu,_dema_fi)
|
|
_reg("TEMA",_tema_ft,_tema_tl,_tema_pt,_tema_ta,_tema_tu,_tema_fi)
|
|
_reg("T3",_t3_ft,_t3_tl,_t3_pt,_t3_ta,_t3_tu,_t3_fi)
|
|
_reg("TRIMA",_trima_ft,_trima_tl,_trima_pt,_trima_ta,_trima_tu,_trima_fi)
|
|
_reg("KAMA",_kama_ft,_kama_tl,_kama_pt,_kama_ta,_kama_tu,_kama_fi)
|
|
_reg("HULL_MA",_hma_ft,_hma_tl,_hma_pt,_hma_ta,_hma_tu,_hma_fi)
|
|
_reg("VWMA",_vwma_ft,_vwma_tl,_vwma_pt,_vwma_ta,_vwma_tu,_vwma_fi)
|
|
_reg("MIDPOINT",_midpoint_ft,_midpoint_tl,_midpoint_pt,_midpoint_ta,_midpoint_tu,_midpoint_fi)
|
|
_reg("MIDPRICE",_midprice_ft,_midprice_tl,_midprice_pt,_midprice_ta,_midprice_tu,_midprice_fi)
|
|
_reg("RSI",_rsi_ft,_rsi_tl,_rsi_pt,_rsi_ta,_rsi_tu,_rsi_fi)
|
|
_reg("MACD",_macd_ft,_macd_tl,_macd_pt,_macd_ta,_macd_tu,_macd_fi)
|
|
_reg("STOCH",_stoch_ft,_stoch_tl,_stoch_pt,_stoch_ta,_stoch_tu,_stoch_fi)
|
|
_reg("CCI",_cci_ft,_cci_tl,_cci_pt,_cci_ta,_cci_tu,_cci_fi)
|
|
_reg("WILLR",_willr_ft,_willr_tl,_willr_pt,_willr_ta,_willr_tu,_willr_fi)
|
|
_reg("AROON",_aroon_ft,_aroon_tl,_aroon_pt,_aroon_ta,_aroon_tu,_aroon_fi)
|
|
_reg("AROONOSC",_aroonosc_ft,_aroonosc_tl,_aroonosc_pt,_aroonosc_ta,_aroonosc_tu,_aroonosc_fi)
|
|
_reg("ADX",_adx_ft,_adx_tl,_adx_pt,_adx_ta,_adx_tu,_adx_fi)
|
|
_reg("MOM",_mom_ft,_mom_tl,_mom_pt,_mom_ta,_mom_tu,_mom_fi)
|
|
_reg("ROC",_roc_ft,_roc_tl,_roc_pt,_roc_ta,_roc_tu,_roc_fi)
|
|
_reg("CMO",_cmo_ft,_cmo_tl,_cmo_pt,_cmo_ta,_cmo_tu,_cmo_fi)
|
|
_reg("PPO",_ppo_ft,_ppo_tl,_ppo_pt,_ppo_ta,_ppo_tu,_ppo_fi)
|
|
_reg("TRIX",_trix_ft,_trix_tl,_trix_pt,_trix_ta,_trix_tu,_trix_fi)
|
|
_reg("TSF",_tsf_ft,_tsf_tl,_tsf_pt,_tsf_ta,_tsf_tu,_tsf_fi)
|
|
_reg("ULTOSC",_ultosc_ft,_ultosc_tl,_ultosc_pt,_ultosc_ta,_ultosc_tu,_ultosc_fi)
|
|
_reg("BOP",_bop_ft,_bop_tl,_bop_pt,_bop_ta,_bop_tu,_bop_fi)
|
|
_reg("PLUS_DI",_plusdi_ft,_plusdi_tl,_plusdi_pt,_plusdi_ta,_plusdi_tu,_plusdi_fi)
|
|
_reg("MINUS_DI",_minusdi_ft,_minusdi_tl,_minusdi_pt,_minusdi_ta,_minusdi_tu,_minusdi_fi)
|
|
_reg("BBANDS",_bb_ft,_bb_tl,_bb_pt,_bb_ta,_bb_tu,_bb_fi)
|
|
_reg("ATR",_atr_ft,_atr_tl,_atr_pt,_atr_ta,_atr_tu,_atr_fi)
|
|
_reg("NATR",_natr_ft,_natr_tl,_natr_pt,_natr_ta,_natr_tu,_natr_fi)
|
|
_reg("TRANGE",_trange_ft,_trange_tl,_trange_pt,_trange_ta,_trange_tu,_trange_fi)
|
|
_reg("STDDEV",_stddev_ft,_stddev_tl,_stddev_pt,_stddev_ta,_stddev_tu,_stddev_fi)
|
|
_reg("VAR",_var_ft,_var_tl,_var_pt,_var_ta,_var_tu,_var_fi)
|
|
_reg("SAR",_sar_ft,_sar_tl,_sar_pt,_sar_ta,_sar_tu,_sar_fi)
|
|
_reg("KELTNER_CHANNELS",_kc_ft,_kc_tl,_kc_pt,_kc_ta,_kc_tu,_kc_fi)
|
|
_reg("DONCHIAN",_donchian_ft,_donchian_tl,_donchian_pt,_donchian_ta,_donchian_tu,_donchian_fi)
|
|
_reg("SUPERTREND",_supertrend_ft,_supertrend_tl,_supertrend_pt,_supertrend_ta,_supertrend_tu,_supertrend_fi)
|
|
_reg("CHOPPINESS_INDEX",_chop_ft,_chop_tl,_chop_pt,_chop_ta,_chop_tu,_chop_fi)
|
|
_reg("OBV",_obv_ft,_obv_tl,_obv_pt,_obv_ta,_obv_tu,_obv_fi)
|
|
_reg("AD",_ad_ft,_ad_tl,_ad_pt,_ad_ta,_ad_tu,_ad_fi)
|
|
_reg("ADOSC",_adosc_ft,_adosc_tl,_adosc_pt,_adosc_ta,_adosc_tu,_adosc_fi)
|
|
_reg("MFI",_mfi_ft,_mfi_tl,_mfi_pt,_mfi_ta,_mfi_tu,_mfi_fi)
|
|
_reg("VWAP",_vwap_ft,_vwap_tl,_vwap_pt,_vwap_ta,_vwap_tu,_vwap_fi)
|
|
_reg("AVGPRICE",_avgprice_ft,_avgprice_tl,_avgprice_pt,_avgprice_ta,_avgprice_tu,_avgprice_fi)
|
|
_reg("MEDPRICE",_medprice_ft,_medprice_tl,_medprice_pt,_medprice_ta,_medprice_tu,_medprice_fi)
|
|
_reg("TYPPRICE",_typprice_ft,_typprice_tl,_typprice_pt,_typprice_ta,_typprice_tu,_typprice_fi)
|
|
_reg("WCLPRICE",_wclprice_ft,_wclprice_tl,_wclprice_pt,_wclprice_ta,_wclprice_tu,_wclprice_fi)
|
|
_reg("SQRT",_sqrt_ft,_sqrt_tl,_sqrt_pt,_sqrt_ta,_sqrt_tu,_sqrt_fi)
|
|
_reg("LOG10",_log10_ft,_log10_tl,_log10_pt,_log10_ta,_log10_tu,_log10_fi)
|
|
_reg("ADD",_add_ft,_add_tl,_add_pt,_add_ta,_add_tu,_add_fi)
|
|
_reg("LINEARREG",_linearreg_ft,_linearreg_tl,_linearreg_pt,_linearreg_ta,_linearreg_tu,_linearreg_fi)
|
|
_reg("LINEARREG_SLOPE",_linreg_slope_ft,_linreg_slope_tl,_linreg_slope_pt,_linreg_slope_ta,_linreg_slope_tu,_linreg_slope_fi)
|
|
_reg("CORREL",_correl_ft,_correl_tl,_correl_pt,_correl_ta,_correl_tu,_correl_fi)
|
|
_reg("BETA",_beta_ft,_beta_tl,_beta_pt,_beta_ta,_beta_tu,_beta_fi)
|
|
_reg("HT_DCPERIOD",_ht_dcperiod_ft,_ht_dcperiod_tl,_ht_dcperiod_pt,_ht_dcperiod_ta,_ht_dcperiod_tu,_ht_dcperiod_fi)
|
|
_reg("HT_TRENDMODE",_ht_trendmode_ft,_ht_trendmode_tl,_ht_trendmode_pt,_ht_trendmode_ta,_ht_trendmode_tu,_ht_trendmode_fi)
|
|
_reg("CDLENGULFING",_cdlengulfing_ft,_cdlengulfing_tl,_cdlengulfing_pt,_cdlengulfing_ta,_cdlengulfing_tu,_cdlengulfing_fi)
|
|
_reg("CDLDOJI",_cdldoji_ft,_cdldoji_tl,_cdldoji_pt,_cdldoji_ta,_cdldoji_tu,_cdldoji_fi)
|
|
_reg("CDLHAMMER",_cdlhammer_ft,_cdlhammer_tl,_cdlhammer_pt,_cdlhammer_ta,_cdlhammer_tu,_cdlhammer_fi)
|
|
|
|
# ============================================================
|
|
# METADATA
|
|
# ============================================================
|
|
INDICATOR_DEFAULTS: dict[str, dict] = {
|
|
"SMA":{"timeperiod":20},"EMA":{"timeperiod":20},"WMA":{"timeperiod":14},
|
|
"DEMA":{"timeperiod":20},"TEMA":{"timeperiod":20},"T3":{"timeperiod":5},
|
|
"TRIMA":{"timeperiod":20},"KAMA":{"timeperiod":10},"HULL_MA":{"timeperiod":16},
|
|
"VWMA":{"timeperiod":20},"MIDPOINT":{"timeperiod":14},"MIDPRICE":{"timeperiod":14},
|
|
"RSI":{"timeperiod":14},
|
|
"MACD":{"fastperiod":12,"slowperiod":26,"signalperiod":9},
|
|
"STOCH":{"fastk_period":14,"slowk_period":3,"slowd_period":3},
|
|
"CCI":{"timeperiod":14},"WILLR":{"timeperiod":14},
|
|
"AROON":{"timeperiod":14},"AROONOSC":{"timeperiod":14},
|
|
"ADX":{"timeperiod":14},"MOM":{"timeperiod":10},"ROC":{"timeperiod":10},
|
|
"CMO":{"timeperiod":14},"PPO":{"fastperiod":12,"slowperiod":26},
|
|
"TRIX":{"timeperiod":18},"TSF":{"timeperiod":14},
|
|
"ULTOSC":{"timeperiod1":7,"timeperiod2":14,"timeperiod3":28},
|
|
"BOP":{},"PLUS_DI":{"timeperiod":14},"MINUS_DI":{"timeperiod":14},
|
|
"BBANDS":{"timeperiod":20,"nbdevup":2.0,"nbdevdn":2.0},
|
|
"ATR":{"timeperiod":14},"NATR":{"timeperiod":14},"TRANGE":{},
|
|
"STDDEV":{"timeperiod":20},"VAR":{"timeperiod":20},
|
|
"SAR":{"acceleration":0.02,"maximum":0.2},
|
|
"KELTNER_CHANNELS":{"timeperiod":20},"DONCHIAN":{"timeperiod":20},
|
|
"SUPERTREND":{"timeperiod":7},"CHOPPINESS_INDEX":{"timeperiod":14},
|
|
"OBV":{},"AD":{},"ADOSC":{"fastperiod":3,"slowperiod":10},
|
|
"MFI":{"timeperiod":14},"VWAP":{},
|
|
"AVGPRICE":{},"MEDPRICE":{},"TYPPRICE":{},"WCLPRICE":{},
|
|
"SQRT":{},"LOG10":{},"ADD":{},
|
|
"LINEARREG":{"timeperiod":14},"LINEARREG_SLOPE":{"timeperiod":14},
|
|
"CORREL":{"timeperiod":30},"BETA":{"timeperiod":5},
|
|
"HT_DCPERIOD":{},"HT_TRENDMODE":{},
|
|
"CDLENGULFING":{},"CDLDOJI":{},"CDLHAMMER":{},
|
|
}
|
|
|
|
INDICATOR_NAMES = list(INDICATOR_DEFAULTS.keys())
|
|
LIBRARY_NAMES = ["ferro_ta","talib","pandas_ta","ta","tulipy","finta"]
|
|
|
|
INDICATOR_CATEGORIES: dict[str, list[str]] = {
|
|
"Overlap": ["SMA","EMA","WMA","DEMA","TEMA","T3","TRIMA","KAMA","HULL_MA","VWMA","MIDPOINT","MIDPRICE"],
|
|
"Momentum": ["RSI","MACD","STOCH","CCI","WILLR","AROON","AROONOSC","ADX","MOM","ROC","CMO","PPO","TRIX","TSF","ULTOSC","BOP","PLUS_DI","MINUS_DI"],
|
|
"Volatility": ["BBANDS","ATR","NATR","TRANGE","STDDEV","VAR","SAR","KELTNER_CHANNELS","DONCHIAN","SUPERTREND","CHOPPINESS_INDEX"],
|
|
"Volume": ["OBV","AD","ADOSC","MFI","VWAP"],
|
|
"Price Transform": ["AVGPRICE","MEDPRICE","TYPPRICE","WCLPRICE"],
|
|
"Math": ["SQRT","LOG10","ADD"],
|
|
"Statistics": ["LINEARREG","LINEARREG_SLOPE","CORREL","BETA"],
|
|
"Cycle": ["HT_DCPERIOD","HT_TRENDMODE"],
|
|
"Pattern": ["CDLENGULFING","CDLDOJI","CDLHAMMER"],
|
|
}
|
|
|
|
# Cumulative: compare first-differences not absolute values
|
|
CUMULATIVE_INDICATORS = {"OBV","AD","ADOSC"}
|
|
# Binary output: use agreement rate not allclose
|
|
BINARY_INDICATORS = {"CDLENGULFING","CDLDOJI","CDLHAMMER","HT_TRENDMODE"}
|
|
|
|
|
|
def execute_indicator(library, indicator, data, df=None, **kwargs):
|
|
"""Run indicator from library on data dict, return 1-D float64 array."""
|
|
if library not in available_libraries():
|
|
raise KeyError(f"Library not available in this environment: {library!r}")
|
|
|
|
key = (library, indicator)
|
|
if key not in REGISTRY:
|
|
raise KeyError(f"No wrapper for {key!r}")
|
|
if df is None:
|
|
from benchmarks.data_generator import get_pandas_ohlcv
|
|
df = get_pandas_ohlcv(data)
|
|
params = {**INDICATOR_DEFAULTS.get(indicator, {}), **kwargs}
|
|
return REGISTRY[key](data, df, **params)
|