# Volume Lead 전략 가이드 ## 전략 개요 **거래량 선행(Volume Lead) 매집 전략** — 가격이 횡보하는 중 거래량 급증이 발생하면 매집 신호로 기록하고, 이후 일정 수준 이상 상승 시 진입하는 선진입 전략. > 핵심 아이디어: 대형 매수자는 가격을 올리지 않고 조용히 매집한다. > 거래량이 먼저 급증하고, 가격 상승은 그 뒤에 따라온다. **캔들 단위: 40분봉** (Upbit `minute10` API로 수신 후 인메모리 40분 리샘플링) --- ## 진입 조건 (2단계) ### 1단계: 매집 신호 감지 다음 두 조건 동시 충족 시 `signal_price` 기록: | 조건 | 파라미터 | 기본값 | |------|----------|--------| | 2h 가격 변동 < N% (횡보) | `PRICE_QUIET_PCT` | 2.0% | | 직전 40분봉 거래량 ≥ 로컬 5h(7봉) 평균 × M배 | `VOLUME_MULTIPLIER` | 2.0x | - 신호 발생 시 텔레그램 알림 발송 - `SIGNAL_TIMEOUT_H` 내 진입 조건 미달 시 신호 초기화 (기본: 8h) - 신호가 이하 하락 시 즉시 초기화 (매집 실패 판단) > **2h 횡보 체크**: Oracle DB에 저장된 실시간 가격 기록을 조회 (`get_price_n_hours_ago`) > **거래량 체크**: `minute10` → 40분봉 resample → 직전 완성봉 vs 이전 7봉 평균 ### 2단계: 추세 확인 후 진입 `signal_price` 대비 +`TREND_AFTER_VOL`% 이상 상승 확인 시 매수: | 파라미터 | 기본값 | 설명 | |----------|--------|------| | `TREND_AFTER_VOL` | 4.8% | 신호가 대비 진입 임계값 | --- ## 청산 조건 ### 트레일링 스탑 (ATR 기반) - `minute10` → 40분봉 resample 후 최근 7봉(≈5h)의 평균 진폭 계산 - ATR = 평균진폭 × 1.5 계수 → 동적 손절폭 산출 - 최소 1.0% / **최대 2.0%** 범위 내 자동 조정 - 최고가 대비 손절폭 이하 하락 시 즉시 청산 - ATR 캐시: 40분마다 갱신 (캐시 TTL=2400초) ### 타임 스탑 - 보유 `TIME_STOP_HOURS`h 경과 후 수익률 < `TIME_STOP_MIN_GAIN_PCT`% 이면 청산 - 기본값: 8시간 경과 / 수익률 3% 미만 --- ## 리스크 관리 ### Walk-Forward (WF) 필터 | 파라미터 | 기본값 | 설명 | |----------|--------|------| | `WF_WINDOW` | 4 | 이력 윈도우 (직전 N건) — 4연패 시 차단 | | `WF_MIN_WIN_RATE` | 0.01 | 최소 승률 임계값 (1%) | | `WF_SHADOW_WINS` | 2 | 차단 해제 조건 (가상 N연승) | - 직전 2건 모두 손실 → 해당 종목 진입 차단 - 차단 후 가상 추적으로 2연승 달성 시 자동 복귀 - **WF 차단 상태는 Oracle DB(`wf_state` 테이블)에 영속 저장** → 재시작 후에도 복원 ### 예산 관리 (복리) - 수익 발생 시: `운용예산 = 초기예산 + 누적수익` (복리 증가) - 손실 발생 시: `운용예산 = 초기예산 + 누적수익` (차감) - 하한선: 초기예산의 30% (기본: 4,500,000원) - 포지션당 크기: `운용예산 / MAX_POSITIONS` --- ## 시장 레짐 적응 | 레짐 | BTC 1h 변동 | 거래량 기준 | |------|------------|------------| | BULL | +5% 이상 | 1.5x | | NEUTRAL | ±5% 이내 | 2.0x | | BEAR | -5% 이하 | 진입 차단 | - BEAR 레짐 감지 시 신규 진입 전면 차단 - 레짐별 `vol_mult` 조정으로 민감도 제어 --- ## 운용 설정 (.env) ```env # 핵심 전략 PRICE_QUIET_PCT=2.0 # 2h 횡보 기준 (%) TREND_AFTER_VOL=4.8 # 진입 임계값 (신호가 대비 %) SIGNAL_TIMEOUT_H=8.0 # 신호 유효 시간 (h) VOLUME_MULTIPLIER=2.0 # 거래량 배수 기준 # 청산 TIME_STOP_HOURS=8 # 타임스탑 보유 시간 TIME_STOP_MIN_GAIN_PCT=3 # 타임스탑 최소 수익률 # 포트폴리오 MAX_BUDGET=15000000 # 초기 운용 예산 MAX_POSITIONS=3 # 최대 동시 보유 종목 # WF 필터 WF_WINDOW=2 WF_MIN_WIN_RATE=0.01 WF_SHADOW_WINS=2 ``` --- ## 백테스트 결과 요약 ### A. 365일 — 1h봉, WF 적용 (`sim_365.py`) > 기간: 2025-03-02 ~ 2026-03-02 / 데이터: Oracle DB 1h OHLCV / 20종목 | 항목 | 값 | |------|-----| | 초기 예산 | 15,000,000원 | | 최종 자산 | 29,996,109원 | | 수익률 | **+100%** | | 최대 낙폭 | -3.81% (-57만원) | | 거래수 | 190건 (WF 183건 차단) | | 승률 | 46% | | 월평균 수익 | 약 115만원 | ### B. 45일 — 40분봉, WF + 복리 적용 (`sim_45m40.py`) > 기간: 2026-01-20 ~ 2026-03-02 / 데이터: Upbit minute10 캐시 40분 리샘플링 / 20종목 | 항목 | 값 | |------|-----| | 초기 예산 | 15,000,000원 | | 최종 자산 | 21,684,574원 | | 수익률 | **+44.56%** | | 최대 낙폭 | -3.90% (-585,102원) | | 거래수 | 87건 (WF 3건 차단 / MAX_POS 1건 스킵) | | 승률 | 47.1% | | 월평균 수익 | 약 2,228,000원 | | 월 | 거래 | 승률 | 월수익 | 누적수익 | |----|------|------|--------|---------| | 2026-01 | 17건 | 29% | -160,000원 | -160,000원 | | 2026-02 | 61건 | 49% | +6,217,000원 | +6,057,000원 | | 2026-03 | 9건 | 67% | +627,000원 | +6,685,000원 | > **참고 — 봉 단위별 단순 PnL 합산 비교** (WF 미적용, `interval_sweep.py`) > > | 봉 단위 | 거래수 | 승률 | 누적PnL | 최대낙폭 | > |---------|--------|------|---------|---------| > | 10분 | 180 | 33.9% | +15.8% | -32.6% | > | 20분 | 120 | 36.7% | +31.0% | -16.7% | > | 30분 | 91 | 48.4% | +81.7% | -12.9% | > | **40분** | **91** | **48.4%** | **+119.4%** | **-11.2%** ← 채택 | > | 50분 | 83 | 50.6% | +94.7% | -17.1% | > | 60분 | 65 | 50.8% | +88.3% | -11.9% | ### C. ATR_MAX_STOP 스윕 — 1h봉 기준 (`atr_sweep.py`) > 데이터: Oracle DB 1h OHLCV / 20종목 | ATR_MAX | 승률 | 누적PnL | 최대낙폭 | 평균스탑 | |---------|------|---------|---------|---------| | 1.5% | 52.3% | +442% | -3.2% | 1.49% | | **2.0%** | **50.8%** | **+299%** | **-4.1%** | **1.49%** ← 현재 채택 | | 2.5% | 50.8% | +256% | -5.3% | 1.77% | | 4.0% | 45.9% | -52% | -29.1% | 3.11% | --- ## 주요 파일 | 파일 | 역할 | |------|------| | `core/strategy.py` | 진입 신호 로직 (40분봉 vol-lead) | | `core/monitor.py` | ATR 트레일링 스탑 + 타임스탑 (40분봉 ATR) | | `core/trader.py` | 주문 실행 + 복리 예산 관리 | | `core/market_regime.py` | 시장 레짐 감지 | | `core/price_db.py` | 가격 DB + WF 상태 영속화 | | `ohlcv_db.py` | OHLCV 시계열 DB 캐시 관리 | | `sim_365.py` | 365일 복리 시뮬레이션 (1h봉, DB) | | `sim_45m40.py` | 45일 복리 시뮬레이션 (40분봉, 캐시) | | `atr_sweep.py` | ATR_MAX_STOP 파라미터 스윕 | | `sim10m.py` | 10분봉 vs 1h봉 전략 비교 시뮬 | | `interval_sweep.py` | 봉 단위별 성과 비교 (10/20/30/40/50/60분) | --- ## 시뮬레이션 실행 ```bash # 45일 복리 시뮬 — 40분봉 (현재 전략 기준) python sim_45m40.py # 365일 복리 시뮬 — 1h봉 (DB에서 로드) python sim_365.py # 봉 단위별 비교 (10m 캐시 필요) python interval_sweep.py # ATR_MAX_STOP 스윕 (DB에서 로드) python atr_sweep.py # OHLCV DB 상태 확인 python ohlcv_db.py status # 신규 봉 증분 업데이트 python ohlcv_db.py update ```