From 56159a06956b6b287120ac16ad06570a3ae21180 Mon Sep 17 00:00:00 2001 From: ILSEON-RYU Date: Mon, 4 May 2026 19:52:34 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8A=A6=EC=9D=80=20=EC=A7=84=EC=9E=85=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=E2=80=94=20BB=20position=20+=203=EB=B4=89?= =?UTF-8?q?=20=EB=AA=A8=EB=A9=98=ED=85=80=20=ED=95=84=ED=84=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(long/short/strong=20=EC=A0=84=EC=B2=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 문제 30분봉 19:30 short 신호 발화: 가격이 80.5k -> 78.2k 까지 -2.8% 추락 한 직후 79k 부근 반등 시점에 short 진입 신호. 이미 다 떨어진 후 바닥에서 숏 거는 격 -> 즉시 반등에 stop 맞음. 사용자: "이거 청산이야 늦어". 같은 패턴 long 도 발생: 30분봉 18:30 long 신호 (close 79.8k) 후 80.5k 까지만 짧게 오른 뒤 78.2k 까지 추락. 진입 시점이 이미 충분히 오른 후라 결과적으로 손실. ## 수정 모든 진입 신호(long_signal, short_signal, strong_long_signal, strong_short_signal) 에 두 가지 추가 필터: 1. BB position (close 가 BB 범위의 어느 위치인지, 0=하단 1=상단): - long: 0.5 < bb_pos < 0.7 (중간선 위, 상단 70% 미만) - short: 0.3 < bb_pos < 0.5 (중간선 아래, 하단 30% 위) * 이미 한 끝까지 가버린 후의 늦은 진입 차단 2. 3봉 모멘텀 (close vs close 3봉 전): - long: 최근 3봉 동안 +0.5% 미만 상승 - short: 최근 3봉 동안 -0.5% 미만 하락 * 이미 큰 폭으로 움직인 후의 추격 진입 차단 ## 검증 30분봉 19:30 (이전 strong_short + short 동시 발화): - bb_pos = 0.149 (< 0.3) -> short 차단 - 3봉 모멘텀 = -0.85% (< -0.5%) -> short 차단 - 결과: 모든 short 신호 False ✓ vol_long/vol_short 는 이벤트성 (특정 캔들의 매수/매도 폭증) 이므로 필터 미적용 — 그 시점에 잡는 것이 의도. Co-Authored-By: Claude Opus 4.7 (1M context) --- app_streamlit.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app_streamlit.py b/app_streamlit.py index 8caa226..4ed4302 100644 --- a/app_streamlit.py +++ b/app_streamlit.py @@ -299,8 +299,15 @@ def compute_signals(df, interval="5m"): df["bear_ma"] = ( (df["close"] < df["MA7"]) & (df["MA7"] < df["MA25"]) ) - df["long_signal"] = df["bull_ma_2"] & (df["RSI"] < 60) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & (df["close"] > df["BB_mid"]) & (df["close"] < df["BB_upper"]) - df["short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & (df["close"] < df["BB_mid"]) & (df["close"] > df["BB_lower"]) + # BB position: 0 = BB_lower, 0.5 = BB_mid, 1 = BB_upper. + bb_range = (df["BB_upper"] - df["BB_lower"]).replace(0, float("nan")) + df["bb_pos"] = (df["close"] - df["BB_lower"]) / bb_range + # 최근 3봉 모멘텀: 이미 큰 폭으로 움직인 후의 늦은 진입 차단. + # 롱: 최근 3봉 동안 이미 +0.5% 이상 오른 상태면 차단 (이미 늦음). + # 숏: 최근 3봉 동안 이미 -0.5% 이상 떨어진 상태면 차단. + recent_change_pct = (df["close"] - df["close"].shift(3)) / df["close"].shift(3) * 100 + df["long_signal"] = df["bull_ma_2"] & (df["RSI"] < 60) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & (df["bb_pos"] > 0.5) & (df["bb_pos"] < 0.7) & (recent_change_pct < 0.5) + df["short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & (df["bb_pos"] < 0.5) & (df["bb_pos"] > 0.3) & (recent_change_pct > -0.5) df["long_signal"] = df["long_signal"] & (df["long_signal"].rolling(5, min_periods=1).sum().shift(1).fillna(0) == 0) df["short_signal"] = df["short_signal"] & (df["short_signal"].rolling(5, min_periods=1).sum().shift(1).fillna(0) == 0) @@ -324,8 +331,8 @@ def compute_signals(df, interval="5m"): df["fr_long_favor"] = df["taker_buy_vol"].rolling(3).mean() > df["taker_sell_vol"].rolling(3).mean() df["fr_short_favor"] = df["taker_sell_vol"].rolling(3).mean() > df["taker_buy_vol"].rolling(3).mean() - df["strong_long_signal"] = df["bull_ma_2"] & (df["RSI"] < 65) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & df["oi_up_2"] & df["taker_buy_2"] & df["fr_long_favor"] - df["strong_short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & df["oi_down_2"] & df["taker_sell_2"] & df["fr_short_favor"] + df["strong_long_signal"] = df["bull_ma_2"] & (df["RSI"] < 65) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & df["oi_up_2"] & df["taker_buy_2"] & df["fr_long_favor"] & (df["bb_pos"] > 0.5) & (df["bb_pos"] < 0.7) & (recent_change_pct < 0.5) + df["strong_short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & df["oi_down_2"] & df["taker_sell_2"] & df["fr_short_favor"] & (df["bb_pos"] < 0.5) & (df["bb_pos"] > 0.3) & (recent_change_pct > -0.5) df["strong_long_signal"] = df["strong_long_signal"] & (df["strong_long_signal"].rolling(10, min_periods=1).sum().shift(1).fillna(0) == 0) df["strong_short_signal"] = df["strong_short_signal"] & (df["strong_short_signal"].rolling(10, min_periods=1).sum().shift(1).fillna(0) == 0)