전체적인 리팩토링

This commit is contained in:
2026-03-12 09:26:27 +09:00
parent 406af7408a
commit e51d767878
97 changed files with 13651 additions and 363 deletions

View File

@@ -0,0 +1,82 @@
# 자동매매 모델 카탈로그 운영 런북 (Codex/Gemini)
이 문서는 **새 모델이 나왔을 때** 자동매매 모델 선택 UI/서버 설정을 안전하게 갱신하기 위한 운영 절차입니다.
## 1) 목적
1. Codex/Gemini 신모델을 빠르게 목록에 반영한다.
2. 잘못된 모델 ID로 인해 자동매매가 fallback으로 떨어지는 문제를 줄인다.
3. 운영자가 "어디를 고치고 어떻게 검증하는지"를 한 번에 확인할 수 있게 한다.
## 2) 적용 범위
1. 자동매매 설정창 모델 드롭다운
2. 서버 모델 선택 우선순위(env + UI)
3. 전략/신호 응답에서 `providerVendor`, `providerModel` 추적
## 3) 빠른 절차 (입력 -> 처리 -> 결과)
1. 입력: 공식 문서에서 신규 모델 ID 확인
2. 처리: 모델 옵션 상수 + 안내 문구 + 기본 env 값 점검
3. 결과: UI 선택 가능 + 로그/응답에서 실제 모델 확인 가능
## 4) 공식 소스(항상 여기 먼저 확인)
1. OpenAI Codex CLI: <https://developers.openai.com/codex/cli>
2. OpenAI Models: <https://platform.openai.com/docs/models>
3. Gemini CLI model command: <https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/model.md>
4. Gemini CLI model routing: <https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/model-routing.md>
5. Gemini API models: <https://ai.google.dev/gemini-api/docs/models>
## 5) 코드 반영 위치
1. 모델 드롭다운 목록
- `features/autotrade/types/autotrade.types.ts`
- `AUTOTRADE_SUBSCRIPTION_CLI_MODEL_OPTIONS.codex`
- `AUTOTRADE_SUBSCRIPTION_CLI_MODEL_OPTIONS.gemini`
2. 기본값/우선순위 점검
- `lib/autotrade/strategy.ts` (`resolveDefaultSubscriptionCliModel`)
- `lib/autotrade/cli-provider.ts` (`resolveSubscriptionCliModel`)
3. 사용자 안내 문구(필요 시)
- `features/autotrade/components/AutotradeControlPanel.tsx`
4. 샘플 환경변수 문서화
- `.env.example`
## 6) 모델 추가 규칙
1. 모델 ID는 **공식 문서 표기 그대로** 입력한다.
2. preview 모델은 라벨에 `(프리뷰)`를 명시한다.
3. 종료 예정 모델은 라벨/설명에 종료 예정일을 남긴다.
4. 기존 안정형 모델 1개 이상은 항상 남겨둔다.
5. 목록에 없는 모델도 쓸 수 있도록 `직접 입력` 경로는 유지한다.
## 7) 검증 체크리스트
- [ ] 드롭다운에 신규 모델이 보인다.
- [ ] 신규 모델 선택 후 compile/signal 요청 payload에 `subscriptionCliModel`이 들어간다.
- [ ] 응답에 `providerVendor`, `providerModel`이 기대값으로 온다.
- [ ] 자동매매 로그에 `subscription_cli:vendor:model`이 표시된다.
- [ ] `npm run -s lint` 통과
## 8) 수동 검증 포인트(화면 기준)
1. 자동매매 설정 -> 구독형 CLI 엔진 선택(codex 또는 gemini)
2. 신규 모델 선택 후 자동매매 시작
3. 로그에서 아래 3개 필드 확인
- `subscriptionCliVendor`
- `subscriptionCliModel`
- `providerModel`
## 9) 장애 대응
1. 모델 호출 실패 시 우선 `직접 입력`으로 동일 ID 재시도
2. 계속 실패하면 직전 안정 모델로 즉시 롤백
3. `AUTOTRADE_SUBSCRIPTION_CLI_DEBUG=1`로 서버 로그에서 CLI stderr 확인
## 10) 변경 이력 템플릿
```md
- YYYY-MM-DD: [vendor] modelA, modelB 추가
- YYYY-MM-DD: [vendor] modelX 종료 예정 표기
- YYYY-MM-DD: 기본 추천 모델 변경 (old -> new)
```

View File

@@ -0,0 +1,144 @@
# 자동매매 프롬프트 흐름 추적 가이드 (UI -> 함수 -> AI -> 주문)
이 문서는 "전략 프롬프트를 입력하면 실제로 어디 함수로 흘러가고, 어디서 AI가 호출되는지"를 코드 라인 기준으로 설명합니다.
## 1) 한 줄 요약
사용자가 UI에 프롬프트를 입력하면, 시작/검증 시점에 `compile` API로 전달되어 전략 JSON으로 바뀌고, 실행 중에는 그 전략 JSON + 실시간 시세로 신호를 생성해 주문 여부를 결정합니다.
## 2) 구조 그림
```text
[브라우저 UI]
AutotradeControlPanel.tsx
└─ 프롬프트 입력 + 시작/검증 클릭
[브라우저 엔진 훅]
useAutotradeEngine.ts
└─ prepareStrategy()에서 compile/validate 실행
[브라우저 API 클라이언트]
autotrade.api.ts
└─ /api/autotrade/strategies/compile 호출
[Next 서버 route]
strategies/compile/route.ts
└─ OpenAI / subscription_cli / fallback 분기
[AI Provider]
openai.ts 또는 cli-provider.ts
└─ 전략 JSON 반환
[브라우저 엔진 훅]
useAutotradeEngine.ts
└─ compiledStrategy 저장 후 실행 루프 시작
[신호 루프]
/api/autotrade/signals/generate -> 리스크 게이트 -> 주문 API
```
## 3) 프롬프트 입력 -> 전략 컴파일 (상세 추적)
1. 프롬프트 입력 UI
- 컴포넌트: [`AutotradeControlPanel.tsx#L335`](../../features/autotrade/components/AutotradeControlPanel.tsx#L335)
- 입력 이벤트: [`handlePromptChange`](../../features/autotrade/components/AutotradeControlPanel.tsx#L123)
- store 반영: [`patchSetupForm({ prompt })`](../../features/autotrade/components/AutotradeControlPanel.tsx#L126)
- 같은 화면에서 구독형 CLI vendor/model도 선택 가능: `subscriptionCliVendor`, `subscriptionCliModel`
2. 시작/검증 버튼 클릭
- 시작 버튼 핸들러: [`handleStartAutotrade`](../../features/autotrade/components/AutotradeControlPanel.tsx#L102)
- 검증 버튼 핸들러: [`handlePreviewValidation`](../../features/autotrade/components/AutotradeControlPanel.tsx#L113)
3. 엔진 훅에서 전략 준비
- 함수: [`prepareStrategy()`](../../features/autotrade/hooks/useAutotradeEngine.ts#L138)
- compile 호출: [`compileAutotradeStrategy(...)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L153)
4. 브라우저 API 클라이언트
- 함수: [`compileAutotradeStrategy`](../../features/autotrade/apis/autotrade.api.ts#L30)
- HTTP 호출: [`POST /api/autotrade/strategies/compile`](../../features/autotrade/apis/autotrade.api.ts#L36)
- 전달 필드: `aiMode`, `subscriptionCliVendor`, `subscriptionCliModel`, `prompt`, `selectedTechniques`, `confidenceThreshold`
5. Next API route에서 provider 분기
- 엔드포인트: [`strategies/compile/route.ts#L44`](../../app/api/autotrade/strategies/compile/route.ts#L44)
- fallback 전략 준비: [`createFallbackCompiledStrategy`](../../app/api/autotrade/strategies/compile/route.ts#L67)
- OpenAI 분기: [`compileStrategyWithOpenAi`](../../app/api/autotrade/strategies/compile/route.ts#L87)
- 구독형 CLI 분기: [`compileStrategyWithSubscriptionCliDetailed`](../../app/api/autotrade/strategies/compile/route.ts#L119)
6. OpenAI 실제 호출 지점
- OpenAI 전략 함수: [`compileStrategyWithOpenAi`](../../lib/autotrade/openai.ts#L51)
- 공통 호출기: [`callOpenAiJson`](../../lib/autotrade/openai.ts#L203)
- 외부 API: [`https://api.openai.com/v1/chat/completions`](../../lib/autotrade/openai.ts#L19)
7. 컴파일 결과 반영
- compiledStrategy 저장: [`setCompiledStrategy(...)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L160)
- validate 저장: [`setValidation(...)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L173)
## 4) 실행 중 "자동 프롬프트"가 도는 방식
중요: 실행 중 매 틱마다 자연어 프롬프트를 다시 보내지 않습니다.
1. 시작 시점에만 프롬프트를 전략 JSON으로 컴파일합니다.
2. 실행 루프에서는 "컴파일된 전략 JSON + 현재 시세 스냅샷"으로 신호를 만듭니다.
관련 코드:
1. 신호 요청 주기(12초): [`SIGNAL_REQUEST_INTERVAL_MS`](../../features/autotrade/hooks/useAutotradeEngine.ts#L51)
2. 신호 API 호출: [`generateAutotradeSignal(...)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L495)
3. 서버 신호 route: [`signals/generate/route.ts#L74`](../../app/api/autotrade/signals/generate/route.ts#L74)
4. 신호 생성 OpenAI 함수: [`generateSignalWithOpenAi`](../../lib/autotrade/openai.ts#L116)
신호 요청 시 스냅샷 실제 필드:
1. `symbol`
2. `currentPrice`
3. `changeRate`
4. `open`
5. `high`
6. `low`
7. `tradeVolume`
8. `accumulatedVolume`
9. `recentPrices`
## 5) 신호 -> 주문 판단 (자동 실행 핵심)
1. 신호 생성 결과 수신: [`runtime.setLastSignal(signal)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L504)
2. 리스크 게이트 검사: [`evaluateSignalBlockers(...)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L516)
3. 통과 시 주문 API 호출: [`fetchOrderCash(...)`](../../features/autotrade/hooks/useAutotradeEngine.ts#L556)
즉, AI가 `buy/sell`을 주더라도 리스크 게이트를 통과하지 못하면 주문은 실행되지 않습니다.
## 6) AI를 못 쓰는 경우
1. 전략 폴백: [`createFallbackCompiledStrategy`](../../lib/autotrade/strategy.ts#L26)
2. 신호 폴백: [`createFallbackSignalCandidate`](../../lib/autotrade/strategy.ts#L48)
AI(OpenAI/CLI) 응답 실패 시에도 시스템이 멈추지 않고 보수적으로 동작하도록 설계되어 있습니다.
## 7) Codex CLI인지 Gemini CLI인지 확인하는 법
1. 자동매매 로그에서 확인
- `신호 수신 [subscription_cli:codex:gpt-5-codex]` 또는 `신호 수신 [subscription_cli:gemini:flash]`
- 로그 코드: [`useAutotradeEngine.ts`](../../features/autotrade/hooks/useAutotradeEngine.ts#L564)
2. Network 응답에서 확인
- 전략 컴파일 응답: `compiledStrategy.providerVendor`
- 신호 생성 응답: `signal.providerVendor`
3. 실패 시 어떤 순서로 시도했는지 확인
- 파싱 실패 문구에 `selected=vendor:model; attempts=vendor:model:status` 포함
- `status=timeout`이면 CLI 실행시간 초과입니다. `AUTOTRADE_SUBSCRIPTION_CLI_TIMEOUT_MS`를 늘리세요(권장: 60000).
- 생성 코드: [`summarizeSubscriptionCliExecution`](../../lib/autotrade/cli-provider.ts#L112)
4. 모델 선택 환경변수
- `AUTOTRADE_CODEX_MODEL` (예: `gpt-5-codex`)
- `AUTOTRADE_GEMINI_MODEL` (예: `auto`, `pro`, `flash`, `flash-lite`)
- `AUTOTRADE_SUBSCRIPTION_CLI_MODEL` (vendor 전용 값이 없을 때 공통 fallback)
5. 모델 선택 UI (환경변수보다 우선)
- 자동매매 설정창에서 `subscriptionCliVendor`, `subscriptionCliModel` 선택 시 해당 값이 API payload로 전달되어 CLI 실행 인자에 우선 적용됩니다.

View File

@@ -0,0 +1,407 @@
# 자동매매 사용/검증/보안 가이드 (3계층 구조)
이 문서는 자동매매를 아래 3개 영역으로 나눠서 설명합니다.
1. 사용자 브라우저
2. Next.js 서버(API)
3. 워커(Node)
프롬프트 입력값이 실제로 어디 함수/어디 API로 흘러가는지 추적하려면 아래 문서를 같이 보세요.
- `common-docs/features/autotrade-prompt-flow-guide.md`
---
## 1) 한눈에 구조
```text
┌───────────────────────────── 사용자 브라우저 ─────────────────────────────┐
│ /trade 자동매매 UI │
│ - 설정 입력(전략/투자금/손실한도/임계치) │
│ - start/stop/heartbeat/signals 호출 │
└───────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────── Next.js 서버 (API) ──────────────────────────┐
│ /api/autotrade/strategies/* │
│ /api/autotrade/sessions/* │
│ /api/autotrade/signals/generate │
│ /api/autotrade/worker/tick │
└───────────────────────────────────────────────────────────────────────────┘
│ x-autotrade-worker-token
┌────────────────────────────── Worker (Node) ─────────────────────────────┐
│ scripts/autotrade-worker.mjs │
│ - 주기적으로 /api/autotrade/worker/tick 호출 │
│ - heartbeat 만료 세션 정리 │
└───────────────────────────────────────────────────────────────────────────┘
```
---
## 1-1) 개발 실행 시 (내 PC 기준)
1. 브라우저: React 화면 사용
2. Next 개발 서버(`npm run dev`): 화면 + API를 함께 처리
3. 워커(`node scripts/autotrade-worker.mjs`): tick 호출 담당
즉, 개발에서는 보통 `Next 1개 + Worker 1개` 프로세스를 실행합니다.
## 1-2) 운영 배포 시
운영은 보통 아래 2가지 중 하나입니다.
1. 같은 Linux 서버에 Next + Worker 같이 운영
2. Next는 배포 플랫폼, Worker는 별도 Linux 서버에서 운영
공통 원칙:
1. 브라우저는 Next API를 호출
2. 워커도 Next API(`/api/autotrade/worker/tick`)를 호출
3. 워커 인증은 `x-autotrade-worker-token`으로 처리
---
## 2) 레이어별 역할
## 2-1) 사용자 브라우저
하는 일:
1. 자동매매 설정 입력
2. 전략 컴파일/검증 요청
3. 세션 시작 후 10초마다 heartbeat 전송
4. 신호 요청 후 주문 가능 여부 판단
5. 브라우저 종료/외부 이동 시 중지 처리
핵심 소스:
1. UI: [`AutotradeControlPanel`](../../features/autotrade/components/AutotradeControlPanel.tsx#L25)
2. 엔진: [`useAutotradeEngine`](../../features/autotrade/hooks/useAutotradeEngine.ts#L118)
3. heartbeat 루프: [`useAutotradeEngine`](../../features/autotrade/hooks/useAutotradeEngine.ts#L336)
4. 주문 직전 게이트+주문 호출: [`useAutotradeEngine`](../../features/autotrade/hooks/useAutotradeEngine.ts#L426)
## 2-2) Next.js 서버(API)
하는 일:
1. 사용자 인증 검사
2. 전략 compile/validate 처리
3. 세션 start/heartbeat/stop/active 관리
4. AI 호출 실패 시 폴백 전략/신호로 대응
5. 워커 토큰 인증 후 만료 세션 정리
핵심 소스:
1. 공통 유틸: [`_shared.ts`](../../app/api/autotrade/_shared.ts)
2. compile: [`POST /strategies/compile`](../../app/api/autotrade/strategies/compile/route.ts#L22)
3. validate: [`POST /strategies/validate`](../../app/api/autotrade/strategies/validate/route.ts#L19)
4. sessions: [`/sessions/start`](../../app/api/autotrade/sessions/start/route.ts#L21), [`/sessions/heartbeat`](../../app/api/autotrade/sessions/heartbeat/route.ts#L18), [`/sessions/stop`](../../app/api/autotrade/sessions/stop/route.ts#L27), [`/sessions/active`](../../app/api/autotrade/sessions/active/route.ts#L9)
5. 신호 생성: [`POST /signals/generate`](../../app/api/autotrade/signals/generate/route.ts#L41)
## 2-3) 워커(Node)
하는 일:
1. 주기적으로 Next API `/api/autotrade/worker/tick` 호출
2. heartbeat 끊긴 세션을 timeout 종료
3. 정리 결과 로그 출력
핵심 소스:
1. 워커 스크립트: [`autotrade-worker.mjs`](../../scripts/autotrade-worker.mjs)
2. 워커 API: [`POST /worker/tick`](../../app/api/autotrade/worker/tick/route.ts#L12)
3. 만료 정리 함수: [`sweepExpiredAutotradeSessions()`](../../app/api/autotrade/_shared.ts#L147)
---
## 3) 가장 헷갈리는 개념 3개
## 3-1) 폴백 전략(fallback)
뜻:
1. AI를 못 쓰는 상황에서 쓰는 대체 규칙
2. 자동매매를 완전 중지하지 않고 보수적으로 유지
3. 애매하면 `hold`를 더 자주 반환
관련 소스:
1. 전략 폴백: [`createFallbackCompiledStrategy()`](../../lib/autotrade/strategy.ts#L16)
2. 신호 폴백: [`createFallbackSignalCandidate()`](../../lib/autotrade/strategy.ts#L36)
3. AI 호출: [`callOpenAiJson()`](../../lib/autotrade/openai.ts#L187)
## 3-2) heartbeat
뜻:
1. 브라우저가 Next 서버로 보내는 "세션 살아있음" 신호
2. 워커가 보내는 신호가 아님
## 3-3) worker tick
뜻:
1. 워커가 Next 서버로 보내는 "만료 세션 정리 요청"
2. heartbeat가 끊긴 세션을 timeout 종료
---
## 3-4) 구독형 CLI 자동판단(신규)
뜻:
1. OpenAI API 키 대신 서버에 설치된 `gemini` 또는 `codex` CLI를 호출해 자동판단
2. 자동판단 결과(JSON)를 파싱해 전략/신호에 반영
3. CLI 호출 실패 또는 파싱 실패 시 규칙 기반으로 자동 폴백
UI에서 선택:
1. 자동매매 설정창에서 `구독형 CLI 엔진``auto/codex/gemini` 중 선택
2. `codex` 또는 `gemini` 선택 시 공식 문서 기반 추천 모델 목록을 드롭다운으로 선택
3. 목록에 없는 최신 모델은 `직접 입력`으로 설정
모델 우선순위:
1. UI에서 선택한 모델(있을 때)
2. `AUTOTRADE_CODEX_MODEL` / `AUTOTRADE_GEMINI_MODEL`
3. `AUTOTRADE_SUBSCRIPTION_CLI_MODEL`
4. 각 CLI 기본 모델
환경변수:
```env
AUTOTRADE_AI_MODE=subscription_cli
AUTOTRADE_SUBSCRIPTION_CLI=auto
AUTOTRADE_SUBSCRIPTION_CLI_MODEL=
AUTOTRADE_CODEX_MODEL=
AUTOTRADE_GEMINI_MODEL=
AUTOTRADE_SUBSCRIPTION_CLI_TIMEOUT_MS=60000
AUTOTRADE_SUBSCRIPTION_CLI_DEBUG=0
AUTOTRADE_CODEX_COMMAND=
AUTOTRADE_GEMINI_COMMAND=
```
동작 우선순위:
1. `AUTOTRADE_SUBSCRIPTION_CLI=auto`면 codex -> gemini 순서로 시도
2. 모델 선택 우선순위는 `vendor 전용 모델` -> `AUTOTRADE_SUBSCRIPTION_CLI_MODEL` -> `CLI 기본 모델`
3. 둘 다 실패하면 fallback 규칙 신호 사용
4. 로그에 `attempts=codex:default:timeout`가 나오면 CLI 타임아웃이므로 `AUTOTRADE_SUBSCRIPTION_CLI_TIMEOUT_MS`를 더 크게 설정
5. 로그에 `attempts=codex:gpt-5-codex:error(...)`처럼 괄호가 붙으면 실제 실패 원인(stderr/spawn 에러)입니다.
어떤 CLI를 썼는지 확인:
1. 자동매매 로그에서 `신호 수신 [subscription_cli:codex:gpt-5-codex]` 또는 `신호 수신 [subscription_cli:gemini:flash]` 확인
2. Network 응답에서 `providerVendor` 확인
- `/api/autotrade/strategies/compile` 응답: `compiledStrategy.providerVendor`
- `/api/autotrade/signals/generate` 응답: `signal.providerVendor`
3. Network 응답에서 `providerModel` 확인
- `/api/autotrade/strategies/compile` 응답: `compiledStrategy.providerModel`
- `/api/autotrade/signals/generate` 응답: `signal.providerModel`
4. 파싱 실패 시 reason/summary에 `selected=vendor:model; attempts=...` 형태로 시도 결과 포함
`selected=none:default; attempts=codex:gpt-5-codex:error(...)`가 보이면:
1. `AUTOTRADE_SUBSCRIPTION_CLI_DEBUG=1`로 켜고 `npm run dev`를 재시작합니다.
2. Next 서버 콘솔에서 `[autotrade-cli]` 로그를 확인합니다.
3. `spawn:ENOENT`가 보이면 `AUTOTRADE_CODEX_COMMAND` 또는 `AUTOTRADE_GEMINI_COMMAND`에 CLI 절대경로를 넣습니다.
4. 예: `AUTOTRADE_CODEX_COMMAND=C:\\Users\\<계정>\\AppData\\Roaming\\npm\\codex.cmd`
모델 지정 예시:
```env
# Codex만 쓸 때
AUTOTRADE_SUBSCRIPTION_CLI=codex
AUTOTRADE_CODEX_MODEL=gpt-5-codex
# Gemini만 쓸 때
AUTOTRADE_SUBSCRIPTION_CLI=gemini
AUTOTRADE_GEMINI_MODEL=flash
# auto 모드에서 공통 모델 fallback만 쓸 때
AUTOTRADE_SUBSCRIPTION_CLI=auto
AUTOTRADE_SUBSCRIPTION_CLI_MODEL=auto
```
공식 문서:
1. Codex CLI 옵션(`--model`): <https://developers.openai.com/codex/cli>
2. OpenAI 모델 목록(`gpt-5-codex` 포함): <https://platform.openai.com/docs/models>
3. Gemini CLI 모델 선택: <https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/model.md>
4. Gemini CLI 모델 우선순위(`--model` > `GEMINI_MODEL`): <https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/model-routing.md>
모델 갱신 운영 런북:
1. 새 모델 출시 대응 절차: [`autotrade-model-catalog-runbook.md`](./autotrade-model-catalog-runbook.md)
관련 소스:
1. CLI 공급자: [`lib/autotrade/cli-provider.ts`](../../lib/autotrade/cli-provider.ts)
2. 전략 compile 라우트: [`/strategies/compile`](../../app/api/autotrade/strategies/compile/route.ts)
3. 신호 generate 라우트: [`/signals/generate`](../../app/api/autotrade/signals/generate/route.ts)
---
## 4) 환경변수: 어디에 넣는지
## 4-1) 앱(Next.js 서버)
위치:
1. 로컬: `.env.local`
2. 운영: 배포 환경변수
필수:
```env
AUTOTRADE_WORKER_TOKEN=<랜덤시크릿>
OPENAI_API_KEY=<옵션, 없으면 폴백 동작>
```
## 4-2) 워커(Node/PM2)
위치:
1. PM2 실행 셸 환경변수
2. 서버 시스템 환경변수
필수:
```env
AUTOTRADE_WORKER_TOKEN=<앱과동일값>
AUTOTRADE_APP_URL=<Next서버URL>
AUTOTRADE_WORKER_POLL_MS=5000
```
중요:
1. `AUTOTRADE_WORKER_TOKEN`은 사용자별이 아니라 서비스별 시크릿
2. 앱과 워커가 같은 값을 써야 인증 통과
---
## 5) 실행 순서 (앱/워커 분리)
## 5-1) 로컬 개발
터미널 A:
```bash
npm run dev
```
터미널 B:
```bash
AUTOTRADE_WORKER_TOKEN="<앱과같은값>" \
AUTOTRADE_APP_URL="http://127.0.0.1:3001" \
node scripts/autotrade-worker.mjs
```
Windows PowerShell:
```powershell
npm run dev
# 새 터미널
$env:AUTOTRADE_WORKER_TOKEN="<앱과같은값>"
$env:AUTOTRADE_APP_URL="http://127.0.0.1:3001"
$env:AUTOTRADE_WORKER_POLL_MS="5000"
npm run worker:autotrade
```
또는 `.env.local` 기반:
```powershell
npm run worker:autotrade:dev
```
## 5-2) 운영(PM2)
```bash
export AUTOTRADE_WORKER_TOKEN="<앱과같은값>"
export AUTOTRADE_APP_URL="https://your-domain.com"
export AUTOTRADE_WORKER_POLL_MS="5000"
pm2 start scripts/pm2.autotrade-worker.config.cjs
pm2 logs autotrade-worker
```
---
## 6) end-to-end 흐름 (브라우저 -> 서버 -> 워커)
1. 브라우저: 설정 입력
2. 서버: `/strategies/compile` (AI 또는 폴백)
3. 서버: `/strategies/validate` (리스크 계산)
4. 서버: `/sessions/start`
5. 브라우저: 10초마다 `/sessions/heartbeat`
6. 브라우저: 주기적으로 `/signals/generate`
7. 브라우저: 리스크 게이트 통과 시 주문 API 호출
8. 브라우저: 중지 이벤트 시 `/sessions/stop`
9. 워커: `/worker/tick`로 heartbeat 만료 세션 정리
---
## 6-1) AI가 실제로 받는 판단 데이터
자동매매는 "자연어 프롬프트만" 보내는 구조가 아닙니다. 실행 중에는 아래 구조화된 데이터가 같이 전달됩니다.
1. 전략(compile 결과)
- `selectedTechniques`
- `confidenceThreshold`
- `maxDailyOrders`
- `cooldownSec`
- `maxOrderAmountRatio`
2. 시세 스냅샷(signal 요청 시)
- `symbol`
- `currentPrice`
- `changeRate`
- `open/high/low`
- `tradeVolume`
- `accumulatedVolume`
- `recentPrices`(최근 체결가 배열)
3. 서버 리스크 검증 결과
- AI 신호가 `buy/sell`이어도 리스크 게이트 미통과 시 주문 차단
즉, AI는 "현재 종목 + 현재가 + 가격 흐름 + 전략 제약"을 같이 받아 판단하고, 최종 주문은 리스크 게이트를 통과해야 실행됩니다.
관련 소스:
1. 스냅샷 구성: [`useAutotradeEngine.ts`](../../features/autotrade/hooks/useAutotradeEngine.ts)
2. 신호 route 검증: [`signals/generate/route.ts`](../../app/api/autotrade/signals/generate/route.ts)
3. 리스크 게이트: [`risk.ts`](../../lib/autotrade/risk.ts)
---
## 7) 보안: 레이어별 핵심
## 7-1) 브라우저
1. KIS 민감정보는 세션 저장소(sessionStorage) 사용
2. 브라우저 종료 시 세션 저장소 제거
## 7-2) Next 서버
1. 자동매매 API는 사용자 인증 필요
2. 워커 API는 `x-autotrade-worker-token` 인증 필요
3. 민감정보 문자열 마스킹 처리
## 7-3) 워커
1. 토큰이 틀리면 401
2. 토큰은 코드 하드코딩 금지
---
## 8) 역할별로 어디 보면 되는지
1. 기획/대표: 1, 2, 6, 7장
2. QA: 5, 6, 7장 + worker 문서 6, 7장
3. 개발: 2장 소스링크 + worker 문서 전체
---
## 9) 추가 문서
1. 워커 상세 운영: [`autotrade-worker-pm2.md`](./autotrade-worker-pm2.md)

View File

@@ -0,0 +1,269 @@
# 자동매매 워커 운영 가이드 (실행/배포 구조 이해용)
이 문서는 "앱을 실행하면 뭐가 어디서 도는지"를 먼저 설명하고, 그다음 실행 방법을 설명합니다.
## 0) 먼저 용어 정리
1. React 앱: 브라우저에서 보이는 UI (`/trade` 화면)
2. Next.js 서버: React 화면 제공 + API(`/api/*`) 처리
3. 워커(Node): 백그라운드에서 `/api/autotrade/worker/tick` 호출하는 별도 프로세스
중요:
1. React와 API는 보통 같은 Next 프로세스에서 동작합니다.
2. 워커는 Next와 별도 프로세스입니다.
---
## 1) 개발(local)에서 실제로 어디서 도는가
```text
내 PC
┌──────────────────────────────────────────────────────────────────────────┐
│ 브라우저(Chrome) │
│ - /trade 화면 렌더링 │
│ - heartbeat 전송 (/sessions/heartbeat) │
└──────────────────────────────────────────────────────────────────────────┘
│ http://127.0.0.1:3001
┌──────────────────────────────────────────────────────────────────────────┐
│ 터미널 A: Next 개발 서버 (`npm run dev`) │
│ - React 페이지 제공 │
│ - /api/autotrade/* API 처리 │
└──────────────────────────────────────────────────────────────────────────┘
│ x-autotrade-worker-token
┌──────────────────────────────────────────────────────────────────────────┐
│ 터미널 B: 워커 (`node scripts/autotrade-worker.mjs`) │
│ - /api/autotrade/worker/tick 주기 호출 │
└──────────────────────────────────────────────────────────────────────────┘
외부 클라우드 서비스
- Supabase(Auth/DB)
- KIS API
- OpenAI API(선택)
```
핵심:
1. 개발에서는 보통 프로세스 2개를 띄웁니다.
2. Next 1개 + Worker 1개
---
## 2) 운영(prod)에서 실제로 어디서 도는가
## 2-1) 패턴 A: 같은 Linux 서버에 Next + Worker
```text
사용자 브라우저
│ HTTPS
[Linux 서버]
- Next 앱 프로세스 (웹 + API)
- Worker 프로세스 (PM2)
└─ 내부에서 /api/autotrade/worker/tick 호출
```
장점:
1. 구성 단순
2. 네트워크 경로 짧음
## 2-2) 패턴 B: Next는 플랫폼(Vercel 등), Worker는 별도 Linux
```text
사용자 브라우저 ──HTTPS──> Next 배포 플랫폼(웹+API)
│ HTTPS + x-autotrade-worker-token
Linux Worker 서버(PM2)
```
장점:
1. 앱/워커 분리 운영 가능
2. 워커 자원 독립 관리 가능
주의:
1. 워커 서버에서 Next 도메인으로 접근 가능해야 함
2. 토큰/URL 설정을 양쪽에 정확히 맞춰야 함
---
## 3) 서버에서 "무엇이 돌아가는지" 체크표
| 구성요소 | 실제 실행 위치 | 프로세스 | 시작 명령 예시 | 역할 |
|---|---|---|---|---|
| React UI | 사용자 브라우저 | Browser Tab | URL 접속 | 화면 렌더링, 사용자 입력 |
| Next 서버 | Linux/플랫폼 | Node(Next) | `npm run dev` 또는 `npm run start` | 웹 + `/api/autotrade/*` 처리 |
| Worker | Linux/Worker 서버 | Node Script(PM2) | `pm2 start scripts/pm2.autotrade-worker.config.cjs` | 만료 세션 정리 |
---
## 4) heartbeat와 worker/tick 차이
1. heartbeat
브라우저 -> Next 서버
세션 살아있음 알림
2. worker/tick
워커 -> Next 서버
heartbeat 끊긴 세션 정리 요청
즉:
1. heartbeat는 "상태 보고"
2. tick은 "청소 작업"
---
## 5) 토큰/URL: 뭘 어떻게 넣어야 하나
## 5-1) `AUTOTRADE_WORKER_TOKEN`
뜻:
1. 사용자용 토큰 아님
2. 앱 서버와 워커 간 내부 인증 시크릿
3. 환경별(dev/staging/prod)로 1개 사용
생성 예시:
```bash
openssl rand -hex 32
```
## 5-2) `AUTOTRADE_APP_URL`
뜻:
1. 워커가 호출할 Next 서버 주소
예시:
1. 로컬: `http://127.0.0.1:3001`
2. 운영: `https://your-domain.com`
---
## 6) 어디 파일/어디 시스템에 넣나
## 6-1) 앱(Next 서버)
위치:
1. 로컬: `.env.local`
2. 운영: 배포 환경변수
필수:
```env
AUTOTRADE_WORKER_TOKEN=<랜덤시크릿>
```
## 6-2) 워커(Node/PM2)
위치:
1. PM2 실행 셸 환경변수
2. 서버 시스템 환경변수
필수:
```env
AUTOTRADE_WORKER_TOKEN=<앱과동일값>
AUTOTRADE_APP_URL=<Next서버URL>
AUTOTRADE_WORKER_POLL_MS=5000
```
중요:
1. 앱/워커 토큰 값은 완전히 같아야 합니다.
2. 다르면 `/worker/tick`가 401로 실패합니다.
---
## 7) 실행 방법
## 7-1) 로컬 개발
터미널 A (Next):
```bash
npm run dev
```
터미널 B (Worker):
```bash
AUTOTRADE_WORKER_TOKEN="<앱과같은값>" \
AUTOTRADE_APP_URL="http://127.0.0.1:3001" \
AUTOTRADE_WORKER_POLL_MS="5000" \
node scripts/autotrade-worker.mjs
```
## 7-1-a) 로컬 개발 (Windows PowerShell)
터미널 A (Next):
```powershell
npm run dev
```
터미널 B (Worker):
```powershell
$env:AUTOTRADE_WORKER_TOKEN="<앱과같은값>"
$env:AUTOTRADE_APP_URL="http://127.0.0.1:3001"
$env:AUTOTRADE_WORKER_POLL_MS="5000"
npm run worker:autotrade
```
`.env.local` 값을 바로 쓰고 싶으면:
```powershell
npm run worker:autotrade:dev
```
## 7-2) 운영 서버 (PM2)
```bash
npm i -g pm2
export AUTOTRADE_WORKER_TOKEN="<앱과같은값>"
export AUTOTRADE_APP_URL="https://your-domain.com"
export AUTOTRADE_WORKER_POLL_MS="5000"
pm2 start scripts/pm2.autotrade-worker.config.cjs
pm2 status
pm2 logs autotrade-worker
pm2 save
pm2 startup
```
---
## 8) 장애 시 빠른 점검
1. 워커 401
원인: 앱/워커 토큰 불일치
조치: `AUTOTRADE_WORKER_TOKEN` 동일화
2. fetch failed
원인: `AUTOTRADE_APP_URL` 오타, Next 미기동
조치: URL/앱 프로세스 확인
3. 세션이 안 정리됨
원인: heartbeat 정상 수신 중일 수 있음
조치: 브라우저 종료 후 TTL 경과 뒤 확인
---
## 9) 관련 소스
1. 워커: [`scripts/autotrade-worker.mjs`](../../scripts/autotrade-worker.mjs)
2. PM2 설정: [`scripts/pm2.autotrade-worker.config.cjs`](../../scripts/pm2.autotrade-worker.config.cjs)
3. 워커 API: [`app/api/autotrade/worker/tick/route.ts`](../../app/api/autotrade/worker/tick/route.ts)
4. heartbeat API: [`app/api/autotrade/sessions/heartbeat/route.ts`](../../app/api/autotrade/sessions/heartbeat/route.ts)
5. 세션 만료 정리: [`app/api/autotrade/_shared.ts`](../../app/api/autotrade/_shared.ts#L147)

View File

@@ -0,0 +1,134 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-02-26-autotrade-ai-mvp.md
[요구사항 요약]
- `features-autotrade-design.md`를 참고해 자동매매 기능을 실제 코드로 추가한다.
- 설계 항목 중 현재 코드베이스에서 바로 구현 가능한 범위와 불필요/보류 범위를 구분한다.
- "구독형 AI + 유명 기법"(OpenAI 기반 + ORB/VWAP/거래량/이평/갭)을 자동매매 시작 흐름에 반영한다.
- OpenAI API 외에도 서버에 설치된 Codex/Gemini CLI를 이용한 구독형 자동판단 경로를 추가한다.
- Windows 개발 환경에서 워커 실행 방법을 문서와 스크립트로 제공한다.
[확인 질문(필요 시 1~3개)]
- 없음(우선 MVP 범위로 구현 후 동작 가능한 형태를 제공)
[가정]
- 서버 DB(Supabase) 스키마를 이번 작업에서 새로 만들지 않고, 세션/로그는 서버 메모리 + 클라이언트 상태로 우선 구현한다.
- OpenAI 키(`OPENAI_API_KEY`)가 없으면 AI 추론은 휴리스틱 폴백(보수적 hold 중심)으로 동작한다.
- 자동매매는 트레이드 화면에서 선택된 종목 기준으로 우선 실행한다(멀티 종목 동시 엔진은 보류).
[추가/제외 판단]
- 즉시 추가:
- 자동매매 설정 팝업(UI): 프롬프트, 유명 기법 복수 선택, 투자금/손실한도(퍼센트+금액), 동의 체크
- 전략 컴파일/검증 API: `compile`, `validate`
- 런타임 세션 API: `start`, `heartbeat`, `stop`, `active`
- 브라우저 엔진 훅: 신호 평가, 리스크 게이트, 주문 실행, heartbeat, 중지 처리
- 실행 중 경고 배너/상태 카드
- 설정 도움말/추천 프리셋(초보/균형/공격) 추가
- 백엔드 워커 tick API + 리눅스 PM2 실행 스크립트/문서 추가
- 자동 세션 수명주기(start->heartbeat->stop) E2E 스크립트 추가
- 이번에 제외(보류):
- Supabase 테이블 5종 + 감사로그 영구 저장
- 온라인 전략 수집/카탈로그 검수 워크플로우 전체
- 멀티탭 리더 선출 lock + BroadcastChannel 완성형
- 4주 배포 계획/운영 대시보드/Sentry 통합
- AI 다중 제공자(OpenAI/Gemini/Claude) 동시 운영
[영향 범위]
- 수정:
- features/trade/components/TradeContainer.tsx
- .env.example
- utils/supabase/middleware.ts
- package.json
- common-docs/features/autotrade-usage-security-guide.md
- common-docs/features/autotrade-worker-pm2.md
- common-docs/improvement/plans/dev-plan-2026-02-26-autotrade-ai-mvp.md
- 추가:
- features/autotrade/types/autotrade.types.ts
- features/autotrade/stores/use-autotrade-engine-store.ts
- features/autotrade/hooks/useAutotradeEngine.ts
- features/autotrade/components/AutotradeControlPanel.tsx
- features/autotrade/components/AutotradeWarningBanner.tsx
- features/autotrade/apis/autotrade.api.ts
- app/api/autotrade/_shared.ts
- app/api/autotrade/strategies/compile/route.ts
- app/api/autotrade/strategies/validate/route.ts
- app/api/autotrade/sessions/start/route.ts
- app/api/autotrade/sessions/heartbeat/route.ts
- app/api/autotrade/sessions/stop/route.ts
- app/api/autotrade/sessions/active/route.ts
- app/api/autotrade/signals/generate/route.ts
- app/api/autotrade/worker/tick/route.ts
- lib/autotrade/risk.ts
- lib/autotrade/strategy.ts
- lib/autotrade/openai.ts
- lib/autotrade/cli-provider.ts
- scripts/autotrade-session-e2e.mjs
- scripts/autotrade-worker.mjs
- scripts/pm2.autotrade-worker.config.cjs
- common-docs/features/autotrade-worker-pm2.md
- 삭제:
- 없음
[구현 단계]
- [x] 1. 자동매매 타입/리스크 계산 유틸/AI-폴백 전략 컴파일 로직 추가
- 근거: `features/autotrade/types/autotrade.types.ts`, `lib/autotrade/risk.ts`, `lib/autotrade/strategy.ts`, `lib/autotrade/openai.ts`
- [x] 2. 자동매매 API 라우트(`compile/validate/start/heartbeat/stop/active/signal`) 구현
- 근거: `app/api/autotrade/**/route.ts`, `app/api/autotrade/_shared.ts`
- [x] 3. 클라이언트 스토어/엔진 훅 구현(상태, heartbeat, 주문 실행, 중지)
- 근거: `features/autotrade/stores/use-autotrade-engine-store.ts`, `features/autotrade/hooks/useAutotradeEngine.ts`, `features/autotrade/apis/autotrade.api.ts`
- [x] 4. 트레이드 화면에 설정 패널/실행 경고 배너 통합
- 근거: `features/autotrade/components/AutotradeControlPanel.tsx`, `features/autotrade/components/AutotradeWarningBanner.tsx`, `features/trade/components/TradeContainer.tsx`
- [x] 5. 문서/환경변수(.env.example) 반영 및 계획 체크 업데이트
- 근거: `.env.example`, 본 계획 문서 갱신
- [x] 6. 설정 팝업 입력값 설명 강화 + 추천 프리셋(초보/균형/공격) 추가
- 근거: `features/autotrade/components/AutotradeControlPanel.tsx`
- [x] 7. 백엔드 워커 tick API 및 PM2 운영 스크립트/문서 추가
- 근거: `app/api/autotrade/worker/tick/route.ts`, `scripts/autotrade-worker.mjs`, `scripts/pm2.autotrade-worker.config.cjs`, `common-docs/features/autotrade-worker-pm2.md`
- [x] 8. 자동매매 세션 수명주기 E2E 스크립트 추가 및 실행
- 근거: `scripts/autotrade-session-e2e.mjs`, `npm run test:autotrade:lifecycle` PASS
- [x] 9. 구독형 CLI 자동판단 모드 추가(codex/gemini CLI)
- 근거: `lib/autotrade/cli-provider.ts`, `app/api/autotrade/strategies/compile/route.ts`, `app/api/autotrade/signals/generate/route.ts`, `features/autotrade/components/AutotradeControlPanel.tsx`
- [x] 10. Windows 개발 워커 실행 경로 추가
- 근거: `package.json(worker:autotrade:dev)`, `common-docs/features/autotrade-worker-pm2.md`, `common-docs/features/autotrade-usage-security-guide.md`
[사용할 MCP/Skills]
- MCP: next-devtools(nextjs_index/nextjs_call), playwright(스모크), shell_command
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, nextjs-app-router-patterns, vercel-react-best-practices, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker
[참조 문서(common-docs)]
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
- common-docs/api-reference/kis_api_reference.md (주문 연동 시 기존 패턴 준수)
- common-docs/api-reference/kis-error-code-reference.md (에러 표현 패턴 유지)
- 사용자 지정 기획 입력: common-docs/features-autotrade-design.md
[주석/문서 반영 계획]
- 함수 주석: [목적]/[사용처]/[데이터 흐름] 중심으로 핵심 흐름만 보강
- 상태 주석: 자동매매 상태 변경이 화면에 미치는 영향 위주
- 복잡 로직/핸들러: 신호 생성 -> 리스크 검증 -> 주문 실행 단계 주석
- JSX 구역 주석: 설정 패널/경고 배너/상태 카드 구역 분리
[리스크/회귀 포인트]
- 주문 API 호출 빈도 과다 시 중복 주문 위험
- 브라우저 종료 시 stop beacon 실패 가능성
- AI 출력 포맷 불안정 시 잘못된 신호 처리 위험
- 기존 수동 주문 UX와 충돌(버튼/상태 동시 사용)
[검증 계획]
- [x] 1. `npm run lint` 통과
- 근거: ESLint 에러/경고 정리 후 재실행 통과
- [x] 2. `npm run build` 통과
- 근거: Next.js 16.1.6 프로덕션 빌드 성공, 신규 `/api/autotrade/*` 라우트 포함 확인
- [x] 3. Playwright 스모크: `/trade` 자동매매 설정 패널 오픈 + 도움말/추천 프리셋 입력 반영 확인
- 근거: `자동매매 설정` 모달 오픈, 쉬운 설명 문구 노출, `초보 추천` 클릭 시 수치 자동 반영 확인, 콘솔 error 없음
- [x] 4. start -> heartbeat -> stop 상태 전환 검증
- 근거: `npm run test:autotrade:lifecycle` PASS (`start -> heartbeat -> active -> stop -> active(null)`)
[진행 로그]
- 2026-02-26: 초안 작성. 설계서 기준 MVP 범위(즉시 구현/보류) 확정.
- 2026-02-26: 자동매매 MVP 구현 완료. 타입/유틸/API/스토어/엔진/트레이드 화면 통합 및 `.env.example` 갱신.
- 2026-02-26: 검증 완료(`npm run lint`, `npm run build`, Playwright 스모크). 로그인+KIS 인증 기반 수동 E2E는 남은 확인 항목으로 기록.
- 2026-02-26: 설정값 도움말/추천 프리셋(초보/균형/공격) 추가로 입력 이해도 개선.
- 2026-02-26: 워커 tick API + PM2 운영 스크립트/문서 추가, `worker:autotrade:once` 정상 동작 확인.
- 2026-02-26: 수명주기 자동 검증 스크립트(`test:autotrade:lifecycle`) 통과로 검증계획 4 완료.
- 2026-02-26: 구독형 CLI 자동판단 모드(`subscription_cli`) 추가. OpenAI 미사용 환경에서 gemini/codex CLI 호출 후 JSON 파싱, 실패 시 규칙 기반 폴백하도록 리팩토링.
- 2026-02-26: Windows PowerShell 기준 워커 실행 방법(환경변수 + `worker:autotrade(:dev)`) 문서화.

View File

@@ -0,0 +1,50 @@
# 자동매매 가용자산 0원 차단 보완 계획
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-02-26-autotrade-cash-balance-fix.md
[요구사항 요약]
- 자동매매 검증에서 `가용 자산 0원`으로 차단되는 문제를 보완한다.
- `내 계좌 기준`으로 매수가능금액을 추가 조회해 검증 금액에 반영한다.
- 기존 리스크 검증/주문 흐름은 유지한다.
[가정]
- KIS 인증/계좌번호는 이미 설정되어 있다.
- selectedStock의 종목코드와 가격 정보는 자동매매 시작 시점에 확보 가능하다.
[영향 범위]
- 수정: features/autotrade/hooks/useAutotradeEngine.ts
- 수정: features/trade/apis/kis-stock.api.ts
- 수정: features/trade/types/trade.types.ts
- 수정: lib/kis/trade.ts
- 추가: app/api/kis/domestic/orderable-cash/route.ts
[구현 단계]
- [x] 1. KIS 매수가능금액 조회 서버 라우트 추가
- [x] 2. 프론트 API 클라이언트/타입 추가
- [x] 3. 자동매매 prepareStrategy에서 cashBalance 0원 보정 로직 추가
- [x] 4. 로그/주석 보강
[사용할 MCP/Skills]
- Skills: dev-auto-pipeline, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker
[참조 문서(common-docs)]
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
[리스크/회귀 포인트]
- 매수가능금액 조회 실패 시 기존 cashBalance만 사용하도록 폴백 필요
- 종목가격이 0 또는 비정상일 때 조회 파라미터 보정 필요
[검증 계획]
- [x] 1. lint 통과
- [x] 2. build 통과
- [ ] 3. autotrade smoke 테스트 통과
[진행 로그]
- 2026-02-26: 계획 문서 생성
- 2026-02-26: `/api/kis/domestic/orderable-cash` 라우트 및 `executeInquireOrderableCash` 구현
- 2026-02-26: 자동매매 `prepareStrategy`에서 cashBalance 0원 시 매수가능금액 보정 로직 반영
- 2026-02-26: `npx eslint ...` 통과
- 2026-02-26: `npm run build` 통과
- 2026-02-26: smoke 테스트는 현재 3001 실행 프로세스가 dev bypass를 허용하지 않는 환경으로 로그인 필요 응답 확인(추가 환경 정리 후 재실행 필요)

View File

@@ -0,0 +1,58 @@
# 자동매매 CLI 모델 선택 + AI 입력 데이터 흐름 보강 계획
## [계획 문서 경로]
- `common-docs/improvement/plans/dev-plan-2026-02-26-autotrade-cli-model-selection.md`
## [요구사항 요약]
- 자동매매가 AI 판단 시 어떤 데이터를 전달하는지 쉽게 설명한다.
- Codex/Gemini CLI 모델을 공식 옵션 기준으로 선택 가능하게 만든다.
- 로그/응답에서 실제 사용된 vendor/model을 확인 가능하게 만든다.
## [가정]
- 구독형 CLI는 서버(개발/운영)에 설치되어 있고 로그인/인증이 완료되어 있다.
- 모델 선택은 UI 입력보다 서버 환경변수 방식이 운영상 안전하다.
## [영향 범위]
- 수정: `lib/autotrade/cli-provider.ts`
- 수정: `app/api/autotrade/strategies/compile/route.ts`
- 수정: `app/api/autotrade/signals/generate/route.ts`
- 수정: `features/autotrade/types/autotrade.types.ts`
- 수정: `features/autotrade/hooks/useAutotradeEngine.ts`
- 수정: `.env.example`
- 수정: `common-docs/features/autotrade-usage-security-guide.md`
- 수정: `common-docs/features/autotrade-prompt-flow-guide.md`
## [구현 단계]
- [x] 1. CLI 실행 인자에 vendor별 모델 선택 환경변수를 반영한다. (근거: `lib/autotrade/cli-provider.ts`)
- [x] 2. compile/signal 응답에 `providerModel`을 포함해 추적 가능하게 만든다. (근거: `app/api/autotrade/strategies/compile/route.ts`, `app/api/autotrade/signals/generate/route.ts`)
- [x] 3. 런타임 로그에 vendor/model을 함께 노출한다. (근거: `features/autotrade/hooks/useAutotradeEngine.ts`)
- [x] 4. AI 입력 데이터(시세/전략) 흐름 설명을 문서에 보강한다. (근거: `common-docs/features/autotrade-usage-security-guide.md`, `common-docs/features/autotrade-prompt-flow-guide.md`)
## [사용할 MCP/Skills]
- Skills: `dev-auto-pipeline`, `dev-mcp-implementation`, `dev-refactor-polish`, `dev-test-gate`, `dev-plan-completion-checker`
- MCP: 없음(로컬 코드 수정 + 공식 문서 웹 근거 활용)
## [참조 문서(common-docs)]
- `common-docs/features/trade-stock-sync.md` (참고만, 변경 없음)
- `common-docs/ui/GLOBAL_ALERT_SYSTEM.md` (참고만, 변경 없음)
## [주석/문서 반영 계획]
- 함수 주석: CLI 모델 선택 우선순위와 데이터 흐름 주석 보강
- 상태/로그 주석: vendor/model 로그 의미를 한 줄로 명시
- 흐름 문서: UI -> 훅 -> API -> route -> provider 단계 유지
## [리스크/회귀 포인트]
- Codex CLI 모델명이 환경과 불일치하면 CLI 실패 후 fallback으로 전환될 수 있다.
- 응답 스키마 필드 추가(`providerModel`)가 프론트 타입과 불일치하면 TS 오류가 날 수 있다.
## [검증 계획]
- [x] 1. 변경 파일 eslint 검사 통과 (결과: 코드 파일 오류 없음, md 파일은 lint 대상 아님 경고)
- [x] 2. `npm run build` 통과
- [x] 3. 문서의 환경변수/확인 절차가 실제 로그 포맷과 일치
## [진행 로그]
- 2026-02-26: 계획 문서 생성
- 2026-02-26: CLI 모델 선택 환경변수(`AUTOTRADE_CODEX_MODEL`, `AUTOTRADE_GEMINI_MODEL`, `AUTOTRADE_SUBSCRIPTION_CLI_MODEL`) 반영
- 2026-02-26: provider vendor/model 추적값 응답/로그 반영
- 2026-02-26: AI 입력 데이터(시세 스냅샷/전략 제약) 설명 문서 보강
- 2026-02-26: `npx eslint` + `npm run build` 검증 완료

View File

@@ -0,0 +1,71 @@
# 자동매매 모델 선택 + 대시보드 잔고/매도 UX 개선 계획
## [계획 문서 경로]
- `common-docs/improvement/plans/dev-plan-2026-02-26-autotrade-dashboard-ux-cli-models.md`
## [요구사항 요약]
- AI 판단 입력 데이터(시세 스냅샷)가 무엇인지 쉽게 설명한다.
- 자동매매 UI에서 구독형 CLI vendor/model을 선택할 수 있게 개선한다.
- 대시보드 잔고 표시(총자산/순자산) 혼동을 줄이고, 매도 UX에 매도가능수량 정보를 보강한다.
- 보유종목 잔존(전량 매도 후 표시) 문제를 점검하고 수정한다.
- 자동매매 리스크 요약 문구를 초보자 기준으로 이해 가능하게 바꾼다.
## [가정]
- 구독형 CLI 모델 목록은 "공식 문서 기준 추천 프리셋 + 직접 입력" 방식이 운영 안정성에 유리하다.
- KIS 주식잔고조회 output1의 `ord_psbl_qty`(매도가능수량)를 우선 사용한다.
## [영향 범위]
- 수정: `features/autotrade/types/autotrade.types.ts`
- 수정: `lib/autotrade/strategy.ts`
- 수정: `features/autotrade/apis/autotrade.api.ts`
- 수정: `features/autotrade/hooks/useAutotradeEngine.ts`
- 수정: `features/autotrade/components/AutotradeControlPanel.tsx`
- 수정: `app/api/autotrade/strategies/compile/route.ts`
- 수정: `app/api/autotrade/signals/generate/route.ts`
- 수정: `lib/autotrade/cli-provider.ts`
- 수정: `lib/kis/dashboard.ts`
- 수정: `features/dashboard/types/dashboard.types.ts`
- 수정: `features/dashboard/components/StatusHeader.tsx`
- 수정: `features/dashboard/components/HoldingsList.tsx`
- 수정: `features/trade/components/TradeContainer.tsx`
- 수정: `features/trade/components/order/OrderForm.tsx`
- 수정: `common-docs/features/autotrade-usage-security-guide.md`
- 수정: `common-docs/features/autotrade-prompt-flow-guide.md`
## [구현 단계]
- [x] 1. 자동매매 setup form에 CLI vendor/model 선택 필드를 추가한다.
- [x] 2. compile/signal API 요청에 vendor/model 오버라이드를 전달하고 라우트/CLI provider에서 반영한다.
- [x] 3. 공식 문서 기반 모델 프리셋(코덱스/제미나이) + 직접입력 UX를 패널에 추가한다.
- [x] 4. 대시보드 잔고 파싱에서 수량 0 보유종목 제거/매도가능수량 필드를 반영한다.
- [x] 5. 상단 자산 카드 라벨/표시 순서를 총자산 중심으로 개선한다.
- [x] 6. 주문 패널 매도 탭에서 매도가능수량 기반 가이드/검증을 추가한다.
- [x] 7. 자동매매 리스크 요약 문구를 쉬운 용어로 바꾸고 입력값 대비 계산 근거를 함께 노출한다.
- [x] 8. 문서(사용 가이드/흐름 가이드)에 스냅샷 필드 설명과 모델 선택 기준을 반영한다.
## [사용한 공식 문서]
- OpenAI Models: <https://platform.openai.com/docs/models>
- OpenAI Codex CLI: <https://developers.openai.com/codex/cli>
- Gemini CLI model selection: <https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/model.md>
- Gemini CLI model routing precedence: <https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/model-routing.md>
- KIS 매도가능수량조회 경로 참고: `common-docs/api-reference/kis_api_reference.md`, `.tmp/open-trading-api/examples_llm/domestic_stock/inquire_psbl_sell/inquire_psbl_sell.py`
## [리스크/회귀 포인트]
- UI 필드 증가로 기존 자동매매 설정 저장/반영 흐름이 깨질 수 있음.
- 모델명을 강제로 지정했을 때 vendor와 호환되지 않으면 CLI 실패 후 fallback으로 전환될 수 있음.
- 보유종목 필터링 조건이 과도하면 실제 보유 종목이 누락될 수 있음.
## [검증 계획]
- [x] 1. 변경 파일 eslint 통과
- [x] 2. `npm run build` 통과
- [x] 3. 대시보드에서 수량 0 종목 미노출 로직 반영 확인 (`lib/kis/dashboard.ts` 수량 0 필터)
- [x] 4. 매도 탭에서 매도가능수량 초과 입력 차단 로직 반영 확인 (`OrderForm.tsx`)
- [x] 5. 자동매매 로그에 vendor/model 노출 유지 확인 (`useAutotradeEngine.ts`)
## [진행 로그]
- 2026-02-26: 계획 문서 생성
- 2026-02-26: 자동매매 설정창에 구독형 CLI vendor/model 선택 UI 추가
- 2026-02-26: compile/signal route와 CLI provider에 vendor/model override 반영
- 2026-02-26: 대시보드 잔고 파싱에 `ord_psbl_qty` 반영, 수량 0 종목 필터링 적용
- 2026-02-26: StatusHeader 총자산 중심 표기 개편, 매도 UX(매도가능수량 표시/검증) 개선
- 2026-02-26: 리스크 요약 문구를 쉬운 용어로 교체, 스냅샷/모델선택 문서 보강
- 2026-02-26: `npx eslint``npm run build` 통과

View File

@@ -0,0 +1,55 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-02-26-market-indices-display.md
[요구사항 요약]
- 메인 레이아웃의 헤더에 KOSPI 및 KOSDAQ 지수를 표시한다.
- 지수에는 현재가, 전일 대비 등락, 등락률이 포함되어야 한다.
- 데이터는 30초마다 자동으로 새로고침되어야 한다.
[가정]
- 사용자는 로그인 상태이며 KIS API 키가 설정되어 있다고 가정한다.
- `lib/kis/dashboard.ts``getDomesticDashboardIndices` 함수가 정상 동작한다고 가정한다.
[영향 범위]
- 수정:
- `features/layout/components/header.tsx`: `MarketIndices` 컴포넌트를 추가하고 레이아웃을 조정.
- 추가:
- `app/api/kis/indices/route.ts`: KIS 지수 데이터를 조회하는 새로운 API 라우트.
- `features/layout/stores/market-indices-store.ts`: 지수 데이터 상태 관리를 위한 Zustand 스토어.
- `features/layout/hooks/use-market-indices.ts`: 지수 데이터를 가져오는 커스텀 훅.
- `features/layout/components/market-indices.tsx`: 지수 정보를 표시하는 UI 컴포넌트.
- 삭제:
- 없음
[구현 단계]
- [x] 1. KIS 지수 API 라우트 생성 (`app/api/kis/indices/route.ts`): `getDomesticDashboardIndices` 함수를 사용하여 KOSPI, KOSDAQ 지수 정보를 반환하는 GET 엔드포인트를 구현.
- [x] 2. 상태 관리 스토어 생성 (`features/layout/stores/market-indices-store.ts`): 지수 데이터, 로딩 상태, 에러 상태를 관리하기 위한 Zustand 스토어를 생성.
- [x] 3. 커스텀 훅 생성 (`features/layout/hooks/use-market-indices.ts`): 위에서 만든 API 라우트를 호출하고, 스토어의 상태를 업데이트하는 `useMarketIndices` 훅을 구현.
- [x] 4. UI 컴포넌트 생성 (`features/layout/components/market-indices.tsx`): `useMarketIndices` 훅을 사용하여 지수 정보를 받아와 화면에 표시하는 컴포넌트를 생성. 30초마다 데이터를 폴링하는 로직을 포함.
- [x] 5. 헤더에 컴포넌트 추가 (`features/layout/components/header.tsx`): 생성된 `MarketIndices` 컴포넌트를 헤더 중앙에 추가하고, 로그인 및 `blendWithBackground` 상태에 따라 노출 여부를 제어.
[사용할 MCP/Skills]
- MCP: 없음
- Skills: `dev-plan-writer`, `dev-mcp-implementation`, `dev-refactor-polish`, `dev-test-gate`, `dev-plan-completion-checker`
[참조 문서(common-docs)]
- `common-docs/api-reference/kis_api_reference.md`
[주석/문서 반영 계획]
- 각 파일 상단에 파일의 목적과 역할을 설명하는 JSDoc 주석을 추가.
- 주요 함수에 파라미터와 반환 값, 역할을 설명하는 주석을 추가.
[리스크/회귀 포인트]
- KIS API 호출 실패 시 에러 처리가 적절히 이루어지지 않으면 UI가 깨지거나 오류 메시지가 표시되지 않을 수 있다.
- 자동 새로고침 로직이 메모리 누수를 일으키지 않도록 `useEffect`의 cleanup 함수를 정확히 구현해야 한다.
[검증 계획]
- [ ] 1. **API 라우트 검증**: 브라우저나 API 테스트 도구로 `/api/kis/indices`를 직접 호출하여 정상적인 JSON 응답(지수 데이터, fetchedAt)이 오는지 확인.
- [ ] 2. **UI 초기 로딩 검증**: 페이지 로드 시 `MarketIndices` 컴포넌트 영역에 스켈레톤 UI가 먼저 표시되는지 확인.
- [ ] 3. **UI 데이터 표시 검증**: 데이터 로딩 완료 후 KOSPI, KOSDAQ 지수 정보(현재가, 등락, 등락률)가 헤더에 정상적으로 표시되는지 확인. 등락에 따라 색상(빨강/파랑)이 올바르게 적용되는지 확인.
- [ ] 4. **UI 자동 새로고침 검증**: 약 30초가 지난 후 `fetchedAt` 시간이 갱신되며 데이터가 새로고침되는지 네트워크 탭과 화면 표시를 통해 확인.
- [ ] 5. **로그아웃/비로그인 상태 검증**: 로그아웃하거나 비로그인 상태로 접속했을 때, 지수 컴포넌트가 헤더에 표시되지 않는지 확인.
- [ ] 6. **홈 랜딩 페이지 검증**: `blendWithBackground` prop이 `true`로 설정된 홈 랜딩 페이지에서 지수 컴포넌트가 표시되지 않는지 확인.
[진행 로그]
- 2026-02-26: 계획 문서 작성 및 기능 구현 완료.

View File

@@ -0,0 +1,81 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-04-dashboard-market-hub-and-orderbook-rate.md
[요구사항 요약]
- 호가창 각 호가 행에 기준가 대비 퍼센트(등락률)를 추가 표시한다.
- /dashboard 안에서 내 종목/내 재산/주문내역 같은 개인 자산 정보를 별도 메뉴(탭)로 분리한다.
- /dashboard 메인 화면에는 급등주식, 인기종목, 주요 뉴스와 추가 시장 정보 카드를 배치한다.
[가정]
- "메뉴를 하나 새로"는 /dashboard 내부 탭 메뉴(시장 탭/내 자산 탭) 추가로 해석한다.
- 기존 KIS 인증/세션 헤더 체계는 유지하고, 신규 데이터도 동일 헤더로 조회한다.
- 인기종목은 거래량 기준 상위(필요 시 거래대금 기준 포함)로 제공한다.
[영향 범위]
- 수정:
- features/trade/components/orderbook/orderbook-utils.ts
- features/trade/components/orderbook/orderbook-sections.tsx
- features/dashboard/types/dashboard.types.ts
- features/dashboard/apis/dashboard.api.ts
- features/dashboard/hooks/use-dashboard-data.ts
- features/dashboard/components/DashboardContainer.tsx
- lib/kis/dashboard.ts
- 추가:
- app/api/kis/domestic/market-hub/route.ts
- features/dashboard/components/MarketHubSection.tsx
- 삭제:
- features/dashboard/hooks/use-market-movers-alert.ts
[구현 단계]
- [x] 1. 호가창 퍼센트 표시 로직 추가: 기준가 대비 등락률 계산 유틸을 만들고 호가 행 UI에 퍼센트를 노출한다. (`features/trade/components/orderbook/orderbook-utils.ts`, `features/trade/components/orderbook/orderbook-sections.tsx`)
- [x] 2. 대시보드 시장 허브 API 추가: 급등주식/거래량 상위/뉴스(및 보조 지표)를 KIS에서 조회해 단일 응답으로 반환한다. (`lib/kis/dashboard.ts`, `app/api/kis/domestic/market-hub/route.ts`)
- [x] 3. 대시보드 데이터 훅 확장: 기존 balance/indices/activity에 market-hub 데이터를 병렬 조회하고 에러 상태를 분리 관리한다. (`features/dashboard/hooks/use-dashboard-data.ts`, `features/dashboard/apis/dashboard.api.ts`, `features/dashboard/types/dashboard.types.ts`)
- [x] 4. /dashboard 메뉴 분리: "시장" 탭과 "내 자산" 탭을 만들고 개인 자산 컴포넌트를 "내 자산" 탭으로 이동한다. (`features/dashboard/components/DashboardContainer.tsx`)
- [x] 5. 시장 탭 구성: 급등주식, 인기종목, 주요 뉴스, 추가 정보(시장 폭/업다운 카운트)를 카드로 구성한다. (`features/dashboard/components/MarketHubSection.tsx`)
[사용할 MCP/Skills]
- MCP: next-devtools(런타임 점검), web search(요구사항의 검색 반영)
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker, nextjs-app-router-patterns, vercel-react-best-practices
[참조 문서(common-docs)]
- common-docs/api-reference/openapi_all.xlsx
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[주석/문서 반영 계획]
- 함수 주석: [목적]/[사용처]/[데이터 흐름] 중심으로 유지한다.
- 상태 주석: market-hub 로딩/오류 상태가 화면에 미치는 영향 한 줄 주석을 추가한다.
- 복잡 로직: 시장 허브 응답 정규화는 1,2,3 단계 주석으로 분해한다.
[리스크/회귀 포인트]
- KIS 순위/뉴스 API는 파라미터 조합에 따라 빈 응답이 나올 수 있어 폴백 파라미터가 필요하다.
- 신규 시장 API 실패 시에도 기존 내 자산 탭은 정상 동작해야 한다.
- 호가 퍼센트 표시가 모바일에서 줄바꿈/폭 깨짐을 유발할 수 있어 반응형 폭 점검이 필요하다.
[검증 계획]
- [x] 1. lint: 타입/린트 오류 없이 통과하는지 확인. (`npm run lint` 통과)
- [x] 2. build: Next.js 프로덕션 빌드가 통과하는지 확인. (`npm run build` 통과)
- [x] 3. 런타임: /dashboard 진입 후 시장 탭/내 자산 탭 전환이 정상 동작하는지 확인. (Playwright MCP에서 탭 전환 및 화면 반영 확인)
- [x] 4. 런타임: 시장 탭에서 급등/인기/뉴스 카드가 실패 시에도 개별 에러 안내로 안전하게 렌더링되는지 확인. (Playwright MCP route abort로 `/api/kis/domestic/market-hub` 실패 주입 후 `Failed to fetch` + 빈 카드 안전 렌더링 확인)
- [x] 5. 런타임: /trade 호가창에서 각 가격 행에 퍼센트가 표시되는지 확인. (Playwright MCP로 `/dashboard` 종목 클릭 이동 후 일반호가 행 `±x.xx%` 표기 확인)
[진행 로그]
- 2026-03-04: 계획 문서 작성.
- 2026-03-04: 구현 1~5 완료, `npm run lint`/`npm run build` 통과.
- 2026-03-04: 브라우저 스모크 실행 시 `/dashboard`, `/trade`, `/settings`가 비로그인 상태에서 `/login`으로 리다이렉트되는 동작 확인.
- 2026-03-04: 급등주 미노출 대응(등락률 API 파라미터 폴백 + 거래량 기반 폴백) 적용.
- 2026-03-04: 급락주 데이터 및 급등/급락 주기 알림(60초 갱신 + 3분 쿨다운 모달) 추가.
- 2026-03-04: 요청 반영으로 급등/급락 전역 모달 알림 훅 제거.
- 2026-03-04: KIS 문서/코드 기준 급등·급락 웹소켓 수신 가능성 검토 완료(순위는 REST, WS는 종목 체결/호가 중심).
- 2026-03-04: Playwright MCP로 `/dashboard` 시장/내 자산 탭 전환 정상 동작 재검증 완료.
- 2026-03-04: Playwright MCP route abort 주입으로 시장 허브 API 실패 시 에러 안내/빈 상태 카드 안전 렌더링 확인.
- 2026-03-04: Playwright MCP로 급등/급락/인기/거래대금 카드 종목 클릭 시 `/trade` 이동 및 선택 종목 반영 확인.
- 2026-03-04: Playwright MCP로 `/trade` 일반호가 각 가격 행의 퍼센트(등락률) 표기 확인.
[계획 대비 완료체크]
- 완료: 구현 1~5, 검증 1~5
- 부분 완료: 없음
- 미완료: 없음
- 최종 판정: 배포 가능

View File

@@ -0,0 +1,50 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-04-dashboard-modern-brand-layout-refresh.md
[요구사항 요약]
- /dashboard를 모던하고 현대적인 느낌으로 재배치한다.
- 브랜드 컬러(brand 토큰)를 적극 활용해 UI 일관성을 높인다.
- 핵심 정보를 한눈에 확인할 수 있도록 정보 우선순위를 재정렬한다.
[가정]
- 기존 정보 구조(시장 탭/내 자산 탭, API/데이터 모델)는 유지하고 UI/레이아웃 중심으로 개선한다.
- 기존 브랜드 토큰(--brand-*)을 재사용해 전체 앱 디자인 언어와 일관성을 맞춘다.
[영향 범위]
- 수정:
- features/dashboard/components/DashboardContainer.tsx
- features/dashboard/components/StatusHeader.tsx
- features/dashboard/components/MarketSummary.tsx
- features/dashboard/components/MarketHubSection.tsx
- features/dashboard/components/HoldingsList.tsx
- features/dashboard/components/StockDetailPreview.tsx
- features/dashboard/components/ActivitySection.tsx
[구현 단계]
- [x] 1. 대시보드 컨테이너 재배치: 상단 브랜드 히어로/상태 칩 추가, 탭 인터랙션 스타일 강화, 탭별 레이아웃 재정렬.
- [x] 2. 자산 헤더 리디자인: 총자산/손익 중심 카드 + 연결 상태/액션 패널 + 핵심 지표 4분할 구성.
- [x] 3. 시장 지수 카드 리디자인: 실시간 상태 배지, 지수 카드 시각 톤 강화, 카드 대비 개선.
- [x] 4. 시장 허브 리디자인: 급등/급락/인기/거래대금 2x2 구성 및 뉴스 가독성 개선.
- [x] 5. 자산 하위 카드 톤 정렬: 보유종목/선택종목/활동내역 카드 스타일 일관화 및 탭 버튼 강조.
- [x] 6. 사후 버그 수정: 시장 지수 배지의 실시간 상태 판정을 상단 상태칩과 동일 기준으로 통일.
- [x] 7. 사후 버그 수정: Next.js `scroll-behavior` 경고 제거를 위한 루트 html 속성 보완.
[리스크/회귀 포인트]
- 카드 높이/스크롤 높이 조정으로 모바일에서 콘텐츠 길이 체감이 달라질 수 있다.
- 탭 스타일 커스터마이징이 다크 모드 대비에 영향을 줄 수 있다.
[검증 계획]
- [x] 1. lint: `npm run lint` 통과.
- [x] 2. build: `npm run build` 통과.
- [x] 3. 런타임: 로그인 상태에서 /dashboard 시각적 배치/반응형 확인. (Playwright로 데스크톱/모바일, 탭 전환, 메인 왕복 동선 확인)
- [x] 4. 런타임: 브라우저 콘솔 경고/오류 확인. (`warning`/`error` 비어있음)
- [x] 5. 런타임: API 네트워크 응답 확인. (`/api/kis/domestic/indices`, `/api/kis/domestic/market-hub`, `/api/kis/ws/approval` 모두 200)
[진행 로그]
- 2026-03-04: 대시보드 모던 UI 재배치 구현 완료.
- 2026-03-04: `npm run lint` 통과.
- 2026-03-04: `npm run build` 통과.
- 2026-03-04: Playwright로 `/dashboard` 접근 시 `/login` 리다이렉트 동작 및 모바일 뷰포트(390x844) 렌더링 확인.
- 2026-03-04: 시장 지수 배지 상태 문구 불일치(실시간 미연결 vs 수신중) 수정.
- 2026-03-04: `app/layout.tsx``data-scroll-behavior=\"smooth\"` 추가로 Next 경고 제거.
- 2026-03-04: Playwright 재검증(데스크톱/모바일, 로고->메인, 메인->대시보드, 자산 탭 전환) 완료.

View File

@@ -0,0 +1,78 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-05-autotrade-ai-context-layout-boxrange.md
[요구사항 요약]
- 자동매매 신호 생성 시 AI 판단 입력 데이터를 늘린다.
- 자동매매 설정창 높이 문제를 해결하고 레이아웃을 더 간결하게 정리한다.
- 유명기법을 선택하지 않아도 자동매매가 동작하도록 기본 동작을 완화한다.
- "당일 상승 후 박스권 횡보 단타" 기법을 새로 추가한다.
[가정]
- "유명기법 미선택 허용"은 시작 자체 허용 + 서버에서 기본 기법 자동 적용으로 해석한다.
- 박스권 단타 기법은 fallback 엔진(규칙 기반)에서 즉시 동작하도록 우선 구현한다.
- AI/CLI 모드에도 동일한 추가 스냅샷 데이터를 전달해 판단 품질을 함께 높인다.
[영향 범위]
- 수정:
- features/autotrade/types/autotrade.types.ts
- features/autotrade/components/AutotradeControlPanel.tsx
- features/autotrade/hooks/useAutotradeEngine.ts
- features/autotrade/apis/autotrade.api.ts
- lib/autotrade/strategy.ts
- lib/autotrade/openai.ts
- app/api/autotrade/strategies/compile/route.ts
- app/api/autotrade/signals/generate/route.ts
- 추가:
- 없음
- 삭제:
- 없음
[구현 단계]
- [x] 1. 타입/스키마 확장: 자동매매 스냅샷에 체결/호가/파생 지표 필드를 추가하고 클라이언트/서버 타입을 동기화했다. (`features/autotrade/types/autotrade.types.ts`, `features/autotrade/apis/autotrade.api.ts`, `app/api/autotrade/signals/generate/route.ts`)
- [x] 2. AI 입력 데이터 확장: `useAutotradeEngine`에서 추가 지표를 계산해 signal API로 전달하고, OpenAI 프롬프트 안내 문구를 업데이트했다. (`features/autotrade/hooks/useAutotradeEngine.ts`, `lib/autotrade/openai.ts`, `features/autotrade/components/AutotradeControlPanel.tsx`)
- [x] 3. 유명기법 미선택 허용: 시작 버튼 조건/사전 검증 제한을 완화하고, compile 라우트에서 기본 기법 자동 적용을 넣었다. (`features/autotrade/components/AutotradeControlPanel.tsx`, `features/autotrade/hooks/useAutotradeEngine.ts`, `app/api/autotrade/strategies/compile/route.ts`)
- [x] 4. 박스권 단타 기법 추가: 기법 목록에 항목을 추가하고 fallback 신호 로직에 박스권 왕복 단타 판단을 구현했다. (`features/autotrade/types/autotrade.types.ts`, `lib/autotrade/strategy.ts`)
- [x] 5. 자동매매창 레이아웃 개선: 모달 높이 잘림을 없애고(내부 스크롤), 섹션 구조를 간결화했다. (`features/autotrade/components/AutotradeControlPanel.tsx`)
[사용할 MCP/Skills]
- MCP: shell_command, apply_patch, playwright
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker, nextjs-app-router-patterns, vercel-react-best-practices
[참조 문서(common-docs)]
- common-docs/api-reference/openapi_all.xlsx
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[주석/문서 반영 계획]
- 데이터 흐름 주석: "입력 데이터 확장" 구간에 [Step 1]/[Step 2]를 추가한다.
- UI 주석: 모달 섹션을 상단 요약/설정 본문/하단 액션으로 분리해 가독성을 유지한다.
- 박스권 기법 주석: 조건(상승폭, 박스 범위, 상하단 근접)과 신호 방향을 한글로 명확히 남긴다.
[리스크/회귀 포인트]
- 스냅샷 필드 확장 시 signal 라우트 zod 스키마 불일치가 발생할 수 있다.
- 유명기법 미선택 허용 이후에도 과도한 신호가 나오지 않게 fallback 신호 품질을 확인해야 한다.
- 설정 모달 레이아웃 변경 시 모바일에서 버튼 접근/스크롤 충돌이 생길 수 있다.
[검증 계획]
- [x] 1. lint: 타입/린트 오류 없이 통과 (`npm run lint` 통과)
- [x] 2. build: 프로덕션 빌드 통과 (`npm run build` 통과)
- [x] 3. 동작: 기법 미선택 허용 코드 경로 확인 (`canStartAutotrade` 조건 완화, `prepareStrategy` 필수 체크 제거, compile 기본 기법 자동 적용)
- [x] 4. 동작: 박스권 단타 기법이 목록/enum/fallback 로직에 반영됨을 코드 경로 확인
- [x] 5. 동작: 설정 화면 스모크에서 신규 체크박스/설정 UI 접근 및 콘솔 치명 오류 없음 확인 (Playwright). 자동매매 설정 모달은 KIS 미연결 환경으로 직접 실행 검증은 제한
[진행 로그]
- 2026-03-05: 계획 문서 작성.
- 2026-03-05: 자동매매 스냅샷 확장(체결/호가/파생 지표) 및 signal API 스키마 동기화 완료.
- 2026-03-05: 유명기법 미선택 허용(기본 기법 자동 적용) 반영 완료.
- 2026-03-05: "상승 후 박스권 단타" 기법 추가 및 fallback 신호 로직 구현 완료.
- 2026-03-05: 자동매매 설정 모달 레이아웃 간소화/높이 잘림 개선(내부 스크롤) 적용.
- 2026-03-05: `npm run lint`, `npm run build` 통과.
- 2026-03-05: Playwright 스모크(`/trade`, `/dashboard`, `/settings`) 확인, 콘솔 치명 오류 없음.
[계획 대비 완료체크]
- 완료: 구현 1~5, 검증 1~5
- 부분 완료: 없음
- 미완료: 없음
- 최종 판정: 배포 가능

View File

@@ -0,0 +1,87 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-05-autotrade-observability-momentum-scalp.md
[요구사항 요약]
- 자동매매 로그에 AI 진행상태/응답 근거/주요 수치가 보이도록 개선한다.
- 자동매매에서 AI로 보내는 데이터 항목을 코드 기준으로 명확히 보여준다(로그/설명 근거 강화).
- 1분봉 상승구간 단타(눌림-재돌파) 기법을 새로 추가한다.
[가정]
- "좋은 데이터 로그"는 사용자 화면에서 즉시 확인 가능한 런타임 로그 품질 개선(단계, 공급자, 핵심 수치, AI 근거)으로 해석한다.
- AI 전송 데이터 "상세" 요구는 코드 반영(진단 로그) + 최종 보고에서 필드 목록/흐름 설명으로 충족한다.
- 신규 전략은 규칙 기반 fallback에서 즉시 동작하고, OpenAI/CLI 프롬프트 가이드에도 동일 기법명을 반영한다.
[영향 범위]
- 수정:
- features/autotrade/types/autotrade.types.ts
- features/autotrade/stores/use-autotrade-engine-store.ts
- features/autotrade/hooks/useAutotradeEngine.ts
- features/autotrade/components/AutotradeControlPanel.tsx
- lib/autotrade/strategy.ts
- lib/autotrade/openai.ts
- app/api/autotrade/signals/generate/route.ts (필요 시)
- common-docs/improvement/plans/dev-plan-2026-03-05-autotrade-observability-momentum-scalp.md
- 추가:
- 없음
- 삭제:
- 없음
[구현 단계]
- [x] 1. 로그 타입 확장: 런타임 로그에 단계(stage)와 상세 데이터(detail)를 담을 수 있게 타입/스토어를 확장한다. (`features/autotrade/types/autotrade.types.ts`, `features/autotrade/stores/use-autotrade-engine-store.ts`)
- [x] 2. 엔진 로그 강화: compile/signal/risk/order 흐름에서 "요청 전송", "AI 응답", "주문 차단/실행"을 구조화 로그로 남긴다. (`features/autotrade/hooks/useAutotradeEngine.ts`)
- [x] 3. 로그 UI 개선: 상단 최근 로그 영역에서 단계/레벨/상세 데이터를 읽기 쉽게 표시한다. (`features/autotrade/components/AutotradeControlPanel.tsx`)
- [x] 4. 상승구간 단타 기법 추가: 기법 enum/옵션 추가 + fallback 로직(추세 필터, 눌림 구간, 재돌파, 거래량 확인) 구현. (`features/autotrade/types/autotrade.types.ts`, `lib/autotrade/strategy.ts`)
- [x] 5. OpenAI 가이드 반영: 신규 기법 설명과 판단 제약을 프롬프트에 반영한다. (`lib/autotrade/openai.ts`)
[사용할 MCP/Skills]
- MCP: shell_command, apply_patch, tavily-remote, playwright
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker, vercel-react-best-practices
[참조 문서(common-docs)]
- common-docs/api-reference/openapi_all.xlsx
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[외부 근거(전략 설계)]
- Investopedia Flag Pattern: 상승 추세 + 조정 중 거래량 축소 + 돌파 시 거래량 확인
- Investopedia Low Volume Pullback: 저거래량 눌림 후 추세 재개 확률
- Fidelity Technical Analysis(학습 PDF): 이동평균 기반 추세/눌림 해석, 거래량/모멘텀 보조 확인
[주석/문서 반영 계획]
- 함수 주석: [목적]/[데이터 흐름] 유지
- 상태 주석: 로그 stage/detail 도입 영향 표시
- 복잡 로직: 신규 상승구간 단타 판단 함수를 [Step 1~3] 주석으로 분리
- JSX 구역 주석: 로그 카드 영역을 단계/상세 구분 렌더링으로 분리
[리스크/회귀 포인트]
- 로그 데이터가 과도하면 UI 가독성이 저하될 수 있어 길이 제한/요약이 필요하다.
- 신규 전략이 기존 박스권 단타와 동시에 점수를 높여 과매수 신호가 늘 수 있어 임계값을 보수적으로 둔다.
- 타입 확장 시 기존 appendLog 호출과의 호환성을 유지해야 한다.
[검증 계획]
- [x] 1. lint: 타입/린트 오류 없는지 확인 (`npm run lint` 통과)
- [x] 2. build: Next 빌드 통과 확인 (`npm run build` 통과)
- [x] 3. 동작: 자동매매 로그에 stage/detail이 표시되는지 코드 경로/UI 확인 (`useAutotradeEngine` 로그 작성 + `AutotradeControlPanel` 렌더 반영)
- [x] 4. 동작: 신규 기법이 목록과 fallback 로직에 반영됐는지 확인 (`intraday_breakout_scalp` enum/옵션/룰 추가)
- [x] 5. 동작: /trade 화면 스모크에서 콘솔 오류 없이 렌더링 확인 (Playwright). 비로그인 환경으로 `/login` 리다이렉트 확인, 콘솔 error 없음
[진행 로그]
- 2026-03-05: 계획 문서 작성.
- 2026-03-05: 런타임 로그 구조(stage/detail) 확장 및 로그 UI 상세표시 반영.
- 2026-03-05: 로그 UI를 기본 접힘(차트 가림 최소화) + 쉬운 문장 요약 + 개발자 상세 토글 + 라이브 커서 표시로 개선.
- 2026-03-05: AI 신호 요청/응답/리스크게이트/주문실행 흐름 구조화 로그 반영.
- 2026-03-05: 상승구간 눌림-재돌파 단타(`intraday_breakout_scalp`) 기법 추가.
- 2026-03-05: AI 신호 사유 한글 강제(프롬프트 + 서버 후처리) 반영.
- 2026-03-05: 상단 예산 카드에 검증 전 입력 기준 예산 표시 추가.
- 2026-03-05: 신호 API 호출을 in-flight 순차 처리로 변경(이전 응답 완료 전 재호출 차단).
- 2026-03-05: 상단 로그를 `입력 -> 답변` 1쌍 고정 표시로 개선(응답 대기 상태 포함).
- 2026-03-05: `npm run lint`, `npm run build` 통과.
- 2026-03-05: Playwright 스모크(`/trade`, `/dashboard`, `/settings`) 실행, 비로그인 리다이렉트 경로에서 콘솔 error 없음.
[계획 대비 완료체크]
- 완료: 구현 1~5, 검증 1~5
- 부분 완료: 없음
- 미완료: 없음
- 최종 판정: 배포 가능

View File

@@ -0,0 +1,63 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-05-autotrade-risk-input-simplify.md
[요구사항 요약]
- 자동매매 투자금/손실 설정의 기존 복잡한 계산 로직(작은 값 선택)을 제거한다.
- 사용자가 입력한 투자금 금액/손실 금액이 실제 거래 기준으로 직접 반영되게 한다.
- 퍼센트 입력은 유지하되, 이해하기 쉬운 기준(경고/참고)으로 단순화한다.
[가정]
- "로직 없애고"는 `min(퍼센트 계산값, 금액)` 기반 자동 축소 로직 제거로 해석한다.
- 실제 주문 예산은 `투자금 금액(allocationAmount)` 그대로 사용한다.
- 자동중지 손실선은 `손실 금액(dailyLossAmount)` 그대로 사용한다.
- 퍼센트 입력값은 유지하고, 금액과 충돌 시 차단 대신 경고로 안내한다.
[영향 범위]
- 수정:
- lib/autotrade/risk.ts
- features/autotrade/components/AutotradeControlPanel.tsx
- common-docs/improvement/plans/dev-plan-2026-03-05-autotrade-risk-input-simplify.md
- 추가:
- 없음
- 삭제:
- 없음
[구현 단계]
- [x] 1. 리스크 계산식 단순화: 실적용 투자금/손실한도를 입력 금액 그대로 쓰도록 변경했다. (`lib/autotrade/risk.ts`)
- [x] 2. 퍼센트 해석 단순화: 퍼센트는 참고 기준 경고로만 반영했다. (`lib/autotrade/risk.ts`, `app/api/autotrade/strategies/validate/route.ts`)
- [x] 3. UI 문구 정리: "중 작은 값" 설명을 제거하고 "입력값 직접 적용"으로 변경했다. (`features/autotrade/components/AutotradeControlPanel.tsx`)
- [x] 4. 리스크 요약 카드 문구를 새 계산식에 맞게 정리했다. (`features/autotrade/components/AutotradeControlPanel.tsx`)
[사용할 MCP/Skills]
- MCP: shell_command, apply_patch
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker
[참조 문서(common-docs)]
- common-docs/api-reference/openapi_all.xlsx
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[리스크/회귀 포인트]
- 기존보다 공격적으로 주문이 나갈 수 있어(자동 축소 제거) 금액 입력 검증이 중요하다.
- 퍼센트 필드가 무의미하게 보이지 않도록 경고 기준 문구를 명확히 해야 한다.
[검증 계획]
- [x] 1. lint 통과 (`npm run lint` 통과)
- [x] 2. build 통과 (`npm run build` 통과)
- [x] 3. 코드 경로 확인: 주문 수량 계산에 쓰이는 `effectiveAllocationAmount`가 입력 금액 기준으로 세팅됨 확인 (`lib/autotrade/risk.ts` -> `features/autotrade/hooks/useAutotradeEngine.ts` -> `resolveOrderQuantity`)
- [x] 4. UI 문구 확인: "작은 값" 문구 제거 확인 (`features/autotrade/components/AutotradeControlPanel.tsx`)
[진행 로그]
- 2026-03-05: 계획 문서 작성.
- 2026-03-05: 투자금/손실 계산 로직을 입력 금액 직접 적용 방식으로 단순화.
- 2026-03-05: 퍼센트 필드를 참고 경고용으로 전환하고 검증 스키마를 nonnegative로 완화.
- 2026-03-05: 자동매매 설정/리스크 요약 문구를 새 계산식 기준으로 업데이트.
- 2026-03-05: `npm run lint`, `npm run build` 통과.
[계획 대비 완료체크]
- 완료: 구현 1~4, 검증 1~4
- 부분 완료: 없음
- 미완료: 없음
- 최종 판정: 배포 가능

View File

@@ -0,0 +1,69 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-05-kis-remember-credentials-checkbox.md
[요구사항 요약]
- 설정 화면에서 앱토큰(앱키), 앱시크릿키, 계좌번호에 대해 "기억하기" 체크박스를 제공한다.
- 체크한 항목만 브라우저 재시작 후에도 복원되도록 로컬 저장을 추가한다.
- 기존 KIS 검증/계좌인증 동작은 그대로 유지한다.
[가정]
- 사용자 요청의 "앱토큰"은 현재 화면 필드명 기준 "앱키(appKey)"로 해석한다.
- "기억하기"는 장기 저장(localStorage), 미체크는 저장하지 않음으로 해석한다.
- 기존 세션값이 있으면(이미 입력/검증된 상태) 기억값 자동 복원으로 덮어쓰지 않는다.
[영향 범위]
- 수정:
- features/settings/components/KisAuthForm.tsx
- features/settings/components/KisProfileForm.tsx
- features/layout/components/user-menu.tsx
- features/auth/components/session-manager.tsx
- 추가:
- features/settings/lib/kis-remember-storage.ts
- 삭제:
- 없음
[구현 단계]
- [x] 1. 기억하기 저장 유틸 추가: 앱키/앱시크릿/계좌별 체크 상태/값을 localStorage로 읽기/쓰기/삭제하는 공통 함수를 만들었다. (`features/settings/lib/kis-remember-storage.ts`)
- [x] 2. 앱키/앱시크릿 체크박스 UI 추가: 인증 폼에 2개 체크박스를 추가하고, 체크 여부에 따라 자동 저장/삭제를 연결했다. (`features/settings/components/KisAuthForm.tsx`)
- [x] 3. 계좌번호 체크박스 UI 추가: 계좌 인증 폼에 체크박스를 추가하고 동일한 저장/복원 흐름을 연결했다. (`features/settings/components/KisProfileForm.tsx`)
- [x] 4. 로그아웃/세션만료 시 정리 연동: 기존 세션 정리 루틴에 기억값 키를 포함해 민감 정보가 남지 않게 했다. (`features/layout/components/user-menu.tsx`, `features/auth/components/session-manager.tsx`)
[사용할 MCP/Skills]
- MCP: shell_command(코드 탐색/수정), apply_patch(파일 수정)
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker, nextjs-app-router-patterns, vercel-react-best-practices
[참조 문서(common-docs)]
- common-docs/api-reference/openapi_all.xlsx
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[주석/문서 반영 계획]
- 상태 주석: 기억하기 체크 상태가 입력 필드 자동복원/저장에 미치는 영향을 한 줄 주석으로 추가한다.
- 복잡 로직: "초기 복원"과 "변경 저장"을 [Step 1], [Step 2] 주석으로 분리한다.
- JSX 구역 주석: 입력/체크박스 구역을 나눠 화면 구조를 더 쉽게 읽게 유지한다.
[리스크/회귀 포인트]
- 체크박스 초기화 시 하이드레이션 타이밍 차이로 깜빡임이 생길 수 있다.
- store 입력 setter 호출은 인증 상태를 리셋하므로, 복원 시 기존 세션값을 덮어쓰지 않도록 조건이 필요하다.
- 민감값 장기 저장 정책 변경이므로 로그아웃 시 정리 누락이 없어야 한다.
[검증 계획]
- [x] 1. lint: 타입/린트 오류 없이 통과했다. (`npm run lint` 통과)
- [x] 2. build: Next.js 프로덕션 빌드가 통과했다. (`npm run build` 통과)
- [x] 3. 동작: 체크박스/저장 로직을 코드 경로로 검증했다. (기억하기 on/off -> `setKisRememberEnabled` -> `setRememberedKisValue`)
- [x] 4. 동작: 복원 로직을 코드 경로로 검증했다. (`hasHydrated` 이후 입력값 비어 있을 때만 `getRememberedKisValue` 복원)
- [x] 5. 동작: 로그아웃/세션만료 시 기억값 정리 키 포함을 반영했다. (`SESSION_RELATED_STORAGE_KEYS``KIS_REMEMBER_LOCAL_STORAGE_KEYS` 추가)
[진행 로그]
- 2026-03-05: 계획 문서 작성.
- 2026-03-05: 구현 1~4 완료 (기억하기 체크박스 + localStorage 유틸 + 세션 정리 키 반영).
- 2026-03-05: `npm run lint`, `npm run build` 통과.
- 2026-03-05: Playwright 스모크에서 `/settings` 접근 시 `/login` 리다이렉트 및 콘솔 치명 오류 없음 확인(인증 미보유로 설정 폼 직접 상호작용은 환경상 제한).
[계획 대비 완료체크]
- 완료: 구현 1~4, 검증 1~5
- 부분 완료: 없음
- 미완료: 없음
- 최종 판정: 배포 가능

View File

@@ -0,0 +1,71 @@
# [계획 문서]
- 경로: `common-docs/improvement/plans/dev-plan-2026-03-05-trade-chart-timeframes-and-history.md`
## [요구사항 요약]
- 차트 표시/상호작용을 개선한다. (공식 문서 기준 반영)
- 분봉 옵션에 5분/10분/15분을 추가한다.
- 1시간봉 과거 데이터가 짧게 보이는 원인을 수정한다.
## [가정]
- 기존 차트 라이브러리는 `lightweight-charts@5.1.0`을 유지한다.
- KIS 분봉 API는 당일/일별 분봉 API를 조합해 과거 데이터를 이어 붙인다.
- UI 레이아웃 전체 재설계보다 차트 영역 중심 개선을 우선한다.
## [영향 범위]
- 수정: `features/trade/types/trade.types.ts`
- 수정: `features/trade/components/chart/stock-line-chart-meta.ts`
- 수정: `features/trade/components/chart/chart-utils.ts`
- 수정: `features/trade/components/chart/StockLineChart.tsx`
- 수정: `lib/kis/domestic-helpers.ts`
- 수정: `app/api/kis/domestic/chart/route.ts`
## [구현 단계]
- [x] 1. 차트/타임프레임 타입 확장 (`1m/5m/10m/15m/30m/1h/1d/1w`)
- 근거: `features/trade/types/trade.types.ts`
- [x] 2. 분봉 버킷 계산 로직 확장 (5/10/15분 지원)
- 근거: `lib/kis/domestic-helpers.ts`, `features/trade/components/chart/chart-utils.ts`, `app/api/kis/domestic/chart/route.ts`
- [x] 3. 차트 초기 과거 로드량을 시간프레임별로 확장해 1시간봉 과거 구간 부족 개선
- 근거: `features/trade/components/chart/stock-line-chart-meta.ts`, `features/trade/components/chart/StockLineChart.tsx`
- [x] 4. infinite history 로딩 트리거를 공식 문서 권장 패턴(`barsInLogicalRange`)으로 보강
- 근거: `features/trade/components/chart/StockLineChart.tsx`
- [x] 5. 차트 가시성 옵션(축 여백/우측 여백/가격선) 미세 개선
- 근거: `features/trade/components/chart/StockLineChart.tsx` (`timeScale.rightOffset/barSpacing/minBarSpacing/rightBarStaysOnScroll`)
## [사용할 MCP/Skills]
- MCP: `tavily-remote` (lightweight-charts 공식 문서 확인)
- MCP: `mcp:kis-code-assistant-mcp` (KIS 분봉 API 파라미터/제약 확인)
- Skills: `dev-auto-pipeline`, `vercel-react-best-practices`
## [참조 문서(common-docs)]
- `common-docs/api-reference/openapi_all.xlsx`
- `common-docs/api-reference/kis_api_reference.md`
- `common-docs/api-reference/kis-error-code-reference.md`
- `common-docs/features/trade-stock-sync.md`
- `common-docs/ui/GLOBAL_ALERT_SYSTEM.md`
## [리스크/회귀 포인트]
- 분봉 추가 후 기존 30분/1시간 정렬 경계가 깨질 수 있음
- 과거 로드량 증가 시 초기 로딩 시간이 늘 수 있음
- 무한 스크롤 조건 변경 시 중복 API 호출이 발생할 수 있음
## [검증 계획]
- [x] 1. 타입/빌드 검증: `npm run lint`
- 근거: 통과
- [x] 2. 프로덕션 빌드 검증: `npm run build`
- 근거: 통과
- [x] 3. 수동 점검: 분봉 드롭다운(1/5/10/15/30/60분) 노출 확인
- 근거: Playwriter 스냅샷에서 `1분/5분/10분/15분/30분/1시간` 버튼 노출 확인
- [x] 4. 수동 점검: 1시간봉 진입 직후 과거 구간 확장 여부 확인
- 근거: `/api/kis/domestic/chart?timeframe=1h` 초기 요청 19건 확인, 최소 시각 `2026-02-26 09:00:00(KST)`까지 로드
- [x] 5. 수동 점검: 좌측 스크롤 시 과거 데이터 추가 로딩 유지 확인
- 근거: 차트 드래그 후 `timeframe=1h` 추가 요청 5건 발생, 최소 시각 `2026-02-25 09:00:00(KST)`로 확장
## [진행 로그]
- 2026-03-05: 계획 문서 생성.
- 2026-03-05: `lightweight-charts` 공식 문서 확인 (`subscribeVisibleLogicalRangeChange`, `barsInLogicalRange`, infinite history 데모).
- 2026-03-05: `kis-code-assistant-mcp``inquire_time_itemchartprice`, `inquire_time_dailychartprice` 예제 확인 (당일/과거 분봉 API 호출 제약 확인).
- 2026-03-05: 차트 타임프레임 확장(5/10/15분) + 과거 로드 로직 개선 + KIS 분봉 cursor 파싱 보강 적용.
- 2026-03-05: `npm run lint`, `npm run build` 통과.
- 2026-03-05: Playwriter 실브라우저 검증 수행(`/trade`), 분봉 메뉴/1시간봉 과거 로드/좌측 스크롤 추가 로드 확인.
- 2026-03-05: 1시간봉 초기 과거 로드 상한 추가 상향(페이지 수 + 목표 봉 수 + 12초 예산), 재검증 시 최소 시각 `2026-02-05 09:00:00(KST)`까지 자동 로드 확인.
- 2026-03-05: 창 확장 시 좌측 공백 보완 로직 추가(초기 fitContent 보강 + left whitespace 자동 추가 로드), 1920px 기준 재검증 시 최소 시각 `2026-01-30 13:00:00(KST)`까지 자동 로드 확인.

View File

@@ -0,0 +1,71 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-06-autotrade-ai-signal-context.md
[요구사항 요약]
- 자동매매에서 AI에 넘기는 신호 생성 입력값이 신규 프롬프트 요구사항을 만족하는지 점검한다.
- 부족한 데이터가 있으면 실제 신호 요청 payload에 추가한다.
- 변경 후 검증 결과까지 남긴다.
[가정]
- 신규 프롬프트의 핵심 요구는 `직전 강한 움직임 + 최근 1분봉 압축 구간` 판단이다.
- 현재 전달 중인 최근 체결/호가 파생값만으로는 캔들 구조 판단이 부족하다.
- 실시간 주문 루프는 유지하되, 추가 데이터는 기존 KIS 차트 API를 재사용해 보강한다.
[영향 범위]
- 수정: features/autotrade/hooks/useAutotradeEngine.ts
- 수정: features/autotrade/apis/autotrade.api.ts
- 수정: features/autotrade/types/autotrade.types.ts
- 수정: app/api/autotrade/signals/generate/route.ts
- 수정: lib/autotrade/openai.ts
- 수정: lib/autotrade/cli-provider.ts
- 수정: common-docs/improvement/plans/dev-plan-2026-03-06-autotrade-ai-signal-context.md
- 추가: 없음
- 삭제: 없음
[구현 단계]
- [x] 1. 현재 신호 생성 입력값과 신규 프롬프트 요구사항 차이를 정리한다.
- 근거: 기존 signal payload에는 틱/호가/체결 파생값만 있고, 최근 1분봉 OHLCV와 원본 사용자 prompt가 빠져 있었음.
- [x] 2. 최근 1분봉 OHLCV와 관련 파생값을 담을 타입/요청 스키마를 추가한다.
- 근거: `features/autotrade/types/autotrade.types.ts`, `app/api/autotrade/signals/generate/route.ts`
- [x] 3. 자동매매 훅에서 최근 1분봉 데이터를 조회/캐시하고 신호 요청 snapshot에 포함한다.
- 근거: `features/autotrade/hooks/useAutotradeEngine.ts`
- [x] 4. OpenAI/구독형 CLI 프롬프트가 새 입력값을 활용하도록 지시문을 보강한다.
- 근거: `lib/autotrade/openai.ts`, `lib/autotrade/cli-provider.ts`
- [x] 5. 로그 요약에 새 입력 데이터가 보이도록 정리한다.
- 근거: `features/autotrade/hooks/useAutotradeEngine.ts`
[사용할 MCP/Skills]
- MCP: next-devtools(init), update_plan
- Skills: dev-auto-pipeline, dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker, vercel-react-best-practices
[참조 문서(common-docs)]
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[주석/문서 반영 계획]
- 함수 주석: [목적]/[사용처]/[데이터 흐름] 유지
- 상태 주석: 값 변경 시 화면/주문 루프 영향 한 줄 설명
- 복잡 로직/핸들러: [Step 1], [Step 2], [Step 3] 구조 유지
- JSX 구역 주석: 기존 구조 유지, 필요 시 최소 보강
[리스크/회귀 포인트]
- 1분봉 조회를 신호 루프마다 과도하게 호출하면 응답 지연이 늘 수 있다.
- 차트 조회 실패 시 신호 생성 자체가 막히지 않도록 기존 snapshot fallback을 유지해야 한다.
- 타입 확장 후 route/request schema가 불일치하면 신호 요청이 400으로 실패할 수 있다.
[검증 계획]
- [x] 1. 타입/요청 스키마가 일치하는지 `npm run lint`로 확인한다.
- 결과: 통과
- [x] 2. OpenAI/CLI 프롬프트에 1분봉 데이터와 압축 구간 판단 지시가 반영됐는지 코드로 확인한다.
- 결과: `operatorPrompt`, `recentMinuteCandles`, `minutePatternContext` 활용 지시 반영 완료
- [x] 3. 신호 요청 snapshot 로그에 새 필드가 노출되는지 코드 기준으로 확인한다.
- 결과: `snapshotSummary`, `snapshot` 로그에 minutePattern/recentMinuteCandlesTail 반영 완료
[진행 로그]
- 2026-03-06: 기존 snapshot은 틱/호가/체결 파생값은 충분하지만, 1분봉 캔들 구조 데이터가 없어 신규 패턴 프롬프트 기준으로는 입력이 부족하다고 판단함.
- 2026-03-06: 신호 요청에 원본 사용자 prompt를 추가해, 전략 요약으로 축약되던 세부 규칙이 신호 생성 단계에도 직접 전달되도록 수정함.
- 2026-03-06: 최근 1분봉 OHLCV 24개와 minutePatternContext(직전 추세/압축 범위/압축 거래량비/박스 상하단)를 snapshot에 추가함.
- 2026-03-06: `npm run lint`, `npm run build` 통과. `nextjs_call(get_errors)` 기준 3001 개발 서버에서 브라우저 세션 오류 없음 확인. 브라우저 자동화 스모크는 로컬 Chrome 프로필 충돌로 미실행.
- 2026-03-06: BUY 신호인데 주문이 나가지 않는 원인을 추가 점검한 결과, `maxOrderAmountRatio`가 낮으면 전체 예산으로 1주를 살 수 있어도 주문 수량이 0주가 되는 문제가 확인됨. `lib/autotrade/risk.ts`에서 최소 1주 보정 로직을 추가하고 `npm run lint`, `npm run build` 재통과 확인.

View File

@@ -0,0 +1,126 @@
[계획 문서 경로]
- common-docs/improvement/plans/dev-plan-2026-03-06-autotrade-real-execution-budget-tax.md
[요구사항 요약]
- 내 예산 기준으로 실제 몇 주를 살 수 있는지 계산하고, 자동매매 설정창에서 정한 비율대로 매수 수량이 정해지게 만든다.
- 매도는 현재 보유/매도가능 수량과 비교해서 가능한 수량만 나가게 한다.
- 수수료/세금/실현손익까지 고려해 진짜 자동매매처럼 동작하게 만든다.
[가정]
- 자동매매 설정창의 `allocationPercent`는 "이번 종목/이번 주문에 실제로 쓸 비율"로 사용한다.
- `allocationAmount`는 절대 상한(최대 투자금)으로 사용한다.
- 수수료/세금은 계좌/환경/정책에 따라 달라질 수 있으므로, 구현 시 하드코딩보다 `설정값 + KIS 실제 체결/매매일지 값`을 함께 쓴다.
- 국내주식 단주가 아닌 1주 단위 주문 기준으로 계획한다.
[영향 범위]
- 수정: features/autotrade/hooks/useAutotradeEngine.ts
- 수정: lib/autotrade/risk.ts
- 수정: features/autotrade/types/autotrade.types.ts
- 수정: features/autotrade/components/AutotradeControlPanel.tsx
- 수정: app/api/autotrade/signals/generate/route.ts
- 수정: lib/autotrade/openai.ts
- 수정: lib/autotrade/cli-provider.ts
- 수정: package.json
- 추가: lib/autotrade/execution-cost.ts
- 추가: lib/autotrade/executable-order-quantity.ts
- 추가: tests/autotrade/risk-budget.test.ts
- 추가: tests/autotrade/order-guard-cost.test.ts
- 추가: common-docs/improvement/plans/dev-plan-2026-03-06-autotrade-real-execution-budget-tax.md
- 삭제: 없음
[현재 코드 기준 핵심 문제]
- `allocationPercent`가 실주문 계산 기준이 아니라 참고 경고 수준으로만 쓰이고 있다.
- 쉬운 말: 설정창에서 10%, 25%를 바꿔도 실제 자동매매 수량 계산에는 약하게만 반영된다.
- 매수 수량은 `effectiveAllocationAmount``maxOrderAmountRatio` 중심이라, 내 예산/비율/호가/예상 비용을 함께 계산하는 구조가 아니다.
- 매도는 `보유수량/매도가능수량` 차단은 있지만, 포지션 기준 목표 청산 비율, 부분 청산, 순손익 기준 청산 조건이 없다.
- 세금/수수료는 대시보드 조회/표시에는 일부 있지만, 자동매매의 진입/청산/손실 한도 계산에는 거의 반영되지 않는다.
- 일일 손실 한도는 입력 금액 기준이고, 실제 체결 후 순손익(수수료/세금 포함)과 연결되지 않는다.
[구현 단계]
- [x] 1. 주문 가능 예산 모델 재정의
- 입력: 가용 예수금, 매수가능금액, allocationPercent, allocationAmount, 전략별 maxOrderAmountRatio
- 처리: `실주문가능예산 = min(매수가능금액, allocationAmount 상한, 예수금 * allocationPercent)` 구조로 통일
- 결과: "현재 이 종목에 실제로 쓸 수 있는 예산" 1개 값으로 고정
- [x] 2. 매수 수량 계산 로직 교체
- 입력: 실주문가능예산, 현재가/주문가, 예상 수수료, 최소 안전여유금
- 처리: 비용 포함 기준으로 최대 주문 가능 수량 계산
- 결과: "내 예산 기준으로 지금 몇 주 살 수 있는지"를 로그와 UI에 함께 표시
- [x] 3. 매도 수량 계산 로직을 포지션 기준으로 확장
- 입력: 보유수량, 매도가능수량, 평균단가, 평가손익, AI 제안 수량/비율
- 처리: 없는 주식은 절대 매도 금지, 보유보다 큰 수량 금지, 부분 매도 허용
- 결과: "실제 보유 중인 수량 안에서만 매도" 보장
- [x] 4. 수수료/세금 추정 모듈 추가
- 입력: 주문금액, 매수/매도 구분, 계좌/환경 정책
- 처리: 주문 전 예상 비용 계산, 주문 후 실제 체결/매매일지로 정산값 보정
- 결과: 순손익 기준 판단 가능
- [x] 5. 자동매매 위험 관리 기준을 순손익 기준으로 보강
- 입력: 실현손익, 평가손익, 누적 수수료, 누적 세금
- 처리: 일일 손실선/청산 조건을 총손익이 아니라 순손익 기준으로 갱신
- 결과: 세금/수수료 때문에 실제 손실이 커지는 상황 반영
- [x] 6. AI 입력값도 포지션/비용 기준으로 보강
- 입력: holdingQuantity, sellableQuantity, averagePrice, estimatedFee, estimatedTax, netProfitEstimate
- 처리: AI가 매도 시 "팔 수 있는지/팔면 순손익이 어떤지"를 함께 보게 함
- 결과: 보유 없는 SELL, 손익 무시 SELL/BUY 감소
- [x] 7. UI/로그 보강
- 자동매매 설정창/로그에 아래 항목 노출
- 현재 주문 가능 예산
- 현재 매수 가능 수량
- 현재 보유 수량 / 매도 가능 수량
- 예상 수수료 / 예상 세금 / 예상 순손익
- [x] 8. 체결 후 실제값 동기화
- 주문 후 잔고/활동 API 재조회
- 체결 후 보유수량, sellableQuantity, realized fee/tax, realized profit을 스토어에 반영
- 다음 주문은 이 최신값을 기준으로 계산
[사용할 MCP/Skills]
- MCP: next-devtools, sequential-thinking, mcp:kis-code-assistant-mcp
- Skills: dev-plan-writer, dev-mcp-implementation, dev-refactor-polish, dev-test-gate, dev-plan-completion-checker, vercel-react-best-practices
[참조 문서(common-docs)]
- common-docs/api-reference/kis_api_reference.md
- common-docs/api-reference/kis-error-code-reference.md
- common-docs/features/trade-stock-sync.md
- common-docs/ui/GLOBAL_ALERT_SYSTEM.md
[주석/문서 반영 계획]
- 함수 주석: [목적]/[사용처]/[데이터 흐름] 유지
- 수량 계산/비용 계산 함수에는 입력 -> 처리 -> 결과 주석 추가
- 자동매매 로그에는 "왜 주문됐는지/왜 차단됐는지" 숫자 기준 노출
[리스크/회귀 포인트]
- 계좌별 수수료 정책이 다르면 세금/수수료 추정이 실제와 다를 수 있다.
- 매수가능금액/잔고/매매일지 API 응답 타이밍이 어긋나면 체결 직후 수량이 잠깐 다르게 보일 수 있다.
- 모의투자는 실전과 세금/수수료/매매일지 지원 방식이 다를 수 있다.
- 주문 전 추정 비용과 주문 후 실제 비용이 다를 수 있으므로, 최종 손익 기준은 실제 체결/매매일지 값으로 재정산해야 한다.
[검증 계획]
- [x] 1. `allocationPercent`, `allocationAmount`, `매수가능금액` 조합별로 매수 수량이 기대값대로 계산되는지 단위 테스트 추가
- [x] 2. 보유 없음 / 보유 1주 / 매도가능수량 부족 상황에서 SELL이 차단되는지 테스트
- [x] 3. 수수료/세금 추정 로직과 실제 activity API 정산값 연결 테스트
- [x] 4. `npm run lint`
- [x] 5. `npm run build`
- [x] 6. 자동매매 스모크 시나리오
- 예산 30만원, 비율 10%, 주가 16,000원일 때 매수 가능 수량 계산 확인
- 보유 5주, 매도가능 3주일 때 SELL 수량 제한 확인
- 체결 후 잔고/활동 재조회로 보유/손익이 갱신되는지 확인
- Playwright 인증 필요 구간에서는 사용자(본인)가 로그인/앱키/계좌 인증을 완료할 때까지 테스트를 대기하고, 완료 신호를 받은 뒤 다음 단계를 진행
[진행 로그]
- 2026-03-06: 현재 자동매매 코드를 점검한 결과, 매도가능수량 비교는 일부 구현되어 있으나 `allocationPercent` 실주문 반영, 세금/수수료 반영, 순손익 기준 손실 관리, 체결 후 정산 반영은 미흡한 상태로 판단함.
- 2026-03-06: 구현 방향을 `예산 계산 -> 주문 수량 계산 -> 보유/매도가능 수량 검증 -> 비용 추정 -> 체결 후 실제 정산` 순서로 재설계하기로 함.
- 2026-03-06: `lib/autotrade/risk.ts`에서 `allocationPercent`를 실주문 예산 계산에 강제 반영하도록 변경하고, BUY/SELL 수량 계산 경로를 분리함.
- 2026-03-06: `useAutotradeEngine.ts`에 비용 추정(수수료/세금), 체결 전후 활동/잔고 재조회, 누적 손실 한도 자동중지 로직을 반영함.
- 2026-03-06: AI 신호 스냅샷에 `budgetContext`, `portfolioContext`, `executionCostProfile`을 추가하고 OpenAI/CLI 프롬프트 규칙에 예산/보유/비용 제약을 반영함.
- 2026-03-06: 검증 결과 `npm run lint`, `npm run build` 통과. `npm run test:autotrade:smoke`는 로그인 필요(개발 우회 토큰 미적용 환경)로 실패함.
- 2026-03-06: Playwright 스모크로 `/`, `/trade`(로그인 리다이렉트 확인), `/settings`(로그인 리다이렉트 확인) 화면 로드 및 콘솔 error 없음 확인.
- 2026-03-06: Playwright 테스트 협업 규칙 추가 - 로그인/앱키/계좌 인증은 사용자가 직접 완료하고, 완료 전에는 테스트를 대기하도록 문서에 명시함.
- 2026-03-06: `lib/autotrade/executable-order-quantity.ts` 순수 clamp 유틸을 추가하고, `useAutotradeEngine.ts`의 실제 주문수량 검증에 연결함.
- 2026-03-06: 단위 테스트 추가(`tests/autotrade/risk-budget.test.ts`, `tests/autotrade/order-guard-cost.test.ts`) 후 `npm run test:autotrade:unit` 통과.
- 2026-03-06: `.env.local`의 실제 `AUTOTRADE_DEV_BYPASS_TOKEN`, `AUTOTRADE_WORKER_TOKEN`으로 스모크 재실행하여 `npm run test:autotrade:smoke` 통과.
- 2026-03-06: Playwriter 실브라우저 디버깅으로 `/trade` 화면에서 `내 설정 점검 -> 자동매매 시작 -> 수동 중지` 흐름 확인(세션 시작/중지 로그 정상, 브라우저 콘솔 error 없음). 장중 실시간 틱 부재로 신호요청/주문실행 로그는 미발생.
- 2026-03-06: AI 스냅샷의 `estimatedBuyableQuantity` 계산을 실제 주문 함수(`resolveOrderQuantity`)와 동일하게 통일해, 비율 예산으로 0주가 나와도 전체 예산 1주 가능 시 `1주`가 전달되도록 핫픽스함.
- 2026-03-06: Playwriter 네트워크 검증으로 `/api/autotrade/signals/generate` 요청 본문에 `estimatedBuyableQuantity=1`, `effectiveAllocationAmount=21631`, `effectiveOrderBudgetAmount=7570`, `currentPrice=16790`이 전달되는 것을 확인함(수량 0 전달 이슈 해소).
- 2026-03-06: 검증 자금 산정 로직을 `예수금 + 매수가능금액` 동시 조회 기반으로 변경하고, 두 값이 모두 있을 때는 더 보수적인 값(min)을 사용하도록 반영함.
- 2026-03-06: 자동매매 설정창의 투자비율 입력 UX를 퍼센트 프리셋 버튼 + 슬라이더 + 금액 자동입력 버튼으로 개선하고, 안전 점검 라벨을 `가용 예수금`에서 `주문 기준 자금`으로 변경함.
- 2026-03-06: `setNumberField`를 필드별 범위(clamp) 보정 방식으로 바꿔 퍼센트/신뢰도 입력이 비정상 값(음수, 100% 초과, 임계값 범위 이탈)으로 저장되지 않도록 정리함.
- 2026-03-06: 회귀 검증으로 `npm run test:autotrade:unit`, `npm run lint`, `npm run build` 재실행 모두 통과함.