일일 리포트에 2배 시간 검증 두 번째 메시지 추가
## 동작 자정 KST 발송 시 텔레그램 알림 2개를 연속 발송: 1. 1배 시간 (다음 봉 검증) — 기존 로직, 신호 발화 캔들의 다음 캔들에서 반대 신호가 뜨면 실패. 2. 2배 시간 (2번째 봉 검증) — 신규, 신호 발화 캔들의 2개 뒤 캔들에서 반대 신호가 뜨면 실패. 예: 5분봉 14:00 숏 진입 신호 1배 검증: 14:05 캔들에 반대(롱)신호 -> F 2배 검증: 14:10 캔들에 반대(롱)신호 -> F ## 구현 - _count_daily_signals_per_type 에 offset 파라미터 추가 (기본 1). - _build_daily_report_lines 헬퍼 추출 — 동일 dfs 와 cutoff 로 offset 만 바꿔서 두 메시지 본문 생성. - send_daily_report 에서 시간봉별 df 한 번만 빌드 후 1x / 2x 두 번 포맷 -> 두 메시지 발송 (API 비용 중복 제거). ## 메시지 헤더 변화 이전: "📊 24시간 신호 통계 (BTCUSDT)" 이후: "📊 24시간 신호 통계 (BTCUSDT) - 1배 시간 (다음 봉 검증)" "📊 24시간 신호 통계 (BTCUSDT) - 2배 시간 (2번째 봉 검증)" Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+29
-17
@@ -689,40 +689,37 @@ DAILY_REPORT_SIGNAL_LABELS = [
|
||||
("vol_short_signal", "볼륨 숏"),
|
||||
]
|
||||
|
||||
def _count_daily_signals_per_type(df, cutoff_kst):
|
||||
def _count_daily_signals_per_type(df, cutoff_kst, offset=1):
|
||||
result = {sig: [0, 0] for sig, _ in DAILY_REPORT_SIGNAL_LABELS}
|
||||
if df is None or df.empty or "open_time" not in df.columns:
|
||||
return result
|
||||
recent = df[df["open_time"] >= cutoff_kst].reset_index(drop=True)
|
||||
if len(recent) < 2:
|
||||
if len(recent) <= offset:
|
||||
return result
|
||||
for long_sig, short_sig in DAILY_REPORT_PAIRS:
|
||||
if long_sig not in recent.columns or short_sig not in recent.columns:
|
||||
continue
|
||||
for i in range(len(recent) - 1):
|
||||
for i in range(len(recent) - offset):
|
||||
row = recent.iloc[i]
|
||||
nxt = recent.iloc[i + 1]
|
||||
future = recent.iloc[i + offset]
|
||||
if bool(row.get(long_sig, False)):
|
||||
result[long_sig][0] += 1
|
||||
if bool(nxt.get(short_sig, False)):
|
||||
if bool(future.get(short_sig, False)):
|
||||
result[long_sig][1] += 1
|
||||
if bool(row.get(short_sig, False)):
|
||||
result[short_sig][0] += 1
|
||||
if bool(nxt.get(long_sig, False)):
|
||||
if bool(future.get(long_sig, False)):
|
||||
result[short_sig][1] += 1
|
||||
return result
|
||||
|
||||
def send_daily_report(symbol="BTCUSDT"):
|
||||
now_kst = (datetime.now(timezone.utc) + KST).replace(tzinfo=None)
|
||||
cutoff_kst = now_kst - timedelta(hours=24)
|
||||
lines = [f"📊 24시간 신호 통계 ({symbol})", f"기준: {now_kst.strftime('%Y-%m-%d %H:%M')} KST"]
|
||||
def _build_daily_report_lines(dfs, cutoff_kst, now_kst, symbol, offset, header_suffix):
|
||||
lines = [
|
||||
f"📊 24시간 신호 통계 ({symbol}) - {header_suffix}",
|
||||
f"기준: {now_kst.strftime('%Y-%m-%d %H:%M')} KST",
|
||||
]
|
||||
for tf in DAILY_REPORT_TIMEFRAMES:
|
||||
try:
|
||||
df = _build_signal_df(symbol, tf, DAILY_REPORT_KLINES_LIMIT[tf])
|
||||
counts = _count_daily_signals_per_type(df, cutoff_kst)
|
||||
except Exception as e:
|
||||
print(f"[일일리포트 {tf} 오류] {e}")
|
||||
counts = {sig: [0, 0] for sig, _ in DAILY_REPORT_SIGNAL_LABELS}
|
||||
df = dfs.get(tf)
|
||||
counts = _count_daily_signals_per_type(df, cutoff_kst, offset=offset)
|
||||
lines.append("")
|
||||
lines.append(f"[{TF_LABEL_MAP.get(tf, tf)}]")
|
||||
total_all = 0
|
||||
@@ -736,7 +733,22 @@ def send_daily_report(symbol="BTCUSDT"):
|
||||
passed_all = total_all - failed_all
|
||||
rate = (passed_all / total_all * 100) if total_all > 0 else 0.0
|
||||
lines.append(f"합계: {passed_all}T {failed_all}F (승률 {rate:.2f}%)")
|
||||
send_telegram("\n".join(lines))
|
||||
return "\n".join(lines)
|
||||
|
||||
def send_daily_report(symbol="BTCUSDT"):
|
||||
now_kst = (datetime.now(timezone.utc) + KST).replace(tzinfo=None)
|
||||
cutoff_kst = now_kst - timedelta(hours=24)
|
||||
dfs = {}
|
||||
for tf in DAILY_REPORT_TIMEFRAMES:
|
||||
try:
|
||||
dfs[tf] = _build_signal_df(symbol, tf, DAILY_REPORT_KLINES_LIMIT[tf])
|
||||
except Exception as e:
|
||||
print(f"[일일리포트 {tf} 데이터 오류] {e}")
|
||||
dfs[tf] = None
|
||||
msg_1x = _build_daily_report_lines(dfs, cutoff_kst, now_kst, symbol, offset=1, header_suffix="1배 시간 (다음 봉 검증)")
|
||||
send_telegram(msg_1x)
|
||||
msg_2x = _build_daily_report_lines(dfs, cutoff_kst, now_kst, symbol, offset=2, header_suffix="2배 시간 (2번째 봉 검증)")
|
||||
send_telegram(msg_2x)
|
||||
|
||||
_last_report_date = None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user