def ta_rsi(df: _PANDAS, period=12): returns = df.diff() pos = _wilders(returns.clip(lower=0), period) neg = _wilders(_np.abs(returns.clip(upper=0)), period) return _wcs(f"rsi_{period}", pos / (pos + neg), returns)
def ta_stddev(df: _PANDAS, period=12, nbdev=1, ddof=1, downscale=True) -> _PANDAS: return _wcs(f"stddev_{period}", (df.rolling(period).std(ddof=ddof) * nbdev) / (100 if downscale else 1))
def ta_apo(df: _PANDAS, fast_period=12, slow_period=26, exponential=False, relative=True) -> _PANDAS: fast = _ema(df, fast_period) if exponential else _sma(df, fast_period) slow = _ema(df, slow_period) if exponential else _sma(df, slow_period) apo = (fast / slow) if relative else (fast - slow) return _wcs(f"apo_{fast_period},{slow_period},{int(exponential)}", apo, df)
def ta_ma_ratio(df: Typing.PatchedPandas, period=12, lag=0, ma='sma', **kwargs): mafunc = getattr(_f, f'ta_{ma}') return _wcs(f"{ma}({period}) x 1/", df / mafunc(df, period=period, **kwargs).shift(lag).values - 1, df)
def ta_ppo(df: _pd.DataFrame, fast_period=12, slow_period=26, exponential=True) -> _PANDAS: fast = _ema(df, period=fast_period) if exponential else _sma( df, period=fast_period) slow = _ema(df, period=slow_period) if exponential else _sma( df, period=slow_period) return _wcs(f"ppo_{fast_period},{slow_period},{int(exponential)}", (fast - slow) / slow, df)
def ta_wilders(df: _PANDAS, period=12) -> _PANDAS: if has_indexed_columns(df): resdf = _pd.DataFrame({}, index=df.index) for col in df.columns: s = df[col].dropna() res = _np.zeros(s.shape) _ws(s.values, period, res) resdf = resdf.join(_pd.DataFrame({col: res}, index=s.index)) res = resdf else: res = ta_wilders(df.to_frame(), period).iloc[:, 0] return _wcs(f"wilders_{period}", res)
def ta_mom(df: _PANDAS, period=10) -> _PANDAS: return _wcs(f"mom_{period}", df.diff(period))
def ta_trix(df: _PANDAS, period=30) -> _PANDAS: return _wcs( f"trix_{period}", _ema(_ema(_ema(df, period), period), period).pct_change() * 100, df)
def ta_zscore(df: _PANDAS, period=20, ddof=1): res = df.rolling(period).apply(lambda c: zscore(c, ddof=ddof)[-1]) return _wcs(f"z_{period}", res)
def ta_sma(df: _PANDAS, period=12) -> _PANDAS: return _wcs(f"sma_{period}", df.rolling(period).mean())
def ta_ema(df: _PANDAS, period=12) -> _PANDAS: return _wcs( f"ema_{period}", df.ewm(span=period, adjust=False, min_periods=period - 1).mean())
def ta_roc(df: _PANDAS, period=12) -> _PANDAS: return _wcs(f"roc_{period}", df.pct_change(period))
def ta_mom(df: _PANDAS, period=12, relative=True) -> _PANDAS: return _wcs(f"mom_{period}", df.pct_change(period) if relative else df.diff(period))
def ta_zscore(df: _PANDAS, period=20, ddof=1, downscale=True): res = df.rolling(period).apply(lambda c: zscore(c, ddof=ddof)[-1] / (4 if downscale else 1)) return _wcs(f"z_{period}", res)
def ta_stddev(df: _PANDAS, period=5, nbdev=1, ddof=1) -> _PANDAS: return _wcs(f"stddev_{period}", (df.rolling(period).std(ddof=ddof) * nbdev))
def ta_log_returns(df: Typing.PatchedPandas, period=1): current = df lagged = df.shift(period) return _wcs("log_return", np.log(current) - np.log(lagged))
def ta_returns(df: Typing.PatchedPandas, period=1): return _wcs("return", df.pct_change(periods=period))
def ta_returns(df: Typing.PatchedPandas): return _wcs("return", df.pct_change())