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>
This commit is contained in:
joungmin
2026-03-04 09:51:39 +09:00
parent cfbacdacbc
commit 2499ea08ef

View File

@@ -8,49 +8,36 @@
> 핵심 아이디어: 대형 매수자는 가격을 올리지 않고 조용히 매집한다. > 핵심 아이디어: 대형 매수자는 가격을 올리지 않고 조용히 매집한다.
> 거래량이 먼저 급증하고, 가격 상승은 그 뒤에 따라온다. > 거래량이 먼저 급증하고, 가격 상승은 그 뒤에 따라온다.
**캔들 단위: 40분봉** (Upbit `minute10` API로 수신 후 인메모리 40분 리샘플링) **캔들 단위: 10분봉** (Upbit `minute10` API 직접 사용 — 리샘플링 없음)
--- ---
## 진입 조건 (2단계) ## 진입 조건 (2단계)
### 1단계: 매집 신호 감지 ### 1단계: 매집 신호 감지
다음 두 조건 동시 충족 시 `signal_price` + `vol_ratio` 기록: 다음 두 조건 동시 충족 시 `signal_price` + `vol_ratio` 기록:
| 조건 | 파라미터 | 기본값 | | 조건 | 파라미터 | 기본값 |
|------|----------|--------| |------|----------|--------|
| 2h 가격 변동 < N% (횡보) | `PRICE_QUIET_PCT` | 2.0% | | QN봉(120분) 이전 종가 대비 가격 변동 < N% (횡보) | `PRICE_QUIET_PCT` | 2.0% |
| 직전 40분봉 거래량 ≥ 로컬 5h(7봉) 평균 × M배 | `VOLUME_MULTIPLIER` | 2.0x | | 직전 완성 10분봉 거래량 ≥ 로컬 LV봉(280분=28봉) 평균 × M배 | `VOL_THRESH_*` | 5.0x / 6.0x |
- 신호 발생 시 텔레그램 알림 발송 - 신호 발생 시 텔레그램 🔍 알림 발송
- `SIGNAL_TIMEOUT_H` 내 진입 조건 미달 시 신호 초기화 (기본: 8h) - `SIGNAL_TIMEOUT_MIN`(480분=8h) 초과 시 신호 초기화
- 신호가 이하 하락 시 즉시 초기화 (매집 실패 판단) - **신호불사**: 가격이 신호가 아래로 내려가도 신호 유지 (sig_p 고정, 만료까지 대기)
- **vol 갱신**: 더 강한 vol_ratio가 오면 신호가(sig_p)와 만료 시간 갱신
> **2h 횡보 체크**: Oracle DB에 저장된 실시간 가격 기록을 조회 (`get_price_n_hours_ago`) > **거래량 기준봉**: `df10["volume"].iloc[-2]` (직전 완성봉) vs 이전 28봉 평균
> **거래량 체크**: `minute10` → 40분봉 resample → 직전 완성봉 vs 이전 7봉 평균 > **횡보 기준봉**: `df10["close"].iloc[-(QUIET_CANDLES+1)]` = 12봉(120분) 이전 종가
### 2단계: 추세 확인 후 진입 (거리 기반 OR 속도 기반 — 먼저 충족되는 조건으로 진입) ### 2단계: 추세 확인 후 진입
**A. 거리 기반**: `signal_price` 대비 +임계값% 이상 상승 시 매수 (vol_ratio에 따라 동적 조정) 신호가 대비 `TREND_AFTER_VOL`% 이상 상승 확인 시 매수.
| vol_ratio | 진입 임계값 | 설명 |
|-----------|------------|------|
| ≥ 5.0x | +1.0% | 매우 강한 신호 |
| ≥ 3.5x | +2.0% | 강한 신호 |
| ≥ 2.5x | +3.0% | 중간 신호 |
| < 2.5x | +`TREND_AFTER_VOL`% | 기본 임계값 |
**B. 속도 기반 (조기 진입)**: 신호 후 가격 상승 속도가 `VELOCITY_THRESHOLD` 이상이면 즉시 진입
| 파라미터 | 기본값 | 설명 | | 파라미터 | 기본값 | 설명 |
|----------|--------|------| |----------|--------|------|
| `TREND_AFTER_VOL` | 4.8% | 거리 기반 기본 임계값 | | `TREND_AFTER_VOL` | 4.8% | 신호가 대비 추가 상승 진입 임계값 |
| `VELOCITY_THRESHOLD` | 0.10%/분 | 속도 기준 (6%/h — 가파른 상승 감지) |
| `VELOCITY_MIN_MOVE` | 0.5% | 속도 체크 전 최소 이동 % |
| `VELOCITY_MIN_AGE_M` | 5분 | 속도 체크 전 최소 경과 시간 |
> **예시 (BTC 23:20 신호)**: 23:30에 +1.26%/6분 = 0.21%/분 → 속도 기준 충족 → 조기 진입
> 실제 진입(00:34, 100,840,000) 대비 약 1시간 빠른 23:30(97,286,000) 진입 가능
### 신호 감시 스레드 (Fast Poll) ### 신호 감시 스레드 (Fast Poll)
@@ -61,123 +48,123 @@
| `SCAN_INTERVAL` | 60초 | 전체 시장 스캔 주기 | | `SCAN_INTERVAL` | 60초 | 전체 시장 스캔 주기 |
| `SIGNAL_POLL_INTERVAL` | 15초 | 신호 종목 집중 감시 주기 | | `SIGNAL_POLL_INTERVAL` | 15초 | 신호 종목 집중 감시 주기 |
- 신호 발생 시 별도 스레드(`signal-fast-poll`)가 15초마다 해당 종목만 체크 ---
- 목표 임계값(거리 or 속도) 도달 즉시 매수 → 60초 지연 제거
## 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 기반) ### 트레일링 스탑 (ATR 기반)
- `minute10` → 40분봉 resample 후 최근 7봉(≈5h)의 평균 진폭 계산
- ATR = 평균진폭 × 1.5 계수 → 동적 손절폭 산출 - 10분봉 최근 ATR_N봉(7봉=70분) 평균 진폭 계산
- 최소 1.0% / **최대 2.0%** 범위 내 자동 조정 - `stop_pct = 평균진폭 × ATR_MULT(1.5)` → 동적 손절폭
-고가 대비 손절폭 이하 하락 시 즉시 청산 -`ATR_MIN=1.0%` / 최대 `ATR_MAX=2.0%` 범위 내 자동 조정
- ATR 캐시: 40분마다 갱신 (캐시 TTL=2400초) - 최고가(peak) 대비 `stop_pct` 이하 하락 시 즉시 청산
### 타임 스탑 ### 타임 스탑
- 보유 `TIME_STOP_HOURS`h 경과 후 수익률 < `TIME_STOP_MIN_GAIN_PCT`% 이면 청산
- 기본값: 8시간 경과 / 수익률 3% 미만
--- - 보유 `TS_N`봉(48봉=480분=8h) 경과 후 수익률 < `TIME_STOP_MIN_PCT`(3.0%)이면 청산
## 진입 사전 필터
### F&G (공포탐욕지수) 필터 — `core/fng.py`
**alternative.me API** 기반 일일 공포탐욕지수(0~100) 조회. 극공포·공포 구간에서는
신규 매수를 전면 차단한다.
| F&G 구간 | 레이블 | 진입 여부 |
|----------|--------|-----------|
| 76 ~ 100 | 극탐욕 | ✅ 허용 |
| 56 ~ 75 | 탐욕 | ✅ 허용 |
| 46 ~ 55 | 중립 | ✅ 허용 |
| 41 ~ 45 | 약공포 | ✅ 허용 |
| 26 ~ 40 | 공포 | ❌ 차단 |
| 0 ~ 25 | 극공포 | ❌ 차단 |
- 환경변수 `FNG_MIN_ENTRY=41` (기본값) — 이 값 미만이면 스캔 전체 스킵
- API는 하루 1회 KST 09:00 업데이트 → 캐시 TTL 24시간
- API 실패 시 폴백: 50 (중립) — 안전하게 진입 허용
- BEAR 레짐 차단과 독립적으로 동작 (둘 다 통과해야 스캔 진행)
**1년 백테스트 검증 결과** (2025-03-03 ~ 2026-03-03, 18종목 1h봉):
| 구성 | 거래수 | 승률 | 평균PnL | 누적PnL(KRW) |
|------|--------|------|---------|------------|
| 필터 없음 | 820건 | 32.7% | +0.012% | +95,743원 |
| **F&G≥41** | **372건** | **39.5%** | **+0.462%** | **+1,719,047원** |
- 차단 거래 452건 평균 PnL: **-0.372%** → 손실 거래 제거 효과
- 극공포 구간(0~25): 23.5% 승률, -0.540%/건 → 파라미터 조정으로 개선 불가 (검증됨)
--- ---
## 리스크 관리 ## 리스크 관리
### Walk-Forward (WF) 필터 ### Walk-Forward (WF) 필터
| 파라미터 | 기본값 | 설명 | | 파라미터 | 기본값 | 설명 |
|----------|--------|------| |----------|--------|------|
| `WF_WINDOW` | 4 | 이력 윈도우 (직전 N건) — 4연패 시 차단 | | `WF_WINDOW` | 5 | 직전 N건 이력 윈도우 |
| `WF_MIN_WIN_RATE` | 0.01 | 최소 승률 임계값 (1%) | | `WF_MIN_WIN_RATE` | 0.40 | 최소 승률 임계값 (40%) |
| `WF_SHADOW_WINS` | 2 | 차단 해제 조건 (가상 N연승) | | `WF_SHADOW_WINS` | 2 | 차단 해제 조건 (가상 N연승) |
- 직전 4건 승률 < 1% → 해당 종목 진입 차단 - 직전 5건 승률 < 40% → 해당 종목 진입 차단 + 가상(shadow) 포지션으로 재활 추적
- 차단 후 가상 추적으로 2연승 달성 시 자동 복귀 - 가상 2연승 달성 시 자동 복귀
- **WF 차단 상태는 Oracle DB(`wf_state` 테이블)에 영속 저장** → 재시작 후에도 복원 - **WF 차단 상태는 Oracle DB(`wf_state` 테이블)에 영속 저장** → 재시작 후에도 복원
### 재매수 차단
- 직전 거래가 손실이었을 경우: 현재가 < 직전매도가 × 1.01 이면 재진입 차단
- 직전 거래가 수익이었을 경우: 필터 스킵 (추가 상승 재진입 허용)
### 예산 관리 (복리) ### 예산 관리 (복리)
- 수익 발생 시: `운용예산 = 초기예산 + 누적수익` (복리 증가)
- 손실 발생 시: `운용예산 = 초기예산 + 누적수익` (차감) - 수익/손실 시 운용예산 실시간 반영 (복리)
- 하한선: 초기예산의 30% (기본: 4,500,000원) - 하한선: 초기예산의 30% (기본: 4,500,000원)
- 포지션당 크기: `운용예산 / MAX_POSITIONS` - 포지션당 크기: `운용예산 / MAX_POSITIONS`
--- ---
## 시장 레짐 적응
BTC·ETH·SOL·XRP 가중평균 **2h 추세 score**로 레짐 결정.
| 종목 | 가중치 |
|------|--------|
| KRW-BTC | 40% |
| KRW-ETH | 30% |
| KRW-SOL | 15% |
| KRW-XRP | 15% |
| 레짐 | score 기준 | vol_mult | 신규 진입 |
|------|-----------|----------|---------|
| BULL | ≥ +1.5% | 1.5x | 허용 |
| NEUTRAL | -0.5% ~ +1.5% | 2.0x | 허용 |
| BEAR | < -0.5% | 3.5x | **전면 차단** |
- BEAR 레짐 감지 시 신규 매수 전면 차단 (기존 포지션 청산은 정상 진행)
- 레짐 캐시 TTL: 10분 (API 호출 최소화)
- 현재가는 매 레짐 계산 시 Oracle DB(`price_history`)에 저장 → 2h 전 가격 조회에 재활용
> **2026-03-03 조정**: BEAR 기준 -1.0% → **-0.5%**로 강화
> 완만한 하락장(score ≈ -0.4%)에서 NEUTRAL로 오판하던 문제 수정
---
## 운용 설정 (.env) ## 운용 설정 (.env)
```env ```env
# 핵심 전략 # 핵심 전략 (10분봉 직접 감지)
PRICE_QUIET_PCT=2.0 # 2h 횡보 기준 (%) LOCAL_VOL_CANDLES=28 # 로컬 vol 평균 구간 (28봉=280분)
QUIET_CANDLES=12 # 횡보 체크 구간 (12봉=120분)
PRICE_QUIET_PCT=2.0 # 횡보 기준 (%)
TREND_AFTER_VOL=4.8 # 진입 임계값 (신호가 대비 %) TREND_AFTER_VOL=4.8 # 진입 임계값 (신호가 대비 %)
SIGNAL_TIMEOUT_H=8.0 # 신호 유효 시간 (h) SIGNAL_TIMEOUT_MIN=480 # 신호 유효 시간 (분=8h)
VOLUME_MULTIPLIER=2.0 # 거래량 배수 기준
# 속도 기반 조기 진입 # F&G 기반 거래량 임계값
VELOCITY_THRESHOLD=0.10 # %/분 (0.10 = 6%/h) VOL_THRESH_NORMAL=5.0 # 중립 구간 (F&G 41~50)
VELOCITY_MIN_MOVE=0.5 # 최소 이동 % (잡음 제거) VOL_THRESH_FEAR=6.0 # 공포/극공포 (F&G ≤ 40)
VELOCITY_MIN_AGE_M=5.0 # 최소 경과 시간 (분) 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_HOURS=8 # 타임스탑 보유 시간 TIME_STOP_MIN_PCT=3.0 # 타임스탑 최소 수익률
TIME_STOP_MIN_GAIN_PCT=3 # 타임스탑 최소 수익률 # TS_N=48봉(480분), ATR_MULT=1.5, ATR_MIN=1%, ATR_MAX=2% (코드 내 고정)
# 포트폴리오 # 포트폴리오
MAX_BUDGET=15000000 # 초기 운용 예산 MAX_BUDGET=15000000 # 초기 운용 예산
@@ -187,93 +174,68 @@ MAX_POSITIONS=3 # 최대 동시 보유 종목
SIGNAL_POLL_INTERVAL=15 # 신호 종목 빠른 감시 (초) SIGNAL_POLL_INTERVAL=15 # 신호 종목 빠른 감시 (초)
# WF 필터 # WF 필터
WF_WINDOW=4 WF_WINDOW=5
WF_MIN_WIN_RATE=0.01 WF_MIN_WIN_RATE=0.40
WF_SHADOW_WINS=2 WF_SHADOW_WINS=2
# F&G 필터
FNG_MIN_ENTRY=41 # 이 값 미만(공포/극공포) 시 신규 매수 전면 차단
``` ```
--- ---
## 백테스트 결과 요약 ## 백테스트 결과 요약
### A. 365일 — 1h봉, WF 적용 (`sim_365.py`) ### A. 1년 — 10분봉 직접, FNG_MAX_ENTRY=50 (`tests/sim_10m_vol.py`)
> 기간: 2025-03-02 ~ 2026-03-02 / 데이터: Oracle DB 1h OHLCV / 20종목 > 기간: 2025-03-03 ~ 2026-03-03 / 데이터: Upbit minute10 캐시 / 20종목
| 항목 | | | 항목 | 필터 없음 | FNG_MAX_ENTRY=50 적용 |
|------|-----| |------|---------|---------------------|
| 초기 예산 | 15,000,000원 | | 수익률 | +6.80% | **+18.81%** |
| 최종 자산 | 29,996,109원 | | 최대 낙폭 | -17.0% | **-14.3%** |
| 수익률 | **+100%** | | 거래수 | 286건 | 218건 |
| 최대 낙폭 | -3.81% (-57만원) | | 승률 | 42.0% | 46.3% |
| 거래수 | 190건 (WF 183건 차단) |
| 승률 | 46% |
| 월평균 수익 | 약 115만원 |
### B. 45일 — 40분봉, WF + 복리 적용 (`sim_45m40.py`) ### B. 월별 성과 — 1년 10분봉 (`tests/sim_regime_1y.py`)
> 기간: 2026-01-20 ~ 2026-03-02 / 데이터: Upbit minute10 캐시 40분 리샘플링 / 20종목 > FNG_MAX_ENTRY=50, VOL_THRESH_FEAR=6.0, VOL_THRESH_NORMAL=5.0
| 항목 | 값 | | 월 | 거래 | 승률 | 월수익(KRW) | F&G 특징 |
|------|-----| |----|------|------|------------|---------|
| 초기 예산 | 15,000,000원 | | 2025-03 | 14건 | 57% | +447,000원 | 공포→중립 |
| 최종 자산 | 21,684,574원 | | 2025-04 | 5건 | 60% | +289,000원 | 중립 |
| 수익률 | **+44.56%** | | 2025-05 | 11건 | 55% | +506,000원 | 공포 |
| 최대 낙폭 | -3.90% (-585,102원) | | 2025-06 | 4건 | 25% | -88,000원 | 탐욕(차단) |
| 거래수 | 87건 (WF 3건 차단 / MAX_POS 1건 스킵) | | 2025-07 | 18건 | 44% | +311,000원 | 공포 |
| 승률 | 47.1% | | 2025-08 | 12건 | 50% | +370,000원 | 공포 |
| 월평균 수익 | 약 2,228,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종목
| 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`) | THRESH | 진입 | 승률 | 평균손익 | 수익률 | 최대낙폭 |
> |--------|------|------|---------|--------|---------|
> | 봉 단위 | 거래수 | 승률 | 누적PnL | 최대낙폭 | | 0.0% | 3552건 | 26.6% | -0.33% | -70.0% | -70.4% |
> |---------|--------|------|---------|---------| | 1.0% | 2012건 | 25.6% | -0.35% | -70.0% | -70.1% |
> | 10분 | 180 | 33.9% | +15.8% | -32.6% | | 2.0% | 1075건 | 27.9% | -0.27% | -62.1% | -62.9% |
> | 20분 | 120 | 36.7% | +31.0% | -16.7% | | 3.0% | 660건 | 28.2% | -0.23% | -40.9% | -42.0% |
> | 30분 | 91 | 48.4% | +81.7% | -12.9% | | 4.0% | 398건 | 29.6% | -0.14% | -17.2% | -22.7% |
> | **40분** | **91** | **48.4%** | **+119.4%** | **-11.2%** ← 채택 | | **4.8%** | **272건** | **36.4%** | **+0.09%** | **+7.6%** | **-12.3%** ← 현재 |
> | 50분 | 83 | 50.6% | +94.7% | -17.1% | | **6.0%** | **180건** | **38.9%** | **+0.18%** | **+10.6%** | **-7.7%** ← 최적 |
> | 60분 | 65 | 50.8% | +88.3% | -11.9% | | 8.0% | 100건 | 44.0% | +0.12% | +3.8% | -4.8% |
### C. ATR_MAX_STOP 스윕 — 1h봉 기준 (`atr_sweep.py`) > vol spike 직후 진입(0~4%)은 가짜 펌프 위험으로 전부 손실.
> 데이터: Oracle DB 1h OHLCV / 20종목 > 추가 상승 확인(4.8%+)이 필수. 최적값은 6.0%이나 신호 포착 빈도와 트레이드오프.
| ATR_MAX | 승률 | 누적PnL | 최대낙폭 | 평균스탑 | ### D. F&G 탐욕 차단 효과 — 1년 10분봉
|---------|------|---------|---------|---------|
| 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% |
### D. F&G 필터 효과 비교 — 1h봉 (`tests/fng_sim_comparison.py`) | 구성 | 수익률 | 최대낙폭 | 거래수 |
> 기간: 2025-03-03 ~ 2026-03-03 / 데이터: Oracle DB 1h OHLCV / 18종목 |------|--------|---------|--------|
| 차단 없음 | +6.8% | -17.0% | 286건 |
| 구성 | 거래수 | 승률 | 평균PnL | 누적(KRW) | | FNG_MAX_ENTRY=60 | +12.4% | -15.8% | 254건 |
|------|--------|------|---------|----------| | **FNG_MAX_ENTRY=50** | **+18.8%** | **-14.3%** | **218건** |
| 필터 없음 | 820건 | 32.7% | +0.012% | +95,743원 | | FNG_MAX_ENTRY=45 | +15.1% | -13.8% | 195 |
| **F&G≥41** | **372건** | **39.5%** | **+0.462%** | **+1,719,047원** |
- 차단 452건 평균 PnL -0.372% → 약 168만원 손실 방지
- 극공포 적응 파라미터 테스트(`tests/fng_adaptive_backtest.py`): 어떤 파라미터도 극공포 성과 개선 불가 → 진입 차단이 유일한 해결책
### E. 속도 진입 효과 비교 — 10분봉 (`tests/velocity_backtest.py`)
> 기간: 2026-01-19 ~ 2026-03-02 / 10분봉 캐시 / 20종목
| 설정 | 속도진입 | 승률 | 수익률 | 최대낙폭 |
|------|---------|------|--------|---------|
| A: 거리 기반만 | 0건 | 34.7% | +8.83% | -8.35% |
| B: +속도(0.10) | 89건 | 33.6% | +13.36% | **-4.50%** |
| B: +속도(0.15) | 39건 | 35.7% | +17.19% | -7.84% |
- **0.10 채택**: 낙폭 -8.35% → -4.50% 개선, 수익률 +4.5%p
- 속도진입 BTC 예시: 0.21%/분 → 0.10 기준 충족 (0.20도 아슬하게 충족)
--- ---
@@ -283,61 +245,50 @@ FNG_MIN_ENTRY=41 # 이 값 미만(공포/극공포) 시 신규 매수
| 파일 | 역할 | | 파일 | 역할 |
|------|------| |------|------|
| `core/strategy.py` | 진입 신호 로직 (40분봉 vol-lead + 속도 기반 조기 진입) | | `core/strategy.py` | 진입 신호 로직 (10분봉 vol-lead + 신호불사 + 관찰알림) |
| `core/fng.py` | F&G 필터 (alternative.me API, 24h 캐시) | | `core/fng.py` | F&G 필터 (alternative.me API, 24h 캐시) |
| `core/monitor.py` | ATR 트레일링 스탑 + 타임스탑 (40분봉 ATR) | | `core/monitor.py` | ATR 트레일링 스탑 + 타임스탑 |
| `core/trader.py` | 주문 실행 + 복리 예산 관리 | | `core/trader.py` | 주문 실행 + 복리 예산 + WF 필터 |
| `core/market_regime.py` | 시장 레짐 감지 (BTC/ETH/SOL/XRP 가중 2h 추세) | | `core/notify.py` | 텔레그램 알림 (매수/매도/신호/관찰/상태) |
| `core/price_db.py` | 가격 DB + WF 상태 영속화 | | `core/market.py` | 상위 거래량 종목 조회 |
| `core/notify.py` | 텔레그램 알림 (매수/매도/신호/상태) |
| `daemon/runner.py` | 전체 스캔 루프 + 신호 종목 fast-poll 스레드 | | `daemon/runner.py` | 전체 스캔 루프 + 신호 종목 fast-poll 스레드 |
| `main.py` | 진입점 (스레드 시작 + pm2) | | `main.py` | 진입점 (스레드 시작 + pm2) |
| `ecosystem.config.js` | pm2 설정 (로그 경로 `logs/`) |
**백테스트 / 분석 (`tests/`)** **백테스트 / 분석 (`tests/`)**
| 파일 | 역할 | | 파일 | 역할 |
|------|------| |------|------|
| `tests/fng_sim_comparison.py` | F&G 필터 적용 전후 수익 비교 (1년) | | `tests/collect_1y_data.py` | 1년치 10분봉 데이터 수집 + 캐시 저장 |
| `tests/fng_1y_backtest.py` | F&G 구간별 성과 분석 (7개 구간, 1년) | | `tests/refresh_cache.py` | 캐시 최신화 (최근 데이터 추가) |
| `tests/fng_adaptive_backtest.py` | F&G 구간별 적응 파라미터 테스트 | | `tests/sim_10m_vol.py` | 1년 10분봉 복리 시뮬레이션 (현재 전략) |
| `tests/sim_365.py` | 365일 복리 시뮬레이션 (1h봉, DB) | | `tests/sim_current.py` | 특정 날짜 기준 당일/전일 시뮬 |
| `tests/sim_45m40.py` | 45일 복리 시뮬레이션 (40분봉, 캐시) | | `tests/sim_regime_1y.py` | 1년 월별 성과 분석 |
| `tests/velocity_backtest.py` | 속도 진입 효과 비교 백테스트 | | `tests/sim_regime_sweep.py` | REGIME_N 파라미터 스윕 (레거시) |
| `tests/atr_sweep.py` | ATR_MAX_STOP 파라미터 스윕 | | `tests/sim_vol_override.py` | VOL_THRESH / THRESH 파라미터 스윕 |
| `tests/interval_sweep.py` | 봉 단위별 성과 비교 | | `tests/sim_45m40.py` | 40분봉 복리 시뮬레이션 (레거시) |
| `tests/backtest_db.py` | 백테스트 결과 Oracle DB 저장 |
| `tests/ohlcv_db.py` | OHLCV 시계열 DB 캐시 관리 |
--- ---
## 시뮬레이션 실행 ## 시뮬레이션 실행
```bash ```bash
# F&G 필터 효과 비교 (필터 없음 vs F&G≥41) # 1년치 10분봉 데이터 수집 (최초 1회, ~13분 소요)
python tests/fng_sim_comparison.py python tests/collect_1y_data.py
# F&G 구간별 성과 분석 (7개 구간, 1년) # 캐시 최신화 (기존 데이터에 최근분 추가)
python tests/fng_1y_backtest.py python tests/refresh_cache.py
# 45일 복리 시뮬 — 40분봉 (현재 전략 기준) # 1년 복리 시뮬 — 현재 전략 기준
python tests/sim_45m40.py python tests/sim_10m_vol.py
# 365일 복리 시뮬 — 1h봉 (DB에서 로드) # 특정 날짜 기준 시뮬 (당일 신호 확인용)
python tests/sim_365.py python tests/sim_current.py
# 속도 진입 효과 비교 # 1년 월별 성과 분석
python tests/velocity_backtest.py python tests/sim_regime_1y.py
# 봉 단위별 비교 (10m 캐시 필요) # THRESH / VOL_THRESH 파라미터 스윕
python tests/interval_sweep.py python tests/sim_vol_override.py
# ATR_MAX_STOP 스윕 (DB에서 로드)
python tests/atr_sweep.py
# OHLCV DB 상태 확인 / 업데이트
python tests/ohlcv_db.py status
python tests/ohlcv_db.py update
``` ```
--- ---
@@ -346,12 +297,13 @@ python tests/ohlcv_db.py update
| 날짜 | 변경 내용 | | 날짜 | 변경 내용 |
|------|---------| |------|---------|
| 2026-03-03 | **F&G 필터 추가** (`FNG_MIN_ENTRY=41`) — 1년 백테스트로 검증, 수익 +95K→+1.72M원 | | 2026-03-04 | **전략 전면 재작성** — 10분봉 직접 감지, 신호불사, vol 갱신 |
| 2026-03-03 | F&G 정보 텔레그램 알림 통합 (매수/신호/상태 리포트) | | 2026-03-04 | F&G 3구간 시스템: ≤40→6x / 41~50→5x / >50→차단 (`FNG_MAX_ENTRY=50`) |
| 2026-03-03 | F&G API 캐시 TTL 24시간 (하루 1회 KST 09:00 업데이트) | | 2026-03-04 | 관찰 알림(Watch Alert) 추가: 4x~신호임계값 근접 시 텔레그램 👀 알림 |
| 2026-03-03 | 프로젝트 구조 정리: `tests/` `data/` `logs/` 폴더 분리 | | 2026-03-04 | 1년 10분봉 시뮬레이션 추가 (20종목, `data/sim1y_cache.pkl`) |
| 2026-03-03 | `ecosystem.config.js` 추가 — pm2 로그 경로 `logs/` 통일 | | 2026-03-04 | THRESH 스윕 결과: 현재 4.8% 유지, 최적값 6.0% 확인 |
| 2026-03-03 | BEAR_THRESHOLD -1.0% → **-0.5%** 강화 (완만한 하락장 오판 수정) | | 2026-03-04 | runner.py: Bear레짐 차단 제거, FNG_MAX_ENTRY(>50) 차단으로 통일 |
| 2026-03-03 | 속도 기반 조기 진입 추가 (`VELOCITY_THRESHOLD=0.10%/분`) | | 2026-03-03 | F&G 필터 최초 추가 (`FNG_MIN_ENTRY=41`) |
| 2026-03-03 | 속도 기반 조기 진입 추가 (현재 제거됨) |
| 2026-03-03 | 신호 종목 fast-poll 스레드 추가 (`SIGNAL_POLL_INTERVAL=15s`) | | 2026-03-03 | 신호 종목 fast-poll 스레드 추가 (`SIGNAL_POLL_INTERVAL=15s`) |
| 2026-03-03 | vol_ratio 강도별 진입 임계값 티어 추가 (5x→1%, 3.5x→2%, 2.5x→3%) | | 2026-03-03 | 프로젝트 구조 정리: `tests/` `data/` `logs/` 폴더 분리 |