docs: Update CLAUDE.md to enforce DB worker architecture rules

This commit is contained in:
2026-02-24 12:30:40 +09:00
parent 883f87753c
commit 8b27b9cbb0

View File

@@ -22,7 +22,7 @@
백엔드의 핵심 로직은 `backend/app/` 안에 집약되어 있다. API 엔드포인트는 `api/endpoints/` 아래에 기능별로 분리되어 있으며, 주요 파일로는 시세 조회(`market_data.py`), 포트폴리오 관리 및 ATR 기반 청산(`portfolio.py`), 주문·체결 처리(`trades.py`), 규칙 기반 추천과 자동매매(`recommendations.py`), 매매 규칙 CRUD(`trading_rules.py`), 리스크 관리(`risk_management.py`), ML 앙상블 엔드포인트(`ml_ensemble.py`), 모니터링(`monitoring.py`)이 있다. 백엔드의 핵심 로직은 `backend/app/` 안에 집약되어 있다. API 엔드포인트는 `api/endpoints/` 아래에 기능별로 분리되어 있으며, 주요 파일로는 시세 조회(`market_data.py`), 포트폴리오 관리 및 ATR 기반 청산(`portfolio.py`), 주문·체결 처리(`trades.py`), 규칙 기반 추천과 자동매매(`recommendations.py`), 매매 규칙 CRUD(`trading_rules.py`), 리스크 관리(`risk_management.py`), ML 앙상블 엔드포인트(`ml_ensemble.py`), 모니터링(`monitoring.py`)이 있다.
전략 로직은 `services/` 아래에 모여 있다. RSI+볼린저 평균회귀 전략은 `mean_reversion_strategy.py`(v2)가 담당하고, 코스닥 전종목 스캐너는 `kosdaq_scanner.py`, 15분봉 단기 전략은 `short_term_strategy.py`가 각각 구현한다. 그 외에 MDD 관리(`mdd_manager.py`), 연속 손실 추적(`loss_tracker.py`), 피처 엔지니어링(`feature_engineering.py`), ML 앙상블(`ml_ensemble.py`), TensorFlow 예측(`tensorflow_predictor.py`)도 같은 디렉터리에 위치한다. 전략 로직은 `services/` 아래에 모여 있다. RSI+볼린저 평균회귀 전략은 `mean_reversion_strategy.py`(v2)가 담당하고, 코스닥 전종목 스캐너는 `kosdaq_scanner.py`, 15분봉 단기 전략은 `short_term_strategy.py`가 각각 구현한다. 그 외에 MDD 관리(`mdd_manager.py`), 연속 손실 추적(`loss_tracker.py`), 피처 엔지니어링(`feature_engineering.py`), ML 앙상블(`ml_ensemble.py`), TensorFlow 예측(`tensorflow_predictor.py`), **DB 락을 방지하는 전용 비동기 워커(`db_worker.py`)**도 같은 디렉터리에 위치한다.
MCP 서버는 `mcp-server/` 아래에서 독립적으로 동작한다. `stdio_server.py`가 Claude CLI와의 stdin/stdout 통신을 처리하고, `auto_trade_claude.py`와 `trade_monitor.py`가 실제 매매 판단과 모니터링을 수행한다. MCP 서버는 `mcp-server/` 아래에서 독립적으로 동작한다. `stdio_server.py`가 Claude CLI와의 stdin/stdout 통신을 처리하고, `auto_trade_claude.py`와 `trade_monitor.py`가 실제 매매 판단과 모니터링을 수행한다.
@@ -38,12 +38,18 @@ MCP 서버는 `mcp-server/` 아래에서 독립적으로 동작한다. `stdio_se
--- ---
## 4. 코딩 규칙 ## 4. 코딩 규칙 및 아키텍처 원칙 (핵심)
코드 수정 시 가장 중요한 원칙은 기존 함수·클래스의 시그니처를 변경하지 않는 것이다. 새로운 전략이나 기능을 추가할 때는 반드시 별도의 파일이나 클래스로 분리하고, 파일명에 `_v2`, `_v3` 같은 버전 접미사를 붙인다. 코드 수정 시 가장 중요한 원칙은 기존 함수·클래스의 시그니처를 변경하지 않는 것이다. 새로운 전략이나 기능을 추가할 때는 반드시 별도의 파일이나 클래스로 분리하고, 파일명에 `_v2`, `_v3` 같은 버전 접미사를 붙인다.
`json.dumps`는 직접 사용하지 않는다. 코드베이스 전체에서 `_dumps()` 헬퍼 함수(`core/json_helpers.py`)를 통해 JSON을 직렬화해야 한다. 이 헬퍼는 `TOKEN_SAVE_MODE`가 활성화된 경우 자동으로 compact 포맷을 적용하여 Claude API 호출 시 토큰 소비를 줄여준다. `json.dumps`는 직접 사용하지 않는다. 코드베이스 전체에서 `_dumps()` 헬퍼 함수(`core/json_helpers.py`)를 통해 JSON을 직렬화해야 한다. 이 헬퍼는 `TOKEN_SAVE_MODE`가 활성화된 경우 자동으로 compact 포맷을 적용하여 Claude API 호출 시 토큰 소비를 줄여준다.
**[아키텍처 원칙: DB I/O와 실시간 API 처리 분리]**
DB 병목, 트랜잭션 충돌, 매매일지 누락을 방지하기 위해 **"실시간 처리/API 응답"과 "DB 영속화"를 철저히 분리**한다.
- 체결 콜백 등 실시간 스레드에서 직접 `AsyncSessionLocal()`을 열어 INSERT/UPDATE 하지 않는다.
- 데이터 삽입/갱신 작업은 `app.services.db_worker`의 `db_task_queue`에 던져서 백그라운드 워커가 순차적으로 처리하게 한다.
- 메인 스케줄러(`auto_trade_scheduler`)는 무거운 DB 조회를 최소화하고 메모리 캐시를 우선 참조해야 한다.
AI 프롬프트는 간결하게 작성한다. 필수 필드만 명시하고, JSON 예시는 최소화해야 한다. 변경 단위는 작게 유지하는 것을 원칙으로 하며, 큰 기능 변경보다 작고 검증 가능한 단위로 나누어 커밋한다. AI 프롬프트는 간결하게 작성한다. 필수 필드만 명시하고, JSON 예시는 최소화해야 한다. 변경 단위는 작게 유지하는 것을 원칙으로 하며, 큰 기능 변경보다 작고 검증 가능한 단위로 나누어 커밋한다.
--- ---
@@ -90,7 +96,7 @@ MDD가 -10%를 돌파하면 신규 진입을 일시 중단하고, 기존 포지
### 청산 조건 ### 청산 조건
1차 익절은 RSI(14)가 50 이상으로 회복되거나 종가가 볼린저 중앙선을 상회하거나 수익이 2 × ATR_pct 이상일 때 발동한다. 상승장에서는 40%를 익절하고, 하락장에서는 60%를 익절한다. 1차 익절은 RSI(14)가 50 이상으로 회복되거나 종가가 볼린저 중앙선을 상회하거나 수익이 2 × ATR_pct 이상일 때 발동한다. 상승장에서는 40%를 익절하고, 하락장에서는 60% 익절한다.
2차 익절(전량 청산)은 `최고가 - 1.5 × ATR` 트레일링 스탑에 걸리거나, RSI가 65 이상으로 과열되거나, 종가가 볼린저 상단의 99% 이상에 도달할 때 이루어진다. 2차 익절(전량 청산)은 `최고가 - 1.5 × ATR` 트레일링 스탑에 걸리거나, RSI가 65 이상으로 과열되거나, 종가가 볼린저 상단의 99% 이상에 도달할 때 이루어진다.
@@ -124,8 +130,16 @@ MDD가 -10%를 돌파하면 신규 진입을 일시 중단하고, 기존 포지
코드를 수정하거나 추가할 때는 반드시 다음 원칙을 지켜야 한다. 코드를 수정하거나 추가할 때는 반드시 다음 원칙을 지켜야 한다.
첫째, 기존 코드의 함수·클래스 시그니처는 절대 변경하지 않는다. 새 기능은 항상 `_v2`, `_v3` 접미사가 붙은 별도 파일이나 클래스로 추가한다. 둘째, 백테스트를 거치지 않은 코드를 실전 환경에 즉시 적용해서는 안 된다. 워크포워드 테스트를 포함한 충분한 검증이 선행되어야 한다. 셋째, `json.dumps`를 직접 사용하는 코드는 작성하지 않는다. 반드시 `_dumps()` 헬퍼를 경유해야 한다. 넷째, 포지션 크기·손절가·MDD 규칙·가격 필터 등 리스크 규칙은 어떤 전략에도 예외 없이 기본 적용된다. 다섯째, SIDEWAYS 구간에서 발생한 평균회귀 신호는 코드 레벨에서 무시 처리해야 하며, 사용자에게 진입을 유도하는 응답을 해서는 안 된다. 여섯째, 15분봉 단기 전략의 자본 배분은 전체의 25%를 절대 초과할 수 없다. 일곱째, MDD -10% 돌파 시 단기 전략을 즉시 중단하는 로직이 호출 측에 존재하는지 항상 확인한다. 여덟째, 코스닥 스캐너가 종목을 선별할 때 가격 5,000원 이상 + 거래대금 상위 20% 필터가 반드시 적용되어야 한다. 첫째, 기존 코드의 함수·클래스 시그니처는 절대 변경하지 않는다. 새 기능은 항상 `_v2`, `_v3` 접미사가 붙은 별도 파일이나 클래스로 추가한다.
둘째, 백테스트를 거치지 않은 코드를 실전 환경에 즉시 적용해서는 안 된다. 워크포워드 테스트를 포함한 충분한 검증이 선행되어야 한다.
셋째, `json.dumps`를 직접 사용하는 코드는 작성하지 않는다. 반드시 `_dumps()` 헬퍼를 경유해야 한다.
넷째, 포지션 크기·손절가·MDD 규칙·가격 필터 등 리스크 규칙은 어떤 전략에도 예외 없이 기본 적용된다.
다섯째, SIDEWAYS 구간에서 발생한 평균회귀 신호는 코드 레벨에서 무시 처리해야 하며, 사용자에게 진입을 유도하는 응답을 해서는 안 된다.
여섯째, 15분봉 단기 전략의 자본 배분은 전체의 25%를 절대 초과할 수 없다.
일곱째, MDD -10% 돌파 시 단기 전략을 즉시 중단하는 로직이 호출 측에 존재하는지 항상 확인한다.
여덟째, 코스닥 스캐너가 종목을 선별할 때 가격 5,000원 이상 + 거래대금 상위 20% 필터가 반드시 적용되어야 한다.
아홉째, **실시간 처리 로직 내부에서는 DB 세션을 열어 직접 데이터를 넣거나 갱신하지 말 것. 모든 영속성 작업은 전용 비동기 큐(`db_worker.py`)를 통해 우회 처리한다.**
--- ---
*Last updated: 2026-02-22* *Last updated: 2026-02-24*