Harden scheduler and stale breakout reentry

This commit is contained in:
whdwo
2026-06-15 18:52:42 +09:00
parent eac4ece01e
commit 901243348e
16 changed files with 181 additions and 61 deletions
+20 -4
View File
@@ -47,6 +47,7 @@ class VolatilityBreakout:
self._entry_times: dict = {} # ticker → 마지막 진입 datetime (쿨다운 추적)
self._exit_times: dict = {} # ticker -> 마지막 최종 청산 datetime (쿨다운 추적)
self._tp_closed_tickers: set[str] = set() # TP로 전량 청산된 당일 재진입 차단
self._rebreak_required_tickers: set[str] = set() # TIME/FORCE 후 목표가 재돌파 대기
# ── AI 컨텍스트 로드 ──
@@ -103,6 +104,9 @@ class VolatilityBreakout:
if not prev:
logger.info(f"목표가 제외({ticker}): 전일 데이터 없음")
return
if open_price <= 0:
logger.info(f"목표가 제외({ticker}): 당일 시가 미확정({open_price})")
return
if prev["amount"] < MIN_TRADE_AMOUNT:
logger.info(
f"목표가 제외({ticker}): 전일 거래대금 {prev['amount']/1e8:.0f}"
@@ -126,8 +130,10 @@ class VolatilityBreakout:
exit_time = exit_time or datetime.now()
if reason in ("TIME", "FORCE"):
self._exit_times[ticker] = exit_time
self._rebreak_required_tickers.add(ticker)
elif reason in ("TP1", "TP2"):
self._tp_closed_tickers.add(ticker)
self._rebreak_required_tickers.discard(ticker)
# ── 진입 신호 판단 ──
@@ -151,6 +157,16 @@ class VolatilityBreakout:
result["reason"] = "TP 당일 재진입 차단"
return result
# 목표가 확인
target = self.targets.get(ticker, 0)
if target <= 0:
result["reason"] = "목표가 없음"
return result
# TIME/FORCE 이후 쿨다운 중이라도 목표가 아래로 내려온 사실은 기록한다.
if ticker in self._rebreak_required_tickers and current_price < target:
self._rebreak_required_tickers.discard(ticker)
# TIME/FORCE 청산 후 쿨다운은 진입 시각이 아니라 청산 시각 기준이다.
last_exit = self._exit_times.get(ticker)
if last_exit is not None:
@@ -159,10 +175,10 @@ class VolatilityBreakout:
result["reason"] = f"재진입 쿨다운 ({elapsed:.0f}분 / {TICKER_REENTRY_COOLDOWN_MIN}분)"
return result
# 목표가 확인
target = self.targets.get(ticker, 0)
if target <= 0:
result["reason"] = "목표가 없음"
# TIME/FORCE 청산 뒤에는 남아 있는 당일 돌파 신호를 그대로 재사용하지 않는다.
# 목표가 아래로 식은 뒤 다시 돌파해야 새로운 진입 신호로 인정한다.
if ticker in self._rebreak_required_tickers:
result["reason"] = f"재돌파 대기 ({current_price:,} >= {target:,.0f})"
return result
# 기술적 조건: 현재가 >= 목표가