트레이딩창 UI 배치 및 UX 수정 및 기획서 추가
This commit is contained in:
266
common-docs/features-autotrade-design.md
Normal file
266
common-docs/features-autotrade-design.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# 브라우저 상주 자동매매 통합 계획서 v3.1 (AI/무저장 정책 반영)
|
||||
|
||||
## 요약
|
||||
1. 자동매매는 브라우저가 켜져 있을 때만 동작합니다.
|
||||
2. 백그라운드 탭(가려진 탭)에서는 동작을 허용합니다.
|
||||
3. 탭 종료, 브라우저 종료, 앱 종료, 외부 페이지 이탈 시 자동주문은 즉시 중지됩니다.
|
||||
4. 종료 직전 강한 경고를 보여주고 중지 이벤트를 서버에 기록합니다.
|
||||
5. 투자금/손실한도는 퍼센트와 금액을 동시에 받고 더 보수적인 값(더 작은 값)을 실적용합니다.
|
||||
6. 전략 선택은 프롬프트 입력, 검수 카탈로그, 온라인 실시간 수집을 모두 지원하며 복수선택 가능합니다.
|
||||
7. 실거래 우선, 장중 기본, 보수적 위험관리 기본값을 유지합니다.
|
||||
8. AI(인공지능)로 매수/매도 신호 후보를 만들고, 최종 주문은 규칙 엔진(고정 검증 로직)이 결정합니다.
|
||||
9. 한국투자증권 API 키/시크릿/계좌번호는 서버 DB에 저장하지 않습니다.
|
||||
10. KIS 민감정보는 브라우저 실행 세션 기준으로만 유지하고, 서버는 요청 처리 시에만 일시 사용합니다.
|
||||
|
||||
## 1) 기술 아키텍처
|
||||
1. 프론트엔드: Next.js 16 App Router + React 19 + TypeScript.
|
||||
2. 상태관리: Zustand 기반 `autotrade-engine-store` 신규.
|
||||
3. 실시간: 기존 KIS WebSocket 스토어 재사용, 자동매매 엔진 훅으로 연결.
|
||||
4. 서버 API: Next.js Route Handler(Node 런타임)로 전략/세션/로그/중지 API 제공.
|
||||
5. 데이터 저장: Supabase Postgres + RLS(행 단위 권한).
|
||||
6. 인증: Supabase Auth 세션 필수.
|
||||
7. 보안: KIS 민감정보는 서버 저장 금지, 요청 단위(한 번 호출)로만 처리.
|
||||
|
||||
## 2) 배포 구조
|
||||
1. 앱 배포: Vercel(기존 유지).
|
||||
2. DB/인증: Supabase(기존 유지).
|
||||
3. 자동매매 엔진: 브라우저 내부 실행(별도 워커 서버 없음).
|
||||
4. 서버 역할: 주문 위임, 상태 기록, 위험한도 검증, 감사로그 저장(민감정보 저장 제외).
|
||||
5. 만료 정리: Vercel Cron(1분 주기) 또는 DB 함수로 heartbeat 만료 세션 `stopped` 전환.
|
||||
6. 장애 로그: Vercel Logs + Supabase Logs + Sentry(권장) 연동.
|
||||
|
||||
## 3) 필수 환경변수
|
||||
1. `NEXT_PUBLIC_SUPABASE_URL`
|
||||
2. `NEXT_PUBLIC_SUPABASE_ANON_KEY`
|
||||
3. `SUPABASE_SERVICE_ROLE_KEY`
|
||||
4. `AUTOTRADE_HEARTBEAT_TTL_SEC` (기본 90)
|
||||
5. `AUTOTRADE_MAX_DAILY_ORDERS_DEFAULT` (기본 20)
|
||||
6. `AUTOTRADE_ONLINE_STRATEGY_ENABLED` (기본 true)
|
||||
7. `ONLINE_STRATEGY_PROVIDER_KEY` (온라인 수집용 키)
|
||||
8. `KIS_SERVER_STORAGE_DISABLED` (고정값 `true`, 서버 저장 차단 가드)
|
||||
|
||||
## 3-1) KIS 키/계좌 무저장 정책(추가)
|
||||
1. 저장 금지 대상: `appKey`, `appSecret`, `accountNo`, `accountProductCode`.
|
||||
2. 서버 DB(Supabase 포함)에는 위 값을 절대 저장하지 않습니다.
|
||||
3. 서버 로그에도 원문을 남기지 않고 마스킹(일부 가리기) 처리합니다.
|
||||
4. 자동매매 요청 시 민감정보는 헤더로 전달하고, 요청 처리 후 즉시 폐기합니다.
|
||||
5. 브라우저 보관은 `sessionStorage` 우선, `localStorage` 영구 저장은 자동매매 모드에서 금지합니다.
|
||||
6. UI 흐름: 설정 UI 입력 -> 메모리/세션 저장 -> API 호출 헤더 전달 -> 서버 즉시 사용 후 폐기.
|
||||
|
||||
## 4) 데이터 모델(Supabase)
|
||||
1. `auto_trade_strategies`
|
||||
2. 주요 컬럼: `user_id`, `name`, `strategy_source_type(prompt|catalog|online)`, `symbols[]`, `allocation_percent`, `allocation_amount`, `effective_allocation_amount`, `daily_loss_percent`, `daily_loss_amount`, `effective_daily_loss_limit`, `resolved_params(jsonb)`, `status`.
|
||||
3. `auto_trade_sessions`
|
||||
4. 주요 컬럼: `strategy_id`, `desired_state`, `runtime_state`, `leader_tab_id`, `last_heartbeat_at`, `started_at`, `ended_at`, `stop_reason`.
|
||||
5. `auto_trade_order_attempts`
|
||||
6. 주요 컬럼: `session_id`, `symbol`, `idempotency_key(unique)`, `request_payload`, `response_payload`, `status`, `blocked_reason`.
|
||||
7. `auto_trade_signal_logs`
|
||||
8. 주요 컬럼: `session_id`, `signal_payload`, `decision(execute|skip|block)`, `decision_reason`, `source_type`, `risk_grade`.
|
||||
9. `auto_trade_online_strategies`
|
||||
10. 주요 컬럼: `title`, `source_url`, `strategy_text`, `fetched_at`, `parser_score`, `risk_grade`, `is_approved`.
|
||||
11. `auto_trade_audit_logs`
|
||||
12. 주요 컬럼: `user_id`, `action`, `payload`, `created_at`.
|
||||
13. `kis_credentials*` 계열 테이블은 만들지 않습니다(무저장 정책).
|
||||
|
||||
## 5) API 설계
|
||||
1. `POST /api/autotrade/strategies/compile`
|
||||
2. 입력: 프롬프트/온라인 텍스트.
|
||||
3. 출력: 표준 규칙(JSON) + 검증결과.
|
||||
4. `POST /api/autotrade/strategies/validate`
|
||||
5. 출력: 실행 가능 여부, 차단 사유.
|
||||
6. `GET /api/autotrade/templates`
|
||||
7. 검수 카탈로그 전략 목록 제공.
|
||||
8. `POST /api/autotrade/strategies/discover`
|
||||
9. 온라인 실시간 수집 전략 목록 제공.
|
||||
10. `POST /api/autotrade/strategies`
|
||||
11. 전략 저장(배분/손실한도 실적용값 계산 포함).
|
||||
12. `POST /api/autotrade/sessions/start`
|
||||
13. 세션 시작 + 리스크 스냅샷 생성.
|
||||
14. `POST /api/autotrade/sessions/heartbeat`
|
||||
15. 리더 탭 생존신호 갱신.
|
||||
16. `POST /api/autotrade/sessions/stop`
|
||||
17. `reason`: `browser_exit|external_leave|manual|emergency|heartbeat_timeout`.
|
||||
18. `GET /api/autotrade/sessions/active`
|
||||
19. 현재 실행 세션/리더 정보 조회.
|
||||
20. `GET /api/autotrade/sessions/{id}/logs`
|
||||
21. 신호/주문/오류 로그 조회.
|
||||
22. 자동매매 관련 API(주문/세션/리스크)는 요청 헤더에 KIS 정보 포함이 필수입니다.
|
||||
23. 서버는 헤더 값 유효성만 검사하고 DB에는 저장하지 않습니다.
|
||||
24. 실패 응답/에러 로그에서도 민감정보는 마스킹합니다.
|
||||
|
||||
## 5-1) AI 자동매매 설계(추가)
|
||||
1. 핵심 원칙: AI는 "신호 후보 생성기", 최종 주문 판단은 "규칙 엔진"이 담당.
|
||||
2. 이유: AI 단독 주문은 일관성(항상 같은 판단)과 추적성이 약해 리스크가 큽니다.
|
||||
3. AI 입력 데이터:
|
||||
4. 실시간 체결/호가, 최근 변동성, 거래량, 전략 파라미터, 장 상태(정규장/시간외).
|
||||
5. AI 출력 데이터:
|
||||
6. `signal`(buy/sell/hold), `confidence`(신뢰도), `reason`(한 줄 근거), `ttlSec`(신호 유효시간).
|
||||
7. 실행 흐름:
|
||||
8. 사용자 전략 선택/프롬프트 입력 -> AI 해석 -> 규칙 JSON 변환 -> 리스크 검증 -> 주문 실행/차단.
|
||||
9. 온라인 유명 단타 기법 처리:
|
||||
10. 실시간 수집 -> 정규화(형식 맞추기) -> 위험등급 부여 -> 사용자 선택 -> 검증 통과 시 활성화.
|
||||
11. AI 장애 대응:
|
||||
12. AI 응답 지연/실패 시 신규 주문 중지 또는 보수 모드(`hold`) 강제.
|
||||
13. AI 드리프트(성능 저하) 대응:
|
||||
14. 최근 N건 성능 추적 후 기준 미달 전략 자동 일시정지.
|
||||
15. UI 흐름:
|
||||
16. 전략 화면 -> "AI 제안 받기" 클릭 -> 제안 전략 목록 표시 -> 사용자 선택/수정 -> 저장/시뮬레이션 -> 시작.
|
||||
17. 운영 기본값:
|
||||
18. `confidence`가 임계치(예: 0.65) 미만이면 주문 차단.
|
||||
19. `reason`이 비어 있으면 주문 차단(설명 없는 주문 금지).
|
||||
20. 동일 종목 반대 신호가 짧은 시간에 반복되면 쿨다운 연장.
|
||||
|
||||
## 5-2) 자동매매 설정 팝업 UX(사용자 요청 반영)
|
||||
1. 진입 흐름:
|
||||
2. 자동매매 버튼 클릭 -> 자동매매 설정 팝업 오픈 -> 설정 입력 -> "자동매매 시작" 클릭.
|
||||
3. 팝업 필수 입력:
|
||||
4. 전략 프롬프트(자유 입력)
|
||||
5. 유명 기법 선택(복수 선택): ORB(시가 범위 돌파), VWAP 되돌림, 거래량 돌파, 이동평균 교차, 갭 돌파.
|
||||
6. 투자금 설정: 퍼센트(%) + 금액(원) 동시 입력.
|
||||
7. 전략별 일일 손실한도: 퍼센트(%) + 금액(원) 동시 입력.
|
||||
8. 거래 대상: 종목 다중 선택(또는 관심종목 가져오기).
|
||||
9. 실행 전 검증:
|
||||
10. AI 해석 결과 미리보기(어떤 근거로 매수/매도할지 요약)
|
||||
11. 리스크 요약(실적용 투자금, 실적용 손실한도, 예상 최대 주문 수)
|
||||
12. 동의 체크(브라우저 종료/외부 이탈 시 즉시 중지)
|
||||
13. 버튼 정책:
|
||||
14. 필수값 누락 또는 검증 실패 시 시작 버튼 비활성화.
|
||||
15. 시작 성공 시 상단 고정 배너와 세션 상태 카드 즉시 표시.
|
||||
|
||||
## 5-3) AI API 선택 권장안(실행 가능한 추천)
|
||||
1. 결론:
|
||||
2. 1차는 OpenAI API를 기본으로 시작하고, 2차에서 Gemini/Claude를 붙일 수 있게 다중 제공자 어댑터(연결 레이어) 구조로 개발합니다.
|
||||
3. 추천 이유(요약):
|
||||
4. Structured Outputs(스키마 고정 출력) + Function Calling(함수 호출) 문서/생태계가 성숙해서 자동매매 검증 파이프라인 구성에 유리합니다.
|
||||
5. 비용/속도 최적화 모델 선택지가 넓어 PoC(개념검증) -> 운영 전환이 쉽습니다.
|
||||
6. 제공자별 특징:
|
||||
7. OpenAI: 엄격 모드(`strict`) 기반 함수 스키마 강제가 명확하고, `parallel_tool_calls=false`로 1회 1액션 제어가 쉽습니다.
|
||||
8. Gemini: 함수 호출 모드(`AUTO`/`ANY`/`NONE`/`VALIDATED`)가 명확하고 JSON 스키마 출력 지원이 좋아 대체 제공자로 적합합니다.
|
||||
9. Claude: `strict: true` 도구 호출과 구조화 출력이 강점이며, 보조/백업 제공자로 적합합니다.
|
||||
10. 운영 권장:
|
||||
11. 1차: OpenAI 단일 운영
|
||||
12. 2차: OpenAI 실패/지연 시 Gemini 폴백(대체 경로)
|
||||
13. 3차: Claude까지 확장하는 3중화(고가용성)
|
||||
|
||||
## 5-4) AI 판단 -> 주문 실행 파이프라인(실전형)
|
||||
1. Step 1. 입력 수집:
|
||||
2. 사용자 프롬프트 + 선택한 유명 기법 + 실시간 시세/호가 + 보유/가용자산 + 리스크 한도.
|
||||
3. Step 2. AI 해석:
|
||||
4. AI가 `signal`, `confidence`, `reason`, `ttlSec`, `proposed_order`를 JSON으로 반환.
|
||||
5. Step 3. 규칙 엔진 검증:
|
||||
6. 스키마 검증(형식), 정책 검증(리스크), 시장상태 검증(장중 여부), 중복주문 검증(idempotency).
|
||||
7. Step 4. 주문 결정:
|
||||
8. 검증 통과 -> KIS 주문 API 호출.
|
||||
9. 검증 실패 -> 주문 차단 + 사유 로그 기록.
|
||||
10. Step 5. 사후 평가:
|
||||
11. 체결/미체결 결과를 AI 평가 입력으로 재사용해 프롬프트/기법 가중치 조정.
|
||||
|
||||
## 5-5) AI 호출 프롬프트/출력 표준(권장 JSON)
|
||||
1. 시스템 프롬프트 핵심:
|
||||
2. "너는 주문 실행기가 아니라 신호 생성기다. 스키마에 맞는 JSON만 반환하고 설명문은 금지한다."
|
||||
3. 출력 스키마:
|
||||
4. `signal`: `buy|sell|hold`
|
||||
5. `confidence`: `0~1`
|
||||
6. `reason`: 짧은 한국어 근거
|
||||
7. `proposed_order`: `{symbol, side, orderType, price, quantity}`
|
||||
8. `risk_flags`: `string[]`
|
||||
9. `ttlSec`: 신호 만료 시간
|
||||
10. 차단 규칙:
|
||||
11. `confidence < threshold` 또는 `reason` 누락 또는 `risk_flags`에 차단 사유 포함 시 주문 금지.
|
||||
|
||||
## 5-6) 서버 무저장 정책과 AI 호출 결합 방식
|
||||
1. KIS 민감정보(`appKey`, `appSecret`, `accountNo`)는 AI API 호출 입력에 넣지 않습니다.
|
||||
2. AI에는 가격/지표/포지션 요약 같은 비식별 데이터(개인 식별이 어려운 데이터)만 전달합니다.
|
||||
3. 실제 주문 직전 단계에서만 브라우저 세션의 KIS 정보로 주문 API를 호출합니다.
|
||||
4. 서버는 주문 처리 중 헤더를 일시 사용 후 폐기하며 DB/로그 저장을 금지합니다.
|
||||
5. 에러 로그/감사로그에는 주문 사유와 결과만 남기고 민감값은 마스킹 처리합니다.
|
||||
|
||||
## 6) 브라우저 엔진 동작
|
||||
1. 엔진 상태: `IDLE`, `ARMED`, `RUNNING`, `STOPPING`, `STOPPED`, `ERROR`.
|
||||
2. 멀티탭 제어: `localStorage` lock + `BroadcastChannel` 동기화.
|
||||
3. 리더 탭만 주문 실행, 팔로워 탭은 조회 전용.
|
||||
4. 주문은 틱 이벤트(WebSocket 수신) 기반으로 처리해 백그라운드 타이머 지연 영향을 줄입니다.
|
||||
5. heartbeat 10초 주기 전송, TTL 90초 초과 시 서버 강제 종료.
|
||||
6. 새로고침 시 로컬 snapshot으로 이어서 실행.
|
||||
7. 브라우저 완전 종료 후 재진입 시 자동 재개 금지, `중지 상태`로 복구 후 사용자 재시작 필요.
|
||||
8. 백그라운드 탭에서도 WebSocket 이벤트 기반으로 신호 계산/주문은 유지합니다.
|
||||
|
||||
## 7) 강한 경고/즉시 중지 UX
|
||||
1. 실행 중 상단 빨간 경고 바 고정: "브라우저/탭 종료 또는 외부 이동 시 자동주문이 즉시 중지됩니다."
|
||||
2. 외부 링크 클릭 시 사전 모달 강제: "이동하면 자동매매가 중지됩니다. 계속할까요?"
|
||||
3. 탭 닫기/브라우저 종료는 `beforeunload` 기본 경고 사용.
|
||||
4. 종료 시퀀스: `STOPPING` 전환 -> 신규 주문 차단 -> `sendBeacon(stop)` -> lock 해제 -> `STOPPED`.
|
||||
5. 브라우저 보안 제한으로 `beforeunload` 커스텀 문구는 사용하지 않습니다(표준 경고만 가능).
|
||||
|
||||
## 8) 자산 배분/손실한도 입력 규칙
|
||||
1. 투자금 입력: `퍼센트(%)` + `금액(원)` 동시 입력.
|
||||
2. 실적용 투자금: `min(가용자산*퍼센트, 금액)`.
|
||||
3. 일일 손실한도 입력: `퍼센트(%)` + `금액(원)` 동시 입력.
|
||||
4. 실적용 손실한도: `min(전략투자금*퍼센트, 금액)`.
|
||||
5. UI에 실적용 값 실시간 계산 표시.
|
||||
6. 유효성 검증: 0보다 큰 값, 최대 퍼센트 상한, 가용자산 초과 금액 차단.
|
||||
7. UI에 "현재 가용자산 기준 실제 주문 가능 금액"을 즉시 표시합니다.
|
||||
|
||||
## 9) 전략 선택 체계(복수선택)
|
||||
1. 소스 탭 3개: `프롬프트`, `검수 카탈로그`, `온라인 실시간 수집`.
|
||||
2. 사용자는 소스별 전략을 여러 개 선택해 하나의 실행세트로 저장 가능.
|
||||
3. 프롬프트 전략: 자연어 입력 -> 컴파일 -> 검증 통과 시 활성화.
|
||||
4. 카탈로그 전략: 운영 검수 완료 버전만 제공.
|
||||
5. 온라인 전략: 실시간 수집 결과를 보여주되 검증 통과 전에는 실행 금지.
|
||||
6. 온라인/프롬프트 전략은 위험등급(`low|mid|high`) 자동 부여 후 실행 제한에 반영.
|
||||
|
||||
## 10) 보수적 위험관리 기본값
|
||||
1. 전략별 일일 손실한도 기본 2%.
|
||||
2. 전략별 일일 최대 주문 20건.
|
||||
3. 종목별 주문 쿨다운 60초.
|
||||
4. 단일 주문 상한: 전략 투자금의 25%.
|
||||
5. 데이터 지연 5초 초과 시 신규 주문 차단.
|
||||
6. 연속 실패 3회 시 자동 중지.
|
||||
7. lock 충돌 2회 이상 시 자동 중지.
|
||||
8. 비상정지 버튼은 언제나 최상단 고정 노출.
|
||||
|
||||
## 11) 구현 파일 범위
|
||||
1. `features/autotrade/components/*` (전략 선택, 배분 입력, 경고 배너, 실행 상태 패널)
|
||||
2. `features/autotrade/hooks/useAutotradeEngine.ts`
|
||||
3. `features/autotrade/stores/use-autotrade-engine-store.ts`
|
||||
4. `features/autotrade/types/autotrade.types.ts`
|
||||
5. `app/api/autotrade/**/route.ts`
|
||||
6. `lib/autotrade/*` (컴파일, 검증, 리스크 게이트, lock 유틸)
|
||||
7. 기존 `TradeContainer`/`OrderForm`에 자동매매 섹션 통합
|
||||
8. `features/settings/store/use-kis-runtime-store.ts` 자동매매 모드에서 민감정보 `persist` 제외
|
||||
9. `app/api/kis/*` 및 `app/api/autotrade/*` 민감정보 마스킹 유틸 공통 적용
|
||||
|
||||
## 12) 테스트 시나리오
|
||||
1. 멀티탭 3개에서 리더 1개만 주문하는지 확인.
|
||||
2. 백그라운드 탭에서 실시간 신호 기반 주문이 유지되는지 확인.
|
||||
3. 외부 링크 이탈 시 강한 경고 후 즉시 중지되는지 확인.
|
||||
4. 탭 종료/브라우저 종료에서 `sendBeacon` + TTL 강제종료가 동작하는지 확인.
|
||||
5. 퍼센트+금액 입력 시 실적용 값이 작은 값으로 계산되는지 확인.
|
||||
6. 전략별 일일 손실한도 초과 시 즉시 차단되는지 확인.
|
||||
7. 온라인 전략 검증 실패 시 실행이 막히는지 확인.
|
||||
8. 새로고침 후 동일 세션이 중복주문 없이 이어지는지 확인.
|
||||
9. 서버 DB/로그에 KIS 키/계좌 원문이 저장되지 않는지 확인.
|
||||
10. AI 응답 누락/지연 시 주문이 차단되는지 확인.
|
||||
11. AI `confidence` 임계치 미만에서 주문 차단되는지 확인.
|
||||
|
||||
## 13) 단계별 배포 계획
|
||||
1. 1주차: DB 마이그레이션 + API 골격 + 타입 정의.
|
||||
2. 2주차: 브라우저 엔진(lock/heartbeat/stop flow) + 기본 UI.
|
||||
3. 3주차: 전략 소스 3종(프롬프트/카탈로그/온라인) + 컴파일/검증.
|
||||
4. 4주차: 리스크 정책 완성 + 통합/E2E + 운영 모니터링.
|
||||
5. 롤아웃: 기능 플래그로 5% 사용자 -> 30% -> 전체 오픈.
|
||||
|
||||
## 14) 수용 기준
|
||||
1. 실행 중 종료 트리거 발생 시 신규 주문이 즉시 0건이어야 합니다.
|
||||
2. 멀티탭에서 중복 주문이 발생하지 않아야 합니다.
|
||||
3. 사용자는 전략별 투자금/손실한도를 퍼센트+금액으로 모두 설정할 수 있어야 합니다.
|
||||
4. 프롬프트/카탈로그/온라인 전략 복수선택 저장과 실행이 가능해야 합니다.
|
||||
5. 로그 화면에서 신호-판단-주문-중지 이유가 연결되어 추적 가능해야 합니다.
|
||||
|
||||
## 15) 명시적 가정/기본값
|
||||
1. "다른 페이지 이동"은 외부 도메인 이탈 기준입니다.
|
||||
2. 앱 내부 라우트 이동은 중지 트리거가 아닙니다.
|
||||
3. 브라우저가 완전히 종료되면 자동매매는 반드시 중지 상태로 종료됩니다.
|
||||
4. 브라우저 재진입 시 자동 재개는 하지 않고 사용자 재시작으로만 실행합니다.
|
||||
5. 온라인 전략은 "실시간 수집 가능"이지만 "검증 통과 후 실행"을 강제합니다.
|
||||
6. KIS API 키/계좌 정보는 서버 저장을 금지하고 요청 단위 처리만 허용합니다.
|
||||
Reference in New Issue
Block a user