refactor: enhance Optuna backtesting framework, optimize orderbook filtering, and update database management utilities.

This commit is contained in:
Your Name
2026-08-12 10:19:19 +09:00
parent cb7e5037a0
commit c6bd62a25f
218 changed files with 31613 additions and 759 deletions

264
.agents/AGENTS.md Normal file
View File

@@ -0,0 +1,264 @@
# kis_bot 프로젝트 에이전트 규칙 (필수 준수 사항)
## 📖 필수 참조 폴더 (`docs/like_mcp.md/`) 및 문서
이 프로젝트에서 작업할 때는 `docs/like_mcp.md/` 디렉토리 내의 핵심 문서들을 **항상** 인지하고 참조해야 합니다.
### 필수 문서 목록 (경로: `docs/like_mcp.md/`)
| 문서 | 정확한 파일 경로 | 용도 및 시점 |
|------|------|------|
| **코드 수정 가이드** | `docs/like_mcp.md/MODIFICATION_GUIDE.md` | **[수정 전 필수]** 수정 유형별 필수 `grep` 체크리스트 및 사이드 이펙트 검증 절차 |
| **코드 아키텍처 & 의존성 맵** | `docs/like_mcp.md/code_architecture.md` | **[구조 파악]** 파일 간 import 의존성, 핵심 허브 파일 Top 20, 전략별 모듈 분류 |
| **DB ERD & DDL** | `docs/like_mcp.md/db_erd.md` | **[DB 참고]** MariaDB 테이블 스키마, 컬럼 정의, PK/인덱스 및 관계 |
---
## ⚖️ MCP 도구 vs MD 문서 활용 원칙 (토큰 최적화 & 정확도)
프로젝트 분석 및 코드 작성 시, **MCP 도구(kis-code-assistant 등)**와 **MD 참조 문서**를 아래 역할 분담에 맞춰 사용합니다:
1. **거시적 구조 & 영향 범위 파악 → MD 문서 (`docs/like_mcp.md/`)**
- 새 대화 시 또는 작업 전 전체적인 지도(Layer, Hub 파일)가 필요할 때 목차 및 관련 섹션을 빠르게 참고합니다.
2. **미시적 코드 & API 조회 → MCP 도구 우선 사용**
- 특정 파일의 소스코드를 보거나 API 스펙을 탐색할 때는 파일 전체를 읽어 토큰을 낭비하지 말고, MCP 도구(`read_source_code`, `search_*_api` 등)나 `grep_search`를 우선 사용하여 실시간 최신 상태를 조회합니다.
3. **수정 전 `grep` 필수 실행**
- MD 문서는 "어디를 검색할지" 알려주는 지도입니다. 실제 수정을 단행하기 전에는 반드시 `MODIFICATION_GUIDE.md`에 명시된 필수 `grep` 명령을 실행하여 관련 파일 목록을 정확히 확정하세요.
---
## 🔄 코드 변경 시 MD 문서 필수 업데이트 룰 (Stale 방지)
코드를 수정하거나 새로운 기능을 추가한 후(특히 커밋 전/후)에는 **반드시 MD 문서와의 완결성을 유지**해야 합니다. 아래 상황 발생 시 문서를 무조건 업데이트하세요:
1. **파일 추가/삭제/이동 또는 import 변경 시**
- `code_architecture.md` 갱신 (스크립트 활용 또는 내용 반영)
2. **DB 테이블/컬럼 또는 환경변수(ENV) 추가/변경 시**
- `db_erd.md``MODIFICATION_GUIDE.md` 체크리스트 반영
3. **검증 의무 (실매매 엔진 사전 100% 무결성 검열 필수에 관한 절대 규칙)**
- 코드를 수정하면 실매매/백테스트/웹/파라미터서치 정합성 및 영향도를 100% 검증하고 완료 알림에 변경 내용을 명시합니다.
- **핵심 실매매 코드 수정 또는 DB 파라미터/환경변수(ENV)/스키마 변경 시**에는 반드시 최종 완료 전 `.venv/bin/python3 scripts/test_live_execution_validation.py`를 가동하여 1~5단계 전 구간 100% 통과(`👑 [최종 판정] 완결!`)를 확정 지어야 합니다.
---
## 🚨 하드코딩 절대 금지 (NO HARDCODING)
- 어떠한 경우에도 코드 내부에 임계값, 비율, 점수, 시간 등의 수치를 직접 하드코딩하지 마세요.
- 숫자값을 추가하거나 수정할 때는 **반드시** `get_env_float()`, `get_env_int()`, `get_env_bool()`을 사용하여 DB/Env에서 불러오도록 작성하세요.
-`if rsi > 78:` (절대 금지)
-`rsi_limit = get_env_float("RSI_LIMIT", 78.0); if rsi > rsi_limit:` (필수 적용)
- 변수명은 직관적인 대문자 스네이크 케이스(예: `MAX_DROP_RATE`)로 작성하고 기본값을 설정하세요.
- **신규 env 키 추가 시 4개 세트 등록 의무**: 아래 4곳을 한 세트로 반드시 등록하세요.
1. 코드 내 `get_env_*` 기본값 지정
2. `database.py` ENV 키 목록에 추가
3. 필요 시 `*_env_keys.py` 키 목록에 추가
4. `apply` 패치 맵에 추가
- 저장 후 `get_env_from_db`**재조회 검증** 필수
---
## 🏗️ 시스템 아키텍처 원칙
### SCAN vs TRIGGER 분리
- **SCAN 단계**: 조건 필터링을 최소화하여 후보를 DB에 최대한 많이 올립니다.
- **TRIGGER 단계**: 실제 매수 직전 모든 엄격한 필터(보조지표, 호가, 수급 등)를 한 번에 검사합니다.
- 무거운 연산(API 추가 호출, 분봉 분석 등)은 절대 5분 주기 스캔 함수에 넣지 말고, **매수 타점 체크 함수에 넣으세요.**
### WebSocket 우선, REST 최소화
- REST는 가능하면 **WebSocket/캐시/DB 재사용**으로 대체하세요.
- REST를 대체할 수 있는 경우에는 최대한 WebSocket을 사용합니다.
- 루프·재큐·벌크 등에서 REST 연타 금지. `SafeRequest`·기존 세마포어·sleep·쿨다운을 우회하는 새 경로를 만들지 마세요.
### 공통 코드 함수화
- 여러 전략에서 공통으로 사용할 수 있는 코드는 **반드시 공통 함수로 분리**하여 재사용하세요.
- 전략별로 동일한 로직을 중복 작성하지 마세요.
### 손절 및 안전 장치 필수
- 모든 매매 로직에는 손절(Stop-loss) 및 예외 처리 로직이 포함되어야 합니다.
- 코드 작성 후 스스로 아래 항목을 검토하세요:
1. 손절(Stop-loss) 및 예외 처리 로직이 포함되었는가?
2. API 호출 제한(429 Error) 및 슬리피지 고려가 되었는가?
3. `None`/`null`로 인한 런타임 오류가 발생하지 않는가?
4. 기존 로직과 100% 동일한 기능을 수행하는가?
---
## 🔄 실매↔백테↔파람 정합 규칙 (필수)
- **실매매 기준으로 백테스트, 파라미터서치 코드를 맞춥니다.** 백테/파람서치 코드는 실매매 코드와 100% 동일해야 합니다.
- **새로 추가한 코드의 기본값은 항상 DB에 추가**해야 하며, 웹 페이지 입력값과 일치해야 합니다.
- 코드 수정 시 **실매매·웹 백테스트·파라미터서치의 결과값이 동일**해야 하며, 검증을 반드시 거쳐야 합니다.
- 수정 사항이 **실매에 영향이 가는지 vs 백테/파라미터에만 영향이 가는지** 명확히 분류한 후 보고하고 수정합니다.
- Optuna 파라미터서치 실행 시:
- 주말/공휴일이면 **최근 거래일**로만 실행
- 그리드 변경 후 **반드시 새 `--study-name`** 사용 (동일 study 재사용 금지)
- `*_SKIP_HTS_SCAN_DUPES`**false 유지**, 임의로 true로 바꾸지 말 것
---
## 🚫 절대 금지 사항 (위반 시 작업 중지)
### 봉 정합·진입 정렬
- **신호 = T1 확정봉, 진입 = T(시가/첫 틱).** `live_backtest_align=True` 잠금.
- 유니버스·신호·진입을 **±1분(또는 ±1봉) 보정·오프셋·슬롯 해킹**으로 맞추는 코드 **절대 금지**.
- **`WS_CANDLE_FREEZE_ON_CONFIRM` 끄기(false) 절대 금지.** 사용자 명시 승인 없이 변경 금지.
### OHLC 폴백 금지
- 틱 청산/진입 ON이면 봉 OHLC(high/low)로 체결·`max_price`·PnL을 채우지 마세요.
- OHLC 폴백으로 숫자를 변조하는 것은 실매와 다른 엔진을 만드는 행위입니다.
### HTS 조건식과 코드 분리
- HTS는 후보 유니버스 참고용입니다. 그리드를 HTS 밴드에 맞추라고 강제하지 말 것.
- `*_SKIP_HTS_SCAN_DUPES` 는 사용자가 언급하기 전까지 **false 유지**. 임의로 true로 바꾸지 말 것.
### DB 쿼리 안전 규칙
- SQL 전 **반드시** `SHOW COLUMNS FROM <table>`로 실제 컬럼 확인. 추측 SELECT 금지.
- PyMySQL: SQL 문자열의 `%`는 포맷으로 해석됨. `LIKE '20260712%'` 금지 → `LIKE %s` + `('20260712%',)` 또는 `%%`.
- 실패 시 원인 고친 뒤 **1회만** 재실행. 같은 가정으로 날짜/strategy만 바꿔 반복 금지.
---
## 🔍 근본원인 먼저, 땜빵 금지
- 증상을 가리는 땜빵용 코딩은 지양합니다. **항상 근본원인을 먼저 찾고** 초등학생도 이해하기 쉽게 설명 후 설계하고 보고합니다.
- "일단 재시도·재발급·봉수 늘리기·±1 보정"으로 증상만 가리기 금지.
- API 관련 코드를 작성/수정할 때는 본인의 지식에 의존하지 말고 **반드시 연동된 MCP 도구를 우선 호출**하여 스펙을 확인하세요.
---
## 🤖 AI 에이전트 행동 및 도구 사용 원칙 (Behavior & Tool Execution Rules)
에이전트는 사용자(USER)와의 페어 프로그래밍 및 코드 관리에서 최고의 품질과 토큰 효율을 발휘하기 위해 아래 지침을 100% 준수합니다.
### 1. 🛠️ 도구 사용 기본 규칙 (Tool Calling)
- **파이썬 임시 구동 시 `python -c` 인라인 실행 절대 금지 (No Inline Python in Shell)**: 복잡한 다중 줄이나 따옴표/퍼센트(`%`) 기호가 포함된 파이썬 구문을 터미널에서 `python -c "..."`로 구동하면 셸 인식 및 줄바꿈 오류로 인해 명령이 멈추거나 터미널이 꼬이므로 **절대 금지**합니다. **반드시 `scratch/` 폴더나 임시 스크립트(`.py`) 파일로 작성(`PYTHONPATH=.` 또는 `sys.path` 설정 필수 포함)한 뒤 단건 파일 실행(`python script.py`)으로 구동**하세요.
- **내부 도구명 언급 금지**: 사용자에게 설명할 때 `replace_file_content 도구를 사용하여...` 또는 `grep_search를 호출하여...`와 같이 내부 도구 이름을 직접 텍스트로 언급하지 마세요. 대신 **"파일을 수정하겠습니다"**, **"코드를 검색하여 파악하겠습니다"** 처럼 자연스럽고 친절한 언어로 소통하세요.
- **불필요한 도구 호출 자제**: 일반적인 질의응답이나 이미 대화 및 문서로 알고 있는 내용, 단순 설명은 불필요하게 도구를 낭비하지 말고 즉시 답변하세요.
- **작업 목적 사전 설명**: 도구(검색, 읽기, 수정, 실행 등)를 사용하기 전에 왜 그 작업이 필요하며 목표 달성에 어떻게 기여하는지 한 문장으로 명쾌하게 먼저 설명하세요.
### 2. ✏️ 코드 수정 및 오류 해결 규칙 (Making Code Changes)
- **채팅창 코드 전문 출력 금지**: 사용자가 "채팅창에 출력해줘"라고 명시하지 않는 한, 긴 코드를 대화창에 텍스트로 장황하게 늘어놓지 마세요. **반드시 편집 도구(Edit Tools)를 사용하여 실제 파일에 직접 안전하게 반영**하세요.
- **동일 파일 수정의 묶음(Batch) 처리**: 같은 파일 내에서 여러 군데를 뜯어고쳐야 할 때, 수정을 여러 턴에 걸쳐 잘게 쪼개어 부르지 말고 **단일 도구 호출(한 번의 패치)에 묶어서 통합 적용**하세요.
- **수정 전 조회(Read-before-Edit) 의무화**: 신규 파일을 만들거나 파일 맨 끝에 간단한 줄을 추가하는 경우를 제외하고는, 코드를 수정하기 전에 **반드시 해당 파일 또는 대상 섹션의 원본 소스를 먼저 읽고 문맥을 완전히 파악한 뒤 수정**하세요. (근거 없는 눈대중 수정 절대 금지)
- **오류 수정 3회 루프 제한 (Anti-Loop)**: 코드 변경 후 린트(Lint)나 문법/런타임 에러가 터졌을 때 확실한 해결 방안이 섰을 때만 수정하세요. **근거 없이 '이렇게 해볼까' 식으로 무리한 시도를 되풀이하지 말 것.** 특히 동일한 파일에서 오류 고치기를 **3회 이상 반복(Loop)하지 마세요**. 3번째 패치 후에도 실패하면 즉시 중단하고 사용자에게 상황을 명명백백히 설명한 뒤 다음 행동 지시를 받으세요.
- **즉시 구동 보장 (Executable Quality)**: 생성하거나 수정한 코드는 사용자가 언제든 터미널을 열어 실행하거나 실매매/백테스트 엔진에 올려도 오류가 없도록 온전하고 실행 가능한 상태로 완성되어야 합니다.
- **기존 코드 구조 존중 (No Over-engineering)**: 잘 작동하는 코드를 '더 나은 구조'를 명목으로 임의로 클래스화하거나 불필요하게 복잡하게 바꾸지 마세요. **기존의 함수형·절차적 구조를 최대한 유지**하는 것이 기본 원칙입니다.
- **핵심 로직 변경 시 선보고·승인 대기**: 매매 로직, 청산 우선순위, 공통 인프라 등 **핵심 로직을 변경해야 할 때는 코드를 바로 수정하지 말고**, 먼저 왜 변경이 필요한지 이유를 설명하고 사용자의 승인을 받은 뒤 수정하세요. (단순 버그 수정이나 오타 교정은 즉시 수정 가능)
- **주석 및 로거 절대 유지**: 기존에 작성된 주석(Comments)과 로거(Logger) 코드는 수정과 무관하게 **절대 삭제하지 마세요.** 새 코드를 추가하거나 수정하더라도 기존 주석과 로그는 그대로 보존합니다.
- **테스트 실행 시 백그라운드 + 로그 경로 안내**: 테스트 코드를 돌릴 때는 백그라운드로 실행하고, `tail -f`로 볼 수 있는 로그 파일 경로를 반드시 함께 안내하세요.
- **🚨 [절대 규칙] 작업 흐름 단절 금지 & 끝까지 자동 보정 완수 (Never Break Flow & Autonomous Retry)**:
- 스크립트 구동, 테스트 검증, DB 반영 등의 작업을 수행할 때 실행 중 오류가 터지거나 탈락하더라도 **사용자에게 로그만 넘기며 대화 턴을 멈추고 흐름을 끊지 마세요.**
- 에이전트는 **단일 대화 턴 내부에서 스스로 실패 로그와 원인 규명 ➔ 코드 보정 ➔ 즉각 재시도**의 루프를 주도적으로 돌려 **100% 정상 완수될 때까지 끝까지 책임을 관철한 뒤, 최종 통과된 완공 상태만 보고**해야 합니다.
- 단기 파괴검사나 수 초 내로 끝나는 검증·진단 모듈 구동 시에는 동기식 실행 대기 시간을 충분히 부여하여 에이전트가 실행 결과를 즉각 회수하고, 스스로 100% 정합성 통과를 확정한 후 대화 턴을 마무리하세요.
- **🚨 [절대 규칙] 핵심 코드·DB 변경 시 실매매 엔진 최종 검증 의무화 (Mandatory Live Execution Validation)**:
- 전략, 주문, 호가 필터, 공통 인프라 등 **핵심 실매매 코드를 수정**하거나, **데이터베이스(ENV 파라미터, 스키마, 테이블 등)에 변화가 생겼을 때**는 반드시 최종 완료 직전에 아래 검증 스크립트를 실행하여 100% 무결성을 증명해야 합니다.
- 실행 커맨드: `.venv/bin/python3 scripts/test_live_execution_validation.py`
- 1~5단계 중 단 하나라도 탈락이나 에러가 발생할 경우 작업을 마쳐서는 안 되며, **끝까지 자동 보정 완수 규칙**에 따라 원인 수정 후 재검증을 돌려 100% 최종 완공 판정(`👑 [최종 판정] 완결!`)을 확인한 뒤 보고하세요.
### 3. 🔎 검색 및 코드 탐색 규칙 (Searching & Reading)
- **효율적인 타겟팅 최우선**: 무작정 루트 디렉토리를 통으로 긁는 것보다, `code_architecture.md`나 MCP 도구, 정밀 정규식 검색 등을 우선 활용하여 목표 범위를 날카롭게 압축하세요.
- **문맥 확보를 위한 충분한 범위 일괄 읽기**: 파일을 조사할 때는 15~20줄씩 쪼개어 여러 턴을 낭비하지 말고, 문맥과 의존성을 안심하고 파악할 수 있도록 **처음부터 필요한 충분한 크기(섹션/블록)를 큼직하게 잡고 한 번에 조회**하세요.
- **목적 달성 시 즉시 탐색 종료**: 수정이나 답변을 하기에 합리적이고 충분한 위치와 정보를 찾았다면, 불필요한 추가 조회 도구 호출을 중단하고 **즉시 코드 수정이나 답변 작성 단계로 진입**하세요.
---
## 🌐 백테스트 웹페이지 운영 및 UI 동기화 규칙 (Web UI & Service Rules)
### 1. 🖥️ 백테스트 웹 서비스 재시작 및 브라우저 검증
- **웹 UI/API 수정 후 필수 재시작**: 웹 서버 코드나 UI 스크립트(`backtest_web.py`, 템플릿 등)를 수정한 뒤에는 반드시 아래 명령어를 가동하여 서비스를 새로고침하고 `active` 상태를 확인하세요.
- 명령어: `sudo systemctl restart kis_backtest_web.service`
- 주의: 웹과 무관한 실매매 봇 전용 로직만 고쳤다면 불필요하게 실매매 서비스를 재시작하지 마세요.
- **전용 URL 브라우저 확인**: 브라우저나 HTTP 검증 시 반드시 **`http://192.168.0.149:5050/`** 주소만 사용하세요. (`127.0.0.1`이나 `localhost`는 브라우저 연결 에러 유발로 금지)
- **진정한 검증 완결**: 단순 `curl 200 OK` 응답만으로 완료라 단정하지 말고, 실제 브라우저/화면상에서 버튼·탭 전환 시 콘솔 `Uncaught`/`ReferenceError` 오류가 없는지 100% 확인한 뒤 보고하세요.
### 2. 🔄 탭 UI 통합 변경 및 국장/해외 동기화
- **전 전략 탭 UI 일치 원칙**: 백테스트 웹페이지 내 한 전략의 UI(인풋 폼, 가상거래내역, 실거래내역 테이블 등)를 수정했다면, 모멘텀·돌파·스캘핑·꼬리잡기 등 **다른 전략 탭도 100% 동일한 구조와 스펙으로 함께 변경**해야 합니다.
- **해외 전략 탭(US_*) UX 동기화**: 해외 전략 웹 탭, Optuna, Top5 보기, 수익률 카드 등은 **국장 탭과 동일한 UX**로 맞추는 것이 기본 원칙입니다. 임의로 생략하거나 단축해서는 안 되며, 통화(USD) 표기나 시간 분리 등 필연적 차이가 있을 때만 선보고 및 문구 기재 후 반영합니다.
- **UI 덮어쓰기 금지**: Optuna 파라미터 폼 채우기나 종목 적용 후 페이지 리로드로 폼 수치가 기존 DB 핀셋 설정에 도로 덮어씌워져 유실되지 않도록 검증(하드새로고침 ➔ 종목선택 ➔ Optuna 수치 유지)을 의무화하세요.
---
## 🚨 증권사 API 인프라 보호 및 DB 안전 조회 규칙 (Infrastructure & DB Safety)
### 1. 🛡️ 키움/KIS API 유량 및 approval 키 보호 (폭주 절대 금지)
- **API 에러 ≠ 데이터 없음**: 키움 `return_code=5`(유량 한도 초과)나 `429 Error`를 '빈 봉/데이터 없음'으로 착각하여 루프·재큐·벌크 요청으로 API를 무한히 연타하지 마세요. 유량 초과 시 백오프(Backoff), 세마포어, 실패 상한선 도달 시 재큐 정지가 필수입니다.
- **WS approval_key 단일 공유 캐시 준수**: KIS WebSocket 실시간 접속키(`approval_key`)는 공용 `KISApprovalManager(공유 캐시)`를 사용하여 전 연결이 1개의 키를 나누어 씁니다. 모듈이 돌아갈 때마다 매번 새 키를 REST로 발급받아 타 소켓을 끊기거나 무효화하는 행위를 절대 금지합니다. (응급 재발급은 기본 6시간 1회 하드캡 지킬 것)
- **백테스트 REST 웜업 최소화**: 전일 장 시작 시가 보강 REST는 짧은 1차(기본 700봉)만 기본 적용하고, 실패할 때만 해당 종목에 한해 1회만 증량(1,500봉) 재시도하세요.
### 2. 🗄️ DB 임시 조회(Ad-hoc) 및 SQL 쿼리 안전 수칙
- **추측 SELECT 금지 (SHOW COLUMNS 필수)**: TradeDB로 SQL을 날리기 전에는 반드시 `SHOW COLUMNS FROM <table>`로 실제 컬럼 스키마를 확인하세요.
- 대표적 오류 사례: `target_candidates` 테이블에는 **`strategy_id` 컬럼이 없음** (code/name/score/price/scan_time/updated_at 등만 존재).
- **🚨 [필수 준수 템플릿]**: 아래와 같이 반드시 `SHOW COLUMNS`로 정확한 테이블명과 컬럼명을 딕셔너리로 받아 확인한 후(문법 고정)에만 본 쿼리를 실행하여 에러를 원천 차단하세요. 따옴표 사용에도 유의하세요.
```python
# 임시 조회 스크립트 작성 시 고정 문법 (python -c 대신 반드시 파일로 작성)
from database import TradeDB
db = TradeDB()
try:
cols1 = [dict(r)["Field"] for r in db.conn.execute("SHOW COLUMNS FROM ws_price_validation").fetchall()]
print(f"ws_price_validation cols: {cols1}")
cols2 = [dict(r)["Field"] for r in db.conn.execute("SHOW COLUMNS FROM ls_ws_ticks").fetchall()]
print(f"ls_ws_ticks cols: {cols2}")
# 확인된 컬럼명(cols1, cols2)을 기반으로 이후 SELECT/조회 실행
finally:
db.close()
```
- **PyMySQL `%` 포맷 충돌 회피**: PyMySQL 실행 시 SQL 문자열 안의 `%` 기호는 문자열 포맷팅으로 해석됩니다. `LIKE '20260712%'` 식의 쿼리를 금지하고 반드시 파라미터 바인딩(`LIKE %s`, `('20260712%',)`) 또는 `%%`를 사용하세요.
- **에러 반복 금지**: `Unknown column`이나 `not enough arguments for format string` 에러가 났을 때 똑같은 가정을 두고 날짜나 전략명만 바꿔가며 실패 쿼리를 수차례 연타하지 마세요. 원인을 규명한 뒤 1회만 고쳐서 재실행하세요.
### 3. ⏳ 파라미터 서치(Optuna) 및 백테스트 토큰·시간 절약
- **휴장일 보정 실행**: 주말이나 공휴일에는 `end=오늘`로 돌려 빈 봉 에러나 0건으로 통째 재실행하는 낭비를 저지르지 마세요. 반드시 **최근 거래일을 기준으로 종료 시점(end)을 보정**하여 1회에 완공하세요.
- **그리드 변경 시 새 study-name 사용**: Optuna 탐색 범위(categorical, TPE 등)나 그리드가 바뀌면 동일한 `--study-name` 재사용 시 `dynamic value space error`가 나므로, 반드시 새로운 스터디명을 부여하여 돌려야 합니다.
- **긴 잡은 백그라운드 구동**: 오래 걸리는 Optuna 나 백테스트는 `nohup`으로 돌리고 로그 파일 경로를 안내하세요. `for+sleep` 식의 무의미한 루프 대기를 걸지 마세요.
---
## 🚨 [절대규칙] Optuna 백테스트 웹 UI 잡 트래킹 실행 방법
### 문제: nohup bash 직접 실행 시 웹 UI에 잡이 보이지 않음
`nohup bash scripts/run_optuna_*.sh` 또는 `python3 kis_trader/backtest/param_search_optuna.py`를 **쉘에서 직접 실행하면** 웹 UI의 프로그레스바 및 최근 잡 목록에 **절대 표시되지 않습니다.**
웹 UI 잡 시스템은 `optuna_web_jobs.py`의 파일 기반 잡 트래킹(`logs/optuna_web_jobs/*.json`)을 통해서만 작동합니다.
### ✅ 올바른 실행 방법: 웹 API(curl)로 실행
쉘에서 실행하면서 웹 UI에도 표시하려면 반드시 **웹 서버의 `/api/optuna/start` 엔드포인트를 통해 실행**해야 합니다.
```bash
# 단일 전략 실행 (웹 UI에 표시됨)
curl -s -X POST http://192.168.0.149:5050/api/optuna/start \
-H "Content-Type: application/json" \
-d '{"strategy":"momentum","start":"2026-08-07","end":"2026-08-07","trials":200,"mode":"fast"}' | python3 -m json.tool
# 4전략 순차 실행 (strategies 배열로 전달)
curl -s -X POST http://192.168.0.149:5050/api/optuna/start \
-H "Content-Type: application/json" \
-d '{"strategies":["momentum","breakout","scalp","tail"],"start":"2026-08-07","end":"2026-08-07","trials":200,"mode":"fast"}' | python3 -m json.tool
# 진행 상황 확인 (job_id는 응답에서 확인)
curl -s http://192.168.0.149:5050/api/optuna/status/<job_id> | python3 -m json.tool
# 잡 목록 확인
curl -s http://192.168.0.149:5050/api/optuna/jobs | python3 -m json.tool
```
### 후처리(호가/휩쏘) 단독 실행은 직접 실행 허용
메인 TPE와 달리 후처리 모듈(`apply_optuna_ob_consensus.py`, `apply_optuna_whipsaw_consensus.py`)은 수 초~수 분 내에 끝나므로 **직접 실행 허용**합니다. 단, 결과 JSON은 별도로 웹 UI 결과 탭에 표시됩니다.
```bash
# 후처리는 직접 실행 허용
python3 scripts/apply_optuna_ob_consensus.py --strategy MOMENTUM --n-trials 1000
python3 scripts/apply_optuna_whipsaw_consensus.py --strategy MOMENTUM --n-trials 500
```
### 스크립트 작성 시 curl API 사용 원칙
에이전트가 Optuna 메인 TPE 실행 스크립트(`.sh`)를 작성할 때는 반드시:
- ❌ `nohup python3 kis_trader/backtest/param_search_optuna.py ...` (직접 실행 금지)
- ✅ `curl -X POST http://192.168.0.149:5050/api/optuna/start -d '...'` (API 통해 실행)
단, 메인 TPE가 이미 실행 중일 때 curl API는 "이미 실행 중" 에러를 반환하므로, 순차 실행 스크립트에서는 완료 폴링(`/api/optuna/status/<job_id>`) 후 다음 전략 시작 로직이 필요합니다.