"""Strategy C: 변동성 돌파 AND 모멘텀 동시 충족 시 매수 신호.""" import logging from .market import get_current_price, get_ohlcv logger = logging.getLogger(__name__) # 변동성 돌파 계수 (래리 윌리엄스 기본값) BREAKOUT_K = 0.5 # 모멘텀 이동평균 기간 MA_PERIOD = 20 # 거래량 급증 배수 VOLUME_MULTIPLIER = 2.0 def check_volatility_breakout(ticker: str) -> bool: """변동성 돌파 조건: 현재가 > 오늘 시가 + 전일 변동폭 × K.""" df = get_ohlcv(ticker, count=2) if df is None or len(df) < 2: return False prev = df.iloc[-2] today = df.iloc[-1] target = today["open"] + (prev["high"] - prev["low"]) * BREAKOUT_K current = get_current_price(ticker) if current is None: return False result = current > target if result: logger.debug(f"[변동성돌파] {ticker} 현재가={current:,.0f} 목표가={target:,.0f}") return result def check_momentum(ticker: str) -> bool: """모멘텀 조건: 현재가 > MA20 AND 오늘 거래량 > 20일 평균 × 2.""" df = get_ohlcv(ticker, count=MA_PERIOD + 1) if df is None or len(df) < MA_PERIOD + 1: return False ma = df["close"].iloc[-MA_PERIOD:].mean() avg_vol = df["volume"].iloc[:-1].mean() # 오늘 제외한 20일 평균 today_vol = df["volume"].iloc[-1] current = get_current_price(ticker) if current is None: return False price_ok = current > ma vol_ok = today_vol > avg_vol * VOLUME_MULTIPLIER result = price_ok and vol_ok if result: logger.debug( f"[모멘텀] {ticker} 현재가={current:,.0f} MA20={ma:,.0f} " f"오늘거래량={today_vol:.1f} 평균={avg_vol:.1f}" ) return result def should_buy(ticker: str) -> bool: """Strategy C: 변동성 돌파 AND 모멘텀 모두 충족 시 True.""" vb = check_volatility_breakout(ticker) if not vb: return False mo = check_momentum(ticker) return vb and mo