"""롤링 피벗 포인트 반등 기법.""" from __future__ import annotations import pandas as pd from deepcoin.techniques.base import BaseTechnique, TechniqueParams, TechniqueSignal from deepcoin.techniques.helpers import make_signal from deepcoin.techniques.indicators import rolling_pivot_points class PivotPointsTechnique(BaseTechnique): """S1 지지 반등 매수, R1 저항 거부 매도.""" technique_id = "pivot_points" technique_name = "피벗 포인트" category = "structure" causal = True description = "롤링 피벗 S1/R1 반전" def default_extra_params(self) -> dict: return {"window": 60, "touch_pct": 0.2} def generate_signals(self, df: pd.DataFrame, params: TechniqueParams) -> list[TechniqueSignal]: window = int(params.extra.get("window", 60)) touch_pct = float(params.extra.get("touch_pct", 0.2)) / 100.0 high = df["high"].astype(float) low = df["low"].astype(float) close = df["close"].astype(float) _, s1, r1 = rolling_pivot_points(high, low, close, window=window) signals: list[TechniqueSignal] = [] touched_s1 = False touched_r1 = False for i in range(window + 1, len(df)): if pd.isna(s1.iloc[i]) or pd.isna(r1.iloc[i]): continue c = float(close.iloc[i]) l = float(low.iloc[i]) h = float(high.iloc[i]) s1_i = float(s1.iloc[i]) r1_i = float(r1.iloc[i]) prev_c = float(close.iloc[i - 1]) if l <= s1_i * (1 + touch_pct): touched_s1 = True if touched_s1 and prev_c <= s1_i and c > s1_i: signals.append(make_signal(df, i, c, "buy", "pivot_s1_bounce", confidence=0.67)) touched_s1 = False if h >= r1_i * (1 - touch_pct): touched_r1 = True if touched_r1 and prev_c >= r1_i and c < r1_i: signals.append(make_signal(df, i, c, "sell", "pivot_r1_reject", confidence=0.67)) touched_r1 = False return signals