Files
auto-stock/CLAUDE.md
shuim 78ab3d7d4e chore: 스윙 자본 상한 70%로 상향 (스윙:DT = 70:30)
스윙이 이미 47%라 신규 매수가 swing_capital_cap 에 막혀(오늘 60건) 표본이 쌓이지 않았다.
- SWING_MAX_CAPITAL_RATIO 0.50 → 0.70
- DAY_TRADE_MAX_RATIO_DT 0.50 → 0.30, DAY_TRADE_MAX_POSITIONS 8 → 5 (5×6%=30%)
- 두 상한의 합이 100%를 넘지 않는지 테스트로 고정

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 14:48:34 +09:00

128 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 자동 주식 매매 시스템 — Claude 가이드
> 모든 코드 수정·분석은 이 문서의 규칙을 엄격히 준수할 것.
## 1. 스택 & 환경
- **백엔드**: Python 3.11 / FastAPI / SQLAlchemy 2.0(Async) / PostgreSQL 15 / Redis 7 / RabbitMQ 3
- **프론트**: React 18 / TypeScript / Vite / Recharts / Lightweight Charts
- **인프라·ML**: Docker Compose, Nginx, Alembic / PyTorch, LightGBM, scikit-learn
- **연동**: 한국투자증권(KIS) REST·WebSocket, MCP 서버(stdio) / AI 계층: `AI_PROVIDER`=claude|gemini
- **주요 .env**: `KIS_MODE`(virtual|real), `TOKEN_SAVE_MODE`(JSON 압축+차트 30일 제한), `AUTO_TRADE_ENABLED`, `US_TRADING_ENABLED`
- **배포**: 코드 수정 후 `docker compose up -d --build`(옛 이미지 재사용 방지) — **스키마(모델) 변경 시 반드시 `alembic upgrade head`를 이미지 기동보다 먼저 실행**(`create_all`은 기존 테이블에 컬럼을 추가하지 않음, H1).
## 2. 구조 (`backend/app/`)
- `api/endpoints/` — 20개 모듈 (portfolio, market_data, trades, day_trading, backtest 등)
- `core/` — config(설정), database, security(require_api_key), json_helpers(_dumps), market_schedule
- `models/models.py` — Portfolio, TradeHistory, ActiveTrade, StockAnalysis, StockBan 등
- `realtime/` — websocket_client, event_handler / `strategy/` — base_strategy, strategy_manager
- `services/` 전략: mean_reversion_strategy(§6), short_term_strategy(§7.2), day_trading_strategy(§7.3), kosdaq_scanner(§7.1), us_stock_strategy
- `services/daytrading/`·`services/swing/` — entry_service, exit_service, position_manager, scheduler
- `services/` 핵심: trade_executor(매매엔진: 매수/매도/체결확인/슬리피지), db_worker(비동기 DB워커), mdd_manager·loss_tracker·correlation_filter(리스크), korea_investment_api·kis_realtime_stream·naver_finance(데이터), feature_engineering·ml_ensemble·technical_indicators(분석)
- `mcp-server/` — stdio_server, auto_trade_claude, claude_client, gemini_client, trade_monitor, risk_validator, mcp_tools
- 배치(`backend/`) — batch_daily_analysis, batch_intraday_analysis, train_ensemble, collect_krx_data
## 3. 아키텍처 원칙 (필수)
1. **실시간 계층 DB I/O 절대 금지** — API 콜백·웹소켓·실시간 스케줄러에서 `AsyncSessionLocal()`/`commit()` 호출 금지.
2. **모든 DB 쓰기는 `db_worker.py`의 `db_task_queue` 경유** (실패 시 지수 백오프 1→2→4초, 최대 3회 재시도). 예외: `sync_portfolio()`만 단일 트랜잭션 필요로 엔드포인트 직접 DB 접근 허용. auth/credentials/bootstrap 시드(회원가입·로그인, `user_kis_credentials` 등록/삭제, 앱 기동 시 관리자·자격증명 시드)도 단일 트랜잭션 직접 접근 허용 — 실시간 계층(콜백·스케줄러) 아님.
3. 지원 task: insert_trade_history, update_trade_history(+_by_order_id), upsert_stock_analysis, bulk_upsert_stock_analysis, upsert_stock_ban, upsert_portfolio, upsert_active_trade, close_active_trade, insert_trade_journal, log_mcp_deny
4. **동시성**: trade_executor `_order_semaphores`(종목별 동시 주문 방지) / Redis 분산 락(워커 간 동시 매도 방지) / loss_tracker·mdd_manager `asyncio.Lock`. 동시 접근 경로에서는 `is_banned_safe()`, `record_trade_result_safe()` 사용.
## 4. 코딩 규칙
- **기존 함수/클래스 시그니처 변경 금지** → 새 전략은 `_v2`/`_v3`, 동기→비동기 확장은 `_safe` 접미사의 새 메서드.
- JSON은 `json.dumps` 금지, `core.json_helpers._dumps()` 사용.
- 쓰기/삭제 엔드포인트에 `Depends(require_api_key)` 필수. 외부 API 호출 `verify=True` 유지(KIS 포함). `SECRET_KEY` 64자+ 랜덤.
- 프롬프트는 토큰 최소화, 컴팩트 포맷.
## 5. 리스크 규칙
### 5.1 사이징·필터
- 종목당 최대 **4%** (`MAX_POSITION_SIZE=0.04`), 최대 **20종목**(`MAX_HOLDINGS_COUNT`), 레버리지/인버스 ETF 최대 **20%**(`LEVERAGE_ETF_MAX_RATIO`).
- 최소 주문금액 **15만원**(`MIN_BUY_AMOUNT_KRW`). 이 값이 종목당 예산에 근접하면 신뢰도·현금 보정으로 깎인 주문이 전부 탈락한다(2026-09-23 하루 141건 차단).
- 가격 필터: 국내 >5,000원, 미국 >$4 (ETF·리츠 예외) (`MIN_PRICE_KRW`, `MIN_PRICE_USD`).
- 상관관계: 섹터당 최대 3종목, 기존 포트폴리오와 상관계수 >0.7 진입 거부 (`correlation_filter`).
- 연속 손실: 동일 종목 **3연패 → 42캘린더일(≈30거래일) 진입 금지** (`loss_tracker`). `record_trade_result()` 후 반드시 `save_to_db()`(db_worker upsert_stock_ban 경유). 재시작 시 `load_from_db()` 복원.
### 5.2 SL/TP (일봉/스윙)
- 기본 SL: **-7%**(안정) / -10%(변동성). ATR SL: `진입가 − 2.5×ATR` (`ATR_STOP_MULTIPLIER=2.5`).
- **SL은 기본/ATR 중 타이트한 쪽 — 항상 `min()`, `max()` 금지.**
- TP: +2R 도달 시 50% 분할 매도, 잔량 트레일링 스탑 `고점 − 1.5×ATR`.
### 5.3 MDD (mdd_manager — portfolio.py·swing/scheduler.py에서 자동 호출, 중복 실행 방지 내장)
- **-10%**: 신규 진입 중단 + 포지션 30% 축소 + 단기·데이트레이딩 중단 (REDUCE_AND_PAUSE)
- **-20%**: 전 포지션 50% 강제 축소, 레버리지/인버스 ETF 우선 청산 (FORCE_REDUCE)
- 잔고가 peak 갱신 시 모든 MDD 플래그 리셋.
## 6. 전략 A: RSI+BB 평균 회귀 v2 (`mean_reversion_strategy`, `swing/`) — 스윙 자본 최대 70%(`SWING_MAX_CAPITAL_RATIO`)
- **시장 국면(일봉)**: BULL = 코스피200>MA200 & MA200 기울기>0 / BEAR = 코스피200<MA200 & 기울기<0 / **SIDEWAYS = ADX<20 or 기울기≈0 → 모든 진입 무시** (market_analyzer: position_multiplier=0, max_trades=0)
- **진입** (RSI 임계값은 §8.3 config 참조): BULL: RSI(14)<46 + BB하단 부근(-3%~+1.5%) + 거래량>20MA / BEAR: RSI<35 + 가격<BB하단 + 거래량>1.5×20MA + 반전캔들 필수 / 선제: 일봉 RSI<46 & 60분봉 RSI<30 & MA5 상향돌파
- **청산**: 50% 부분매도: RSI≥55 or 가격>BB중앙 or 수익>2×ATR / 전량: RSI≥70 or 가격>BB상단(99%) or 트레일링(고점−1.5×ATR)
## 7. 전략 B: 공격적 성장
### 7.1 코스닥 스캐너 (`kosdaq_scanner`) — 자본 25%
코스닥 전 종목(~1,600) / 가격>5,000원 + 거래량 상위 20% / 점수 = `0.5×RSI + 0.3×BB + 0.2×Vol`, ≥0.15 중 상위 20개 선정.
### 7.2 단기 15분봉 (`short_term_strategy`) — 자본 최대 25%, **MDD -10% 시 비활성**
- 타겟: 일봉 RSI<40 / 진입: 15분 RSI<30 + BB하단 부근 + 종가>MA5(상향돌파) + 거래량>1.3×20MA(`SHORT_TERM_VOLUME_MULTIPLIER`) + ATR/close≥0.8%(`SHORT_TERM_MIN_ATR_RATIO`, 거래비용 커버)
- 청산: 15분 RSI>55 or 수익>1.5×ATR(15분) / SL: `min(진입가−1.0×ATR, -2% 하드스탑)` — 타이트한(stop가 높은) 쪽. *§5.2 ATR 2.5×는 일봉/스윙 전용*
### 7.3 데이트레이딩 5분봉 (`day_trading_strategy`, `daytrading/`) — 자본 최대 **30%**(`DAY_TRADE_MAX_RATIO_DT`, 스윙:DT = 70:30, 스윙은 `SWING_MAX_CAPITAL_RATIO=0.70`로 상한), **MDD -10% 시 비활성**
| 전략 | 진입 | SL |
|------|------|-----|
| ORB | 시초 레인지 돌파 + 거래량≥1.5×평균분당 + 직전 5분봉 양봉 | `max(ORB저점, 현재가×(1-ORB_SL%))` + ATR 하한, -2.5% 클램프 |
| VWAP | VWAP 지지 반등 + RSI(14)<40 + 거래량≥1.3× + 양봉 | `min(ATR×1.5, -2.5% 하드)` + 최소 1원 |
| RSI_BB | RSI≤30 + 종가≤BB하단 + 거래량≥1.3× + 양봉 | `min(ATR×1.5, -2.5% 하드)` + 최소 1원 |
- 사이징: 종목당 6%(`DAY_TRADE_MAX_CAPITAL_RATIO`), 동시 5종목(`DAY_TRADE_MAX_POSITIONS`), confidence 조정 `예산×(confidence/0.7)`
- 청산: +2R 시 50% 분할→잔량 트레일링(ATR×1.0) / 진입 30분(6봉)간 +0.3% 미달 시 시간손절 / 5분 RSI≥70 & 수수료 이상 수익 시 / **15:20 EOD 전량 청산**(`DAY_TRADE_EOD_FLAT_*`) / **전일 미청산 포지션은 장중 발견 즉시 전량 청산**(`close_stale_positions`, EOD 누락 안전장치)
- 제한: CRASH/HALTED 국면 차단 / **15:00 이후 신규 마감**(`DAY_TRADE_ENTRY_CUTOFF_*`, 점심 제한은 2026-09-22 제거) / 일일 -3% 손실 시 당일 중단(`DAY_TRADE_DAILY_LOSS_LIMIT`) / 당일 3연패 쿨다운(position_manager) / 전량 매도 시 loss_tracker 기록 + `save_to_db()`
- 감시종목: 09:00에 당일 분석이 없으면 **최근 분석일 결과로 선채움**(ORB 수집 보장), 자동 목록은 30분마다 갱신(수동 설정 목록은 유지)
## 8. Claude 지침
### 8.1 체크포인트
1. DB 쓰기 = db_worker 경유 (예외: sync_portfolio)
2. 모든 매매에 §5 리스크 규칙 적용
3. SIDEWAYS 국면 진입 제안 금지
4. 백테스트·Walk-forward 없이 실전 투입 금지
5. **SL 선택 = 항상 `min()`(타이트한 쪽). `max()` 절대 금지**
6. `record_trade_result()` 후 `save_to_db()` 호출 확인
7. 쓰기/삭제 API에 `require_api_key` 필수
8. JSON 출력 시 `_dumps()` / 새 기능은 새 파일 / 기존 시그니처 수정 금지
### 8.2 config.py 주요값 (백테스트 검증 2023-03~2026-03 완료)
| 설정 | 값 | 비고 |
|------|-----|------|
| `MAX_POSITION_SIZE` | 0.04 | 0.06→0.04 (2026-09-23, 종목 수 확대) |
| `MIN_BUY_AMOUNT_KRW` | 150,000 | 500,000→150,000 (거래 차단 해소) |
| `MAX_HOLDINGS_COUNT` | 20 | |
| `LEVERAGE_ETF_MAX_RATIO` | 0.20 | |
| `ATR_STOP_MULTIPLIER` | 2.5 | 스윙 ATR SL 배수 |
| `STOP_LOSS_PERCENT` | 7.0 | 6.0→7.0 |
| `MEAN_REVERSION_RSI_THRESHOLD` | 46.0 | 40→46 |
| `MEAN_REVERSION_BEAR_RSI_THRESHOLD` | 35.0 | 30→35 |
| `MEAN_REVERSION_RSI_EXIT_THRESHOLD` | 55.0 | 1차 익절, 50→55 |
| `MEAN_REVERSION_RSI_FULL_EXIT` | 70.0 | 전량 청산, 65→70 |
| `DAY_TRADE_MAX_POSITIONS` | 5 | 8→5 (70:30 배분) |
| `DAY_TRADE_ENTRY_CUTOFF` | 15:00 | 14:30→15:00 (시간대 완화) |
| `DAY_TRADE_MAX_RATIO_DT` / `SWING_MAX_CAPITAL_RATIO` | 0.30 / 0.70 | 스윙:DT 70:30 (2026-09-23) |
| `CONSECUTIVE_LOSS_BAN_COUNT` | 3 | |
### 8.3 스윙 듀얼 전략 (3종 병행)
| 전략 | 진입 | 청산 |
|------|------|------|
| 평균회귀 | RSI 과매도 + BB하단 | RSI 55 부분 → RSI 70 전량 |
| 모멘텀 돌파 | 20일 신고가 + 거래량 2× + RSI 50~70 | +10% 30%매도 → +20% 30%매도 → 트레일링 |
| 눌림목 매수 | MA20>MA60 + MA20 근처 조정 + RSI 반등 | 평균회귀와 동일 |
### 8.4 적응형 모드 (`adaptive_strategy.py` 자동 전환)
| 모드 | RSI 진입 | 포지션 | SL | 트리거 |
|------|---------|--------|-----|--------|
| Aggressive | 50 | 7% | -9% | ATR백분위<30 + ADX>25 + 5일수익>+2% |
| Normal | 46 | 6% | -7% | 기본 |
| Defensive | 38 | 4% | -6% | ATR백분위>70 or 5일수익<-3% |
| Crisis | 25 | 1.5% | -3% | ATR백분위>90 or 5일수익<-5% |
*마지막 업데이트: 2026-09-23 (종목당 4%·최소주문 15만원, 시간대 KST 통일, 감사 수정 14건)*