"""RSI 다이버전스 기법.""" from __future__ import annotations import pandas as pd from deepcoin.techniques.base import BaseTechnique, TechniqueParams, TechniqueSignal from deepcoin.techniques.helpers import ( dedupe_signals, detect_bearish_divergence, detect_bullish_divergence, find_confirmed_pivots, make_signal, ) from deepcoin.techniques.indicators import rsi class RsiDivergenceTechnique(BaseTechnique): """RSI 상승·하락 다이버전스 매수·매도.""" technique_id = "rsi_divergence" technique_name = "RSI 다이버전스" category = "divergence" causal = True description = "RSI 상승(Bd)·하락(Sd) 다이버전스" def default_extra_params(self) -> dict: return {"period": 14, "order": 12, "min_bars_between": 15, "max_bars_between": 400} def generate_signals(self, df: pd.DataFrame, params: TechniqueParams) -> list[TechniqueSignal]: period = int(params.extra.get("period", 14)) order = int(params.extra.get("order", 12)) min_bars = int(params.extra.get("min_bars_between", 15)) max_bars = int(params.extra.get("max_bars_between", 400)) close = df["close"].astype(float) low = df["low"].astype(float) high = df["high"].astype(float) rsi_vals = rsi(close, period=period) low_pivots = find_confirmed_pivots(low, order, "low") high_pivots = find_confirmed_pivots(high, order, "high") signals: list[TechniqueSignal] = [] for pivot_idx, _ in detect_bullish_divergence( low_pivots, rsi_vals, min_bars_between=min_bars, max_bars_between=max_bars, ): confirm_idx = pivot_idx + order if confirm_idx >= len(df): continue signals.append( make_signal( df, confirm_idx, float(close.iloc[confirm_idx]), "buy", "rsi_bull_divergence", pivot_bar_index=pivot_idx, confidence=0.78, ) ) for pivot_idx, _ in detect_bearish_divergence( high_pivots, rsi_vals, min_bars_between=min_bars, max_bars_between=max_bars, ): confirm_idx = pivot_idx + order if confirm_idx >= len(df): continue signals.append( make_signal( df, confirm_idx, float(close.iloc[confirm_idx]), "sell", "rsi_bear_divergence", pivot_bar_index=pivot_idx, confidence=0.78, ) ) return dedupe_signals(signals, min_bars=min_bars)