- 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>
7.9 KiB
7.9 KiB
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():
- Upbit
get_balances()로 보유 종목 조회 (balance + locked) - 포지션 복구 (트레일링 스탑 모드)
- 미체결 매수 주문도
pending_buys에 복구 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)
# 총 운용 예산 / 최대 동시 보유 종목
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중 체크 |