feat: add velocity entry, fast-poll thread, tighten BEAR threshold

- Add velocity-based entry signal in strategy.py (VELOCITY_THRESHOLD=0.10,
  VELOCITY_MIN_MOVE=0.5%, VELOCITY_MIN_AGE_M=5)
- Add fast-poll thread in daemon/runner.py (SIGNAL_POLL_INTERVAL=15s)
  for sub-minute velocity event detection
- Add vol_ratio tiered condition and get_active_signals() to strategy.py
- Change BEAR_THRESHOLD -1.0 → -0.5 in market_regime.py to catch
  slow downtrends earlier (weighted 2h score)
- Expand sell_reason VARCHAR2(500) in price_db.py DDL
- Add velocity_backtest.py and sim10m.py for strategy experimentation
- Update STRATEGY.md: correct regime algorithm description (weighted 2h
  score, not BTC 1h ±5%), add fast-poll/velocity sections, add backtest
  section D, add change history table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
joungmin
2026-03-03 10:17:08 +09:00
parent 612055162e
commit 673ce08d84
7 changed files with 986 additions and 36 deletions

View File

@@ -15,7 +15,7 @@
## 진입 조건 (2단계)
### 1단계: 매집 신호 감지
다음 두 조건 동시 충족 시 `signal_price` 기록:
다음 두 조건 동시 충족 시 `signal_price` + `vol_ratio` 기록:
| 조건 | 파라미터 | 기본값 |
|------|----------|--------|
@@ -29,12 +29,40 @@
> **2h 횡보 체크**: Oracle DB에 저장된 실시간 가격 기록을 조회 (`get_price_n_hours_ago`)
> **거래량 체크**: `minute10` → 40분봉 resample → 직전 완성봉 vs 이전 7봉 평균
### 2단계: 추세 확인 후 진입
`signal_price` 대비 +`TREND_AFTER_VOL`% 이상 상승 확인 시 매수:
### 2단계: 추세 확인 후 진입 (거리 기반 OR 속도 기반 — 먼저 충족되는 조건으로 진입)
**A. 거리 기반**: `signal_price` 대비 +임계값% 이상 상승 시 매수 (vol_ratio에 따라 동적 조정)
| 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)
신호 감지 후 전체 스캔 60초를 기다리지 않고 해당 종목만 빠르게 폴링.
| 파라미터 | 기본값 | 설명 |
|----------|--------|------|
| `SCAN_INTERVAL` | 60초 | 전체 시장 스캔 주기 |
| `SIGNAL_POLL_INTERVAL` | 15초 | 신호 종목 집중 감시 주기 |
- 신호 발생 시 별도 스레드(`signal-fast-poll`)가 15초마다 해당 종목만 체크
- 목표 임계값(거리 or 속도) 도달 즉시 매수 → 60초 지연 제거
---
@@ -62,7 +90,7 @@
| `WF_MIN_WIN_RATE` | 0.01 | 최소 승률 임계값 (1%) |
| `WF_SHADOW_WINS` | 2 | 차단 해제 조건 (가상 N연승) |
- 직전 2모두 손실 → 해당 종목 진입 차단
- 직전 4승률 < 1% → 해당 종목 진입 차단
- 차단 후 가상 추적으로 2연승 달성 시 자동 복귀
- **WF 차단 상태는 Oracle DB(`wf_state` 테이블)에 영속 저장** → 재시작 후에도 복원
@@ -76,14 +104,27 @@
## 시장 레짐 적응
| 레짐 | BTC 1h 변동 | 거래량 기준 |
|------|------------|------------|
| BULL | +5% 이상 | 1.5x |
| NEUTRAL | ±5% 이내 | 2.0x |
| BEAR | -5% 이하 | 진입 차단 |
BTC·ETH·SOL·XRP 가중평균 **2h 추세 score**로 레짐 결정.
- BEAR 레짐 감지 시 신규 진입 전면 차단
- 레짐별 `vol_mult` 조정으로 민감도 제어
| 종목 | 가중치 |
|------|--------|
| 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로 오판하던 문제 수정
---
@@ -96,6 +137,11 @@ TREND_AFTER_VOL=4.8 # 진입 임계값 (신호가 대비 %)
SIGNAL_TIMEOUT_H=8.0 # 신호 유효 시간 (h)
VOLUME_MULTIPLIER=2.0 # 거래량 배수 기준
# 속도 기반 조기 진입
VELOCITY_THRESHOLD=0.10 # %/분 (0.10 = 6%/h)
VELOCITY_MIN_MOVE=0.5 # 최소 이동 % (잡음 제거)
VELOCITY_MIN_AGE_M=5.0 # 최소 경과 시간 (분)
# 청산
TIME_STOP_HOURS=8 # 타임스탑 보유 시간
TIME_STOP_MIN_GAIN_PCT=3 # 타임스탑 최소 수익률
@@ -104,8 +150,11 @@ TIME_STOP_MIN_GAIN_PCT=3 # 타임스탑 최소 수익률
MAX_BUDGET=15000000 # 초기 운용 예산
MAX_POSITIONS=3 # 최대 동시 보유 종목
# 감시 주기
SIGNAL_POLL_INTERVAL=15 # 신호 종목 빠른 감시 (초)
# WF 필터
WF_WINDOW=2
WF_WINDOW=4
WF_MIN_WIN_RATE=0.01
WF_SHADOW_WINS=2
```
@@ -167,22 +216,35 @@ WF_SHADOW_WINS=2
| 2.5% | 50.8% | +256% | -5.3% | 1.77% |
| 4.0% | 45.9% | -52% | -29.1% | 3.11% |
### D. 속도 진입 효과 비교 — 10분봉 (`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도 아슬하게 충족)
---
## 주요 파일
| 파일 | 역할 |
|------|------|
| `core/strategy.py` | 진입 신호 로직 (40분봉 vol-lead) |
| `core/strategy.py` | 진입 신호 로직 (40분봉 vol-lead + 속도 기반 조기 진입) |
| `core/monitor.py` | ATR 트레일링 스탑 + 타임스탑 (40분봉 ATR) |
| `core/trader.py` | 주문 실행 + 복리 예산 관리 |
| `core/market_regime.py` | 시장 레짐 감지 |
| `core/market_regime.py` | 시장 레짐 감지 (BTC/ETH/SOL/XRP 가중 2h 추세) |
| `core/price_db.py` | 가격 DB + WF 상태 영속화 |
| `daemon/runner.py` | 전체 스캔 루프 + 신호 종목 fast-poll 스레드 |
| `ohlcv_db.py` | OHLCV 시계열 DB 캐시 관리 |
| `sim_365.py` | 365일 복리 시뮬레이션 (1h봉, DB) |
| `sim_45m40.py` | 45일 복리 시뮬레이션 (40분봉, 캐시) |
| `velocity_backtest.py` | 속도 진입 효과 비교 백테스트 (A vs B vs C) |
| `atr_sweep.py` | ATR_MAX_STOP 파라미터 스윕 |
| `sim10m.py` | 10분봉 vs 1h봉 전략 비교 시뮬 |
| `interval_sweep.py` | 봉 단위별 성과 비교 (10/20/30/40/50/60분) |
---
@@ -196,6 +258,9 @@ python sim_45m40.py
# 365일 복리 시뮬 — 1h봉 (DB에서 로드)
python sim_365.py
# 속도 진입 효과 비교
python velocity_backtest.py
# 봉 단위별 비교 (10m 캐시 필요)
python interval_sweep.py
@@ -208,3 +273,15 @@ python ohlcv_db.py status
# 신규 봉 증분 업데이트
python ohlcv_db.py update
```
---
## 변경 이력
| 날짜 | 변경 내용 |
|------|---------|
| 2026-03-03 | BEAR_THRESHOLD -1.0% → **-0.5%** 강화 (완만한 하락장 오판 수정) |
| 2026-03-03 | 속도 기반 조기 진입 추가 (`VELOCITY_THRESHOLD=0.10%/분`) |
| 2026-03-03 | 신호 종목 fast-poll 스레드 추가 (`SIGNAL_POLL_INTERVAL=15s`) |
| 2026-03-03 | `sell_reason` 컬럼 VARCHAR2(100→500) 자동 확장 |
| 2026-03-03 | vol_ratio 강도별 진입 임계값 티어 추가 (5x→1%, 3.5x→2%, 2.5x→3%) |