2823 lines
59 KiB
Python
2823 lines
59 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)
|