From f19cf092e98557ecf8c0d160db966e3eedf64641 Mon Sep 17 00:00:00 2001 From: dsyoon Date: Sun, 20 Jul 2025 22:03:06 +0900 Subject: [PATCH] init --- README.md | 37 +++++++++++++++++++++++++++++++------ config.py | 2 ++ stock_monitor.py | 18 +++++++++++++++--- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0cb3869..2c0b339 100644 --- a/README.md +++ b/README.md @@ -27,17 +27,42 @@ - 단/중/장기 이동평균선(MA5/20/60) - 거래량 MA5 4. **매수 후보 판정** (`check_buy_signals`) - - 볼린저 하단 근접도 < `BOLLINGER_THRESHOLD` (기본 0.10) - - RSI < 30 (과매도) - - MACD 골든크로스 - - MA5가 MA20 상향 돌파 - - 거래량 급증(현재 > MA5 × 1.5) - 위 조건 중 ① Bollinger & RSI 동시 충족 **또는** ② 최소 2개 이상(+Bollinger 또는 RSI 포함) 만족 시 `buy=True`. +- *아래 새로운 “매수 후보 전략” 섹션 참조* 5. **알림 발송** (`send_*_telegram_message`) multiprocessing Pool을 이용해 다중 메시지를 병렬로 전송합니다. --- +## 매수 후보 전략 + +| 신호 | 변수명 | 조건 | 의미 | +|------|--------|------|------| +| 볼린저 하단 근접 | `bb_signal` | `(현재가 - LowerBand) / (UpperBand - LowerBand) < BOLLINGER_THRESHOLD` | 밴드 하단(과매도 영역) 접근 | +| RSI 과매도 | `rsi_signal` | `RSI < 30` | 추세 과매도 | +| MACD 골든크로스 | `macd_signal` | `이전 MACD < 이전 Signal` **AND** `현재 MACD > 현재 Signal` | 모멘텀 전환 | +| 이동평균 골든크로스 | `ma_signal` | `이전 MA5 < 이전 MA20` **AND** `현재 MA5 ≥ 현재 MA20` | 단기 추세 ↗ 전환 | +| 거래량 급증 | `volume_signal` | `현재 거래량 > MA5 Volume × 1.5` | 수급 증가 | +| **U자 반등 돌파** | `breakout_signal` | ① 최근 `BREAKOUT_LOOKBACK`(30)개 캔들 동안 최고·최저가 차이가 `BUY_THRESHOLD`(15 %) 이상 하락 → ② **현재가가 그 최고가 돌파** | 하락 후 반등의 추세 전환 확인 | + +### 최종 매수 후보 결정 로직 +```text +if breakout_signal: + buy = True # U자 반등 돌파 단독으로도 매수 후보 +else: + # ① 볼린저 + RSI 동시, 또는 ② (신호 ≥ 2개) & (볼린저 또는 RSI 포함) + buy = (bb_signal and rsi_signal) or (signal_count >= 2 and (bb_signal or rsi_signal)) +``` +*`signal_count` = 위 6개 신호 중 True 개수* + +### 메시지 구성 +- `🛒` : 최종 `buy=True`일 때 메시지 맨 앞에 부착 +- `📊신호(n):` 뒤에 활성화된 신호 목록 + - 볼린저/RSI/MACD/MA/거래량/Breakout 각각 표시 + +해당 전략으로 **과매도 바닥근처 매수 기회 + 상승 추세 전환 브레이크아웃** 두 영역을 모두 포착할 수 있습니다. + +--- + ## 스케줄 테이블 (기본값) | 대상 | 실행 시각(서버 기준) | 호출 함수 | |------|----------------------|-----------| diff --git a/config.py b/config.py index caca66d..8f6e43e 100644 --- a/config.py +++ b/config.py @@ -13,6 +13,8 @@ BOLLINGER_STD = 2 # 표준편차 승수 BOLLINGER_THRESHOLD = 0.10 # 하단 밴드 대비 10% 근접 시 알림 BUY_THRESHOLD = 0.15 BREAKOUT_LOOKBACK = 30 # U자 반등 후 돌파 판단에 사용할 과거 캔들 수 (4시간봉 기준 약 5일) +BREAKOUT_WEEK_LOOKBACK = 42 # 4시간봉 1주일 ≒ 42개 +BREAKOUT_WEEK_LIMIT = 0.05 # 1주일 대비 5% 미만 상승 조건 KR_COINS = { "ADA": "ADA", diff --git a/stock_monitor.py b/stock_monitor.py index 3fd7bf8..0e421b6 100644 --- a/stock_monitor.py +++ b/stock_monitor.py @@ -112,12 +112,24 @@ def check_buy_signals(symbol, data): # U자 반등 후 이전 고점 돌파 여부 계산 (BREAKOUT) breakout_signal = False - if len(data) >= BREAKOUT_LOOKBACK + 1: + if len(data) >= max(BREAKOUT_LOOKBACK, BREAKOUT_WEEK_LOOKBACK) + 1: + # ① U자 형태 확인 window_close = data['Close'].iloc[-BREAKOUT_LOOKBACK-1:-1] prev_high = window_close.max() prev_low = window_close.min() - # 가격이 충분히 내려갔다가(BUY_THRESHOLD 비율) 다시 이전 고점을 돌파하면 breakout으로 간주 - if prev_high > 0 and (prev_high - prev_low) / prev_high > BUY_THRESHOLD and current_price > prev_high: + + # ② 1주일(42캔들) 전 가격 대비 5% 이상 상승하지 않았는지 체크 + price_week_ago = data['Close'].iloc[-BREAKOUT_WEEK_LOOKBACK-1] + if price_week_ago > 0: + week_change = (current_price - price_week_ago) / price_week_ago + else: + week_change = 1 # 값이 0이면 조건 불충족 처리 + + # ③ 조건 종합: U자+돌파 && 주간 상승률 ≤ 5% + if ( + prev_high > 0 and (prev_high - prev_low) / prev_high > BUY_THRESHOLD and current_price > prev_high + and week_change <= BREAKOUT_WEEK_LIMIT + ): breakout_signal = True # RSI 과매도 신호 (RSI < 30)