방향 전환 (reversal) 신호 추가 — 추세 꺾임 조기 감지
## 동작 직전 5봉 추세 + 현재 캔들의 반대 방향 강한 움직임 + 거래량 동반. reversal_short_signal (상승 -> 하락 전환): - close[t-1] > close[t-5] (직전 5봉 동안 상승했었음) - close[t] < open[t] 이면서 |body|/open >= 0.3% (현재 캔들 강한 음봉) - volume[t] > 직전 5봉 평균 volume * 1.3 (확신 동반) - 5봉 쿨다운 reversal_long_signal (하락 -> 상승 전환): - 위와 대칭 (직전 하락, 현재 강한 양봉) ## 알림 SIG_DEFS 에 등록되어 다른 진입 신호와 동일하게 텔레그램 발사. LONG_SIGNALS / SHORT_SIGNALS 셋에도 포함되어 진입 추적 + 손절가 체크도 동일하게 동작. 라벨: "🔄 롱 전환" / "🔄 숏 전환" ## 검증 (오늘 24h 데이터) - 5m 19:00 숏 전환 -0.78% - 15m 19:00 숏 전환 -1.36% - 30m 19:00 숏 전환 -1.67% - 30m 19:30 롱 전환 +0.55% - 30m 23:00 롱 전환 +0.58% (현재 발화 케이스) - 1h 10:00 롱 전환 +1.59% 기존 진입 신호 (long/short/strong/vol) 가 추세 추종형이라 반전 타이밍을 놓쳤던 문제를 보완 — reversal 신호가 추세 꺾임 시점에 독립 발사. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+28
-9
@@ -55,8 +55,8 @@ BASE = "https://fapi.binance.com"
|
||||
KST = timedelta(hours=9)
|
||||
|
||||
STOP_LOSS_PCT = 0.0075 # 10x 레버리지 기준 ROI -7.5% (= 가격 0.75% 역방향)
|
||||
LONG_SIGNALS = {"strong_long_signal", "long_signal", "vol_long_signal"}
|
||||
SHORT_SIGNALS = {"strong_short_signal", "short_signal", "vol_short_signal"}
|
||||
LONG_SIGNALS = {"strong_long_signal", "long_signal", "vol_long_signal", "reversal_long_signal"}
|
||||
SHORT_SIGNALS = {"strong_short_signal", "short_signal", "vol_short_signal", "reversal_short_signal"}
|
||||
TF_LABEL_MAP = {
|
||||
"1m": "1분봉", "3m": "3분봉", "5m": "5분봉",
|
||||
"15m": "15분봉", "30m": "30분봉",
|
||||
@@ -80,13 +80,15 @@ def send_telegram(message: str):
|
||||
print(f"[텔레그램 오류] {e}")
|
||||
|
||||
SIG_DEFS = [
|
||||
("strong_long_signal", "strong_long", "🟢 강한 롱", "long"),
|
||||
("strong_short_signal", "strong_short", "🔴 강한 숏", "short"),
|
||||
("long_signal", "long", "🔼 일반 롱", "long"),
|
||||
("short_signal", "short", "🔽 일반 숏", "short"),
|
||||
("vol_long_signal", "vol_long", "🔼 볼륨 롱", "long"),
|
||||
("vol_short_signal", "vol_short", "🔽 볼륨 숏", "short"),
|
||||
("short_caution_signal","short_caution","⚠️ 숏 주의", "caution"),
|
||||
("strong_long_signal", "strong_long", "🟢 강한 롱", "long"),
|
||||
("strong_short_signal", "strong_short", "🔴 강한 숏", "short"),
|
||||
("long_signal", "long", "🔼 일반 롱", "long"),
|
||||
("short_signal", "short", "🔽 일반 숏", "short"),
|
||||
("vol_long_signal", "vol_long", "🔼 볼륨 롱", "long"),
|
||||
("vol_short_signal", "vol_short", "🔽 볼륨 숏", "short"),
|
||||
("reversal_long_signal", "rev_long", "🔄 롱 전환", "long"),
|
||||
("reversal_short_signal","rev_short", "🔄 숏 전환", "short"),
|
||||
("short_caution_signal", "short_caution","⚠️ 숏 주의", "caution"),
|
||||
]
|
||||
|
||||
def check_and_alert(df, symbol, interval):
|
||||
@@ -385,6 +387,23 @@ def compute_signals(df, interval="5m"):
|
||||
else:
|
||||
df["short_caution_signal"] = False
|
||||
|
||||
# 방향 전환 감지: 직전 5봉의 추세 방향과 현재 캔들 방향이 반대 + 강한 폭 + 거래량 동반.
|
||||
# - 추세 판단: close[t-1] vs close[t-5] (현재 캔들 제외, 직전까지의 흐름)
|
||||
# - 현재 캔들 강도: |close-open|/open >= 0.3% (작은 캔들 노이즈 차단)
|
||||
# - 거래량: 직전 5봉 평균의 1.3배 이상 (확신)
|
||||
prior_close = df["close"].shift(1)
|
||||
prior_close_5 = df["close"].shift(5)
|
||||
was_up = prior_close > prior_close_5
|
||||
was_down = prior_close < prior_close_5
|
||||
candle_body_pct = (df["close"] - df["open"]) / df["open"].replace(0, float("nan"))
|
||||
vol_avg5 = df["volume"].rolling(5).mean().shift(1)
|
||||
vol_strong = df["volume"] > vol_avg5 * 1.3
|
||||
rev_short_raw = was_up & (candle_body_pct < -0.003) & vol_strong
|
||||
rev_long_raw = was_down & (candle_body_pct > 0.003) & vol_strong
|
||||
# 5봉 쿨다운 (연쇄 발화 방지)
|
||||
df["reversal_short_signal"] = rev_short_raw & (rev_short_raw.rolling(5, min_periods=1).sum().shift(1).fillna(0) == 0)
|
||||
df["reversal_long_signal"] = rev_long_raw & (rev_long_raw.rolling(5, min_periods=1).sum().shift(1).fillna(0) == 0)
|
||||
|
||||
return df
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user