# AssetMonitor 주식·코인 모니터링 시스템 ## 개요 `AssetMonitor`는 주식‧ETF 및 암호화폐 시장을 실시간으로 감시하여 Bollinger Band, RSI, MACD, 이동평균(Golden-Cross), 거래량 등을 종합 분석한 **매수 후보(signals)**를 텔레그램으로 통보하는 자동화 봇입니다. **주요 개선사항:** - **데이터 표준화**: 모든 코인에 동일한 기술적 분석 기준 적용 - **순수 기술적 분석**: 날짜 기반 조건 제거, 기술적 지표만 사용 - **강화된 기술적 지표**: 스토캐스틱, MFI, OBV, ATR 등 추가 지표 활용 --- ## 주요 구성 파일 | 파일 | 설명 | |------|------| | `config.py` | ✅ API 토큰, 텔레그램 채널 ID, 볼린저 밴드/임계값, 모니터링 자산 목록(KR_COINS, US_STOCKS, KR_ETFS) 등 전역 설정을 보관합니다. | | `stock_monitor.py` | 시스템의 핵심 로직이 담긴 실행 스크립트입니다.
• 데이터 수집 ⇒ 기술적 지표 계산 ⇒ 매수 신호 판단 ⇒ 메시지 포맷팅/발송
• `schedule` 라이브러리로 정해진 시간마다 작업을 자동 실행합니다. | | `requirements.txt` | 프로젝트 의존 패키지를 명시합니다. | --- ## 데이터 흐름 1. **스케줄 트리거** (`run_schedule`) 지정된 시각에 각 모니터링 함수가 호출됩니다. 2. **데이터 획득** *주식 / ETF*: `FinanceDataReader` *암호화폐*: 빗썸 **240분 봉** Open API 3. **데이터 표준화** (`normalize_data`) - 모든 코인에 동일한 정규화 적용 - 20일 롤링 윈도우 기반 Min-Max 정규화 4. **기술적 지표 계산** (`calculate_technical_indicators`) - Bollinger Band (기간 20, ±2σ) - RSI(14) - MACD(12-26-9) - 단/중/장기 이동평균선(MA5/20/60) - 거래량 MA5 - **추가 지표**: 스토캐스틱, OBV, ATR, MFI 5. **매수 후보 판정** (`check_signals`) - *아래 새로운 "매수 후보 전략" 섹션 참조* 6. **알림 발송** (`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 %) 이상 하락 → ② **현재가가 그 최고가 돌파** | 하락 후 반등의 추세 전환 확인 | | **장기 저항 돌파** | `long_breakout_signal` | 장기간 저항선 돌파 감지 | 장기 추세 전환 | | **스토캐스틱 과매도** | `stoch_signal` | `%K < 20 AND %K > 이전 %K` | 스토캐스틱 과매도 반등 | | **MFI 과매도** | `mfi_signal` | `MFI < 20 AND MFI > 이전 MFI` | 자금 흐름 과매도 반등 | | **OBV 상승** | `obv_signal` | `현재 OBV > 이전 OBV × 1.1` | 거래량 가중 상승 | | **ATR 급증** | `atr_signal` | `현재 ATR > ATR 20일 평균 × 1.5` | 변동성 급증 | ### 최종 매수 후보 결정 로직 ```text if breakout_signal or long_breakout_signal: buy = True # 돌파 신호 단독으로도 매수 후보 else: # ① 볼린저 + RSI 동시, 또는 ② (신호 ≥ 3개) & (볼린저 또는 RSI 포함) buy = (bb_signal and rsi_signal) or (signal_count >= 3 and (bb_signal or rsi_signal)) ``` *`signal_count` = 위 11개 신호 중 True 개수* ### 메시지 구성 - `매수` : 최종 `buy=True`일 때 메시지 맨 앞에 부착 - `신호(n):` 뒤에 활성화된 신호 목록 - 볼린저/RSI/MACD/MA/거래량/Breakout/스토캐스틱/MFI/OBV/ATR 각각 표시 해당 전략으로 **과매도 바닥근처 매수 기회 + 상승 추세 전환 브레이크아웃** 두 영역을 모두 포착할 수 있습니다. --- ## 스케줄 테이블 (기본값) | 대상 | 실행 시각(서버 기준) | 호출 함수 | |------|----------------------|-----------| | KRW 코인 | 매시간 04, 14, 24, 34, 44, 54분 | `monitor_coins()` | | 미국 주식 / ETF | 05:10, 16:30, 23:30 | `monitor_us_stocks()` | | 한국 ETF / 주식 | 07:10, 18:20 | `monitor_kr_stocks()` | > 시간은 `config.py`가 아닌 `stock_monitor.py`의 `run_schedule()` 내부에 하드코딩되어 있습니다. 필요 시 직접 수정하세요. --- ## 설치 방법 1. Python ≥ 3.9 환경을 준비합니다. 2. 저장소를 클론하고 디렉터리로 이동: ```bash $ git clone $ cd AssetMonitor ``` 3. 패키지 설치: ```bash $ pip install -r requirements.txt ``` 4. **보안 키 등록** 민감 정보는 코드에 직접 기록하지 말고 *환경 변수*로 주입하기를 권장합니다. ```bash # zsh 예시 export COIN_TELEGRAM_BOT_TOKEN="" export STOCK_TELEGRAM_BOT_TOKEN="" export COIN_TELEGRAM_CHAT_ID="" export STOCK_TELEGRAM_CHAT_ID="" ``` 또는 `config.py` 내부 상수를 직접 수정할 수 있습니다. --- ## 사용 방법 ```bash $ python monitor_coin.py ``` 스크립트가 백그라운드에서 무한 루프로 동작하며 지정된 시간마다 텔레그램 알림을 전송합니다. ### Docker(선택) 컨테이너 실행 예시: ```dockerfile FROM python:3.11-slim WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD ["python", "stock_monitor.py"] ``` --- ## 커스터마이징 - **자산 목록 추가/삭제**: `config.py`의 `KR_COINS`, `US_STOCKS`, `KR_ETFS` 사전을 편집합니다. - **임계값·기간 조정**: `BOLLINGER_PERIOD`, `BOLLINGER_STD`, `BOLLINGER_THRESHOLD`, `BUY_THRESHOLD` 등 변경. --- ## 한계 및 면책 조항 본 프로젝트는 교육·연구 목적의 오픈소스 예제로, 투자 손실에 대해 어떠한 책임도 지지 않습니다. 실거래에 사용하려면 충분한 검증과 백테스트를 진행하십시오. --- ## 라이선스 MIT (프로젝트 루트의 `LICENSE` 파일 참조, 미존재 시 필요에 따라 추가하세요.)