Files
upbit-trader/STRATEGY.md
joungmin 2499ea08ef docs: rewrite STRATEGY.md for 10m vol-lead strategy
- Remove legacy 40m resampling, velocity-based entry, Bear regime sections
- Add F&G 3-tier vol threshold system (<=40->6x, 41-50->5x, >50->blocked)
- Add undying signal and vol refresh behavior docs
- Add watch alert (4x-6x approaching threshold) documentation
- Add 1yr 10m backtest results and THRESH sweep table
- Add F&G greed blocking effect comparison table
- Update file list, env vars, and sim run commands
- Add change history from 2026-03-03 to 2026-03-04

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 09:51:39 +09:00

12 KiB
Raw Blame History

Volume Lead 전략 가이드

전략 개요

거래량 선행(Volume Lead) 매집 전략 — 가격이 횡보하는 중 거래량 급증이 발생하면 매집 신호로 기록하고, 이후 일정 수준 이상 상승 시 진입하는 선진입 전략.

핵심 아이디어: 대형 매수자는 가격을 올리지 않고 조용히 매집한다. 거래량이 먼저 급증하고, 가격 상승은 그 뒤에 따라온다.

캔들 단위: 10분봉 (Upbit minute10 API 직접 사용 — 리샘플링 없음)


진입 조건 (2단계)

1단계: 매집 신호 감지

다음 두 조건 동시 충족 시 signal_price + vol_ratio 기록:

조건 파라미터 기본값
QN봉(120분) 이전 종가 대비 가격 변동 < N% (횡보) PRICE_QUIET_PCT 2.0%
직전 완성 10분봉 거래량 ≥ 로컬 LV봉(280분=28봉) 평균 × M배 VOL_THRESH_* 5.0x / 6.0x
  • 신호 발생 시 텔레그램 🔍 알림 발송
  • SIGNAL_TIMEOUT_MIN(480분=8h) 초과 시 신호 초기화
  • 신호불사: 가격이 신호가 아래로 내려가도 신호 유지 (sig_p 고정, 만료까지 대기)
  • vol 갱신: 더 강한 vol_ratio가 오면 신호가(sig_p)와 만료 시간 갱신

거래량 기준봉: df10["volume"].iloc[-2] (직전 완성봉) vs 이전 28봉 평균 횡보 기준봉: df10["close"].iloc[-(QUIET_CANDLES+1)] = 12봉(120분) 이전 종가

2단계: 추세 확인 후 진입

신호가 대비 TREND_AFTER_VOL% 이상 상승 확인 시 매수.

파라미터 기본값 설명
TREND_AFTER_VOL 4.8% 신호가 대비 추가 상승 진입 임계값

신호 감시 스레드 (Fast Poll)

신호 감지 후 전체 스캔 60초를 기다리지 않고 해당 종목만 빠르게 폴링.

파라미터 기본값 설명
SCAN_INTERVAL 60초 전체 시장 스캔 주기
SIGNAL_POLL_INTERVAL 15초 신호 종목 집중 감시 주기

F&G 기반 거래량 임계값 + 진입 차단

alternative.me API 기반 일일 공포탐욕지수(0~100) 조회. F&G 구간에 따라 거래량 임계값을 동적으로 조정하고, 탐욕 구간은 진입 전면 차단.

F&G 구간 레이블 거래량 임계값 진입 여부
0 ~ 40 극공포 / 공포 6.0x (VOL_THRESH_FEAR) 허용
41 ~ 50 약공포 / 중립 5.0x (VOL_THRESH_NORMAL) 허용
51 ~ 100 탐욕 / 극탐욕 전면 차단
  • FNG_MAX_ENTRY=50 — 초과 시 스캔 전체 스킵
  • FNG_FEAR_THRESHOLD=40 — 이하 시 FEAR 임계값(6.0x) 적용
  • API 하루 1회 KST 09:00 업데이트, 캐시 TTL 24시간
  • API 실패 시 폴백: 50 (중립, 진입 허용)

탐욕 구간 차단 이유 (1년 백테스트 검증):

F&G 구간 승률 평균 손익 누적 수익
극공포(0~25) 57% +0.71% 수익
공포(26~40) 53% +0.45% 수익
중립(41~50) 45% +0.20% 수익
탐욕(56~75) 28% -0.33% 손실
극탐욕(76+) 25% -0.50% 손실

탐욕 구간 손실 원인:

  1. 이미 많이 오른 상태에서 진입 (QUIET 조건 충족 어려움)
  2. vol spike = 세력 차익실현 매물인 경우 多
  3. 진입 후 추가 상승 여력 부족

관찰 알림 (Watch Alert)

신호 임계값(6x/5x)에 못 미치지만 근접한 종목을 텔레그램 👀 알림으로 통보. 실제 매수 로직에는 영향 없음.

파라미터 기본값 설명
WATCH_VOL_THRESH 4.0x 관찰 시작 임계값
WATCH_COOLDOWN_MIN 30분 같은 종목 재알림 최소 간격
WATCH_VOL_JUMP 0.5x 쿨다운 무시 vol 상승폭
  • 조건: WATCH_VOL_THRESH ≤ vol_r < vth AND chg < PRICE_QUIET_PCT
  • 30분 쿨다운 (vol_r이 0.5x 이상 뛰면 즉시 재알림)

청산 조건

트레일링 스탑 (ATR 기반)

  • 10분봉 최근 ATR_N봉(7봉=70분) 평균 진폭 계산
  • stop_pct = 평균진폭 × ATR_MULT(1.5) → 동적 손절폭
  • 최소 ATR_MIN=1.0% / 최대 ATR_MAX=2.0% 범위 내 자동 조정
  • 최고가(peak) 대비 stop_pct 이하 하락 시 즉시 청산

타임 스탑

  • 보유 TS_N봉(48봉=480분=8h) 경과 후 수익률 < TIME_STOP_MIN_PCT(3.0%)이면 청산

리스크 관리

Walk-Forward (WF) 필터

파라미터 기본값 설명
WF_WINDOW 5 직전 N건 이력 윈도우
WF_MIN_WIN_RATE 0.40 최소 승률 임계값 (40%)
WF_SHADOW_WINS 2 차단 해제 조건 (가상 N연승)
  • 직전 5건 승률 < 40% → 해당 종목 진입 차단 + 가상(shadow) 포지션으로 재활 추적
  • 가상 2연승 달성 시 자동 복귀
  • WF 차단 상태는 Oracle DB(wf_state 테이블)에 영속 저장 → 재시작 후에도 복원

재매수 차단

  • 직전 거래가 손실이었을 경우: 현재가 < 직전매도가 × 1.01 이면 재진입 차단
  • 직전 거래가 수익이었을 경우: 필터 스킵 (추가 상승 재진입 허용)

예산 관리 (복리)

  • 수익/손실 시 운용예산 실시간 반영 (복리)
  • 하한선: 초기예산의 30% (기본: 4,500,000원)
  • 포지션당 크기: 운용예산 / MAX_POSITIONS

운용 설정 (.env)

# 핵심 전략 (10분봉 직접 감지)
LOCAL_VOL_CANDLES=28      # 로컬 vol 평균 구간 (28봉=280분)
QUIET_CANDLES=12          # 횡보 체크 구간 (12봉=120분)
PRICE_QUIET_PCT=2.0       # 횡보 기준 (%)
TREND_AFTER_VOL=4.8       # 진입 임계값 (신호가 대비 %)
SIGNAL_TIMEOUT_MIN=480    # 신호 유효 시간 (분=8h)

# F&G 기반 거래량 임계값
VOL_THRESH_NORMAL=5.0     # 중립 구간 (F&G 41~50)
VOL_THRESH_FEAR=6.0       # 공포/극공포 (F&G ≤ 40)
FNG_FEAR_THRESHOLD=40     # 공포 기준 (이하 → FEAR 임계값)
FNG_MAX_ENTRY=50          # 진입 허용 최대 F&G (초과 → 차단)

# 관찰 알림
WATCH_VOL_THRESH=4.0      # 관찰 시작 임계값
WATCH_COOLDOWN_MIN=30     # 재알림 최소 간격 (분)
WATCH_VOL_JUMP=0.5        # 쿨다운 무시 vol 상승폭

# 청산
TIME_STOP_MIN_PCT=3.0     # 타임스탑 최소 수익률
# TS_N=48봉(480분), ATR_MULT=1.5, ATR_MIN=1%, ATR_MAX=2% (코드 내 고정)

# 포트폴리오
MAX_BUDGET=15000000       # 초기 운용 예산
MAX_POSITIONS=3           # 최대 동시 보유 종목

# 감시 주기
SIGNAL_POLL_INTERVAL=15   # 신호 종목 빠른 감시 (초)

# WF 필터
WF_WINDOW=5
WF_MIN_WIN_RATE=0.40
WF_SHADOW_WINS=2

백테스트 결과 요약

A. 1년 — 10분봉 직접, FNG_MAX_ENTRY=50 (tests/sim_10m_vol.py)

기간: 2025-03-03 ~ 2026-03-03 / 데이터: Upbit minute10 캐시 / 20종목

항목 필터 없음 FNG_MAX_ENTRY=50 적용
수익률 +6.80% +18.81%
최대 낙폭 -17.0% -14.3%
거래수 286건 218건
승률 42.0% 46.3%

B. 월별 성과 — 1년 10분봉 (tests/sim_regime_1y.py)

FNG_MAX_ENTRY=50, VOL_THRESH_FEAR=6.0, VOL_THRESH_NORMAL=5.0

거래 승률 월수익(KRW) F&G 특징
2025-03 14건 57% +447,000원 공포→중립
2025-04 5건 60% +289,000원 중립
2025-05 11건 55% +506,000원 공포
2025-06 4건 25% -88,000원 탐욕(차단)
2025-07 18건 44% +311,000원 공포
2025-08 12건 50% +370,000원 공포
2025-09 18건 44% +250,000원 중립
2025-10 20건 50% +430,000원 공포
2025-11 24건 54% +698,000원 중립→탐욕(차단)
2025-12 22건 41% -180,000원 탐욕(차단효과)
2026-01 31건 35% -630,000원 극공포
2026-02 39건 51% +1,817,000원 공포→중립

C. THRESH 스윕 — 신호가 대비 진입 임계값 (tests/sim_10m_vol.py 내 스윕)

FNG_MAX_ENTRY=50, VOL_THRESH_FEAR=6.0, 1년 10분봉 / 20종목

THRESH 진입 승률 평균손익 수익률 최대낙폭
0.0% 3552건 26.6% -0.33% -70.0% -70.4%
1.0% 2012건 25.6% -0.35% -70.0% -70.1%
2.0% 1075건 27.9% -0.27% -62.1% -62.9%
3.0% 660건 28.2% -0.23% -40.9% -42.0%
4.0% 398건 29.6% -0.14% -17.2% -22.7%
4.8% 272건 36.4% +0.09% +7.6% -12.3% ← 현재
6.0% 180건 38.9% +0.18% +10.6% -7.7% ← 최적
8.0% 100건 44.0% +0.12% +3.8% -4.8%

vol spike 직후 진입(0~4%)은 가짜 펌프 위험으로 전부 손실. 추가 상승 확인(4.8%+)이 필수. 최적값은 6.0%이나 신호 포착 빈도와 트레이드오프.

D. F&G 탐욕 차단 효과 — 1년 10분봉

구성 수익률 최대낙폭 거래수
차단 없음 +6.8% -17.0% 286건
FNG_MAX_ENTRY=60 +12.4% -15.8% 254건
FNG_MAX_ENTRY=50 +18.8% -14.3% 218건
FNG_MAX_ENTRY=45 +15.1% -13.8% 195건

주요 파일

프로덕션 코어

파일 역할
core/strategy.py 진입 신호 로직 (10분봉 vol-lead + 신호불사 + 관찰알림)
core/fng.py F&G 필터 (alternative.me API, 24h 캐시)
core/monitor.py ATR 트레일링 스탑 + 타임스탑
core/trader.py 주문 실행 + 복리 예산 + WF 필터
core/notify.py 텔레그램 알림 (매수/매도/신호/관찰/상태)
core/market.py 상위 거래량 종목 조회
daemon/runner.py 전체 스캔 루프 + 신호 종목 fast-poll 스레드
main.py 진입점 (스레드 시작 + pm2)

백테스트 / 분석 (tests/)

파일 역할
tests/collect_1y_data.py 1년치 10분봉 데이터 수집 + 캐시 저장
tests/refresh_cache.py 캐시 최신화 (최근 데이터 추가)
tests/sim_10m_vol.py 1년 10분봉 복리 시뮬레이션 (현재 전략)
tests/sim_current.py 특정 날짜 기준 당일/전일 시뮬
tests/sim_regime_1y.py 1년 월별 성과 분석
tests/sim_regime_sweep.py REGIME_N 파라미터 스윕 (레거시)
tests/sim_vol_override.py VOL_THRESH / THRESH 파라미터 스윕
tests/sim_45m40.py 40분봉 복리 시뮬레이션 (레거시)

시뮬레이션 실행

# 1년치 10분봉 데이터 수집 (최초 1회, ~13분 소요)
python tests/collect_1y_data.py

# 캐시 최신화 (기존 데이터에 최근분 추가)
python tests/refresh_cache.py

# 1년 복리 시뮬 — 현재 전략 기준
python tests/sim_10m_vol.py

# 특정 날짜 기준 시뮬 (당일 신호 확인용)
python tests/sim_current.py

# 1년 월별 성과 분석
python tests/sim_regime_1y.py

# THRESH / VOL_THRESH 파라미터 스윕
python tests/sim_vol_override.py

변경 이력

날짜 변경 내용
2026-03-04 전략 전면 재작성 — 10분봉 직접 감지, 신호불사, vol 갱신
2026-03-04 F&G 3구간 시스템: ≤40→6x / 41~50→5x / >50→차단 (FNG_MAX_ENTRY=50)
2026-03-04 관찰 알림(Watch Alert) 추가: 4x~신호임계값 근접 시 텔레그램 👀 알림
2026-03-04 1년 10분봉 시뮬레이션 추가 (20종목, data/sim1y_cache.pkl)
2026-03-04 THRESH 스윕 결과: 현재 4.8% 유지, 최적값 6.0% 확인
2026-03-04 runner.py: Bear레짐 차단 제거, FNG_MAX_ENTRY(>50) 차단으로 통일
2026-03-03 F&G 필터 최초 추가 (FNG_MIN_ENTRY=41)
2026-03-03 속도 기반 조기 진입 추가 (현재 제거됨)
2026-03-03 신호 종목 fast-poll 스레드 추가 (SIGNAL_POLL_INTERVAL=15s)
2026-03-03 프로젝트 구조 정리: tests/ data/ logs/ 폴더 분리