Files
auto-stock/CLAUDE.md
shuim 5f0f839039 전략 취약점 15건 수정 (코드 리뷰 기반)
## CRITICAL/HIGH (S1-S8)
- S1: Aggressive 모드 %B 스케일링 캡 1.3 (BB 중앙선 위 매수 방지)
- S2: ML scaler train-only fit (데이터 누수 제거)
- S3: SIDEWAYS = ADX<20 AND slope≈0 (트렌드 초기 차단 해소)
- S4: EOD 청산 실패 시 재시도 + CRITICAL 로그
- S5: 일일 손실 한도에 미실현 P&L 포함
- S6: trailing stop 고점 매 사이클 갱신
- S7: 섹터 필터 미매핑 종목 "기타" 분류 (max 3 적용)
- S8: 스캐너 RSI 기준 25→46, BB 점수 -3%~+1.5% 구간

## MEDIUM (M1-M7)
- M1: 스캐너 최소 거래량 100만→10만주
- M2: ADX 히스테리시스 18/22 (국면 플리핑 방지)
- M3: 분할매도 최소 수익 1.0%→0.5%
- M4: ORB 갭 필터 4% + 레인지 폭 0.3% 최소
- M5: 쿨다운 스트릭 부분매도 시 미변경
- M6: MDD 강제매도 loss_tracker 기록 제거 (허위 ban 방지)
- M7: RSI Wilder 스무딩으로 통일

## 인프라/보안
- 인증 누락 엔드포인트 수정 (analysis, journals)
- nginx 보안 헤더 location 블록 누락 수정
- Alembic 마이그레이션 IF NOT EXISTS 가드 추가
- SellRequest/UsOrderRequest 입력 검증 강화
- 차트 네이버 폴백 추가 (DB 데이터 없을 때)
- 서버 이전 시 자동 DB 마이그레이션 + KRX 초기 수집
- CLAUDE.md 섹션 5.1 백테스트 값 동기화 (4%→6%, -6%→-7%)
- MAX_SWING_POSITIONS 25→20 (CLAUDE.md 준수)
- mdd_manager failed_count에서 skip 종목 제외

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:44:14 +09:00

17 KiB
Raw Blame History

자동 주식 매매 시스템 — Claude 컨텍스트 가이드

핵심 지침 (Core Directive): 이 문서는 시스템의 전략, 규칙 및 아키텍처를 정의합니다. 모든 코드 수정 및 분석은 이 가이드라인을 엄격하게 준수해야 합니다.


1. 프로젝트 개요

1.1 기술 스택

  • 백엔드: Python 3.11, FastAPI, SQLAlchemy 2.0 (Async), PostgreSQL 15, Redis 7, RabbitMQ 3
  • 프론트엔드: React 18, TypeScript, Vite, Recharts, Lightweight Charts
  • 인프라: Docker Compose, Nginx, Alembic (DB 마이그레이션)
  • AI 계층: Claude 3.5 Sonnet / Gemini 2.0 Flash (.env의 AI_PROVIDER로 전환)
  • ML: PyTorch, LightGBM, scikit-learn (앙상블 예측)
  • 연동 (Integration): 한국투자증권(KIS) REST/WebSocket API, MCP Server (stdio)

1.2 주요 환경 변수 (.env)

  • AI_PROVIDER: gemini 또는 claude
  • KIS_MODE: virtual (모의투자) 또는 real (실전투자)
  • TOKEN_SAVE_MODE: true (JSON을 압축하고, 차트 데이터를 30일치로 제한함)
  • AUTO_TRADE_ENABLED: 자동 매매 활성화 여부
  • US_TRADING_ENABLED: 미국 주식 매매 활성화 여부

2. 디렉토리 구조

2.1 백엔드 (backend/app/)

  • API: api/endpoints/ — 20개 엔드포인트 모듈 (portfolio, market_data, trades, day_trading, backtest 등)
  • 코어 (Core): core/config.py (전역 설정), core/database.py, core/security.py (API 키 인증), core/json_helpers.py, core/market_schedule.py
  • 모델 (Models): models/models.py — SQLAlchemy ORM (Portfolio, TradeHistory, ActiveTrade, StockAnalysis, StockBan 등)
  • 실시간 (Realtime): realtime/websocket_client.py, realtime/event_handler.py
  • 전략 추상화 (Strategy): strategy/base_strategy.py, strategy/strategy_manager.py

2.2 서비스 (backend/app/services/)

  • 전략 (Strategies):
    • mean_reversion_strategy.py — RSI+BB 평균 회귀 v2 (섹션 6)
    • short_term_strategy.py — 15분봉 단기 전략 (섹션 7.2)
    • day_trading_strategy.py — 5분봉 데이트레이딩 ORB/VWAP/RSI_BB (섹션 7.3)
    • kosdaq_scanner.py — 코스닥 스윙 스캐너 (섹션 7.1)
    • us_stock_strategy.py — 미국 주식 전략
  • 데이트레이딩 모듈 (Modular): daytrading/entry_service.py, daytrading/exit_service.py, daytrading/position_manager.py, daytrading/scheduler.py
  • 스윙 모듈 (Modular): swing/entry_service.py, swing/exit_service.py, swing/position_manager.py, swing/scheduler.py
  • 매매 실행: trade_executor.py — 핵심 매매 엔진 (매수/매도/체결확인/슬리피지)
  • 분석 (Analysis): feature_engineering.py, ml_ensemble.py, tensorflow_predictor.py, technical_indicators.py
  • 리스크: mdd_manager.py (MDD 추적 + 자동 축소 실행), loss_tracker.py (연속 손실 ban), correlation_filter.py (상관관계 필터)
  • 아키텍처: db_worker.py (비동기 DB 처리 워커, 재시도 3회)
  • 데이터: korea_investment_api.py (KIS REST), kis_realtime_stream.py (KIS WebSocket), naver_finance.py
  • 유틸: websocket_manager.py, order_dispatcher.py, signal_types.py, watchlist.py

2.3 MCP (mcp-server/)

  • stdio_server.py, auto_trade_claude.py, claude_client.py, gemini_client.py, trade_monitor.py, risk_validator.py, mcp_tools.py

2.4 배치 스크립트 (backend/)

  • batch_daily_analysis.py — 일일 분석 배치
  • batch_intraday_analysis.py — 장중 분석 배치
  • train_ensemble.py — ML 모델 학습
  • collect_krx_data.py — KRX 데이터 수집

3. 아키텍처 원칙 (필수 준수 사항)

3.1 관심사 분리 (Separation of Concerns)

  • 실시간 계층 (Real-time Layer): API 콜백, 웹소켓 브로드캐스트 및 메모리 캐싱을 처리합니다. DB I/O(데이터베이스 입출력)는 절대 허용되지 않습니다.
  • 영속성 계층 (Persistence Layer): 백그라운드 워커를 통해 DB INSERT/UPDATE 작업을 처리합니다.
  • 예외: sync_portfolio()는 SELECT→UPDATE/DELETE→commit이 같은 트랜잭션에서 이뤄져야 하므로 API 엔드포인트 경로에서 직접 DB 접근을 허용합니다.

3.2 비동기 DB 워커 규칙

  • 직접적인 DB 접근 금지: API 콜백이나 실시간 스케줄러 내부에서 AsyncSessionLocal() 또는 commit()을 절대 호출하지 마십시오.
  • 큐(Queue) 사용: 모든 데이터 저장(매매 내역, 분석 결과 등)은 db_worker.py의 db_task_queue로 보내야 합니다.
  • 워커 (Worker): 백그라운드 워커가 큐를 처리하고 안전한 DB 트랜잭션을 순차적으로 수행합니다.
  • 재시도: 실패한 task는 최대 3회까지 지수 백오프(1→2→4초)로 재시도합니다.
  • 지원 task 타입: insert_trade_history, update_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

3.3 동시성 안전

  • 종목별 세마포어: trade_executor.py의 _order_semaphores로 동일 종목 동시 주문 방지.
  • Redis 분산 락: 여러 워커 프로세스간 동일 종목 동시 매도 방지.
  • loss_tracker 락: asyncio.Lock으로 _tracker 딕셔너리 보호. 동시 접근 경로에서는 is_banned_safe(), record_trade_result_safe() 사용.
  • MDD 매니저 락: asyncio.Lock으로 MDD 업데이트 및 축소 실행 보호.

4. 코딩 가이드라인

4.1 안정성

  • 기존 코드 파괴 금지 (No Breaking Changes): 기존 함수나 클래스의 시그니처를 절대 변경하지 마십시오.
  • 버전 관리: 새로운 전략 구현 시 _v2, _v3 등의 접미사를 사용하십시오.
  • 안전 래퍼: 기존 동기 API를 비동기로 확장할 때 _safe 접미사의 새 메서드를 추가하십시오 (예: is_banned_safe()).

4.2 최적화

  • JSON 처리: json.dumps 대신 항상 core.json_helpers._dumps()를 사용하십시오.
  • 프롬프트 엔지니어링: 토큰 사용을 최소화하고 컴팩트한 포맷을 사용하십시오.

4.3 보안

  • API 인증: 쓰기/삭제 엔드포인트에는 반드시 Depends(require_api_key)를 적용하십시오.
  • SSL 검증: 외부 API 호출 시 verify=True 유지 (KIS API 포함).
  • 비밀키: .env의 SECRET_KEY는 64자 이상 랜덤 문자열 사용.

5. 리스크 관리 규칙

5.1 포지션 사이징 (Position Sizing)

  • 최대 비중: 종목당 총 자본의 6% (config.py: MAX_POSITION_SIZE = 0.06, 백테스트 검증 반영).
  • 최대 보유 종목 수: 20개 (config.py: MAX_HOLDINGS_COUNT = 20).
  • 레버리지: 인버스/레버리지 ETF의 경우 총 자본의 최대 **20%**로 제한 (config.py: LEVERAGE_ETF_MAX_RATIO = 0.20).

5.2 손절(SL) 및 익절(TP) — 일봉/스윙 기준

  • 기본 손절 (SL Base): -7% (안정적 종목), -10% (변동성 종목). (백테스트 검증: 기존 -6% → -7%)
  • ATR 손절: 진입가 - (2.5 * ATR) (config.py: ATR_STOP_MULTIPLIER = 2.5). 기본 손절과 ATR 손절 중 타이트한(더 작은) 쪽 적용 — 코드에서 min(stop_loss, atr_stop_pct) 사용.
  • 익절 (TP): +2R 수익(리스크 대비 2배 수익) 도달 시 50% 분할 매도.
  • 트레일링 스탑 (Trailing Stop): 나머지 50% 물량에 대해 고점 - (1.5 * ATR) 적용.

5.3 MDD(최대 낙폭) 관리

  • MDD -10%: 신규 진입을 중단합니다. 포지션 규모를 30% 축소합니다. 단기 매매 전략 및 데이트레이딩을 중단합니다. (mdd_manager.py: REDUCE_AND_PAUSE)
  • MDD -20%: 모든 포지션을 강제로 50% 축소합니다. 레버리지/인버스 ETF부터 우선 청산합니다. (mdd_manager.py: FORCE_REDUCE)
  • 자동 실행: mdd_manager.execute_reduction()이 portfolio.py와 swing/scheduler.py에서 자동 호출됩니다. 중복 실행 방지 플래그가 내장되어 있습니다.
  • 복구: 잔고가 peak를 갱신하면 모든 MDD 플래그가 리셋됩니다.

5.4 필터 (Filters)

  • 가격: 5,000원 초과 (국내), $4 초과 (미국). (예외: ETF, 리츠). (config.py: MIN_PRICE_KRW = 5000, MIN_PRICE_USD = 4.0)
  • 상관관계 (Correlation): 섹터당 최대 3종목 (correlation_filter.py: max_per_sector = 3). 기존 포트폴리오와의 상관계수가 0.7을 초과하면 진입을 거부합니다.

5.5 연속 손실 관리

  • 동일 종목에서 3회 연속 손실 시 42캘린더일(≈30거래일) 진입 금지 (loss_tracker.py).
  • DB 영속화: save_to_db() → db_worker의 upsert_stock_ban 경유.
  • 앱 재시작 시 load_from_db()로 ban 상태 복원.

6. 전략 A: RSI + 볼린저 밴드 평균 회귀 v2

구현 파일: mean_reversion_strategy.py, swing/ 모듈 자산 배분: 스윙 포트폴리오 (코스닥 스캐너 25% 외 나머지)

6.1 시장 국면 (일봉 기준)

  • 상승장 (BULL): 코스피200 > 200일 이동평균선(MA200) AND MA200 기울기 > 0.
  • 하락장 (BEAR): 코스피200 < MA200 AND MA200 기울기 < 0.
  • 횡보장 (SIDEWAYS): ADX < 20 OR 기울기 ≈ 0. (이 국면에서는 모든 진입 신호를 무시합니다)
    • market_analyzer.py에서 position_multiplier=0.0, max_trades=0 반환.

6.2 진입 조건

  • 상승장: RSI(14) < 40 (기본값, .env에서 MEAN_REVERSION_RSI_THRESHOLD로 조정 가능), 가격이 볼린저 밴드(BB) 하단 부근 (-3% ~ +1.5%), 거래량 > 20일 평균 거래량(20MA).
  • 하락장: RSI(14) < 30, 가격 < 볼린저 밴드 하단, 거래량 > 1.5배 × 20MA, 반전 캔들(Reversal candle) 필수.
  • 선제 진입 (Pre-emptive): 일봉 RSI < 40 AND 60분봉 RSI < 30 AND 5일 이동평균선(MA5) 상향 돌파.

6.3 청산 조건

  • 부분 매도 (50%): RSI >= 50 OR 가격 > 볼린저 밴드 중앙선 OR 수익 > 2×ATR.
  • 전량 매도: RSI >= 65 OR 가격 > 볼린저 밴드 상단 (99%) OR 트레일링 스탑 도달 (고점 - 1.5×ATR).

7. 전략 B: 공격적 성장 (Aggressive Growth)

7.1 코스닥 스캐너 (스윙 매매)

구현 파일: kosdaq_scanner.py

  • 대상 (Scope): 코스닥 전 종목 (약 1,600개).
  • 필터 (Filter): 가격 > 5,000원, 거래량 상위 20%.
  • 점수 (Score): 0.5×RSI_score + 0.3×BB_score + 0.2×Vol_score. 최소 점수 0.15 이상인 종목 중 상위 20개 선정.
  • 자산 배분 (Allocation): 전체 자본의 25%.

7.2 단기 전략 (15분봉)

구현 파일: short_term_strategy.py

  • 타겟 (Target): 일봉 RSI < 40 인 종목.
  • 진입 (Entry): 15분봉 RSI < 30, 가격이 볼린저 밴드 하단 부근, 종가 > MA5 (상향 돌파 확인), 거래량 > 1.3배 × 20MA (config.py: SHORT_TERM_VOLUME_MULTIPLIER = 1.3).
  • 최소 변동성: ATR/close ≥ 0.8% (config.py: SHORT_TERM_MIN_ATR_RATIO = 0.008) — 거래비용 커버 보장.
  • 청산 (Exit): 15분봉 RSI > 55 OR 수익 > 1.5 × ATR(15분봉).
  • 손절 (SL): 진입가 - 1.0 × ATR(15분봉) 또는 -2% 하드 스탑 중 타이트한(더 높은 stop_price) 쪽 — 코드에서 min(atr_stop, hard_stop) 사용. (15분봉 단기전략 전용 — 섹션 5.2 ATR 2.5×는 일봉/스윙 기준)
  • 자산 배분 (Allocation): 전체 자본의 최대 25%. MDD가 -10% 미만이면 비활성화합니다.

7.3 데이트레이딩 (5분봉, ORB/VWAP/RSI_BB)

구현 파일: day_trading_strategy.py, daytrading/ 모듈

전략 3종

전략 진입 조건 손절 기준
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(14) ≤ 30 + 종가 ≤ BB 하단 + 거래량 ≥ 1.3× + 양봉 min(ATR×1.5 기반, 하드스탑 -2.5%) + 최소 1원 보장

포지션 사이징

  • 종목당 최대 4% (섹션 5.1 준수, config.py: DAY_TRADE_MAX_CAPITAL_RATIO = 0.04).
  • 동시 최대 3종목 (config.py: DAY_TRADE_MAX_POSITIONS = 3).
  • confidence 기반 동적 조정: 예산 × (signal.confidence / 0.7).

자산 배분

  • 전체 자본의 최대 25% (config.py: DAY_TRADE_MAX_RATIO_DT = 0.25).

청산 규칙

  • 분할 매도: 목표가(+2R) 달성 시 50% 분할 매도, 잔량은 트레일링 스탑(ATR × 1.0) 적용.
  • 시간 손절: 진입 후 30분(6봉)간 +0.3% 미달 시 청산 (기회비용 관리).
  • 과매수 청산: 5분봉 RSI ≥ 70 AND 수수료 이상 수익 시 청산.
  • EOD 강제 청산: 15:20 이후 전량 청산 (config.py: DAY_TRADE_EOD_FLAT_HOUR/MIN).

필터 및 제한

  • 시장 국면: SIDEWAYS 국면에서 진입 차단 (섹션 6.1 준수).
  • 시간대 제한: 점심시간(11:30~13:00) VWAP/RSI_BB 진입 제한, 14:30 이후 신규 진입 마감.
  • 일일 손실 한도: -3% 초과 시 당일 신규 진입 중단 (config.py: DAY_TRADE_DAILY_LOSS_LIMIT = -0.03).
  • 쿨다운: 당일 3연패 시 신규 진입 차단 (daytrading/position_manager.py).
  • loss_tracker 연동: 전량 매도 시 loss_tracker.record_trade_result() + save_to_db() 호출.
  • MDD -10% 미만이면 비활성화합니다.

8. Claude에 대한 지침

8.1 주요 점검 사항 (Critical Checkpoints)

  1. 아키텍처: 모든 DB 쓰기 작업이 db_worker.py를 사용하는지 확인하십시오. 예외: sync_portfolio().
  2. 안전성 (Safety): 모든 매매에 리스크 규칙(섹션 5)을 항상 적용하십시오.
  3. 시장 국면 (Regime): 횡보장(SIDEWAYS) 국면에서는 진입을 제안하지 마십시오.
  4. 테스트: 백테스트 및 전진 분석(Walk-forward validation) 없이는 실전 투자를 하지 마십시오.
  5. 손절 방향: 손절가 선택 시 항상 min() (타이트한 쪽)을 사용하십시오. max()는 절대 사용하지 마십시오.
  6. loss_tracker 영속화: record_trade_result() 호출 후 반드시 save_to_db() 호출을 확인하십시오.
  7. 인증: 쓰기/삭제 API에는 반드시 require_api_key 의존성을 적용하십시오.

8.2 응답 형식 (Response Format)

  • JSON 출력 시 _dumps()를 사용하십시오.
  • 새로운 기능 개발 시 새 파일을 생성하십시오.
  • 기존 시그니처를 수정하지 마십시오.

8.3 주요 설정값 참조 (config.py) — 백테스트 검증 완료

설정 값 설명 백테스트 변경
MAX_POSITION_SIZE 0.06 종목당 최대 6% 기존 0.04 → 0.06
MAX_HOLDINGS_COUNT 20 동시 보유 최대 유지
LEVERAGE_ETF_MAX_RATIO 0.20 레버리지 ETF 최대 유지
ATR_STOP_MULTIPLIER 2.5 스윙 ATR 손절 배수 유지
STOP_LOSS_PERCENT 7.0 기본 손절 7% 기존 6.0 → 7.0
MEAN_REVERSION_RSI_THRESHOLD 46.0 평균회귀 RSI 임계값 기존 40.0 → 46.0
MEAN_REVERSION_BEAR_RSI_THRESHOLD 35.0 BEAR RSI 임계값 기존 30.0 → 35.0
MEAN_REVERSION_RSI_EXIT_THRESHOLD 55.0 1차 익절 RSI 기존 50.0 → 55.0
MEAN_REVERSION_RSI_FULL_EXIT 70.0 전량 청산 RSI 기존 65.0 → 70.0
DAY_TRADE_MAX_POSITIONS 3 데이트레이딩 동시 최대 유지
DAY_TRADE_ENTRY_CUTOFF 14:30 데이트레이딩 마감 기존 15:00 → 14:30
CONSECUTIVE_LOSS_BAN_COUNT 3 연속 손실 ban 횟수 유지

8.4 듀얼 전략 (백테스트 검증: 2023-03 ~ 2026-03)

스윙 전략은 3가지 진입 전략을 병행합니다:

전략 조건 청산 방식 기여도
평균회귀 RSI 과매도 + BB 하단 RSI 55 부분익절 → RSI 70 전량 베이스 수익
모멘텀 돌파 20일 신고가 + 거래량 2x + RSI 50~70 +10% 30%매도 → +20% 30%매도 → 트레일링 큰 이익
눌림목 매수 MA20>MA60 + MA20 근처 조정 + RSI 반등 평균회귀와 동일 안정 수익

8.5 적응형 모드 (4단계)

시장 상황에 따라 파라미터가 자동 전환됩니다 (adaptive_strategy.py):

모드 RSI 진입 포지션 손절 트리거
Aggressive 50 7% -9% ATR백분위<30 + ADX>25 + 5일수익>+2%
Normal 46 6% -7% 기본
Defensive 38 4% -6% ATR백분위>70 또는 5일수익<-3%
Crisis 25 1.5% -3% ATR백분위>90 또는 5일수익<-5%

마지막 업데이트: 2026-03-25 (백테스트 검증 반영)