Files
upbit-trader/STRATEGY.md
joungmin 976c53ed66 feat: 트레일링 스탑 전환 + 사전 필터 강화 + 예산 증액
- cascade/LLM 매도 제거 -> 트레일링 스탑 (고점 -1.5%, 손절 -2%, 타임아웃 4h)
- 사전 필터 3종 추가: 횡보/고점/연속양봉(>=2) -> LLM 호출 57% 절감
- 현재가 매수 (LLM 가격 제안 제거)
- 종목 30개 -> 10개, BTC 제외
- 예산: 100K/3pos -> 1M/5pos (종목당 200K)
- VOL_KRW_MIN: 2M -> 5M, BUY_TIMEOUT: 60 -> 180초
- LLM 프롬프트: 연패 무시, get_trade_history 제거
- 3월 백테스트: 승률 52.1%, PNL +17,868원
- STRATEGY.md 전면 재작성

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:33:15 +09:00

237 lines
7.9 KiB
Markdown

# upbit-trader 전략 가이드
## 시스템 개요
| 데몬 | 전략 | 상태 |
|------|------|------|
| `tick-trader` | WebSocket 20초봉 + LLM 매수 + 트레일링 청산 | **운용 중** |
| `upbit-trader` | 10분봉 Volume Lead 매집 전략 | 중지 (2026-03-06~) |
---
## 1. tick-trader (WebSocket 20초봉)
### 1.1 아키텍처
```
WebSocket (Upbit trade tick)
-> 20초봉 집계 (on_tick -> finalize_bars)
-> 시그널 감지 (양봉 + VOL >= 5x + 사전 필터 3종)
-> LLM 매수 판단 (get_entry_price)
-> 지정가 매수 (현재가)
-> 트레일링 스탑 / 손절 / 타임아웃 청산
```
### 1.2 감시 종목 (10개)
```
ETH, XRP, SOL, DOGE, SIGN, BARD, KITE, CFG, SXP, ARDR
```
### 1.3 진입 조건
**시그널 감지** -- 20초봉 확정 시 다음 조건 동시 충족:
| 순서 | 조건 | 파라미터 | 값 |
|------|------|----------|------|
| 1 | 양봉 (close > open) | -- | 필수 |
| 2 | 거래량 >= 이전 61봉 평균 x N배 (trimmed mean, 상위 10% 제거) | `VOL_MIN` | 5.0x |
| 3 | 20초봉 거래대금 >= 하한 | `VOL_KRW_MIN` | 5,000,000원 |
| 4 | 횡보 필터: 최근 15봉 변동폭 >= 0.3% | `SPREAD_MIN` | 0.3% |
| 5 | 고점 필터: 30분 구간 내 90%+ 위치 & 변동 1%+ 아닐 것 | `HIGHPOS` | 90% / 1.0% |
| 6 | 연속 양봉 필터: 직전 2봉 이상 연속 양봉 | -- | >= 2 |
**LLM 매수 판단** -- 사전 필터 통과 후 LLM에게 매수 여부 위임:
- LLM이 DB Tool로 시장 데이터 조회 후 `buy` / `skip` 판단
- `buy` 시 현재가로 지정가 매수 (LLM은 가격 결정 안 함)
- `skip` 시 텔레그램 알림 + 사유 기록
- 과거 연패/승률은 고려하지 않도록 프롬프팅 (get_trade_history 제거)
**중복/한도 방지**:
- 이미 보유(`positions`) 또는 매수대기(`pending_buys`) 종목은 스킵
- LLM 호출 전/후 포지션 한도(`MAX_POS`) 이중 체크
- 예산 체크: MAX_BUDGET - (보유 투자금 + 미체결 투자금)
- 미체결 180초 초과 시 자동 취소
### 1.4 청산: 트레일링 스탑
LLM 매도는 제거됨. 규칙 기반 트레일링 스탑으로 청산.
| 조건 | 파라미터 | 값 | 설명 |
|------|----------|------|------|
| 트레일링 스탑 | `TRAIL_PCT` | -1.5% | 고점 대비 하락 시 시장가 청산 |
| 최소 수익 | `MIN_PROFIT_PCT` | +0.5% | 트레일 발동 최소 수익률 |
| 손절 | `STOP_LOSS_PCT` | -2.0% | 진입가 대비 -2% 시 시장가 청산 |
| 타임아웃 | `TIMEOUT_SECS` | 14,400초 (4h) | 경과 시 시장가 청산 |
- 실시간 tick마다 peak 갱신 + 손절/트레일 체크 (`update_positions`)
- 20초봉 확정 시에도 체크 (`check_filled_positions`)
### 1.5 LLM 어드바이저
**모델**: Google Gemini 2.5 Flash (OpenRouter API)
**비용**: ~5원/일 (~150원/월) -- 매도 LLM 제거 + 사전 필터로 대폭 절감
**DB Tool 4개** (매수 판단용):
| Tool | 데이터 소스 | 용도 |
|------|-----------|------|
| `get_price_ticks` | Oracle `price_tick` | 최근 N분 가격 틱 (단기 추세) |
| `get_ohlcv` | Oracle `backtest_ohlcv` | 1분봉 OHLCV (지지/저항) |
| `get_ticker_context` | Oracle `ticker_context` | 종목 평판 (가격 변동, 뉴스) |
| `get_btc_trend` | Oracle `backtest_ohlcv` | BTC 4시간봉 추세 |
**최적화**:
- Tool call 중복 제거: 동일 tool+args 호출 시 캐시된 결과 반환
- max_rounds=5: 최대 5라운드 tool calling 후 강제 응답
### 1.6 재시작 복구
PM2 재시작 시 `restore_positions()`:
1. Upbit `get_balances()`로 보유 종목 조회 (balance + locked)
2. 포지션 복구 (트레일링 스탑 모드)
3. 미체결 매수 주문도 `pending_buys`에 복구
4. `entry_ts` 백데이팅으로 즉시 활성화
### 1.7 가격 표시
`fp()` 헬퍼로 가격대별 소수점 자동 조정:
- >= 100원: 정수 (예: 106,177,000)
- >= 10원: 소수 1자리 (예: 47.5)
- < 10원: 소수 2자리 (예: 0.85)
---
## 2. upbit-trader (10분봉 Volume Lead) [중지됨]
> 중지 사유: tick-trader와 동일 계좌에서 동시 운용 시 예산 초과 문제
- 10분봉 Volume Lead 매집 전략
- 횡보 중 거래량 급증 -> 신호 기록 -> +4.8% 상승 확인 후 진입
- F&G 필터: <=40->6x / 41~50->5x / >50->차단
- ATR 트레일링 스탑 + 타임스탑(8h)
- WF 필터: Oracle DB 영속 저장
---
## 3. 공통 인프라
### 3.1 데이터 수집 데몬
| 데몬 | 주기 | 역할 |
|------|------|------|
| `tick-collector` | 30초 | `price_tick` 30초봉 + `backtest_ohlcv` 1분봉 Oracle 저장 |
| `context-collector` | 1시간 | 종목별 `ticker_context` (가격 통계 + SearXNG 뉴스) |
### 3.2 기술 스택
| 구성 | 기술 |
|------|------|
| 거래소 | Upbit API (REST + WebSocket) |
| DB | Oracle ADB (price_tick, backtest_ohlcv, ticker_context, trade_log, wf_state, position_sync) |
| LLM | Google Gemini 2.5 Flash via OpenRouter |
| 알림 | Telegram Bot API |
| 뉴스 | SearXNG (self-hosted) |
| 프로세스 | PM2 (tick-trader, tick-collector, context-collector) |
### 3.3 예산 관리
| 파라미터 | 값 | 설명 |
|----------|------|------|
| `MAX_BUDGET` | 1,000,000원 | 총 운용 예산 |
| `MAX_POSITIONS` | 5 | 최대 동시 보유 종목 |
| 종목당 예산 | 200,000원 | `MAX_BUDGET / MAX_POSITIONS` |
---
## 4. 프로젝트 구조
### 프로덕션
| 파일 | 역할 |
|------|------|
| `daemons/tick_trader.py` | WebSocket 20초봉 트레이더 (LLM 매수 + 트레일링 청산) |
| `daemons/tick_collector.py` | price_tick + 1분봉 수집 |
| `daemons/context_collector.py` | 종목 컨텍스트 수집 (뉴스 + 가격 통계) |
| `core/llm_advisor.py` | OpenRouter LLM 매수 어드바이저 (tool calling) |
| `core/notify.py` | 텔레그램 알림 |
### 설정
| 파일 | 역할 |
|------|------|
| `.env` | API 키, 전략 파라미터, DB 설정 |
| `ecosystem.config.js` | PM2 프로세스 설정 |
### 백테스트
| 파일 | 역할 |
|------|------|
| `backtest_march.py` | 3월 1분봉 시뮬레이션 (Oracle DB 데이터) |
---
## 5. 운용 설정 (.env)
```env
# 총 운용 예산 / 최대 동시 보유 종목
MAX_BUDGET=1000000
MAX_POSITIONS=5
# LLM (OpenRouter)
OPENROUTER_API_KEY=sk-or-v1-...
LLM_MODEL=google/gemini-2.5-flash
# Oracle ADB
ORACLE_USER=admin
ORACLE_PASSWORD=...
ORACLE_DSN=...
ORACLE_WALLET=...
# Telegram
TELEGRAM_TRADE_TOKEN=...
TELEGRAM_CHAT_ID=...
```
---
## 6. 백테스트 결과
### 3월 시뮬레이션 (1분봉, 연속양봉 필터 적용)
> 기간: 2026-03-01 ~ 2026-03-06 / 10종목 / MAX_POS=3
| 항목 | 필터 전 | 연속양봉 >= 2 적용 |
|------|---------|-------------------|
| 시그널 | 112건 | 48건 (-57%) |
| 승률 | 38.4% | **52.1%** |
| 총 PNL | +11,530원 | **+17,868원** |
| 평균 PNL | +0.13% | **+1.22%** |
| 손절 | 31건 | 12건 |
| 트레일 익절 | 13건 | 18건 |
---
## 7. 변경 이력
| 날짜 | 변경 내용 |
|------|---------|
| 2026-03-06 | 연속 양봉 >= 2 필터 추가 (승률 38% -> 52%) |
| 2026-03-06 | 예산 변경: 100K/3pos -> 1M/5pos (종목당 200K) |
| 2026-03-06 | LLM 매도 제거 -> 트레일링 스탑 전환 (TRAIL -1.5%, SL -2%, 4h timeout) |
| 2026-03-06 | cascade 매도 제거 |
| 2026-03-06 | 사전 필터 3종 추가 (횡보/고점/연속양봉) -> LLM 호출 ~57% 절감 |
| 2026-03-06 | 종목 30개 -> 10개 축소, BTC 제외 |
| 2026-03-06 | 현재가 매수 (LLM 가격 제안 제거) |
| 2026-03-06 | LLM 매수 프롬프트: 연패 무시, get_trade_history 제거 |
| 2026-03-06 | VOL_KRW_MIN: 2M -> 5M, BUY_TIMEOUT: 60 -> 180초 |
| 2026-03-06 | 예산 체크: MAX_BUDGET - 투자금 합계 방식 |
| 2026-03-06 | `_round_price` 호가 단위 수정: 10만~50만 구간 50->100원 |
| 2026-03-06 | 매도 주문 실패 시 자동 재시도 |
| 2026-03-06 | upbit-trader (보조 봇) 중지 |
| 2026-03-05 | `tick-trader` LLM-driven 매수/매도 전환, cascade fallback 구현 |
| 2026-03-05 | LLM 모델 Claude Haiku 4.5 -> Gemini 2.5 Flash (비용 7.5x 절감) |
| 2026-03-05 | `restore_positions()`: 잔고 기반 포지션 복구 |
| 2026-03-05 | 포지션 한도 초과 방지 3중 체크 |