diff --git a/AGENTS.md b/AGENTS.md index c219b93..7da0872 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ -# StockBot v3.0 — Codex 운영 가이드 +# StockBot v3.0 - Codex 운영 가이드 -> 최종 수정: 2026-05-19 +> 최종 수정: 2026-06-04 > 인프라: 로컬 Windows → Synology NAS Docker 이전 예정 > 현재 모드: 모의투자 (KIS_MOCK=true, DRY_RUN=true) @@ -11,13 +11,28 @@ - Parameter changes must be written to `reports/proposals/YYYY-MM-DD_strategy_proposal.md` with evidence and manual approval required. - `FORCE_EXIT = "14:50"` remains immutable. -## Current implementation status - 2026-05-28 +## Current implementation status - 2026-06-04 - Mode: paper trading / dry-run focused. Real-cash trading is not approved yet. - Approved strategy change applied: `ENTRY_START = "09:20"`. +- Applied runtime parameter: `MAX_HOLD_MIN = 90`. - `FORCE_EXIT = "14:50"` remains unchanged. - `avoid_sectors` runtime bug fixed: `main.py` now passes sector context into `check_entry()`. - Sector handling now keeps a `ticker_sectors` cache when available and uses name-based hints for known avoid-sector cases. +- Re-entry controls are active: + - `TIME`/`FORCE` cooldown is based on final exit time, not original entry time. + - `TP1`/`TP2` final exits block same-day re-entry for that ticker. + - Re-entry control state is restored from today's DB rows after bot restart. +- Duplicate execution guards are active: + - `app/main.py` uses `SingleInstanceLock` on `logs/stockbot.lock`. + - `scripts/start_bot.py` stops the PID-file process and scans for existing `app/main.py` processes before starting one new bot. + - `scripts/run_morning.ps1` is the only owner of post-morning bot startup. + - `.claude/commands/morning.md` must not call `/start-bot` or `scripts/start_bot.py`; it only creates and sends morning context. +- KIS stability hardening is active: + - Mode-specific request spacing in `KISClient` (`mock` more conservative than `real`). + - Price lookups retry transient KIS timeout/rate-limit errors. + - DRY_RUN buy/sell paths can reuse the already-read quote as the simulated fill price to reduce extra API calls. +- Daily summary duplicate guard is active; summary Discord failures are logged without crashing settlement. - Data layer: `entry_snapshots` and `post_entry_snapshots` are active for training data. - Post-entry sampling: 60s, 180s, 300s, and 600s after successful entry. - Training data export: `scripts/export_training_dataset.py`. @@ -30,23 +45,28 @@ - Model output: `models/scalping_model.joblib`. - Metrics output: `models/scalping_model.metrics.json`. - Runtime loader: `app/ml/predictor.py`. -- Latest training run: 2026-05-28 20:24, 3,156 rows total (`external_training_dataset.csv` 3,146 + bot dataset 10). -- Latest metrics: `label_stop_loss` ROC-AUC 0.851, `label_win` ROC-AUC 0.719. +- Latest successful training run: 2026-06-02 18:36, 5,773 rows total (`external_training_dataset.csv` 5,720 + bot dataset 53). +- Latest metrics: `label_stop_loss` ROC-AUC 0.896, `label_win` ROC-AUC 0.715. - Training features exclude future/outcome leakage columns such as `ret_*`, `mfe_*`, `mae_*`, `price_*`, `pnl`, and `exit_price`. - AI runtime mode: observation only. If a model exists, entry-time scores are logged and saved to `entry_snapshots`; they do not block or resize trades. -- Training schedule: `StockBot_Training` runs at 16:00 on trading days via `scripts/run_training_pipeline.ps1`; the pipeline was end-to-end verified on 2026-05-28. +- Training schedule: `StockBot_Training` runs at 16:00 on trading days via `scripts/run_training_pipeline.ps1`; latest successful full run was 2026-06-02 18:36. +- Latest daily review/proposal files exist through 2026-06-02. 2026-06-03 was skipped as a market holiday. - Dependency install: - `requirements.txt` includes `app/requirements.txt`. - `scripts/install_dependencies.ps1` installs from `vendor/wheels` when available. - `scripts/download_dependencies.ps1` builds the local wheelhouse. -## Current operational risks - 2026-05-28 +## Current operational risks - 2026-06-04 -- Model is still observation-only and is dominated by external pretraining rows; bot-trade labels are only 10 rows. +- Model is still observation-only and is dominated by external pretraining rows; bot-trade labels are 53 rows. - KIS minute-bar collection is verified for same-day windows, but historical depth and ticker coverage remain limited. - External minute data is pretraining data, not actual bot-trade data. - pykrx daily feature collection can fail for same-day data; KIS fallback is active. +- KIS rate limits can still happen if multiple scripts/processes call KIS concurrently; runtime retries reduce but do not eliminate this. +- 2026-06-03 holiday training run logged a failure at the holiday-check step instead of a clean skip; inspect before relying on holiday automation noise level. +- 2026-06-04 morning duplicate execution happened before the `/morning` instruction fix; next scheduled morning run should be checked for exactly one context run and one `start_bot.py` startup. - Real-cash mode still needs stronger fill, partial-fill, unfilled-order, cancel/replace, and recovery logic. +- Security cleanup is still needed: keep secrets out of tracked files and remote URLs; prefer environment variables for webhooks and credentials. - Existing logs and older docs contain encoding damage; new operational notes should stay ASCII unless the file encoding is intentionally cleaned. --- @@ -67,9 +87,10 @@ ## Codex 권한 및 자동화 설정 -- 모든 Bash/파일 작업 **영구 승인** (`.Codex/settings.json` `bypassPermissions`) -- 글로벌 설정 `~/.Codex/settings.json`에도 `dangerouslySkipPermissions: true` 적용 -- **파일 수정 완료 후 즉시 `git add + commit + push origin master` 자동 실행** (확인 불필요) +- Codex 환경변수는 `.codex/config.toml`에서 관리한다. +- Stop 훅은 `.codex/hooks.json`을 통해 `.claude/discord_notify.py`를 호출한다. +- 파일 수정 완료 후 확인 없이 커밋 + `git push origin master`까지 수행한다. +- 단, `.env`, 실행 중 생성 파일, 사용자 작업 중 파일은 커밋하지 않는다. - 인코딩: `PYTHONUTF8=1`, `PYTHONIOENCODING=utf-8` 환경변수 설정 --- @@ -86,9 +107,9 @@ ## 하루 자동화 흐름 ``` -07:30 StockBot_Morning → run_morning.ps1 → Codex /morning +08:15 StockBot_Morning → run_morning.ps1 → Codex/Claude /morning RSS+네이버 뉴스+KIS 수급 분석 → daily_context.json - 완료 후 자동으로 /start-bot 호출 → 봇 백그라운드 시작 + /morning 종료 후 run_morning.ps1이 python scripts/start_bot.py 호출 08:30 봇이 daily_context.json 로드 → Discord 전송 → 유니버스 30종목 확정 08:50 목표가 계산 09:00 아침 세션 시작 (변동성 돌파 신호 + AI 필터) @@ -101,14 +122,15 @@ 14:50 강제 전량 청산 (절대 불변) 15:10 일일 결산 → Discord 전송 15:30 StockBot_Evening → run_evening.ps1 → Codex /evening - 결과 분석 + 리포트 저장 + 결과 분석 + 리포트/제안서 저장 ``` ### 스케줄러 스크립트 주의사항 (scripts/run_*.ps1) - 경로: `$PROJECT = Split-Path -Parent $PSScriptRoot` (한글 경로 인코딩 문제 방지) -- Codex 실행: `$Codex = "C:\Users\whdwo\AppData\Roaming\npm\Codex.cmd"` (전체 경로 필수) +- CLI 실행: `scripts/stockbot_env.ps1`의 `Resolve-StockBotClaude`가 `claude.cmd`를 우선 찾고 없으면 `codex.cmd`를 사용 - 인코딩: `New-Object System.Text.UTF8Encoding $false` + UTF-8 BOM으로 저장 -- 로그: `logs/bot_start.log`, `logs/morning.log`, `logs/midday.log`, `logs/evening.log` +- 봇 시작: `scripts/run_morning.ps1`이 `/morning` 완료 후 `python scripts/start_bot.py`를 직접 실행 +- 로그: `logs/morning.log`, `logs/midday.log`, `logs/evening.log`, `logs/training.log`, `logs/bot_stderr.log`, `logs/stockbot.log` --- @@ -120,6 +142,7 @@ 2. Codex가 데이터 분석 → 시장 분위기/섹터/boosted_tickers 판단 3. data/daily_context.json 저장 4. Discord로 분석 요약 전송 +5. 여기서는 봇을 시작하지 않음. 봇 시작은 run_morning.ps1만 담당. ``` ### 장중 분석 — `/midday` 슬래시 커맨드 @@ -143,9 +166,10 @@ ### 봇 시작 — `/start-bot` 슬래시 커맨드 ``` -1. 이미 실행 중인지 확인 (중복 방지) -2. app/main.py를 DETACHED_PROCESS로 백그라운드 시작 -3. Discord "[모의투자] 자동매매 봇 시작" 알림 +1. python scripts/start_bot.py 실행 +2. PID 파일 + 프로세스 스캔으로 기존 app/main.py 종료 +3. app/main.py를 DETACHED_PROCESS로 백그라운드 시작 +4. logs/bot.pid 저장 + Discord "[모의투자] 자동매매 봇 시작" 알림 ``` --- @@ -155,7 +179,7 @@ | 채널 | 내용 | 발신 | |------|------|------| | 거래 알림 | 매수/매도/손절/결산 | `app/monitor/notifier.py` | -| 코드 변경 | 커밋 내용 + Push 완료 여부 | `.Codex/discord_notify.py` (Stop 훅) | +| 코드 변경 | 커밋 내용 + Push 완료 여부 | `.claude/discord_notify.py` (Stop 훅, `.codex/hooks.json`에서도 호출) | - 코드 변경 알림: **커밋이 있을 때만** 발송 (스케줄러 태스크 등 노이즈 없음) - Discord 요청 시 반드시 `User-Agent: DiscordBot (stockbot, 1.0)` 헤더 포함 (Cloudflare 차단 방지) @@ -168,10 +192,13 @@ stockbot_v3/ ├── AGENTS.md ├── .env ← API 키 (Git 절대 제외) -├── .Codex/ -│ ├── settings.json ← 권한·훅·환경변수 설정 -│ ├── discord_notify.py ← Stop 훅: 코드 변경 Discord 전송 -│ └── session_start_sha.txt ← 세션 시작 시 HEAD SHA 저장 +├── .codex/ +│ ├── config.toml ← Codex 환경변수 설정 +│ └── hooks.json ← Stop 훅에서 .claude/discord_notify.py 호출 +├── .claude/ +│ ├── commands/ ← /morning, /midday, /evening, /start-bot 명령 +│ ├── settings.json ← Claude 권한 설정 +│ └── discord_notify.py ← 코드 변경 Discord 전송 ├── app/ │ ├── main.py ← 메인 매매 루프 (승인 필요) │ ├── config.py ← 전략 파라미터 (수정 가능) @@ -196,6 +223,8 @@ stockbot_v3/ │ ├── run_morning.ps1 ← 스케줄러용 morning │ ├── run_midday.ps1 ← 스케줄러용 midday (11:20) │ ├── run_evening.ps1 ← 스케줄러용 evening +│ ├── run_training_pipeline.ps1 +│ ├── start_bot.py ← 단일 봇 시작/기존 프로세스 종료 │ └── setup_scheduler.ps1 ← 스케줄러 전체 재등록 ├── reports/ │ ├── daily/ ← 매일 자동 생성 @@ -208,10 +237,13 @@ stockbot_v3/ │ └── market/ └── logs/ ├── stockbot.log ← 봇 메인 로그 (UTF-8) - ├── trades.log - ├── bot_start.log ← /start-bot 실행 로그 + ├── bot_stderr.log ← start_bot.py가 연결한 봇 stdout/stderr + ├── bot.pid ← 현재 봇 PID + ├── stockbot.lock ← 단일 실행 lock (실행 중 생성) ├── morning.log ← /morning 실행 로그 - └── evening.log ← /evening 실행 로그 + ├── midday.log ← /midday 실행 로그 + ├── evening.log ← /evening 실행 로그 + └── training.log ← 학습 파이프라인 로그 ``` --- @@ -225,6 +257,8 @@ stockbot_v3/ - `app/ai/daily_context.json` — 매일 장 전 생성 - `reports/` — 리포트 생성/저장 +주의: 장후 자동 리뷰(`/evening`)에서는 파라미터를 직접 수정하지 않고 `reports/proposals/YYYY-MM-DD_strategy_proposal.md`에 제안서로 남긴다. + ### 승인 필요 (사용자 확인 후 수정) - `app/main.py` — 구조 변경, 스케줄 변경 - `app/execution/` — 주문 로직 변경 @@ -241,7 +275,8 @@ stockbot_v3/ ## Git 규칙 - branch: `master` / remote: `origin` (Gitea NAS) -- 파일 수정 후 **자동으로** `git add -A && git commit && git push origin master` +- 파일 수정 후 **자동으로** 커밋 + `git push origin master` +- 단, `.env`, 실행 중 생성 파일(`logs/stockbot.lock`, `logs/bot.pid`), 사용자가 수정 중인 데이터 파일은 커밋하지 않는다. - 커밋 메시지: `[날짜] 변경내용 요약` - `.env`는 절대 커밋 금지 @@ -296,4 +331,7 @@ stockbot_v3/ ## 다음 단계 - [ ] WebSocket 전환 — REST 폴링 → KIS WebSocket 실시간 시세 +- [ ] `/morning` 중복 시작 수정 후 다음 장전 자동 실행에서 단일 실행 여부 확인 +- [ ] 휴장일 training pipeline이 실패 로그 대신 정상 skip으로 끝나는지 확인/수정 +- [ ] Discord webhook/remote credential 환경변수화 및 노출 이력 회수 검토 - [ ] NAS Docker 이전 (개발 완료 후 `git push` → NAS `git pull` → `docker-compose up -d`) diff --git a/CLAUDE.md b/CLAUDE.md index 0c6979a..9033b69 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ -# StockBot v3.0 — Claude Code 운영 가이드 +# StockBot v3.0 - Claude Code 운영 가이드 -> 최종 수정: 2026-05-19 +> 최종 수정: 2026-06-04 > 인프라: 로컬 Windows → Synology NAS Docker 이전 예정 > 현재 모드: 모의투자 (KIS_MOCK=true, DRY_RUN=true) @@ -11,13 +11,28 @@ - Parameter changes must be written to `reports/proposals/YYYY-MM-DD_strategy_proposal.md` with evidence and manual approval required. - `FORCE_EXIT = "14:50"` remains immutable. -## Current implementation status - 2026-05-28 +## Current implementation status - 2026-06-04 - Mode: paper trading / dry-run focused. Real-cash trading is not approved yet. - Approved strategy change applied: `ENTRY_START = "09:20"`. +- Applied runtime parameter: `MAX_HOLD_MIN = 90`. - `FORCE_EXIT = "14:50"` remains unchanged. - `avoid_sectors` runtime bug fixed: `main.py` now passes sector context into `check_entry()`. - Sector handling now keeps a `ticker_sectors` cache when available and uses name-based hints for known avoid-sector cases. +- Re-entry controls are active: + - `TIME`/`FORCE` cooldown is based on final exit time, not original entry time. + - `TP1`/`TP2` final exits block same-day re-entry for that ticker. + - Re-entry control state is restored from today's DB rows after bot restart. +- Duplicate execution guards are active: + - `app/main.py` uses `SingleInstanceLock` on `logs/stockbot.lock`. + - `scripts/start_bot.py` stops the PID-file process and scans for existing `app/main.py` processes before starting one new bot. + - `scripts/run_morning.ps1` is the only owner of post-morning bot startup. + - `.claude/commands/morning.md` must not call `/start-bot` or `scripts/start_bot.py`; it only creates and sends morning context. +- KIS stability hardening is active: + - Mode-specific request spacing in `KISClient` (`mock` more conservative than `real`). + - Price lookups retry transient KIS timeout/rate-limit errors. + - DRY_RUN buy/sell paths can reuse the already-read quote as the simulated fill price to reduce extra API calls. +- Daily summary duplicate guard is active; summary Discord failures are logged without crashing settlement. - Data layer: `entry_snapshots` and `post_entry_snapshots` are active for training data. - Post-entry sampling: 60s, 180s, 300s, and 600s after successful entry. - Training data export: `scripts/export_training_dataset.py`. @@ -30,23 +45,28 @@ - Model output: `models/scalping_model.joblib`. - Metrics output: `models/scalping_model.metrics.json`. - Runtime loader: `app/ml/predictor.py`. -- Latest training run: 2026-05-28 20:24, 3,156 rows total (`external_training_dataset.csv` 3,146 + bot dataset 10). -- Latest metrics: `label_stop_loss` ROC-AUC 0.851, `label_win` ROC-AUC 0.719. +- Latest successful training run: 2026-06-02 18:36, 5,773 rows total (`external_training_dataset.csv` 5,720 + bot dataset 53). +- Latest metrics: `label_stop_loss` ROC-AUC 0.896, `label_win` ROC-AUC 0.715. - Training features exclude future/outcome leakage columns such as `ret_*`, `mfe_*`, `mae_*`, `price_*`, `pnl`, and `exit_price`. - AI runtime mode: observation only. If a model exists, entry-time scores are logged and saved to `entry_snapshots`; they do not block or resize trades. -- Training schedule: `StockBot_Training` runs at 16:00 on trading days via `scripts/run_training_pipeline.ps1`; the pipeline was end-to-end verified on 2026-05-28. +- Training schedule: `StockBot_Training` runs at 16:00 on trading days via `scripts/run_training_pipeline.ps1`; latest successful full run was 2026-06-02 18:36. +- Latest daily review/proposal files exist through 2026-06-02. 2026-06-03 was skipped as a market holiday. - Dependency install: - `requirements.txt` includes `app/requirements.txt`. - `scripts/install_dependencies.ps1` installs from `vendor/wheels` when available. - `scripts/download_dependencies.ps1` builds the local wheelhouse. -## Current operational risks - 2026-05-28 +## Current operational risks - 2026-06-04 -- Model is still observation-only and is dominated by external pretraining rows; bot-trade labels are only 10 rows. +- Model is still observation-only and is dominated by external pretraining rows; bot-trade labels are 53 rows. - KIS minute-bar collection is verified for same-day windows, but historical depth and ticker coverage remain limited. - External minute data is pretraining data, not actual bot-trade data. - pykrx daily feature collection can fail for same-day data; KIS fallback is active. +- KIS rate limits can still happen if multiple scripts/processes call KIS concurrently; runtime retries reduce but do not eliminate this. +- 2026-06-03 holiday training run logged a failure at the holiday-check step instead of a clean skip; inspect before relying on holiday automation noise level. +- 2026-06-04 morning duplicate execution happened before the `/morning` instruction fix; next scheduled morning run should be checked for exactly one context run and one `start_bot.py` startup. - Real-cash mode still needs stronger fill, partial-fill, unfilled-order, cancel/replace, and recovery logic. +- Security cleanup is still needed: keep secrets out of tracked files and remote URLs; prefer environment variables for webhooks and credentials. - Existing logs and older docs contain encoding damage; new operational notes should stay ASCII unless the file encoding is intentionally cleaned. --- @@ -67,9 +87,10 @@ ## Claude Code 권한 및 자동화 설정 -- 모든 Bash/파일 작업 **영구 승인** (`.claude/settings.json` `bypassPermissions`) -- 글로벌 설정 `~/.claude/settings.json`에도 `dangerouslySkipPermissions: true` 적용 -- **파일 수정 완료 후 즉시 `git add + commit + push origin master` 자동 실행** (확인 불필요) +- Claude 권한은 `.claude/settings.json`에서 관리한다. +- Codex 연동 환경변수/훅은 `.codex/config.toml`, `.codex/hooks.json`에서 관리한다. +- 파일 수정 완료 후 확인 없이 커밋 + `git push origin master`까지 수행한다. +- 단, `.env`, 실행 중 생성 파일, 사용자 작업 중 파일은 커밋하지 않는다. - 인코딩: `PYTHONUTF8=1`, `PYTHONIOENCODING=utf-8` 환경변수 설정 --- @@ -86,9 +107,9 @@ ## 하루 자동화 흐름 ``` -07:30 StockBot_Morning → run_morning.ps1 → claude /morning +08:15 StockBot_Morning → run_morning.ps1 → claude /morning RSS+네이버 뉴스+KIS 수급 분석 → daily_context.json - 완료 후 자동으로 /start-bot 호출 → 봇 백그라운드 시작 + /morning 종료 후 run_morning.ps1이 python scripts/start_bot.py 호출 08:30 봇이 daily_context.json 로드 → Discord 전송 → 유니버스 30종목 확정 08:50 목표가 계산 09:00 아침 세션 시작 (변동성 돌파 신호 + AI 필터) @@ -101,14 +122,15 @@ 14:50 강제 전량 청산 (절대 불변) 15:10 일일 결산 → Discord 전송 15:30 StockBot_Evening → run_evening.ps1 → claude /evening - 결과 분석 + 리포트 저장 + 결과 분석 + 리포트/제안서 저장 ``` ### 스케줄러 스크립트 주의사항 (scripts/run_*.ps1) - 경로: `$PROJECT = Split-Path -Parent $PSScriptRoot` (한글 경로 인코딩 문제 방지) -- Claude 실행: `$CLAUDE = "C:\Users\whdwo\AppData\Roaming\npm\claude.cmd"` (전체 경로 필수) +- CLI 실행: `scripts/stockbot_env.ps1`의 `Resolve-StockBotClaude`가 `claude.cmd`를 우선 찾고 없으면 `codex.cmd`를 사용 - 인코딩: `New-Object System.Text.UTF8Encoding $false` + UTF-8 BOM으로 저장 -- 로그: `logs/bot_start.log`, `logs/morning.log`, `logs/midday.log`, `logs/evening.log` +- 봇 시작: `scripts/run_morning.ps1`이 `/morning` 완료 후 `python scripts/start_bot.py`를 직접 실행 +- 로그: `logs/morning.log`, `logs/midday.log`, `logs/evening.log`, `logs/training.log`, `logs/bot_stderr.log`, `logs/stockbot.log` --- @@ -120,6 +142,7 @@ 2. Claude가 데이터 분석 → 시장 분위기/섹터/boosted_tickers 판단 3. data/daily_context.json 저장 4. Discord로 분석 요약 전송 +5. 여기서는 봇을 시작하지 않음. 봇 시작은 run_morning.ps1만 담당. ``` ### 장중 분석 — `/midday` 슬래시 커맨드 @@ -143,9 +166,10 @@ ### 봇 시작 — `/start-bot` 슬래시 커맨드 ``` -1. 이미 실행 중인지 확인 (중복 방지) -2. app/main.py를 DETACHED_PROCESS로 백그라운드 시작 -3. Discord "[모의투자] 자동매매 봇 시작" 알림 +1. python scripts/start_bot.py 실행 +2. PID 파일 + 프로세스 스캔으로 기존 app/main.py 종료 +3. app/main.py를 DETACHED_PROCESS로 백그라운드 시작 +4. logs/bot.pid 저장 + Discord "[모의투자] 자동매매 봇 시작" 알림 ``` --- @@ -155,7 +179,7 @@ | 채널 | 내용 | 발신 | |------|------|------| | 거래 알림 | 매수/매도/손절/결산 | `app/monitor/notifier.py` | -| 코드 변경 | 커밋 내용 + Push 완료 여부 | `.claude/discord_notify.py` (Stop 훅) | +| 코드 변경 | 커밋 내용 + Push 완료 여부 | `.claude/discord_notify.py` (Stop 훅, `.codex/hooks.json`에서도 호출) | - 코드 변경 알림: **커밋이 있을 때만** 발송 (스케줄러 태스크 등 노이즈 없음) - Discord 요청 시 반드시 `User-Agent: DiscordBot (stockbot, 1.0)` 헤더 포함 (Cloudflare 차단 방지) @@ -167,11 +191,15 @@ ``` stockbot_v3/ ├── CLAUDE.md +├── AGENTS.md ├── .env ← API 키 (Git 절대 제외) +├── .codex/ +│ ├── config.toml ← Codex 환경변수 설정 +│ └── hooks.json ← Stop 훅에서 .claude/discord_notify.py 호출 ├── .claude/ -│ ├── settings.json ← 권한·훅·환경변수 설정 -│ ├── discord_notify.py ← Stop 훅: 코드 변경 Discord 전송 -│ └── session_start_sha.txt ← 세션 시작 시 HEAD SHA 저장 +│ ├── commands/ ← /morning, /midday, /evening, /start-bot 명령 +│ ├── settings.json ← Claude 권한 설정 +│ └── discord_notify.py ← 코드 변경 Discord 전송 ├── app/ │ ├── main.py ← 메인 매매 루프 (승인 필요) │ ├── config.py ← 전략 파라미터 (수정 가능) @@ -196,6 +224,8 @@ stockbot_v3/ │ ├── run_morning.ps1 ← 스케줄러용 morning │ ├── run_midday.ps1 ← 스케줄러용 midday (11:20) │ ├── run_evening.ps1 ← 스케줄러용 evening +│ ├── run_training_pipeline.ps1 +│ ├── start_bot.py ← 단일 봇 시작/기존 프로세스 종료 │ └── setup_scheduler.ps1 ← 스케줄러 전체 재등록 ├── reports/ │ ├── daily/ ← 매일 자동 생성 @@ -208,10 +238,13 @@ stockbot_v3/ │ └── market/ └── logs/ ├── stockbot.log ← 봇 메인 로그 (UTF-8) - ├── trades.log - ├── bot_start.log ← /start-bot 실행 로그 + ├── bot_stderr.log ← start_bot.py가 연결한 봇 stdout/stderr + ├── bot.pid ← 현재 봇 PID + ├── stockbot.lock ← 단일 실행 lock (실행 중 생성) ├── morning.log ← /morning 실행 로그 - └── evening.log ← /evening 실행 로그 + ├── midday.log ← /midday 실행 로그 + ├── evening.log ← /evening 실행 로그 + └── training.log ← 학습 파이프라인 로그 ``` --- @@ -225,6 +258,8 @@ stockbot_v3/ - `app/ai/daily_context.json` — 매일 장 전 생성 - `reports/` — 리포트 생성/저장 +주의: 장후 자동 리뷰(`/evening`)에서는 파라미터를 직접 수정하지 않고 `reports/proposals/YYYY-MM-DD_strategy_proposal.md`에 제안서로 남긴다. + ### 승인 필요 (사용자 확인 후 수정) - `app/main.py` — 구조 변경, 스케줄 변경 - `app/execution/` — 주문 로직 변경 @@ -241,7 +276,8 @@ stockbot_v3/ ## Git 규칙 - branch: `master` / remote: `origin` (Gitea NAS) -- 파일 수정 후 **자동으로** `git add -A && git commit && git push origin master` +- 파일 수정 후 **자동으로** 커밋 + `git push origin master` +- 단, `.env`, 실행 중 생성 파일(`logs/stockbot.lock`, `logs/bot.pid`), 사용자가 수정 중인 데이터 파일은 커밋하지 않는다. - 커밋 메시지: `[날짜] 변경내용 요약` - `.env`는 절대 커밋 금지 @@ -296,4 +332,7 @@ stockbot_v3/ ## 다음 단계 - [ ] WebSocket 전환 — REST 폴링 → KIS WebSocket 실시간 시세 +- [ ] `/morning` 중복 시작 수정 후 다음 장전 자동 실행에서 단일 실행 여부 확인 +- [ ] 휴장일 training pipeline이 실패 로그 대신 정상 skip으로 끝나는지 확인/수정 +- [ ] Discord webhook/remote credential 환경변수화 및 노출 이력 회수 검토 - [ ] NAS Docker 이전 (개발 완료 후 `git push` → NAS `git pull` → `docker-compose up -d`) diff --git a/README.md b/README.md index 67a9cc3..b94a07d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # 단타 자동매매 시스템 v3.0 기획서 v3.0 기준 / KIS Open API / Synology NAS Docker -AI: Claude Code headless (장 전 분석 + 장 후 피드백) +AI: Claude Code/Codex headless (장 전 분석 + 장중 점검 + 장 후 피드백) ## 운영 모드 | KIS_MOCK | DRY_RUN | 동작 | |----------|---------|------| -| true | true | 신호 확인만 (주문 없음) ← 처음 시작 | +| true | true | 신호 확인만 (주문 없음) ← 현재 | | true | false | 모의투자 실제 주문 ← 3개월 검증 | | false | false | 실거래 ← 조건 충족 후 | @@ -47,7 +47,8 @@ docker-compose --profile emergency up kill-switch # 또는 python kill_switch/kill.py ``` -# StockBot Current Status - 2026-05-28 + +# StockBot Current Status - 2026-06-04 This project is currently a paper-trading scalping bot with an AI training pipeline in observation mode. @@ -55,8 +56,23 @@ pipeline in observation mode. Active: - Windows Task Scheduler operation for morning, midday, evening, watchdog, and training jobs. - Approved `ENTRY_START = "09:20"` after the 2026-05-28 evening review. +- Applied `MAX_HOLD_MIN = 90`. - `FORCE_EXIT = "14:50"` remains unchanged. - `avoid_sectors` filtering is active in runtime entry checks. +- Re-entry controls are active: + - TIME/FORCE cooldown is measured from final exit time. + - TP final exits block same-day ticker re-entry. + - Re-entry control state is restored from today's DB rows after restart. +- Duplicate bot startup guards are active: + - `app/main.py` uses `logs/stockbot.lock`. + - `scripts/start_bot.py` kills existing `app/main.py` processes before starting one new bot. + - `scripts/run_morning.ps1` is the only post-morning bot startup owner. + - `/morning` must not call `/start-bot` or `scripts/start_bot.py`. +- KIS stability hardening is active: + - Mode-specific request spacing. + - Retry for transient KIS timeout/rate-limit price errors. + - DRY_RUN simulated fills reuse the current quote to reduce extra KIS calls. +- Daily settlement has a duplicate-summary guard. - Entry snapshots for model training. - Post-entry snapshots at 1m, 3m, 5m, and 10m. - Bot-data export to `data/training_dataset.csv`. @@ -65,21 +81,28 @@ Active: - KIS minute collection excludes ETF/ETN by default and collects multiple windows from 09:30 to 14:00. - RandomForest-based training engine. - Optional AI entry scoring when `models/scalping_model.joblib` exists. -- Latest verified training run: 2026-05-28 20:24. -- Latest training rows: 3,156 total, including 3,146 external pretraining rows and 10 bot-trade rows. -- Latest metrics: `label_stop_loss` ROC-AUC 0.851, `label_win` ROC-AUC 0.719. +- Latest successful training run: 2026-06-02 18:36. +- Latest training rows: 5,773 total, including 5,720 external pretraining rows and 53 bot-trade rows. +- Latest metrics: `label_stop_loss` ROC-AUC 0.896, `label_win` ROC-AUC 0.715. +- Latest daily review/proposal files exist through 2026-06-02; 2026-06-03 was a market holiday. Not active yet: -- AI does not block buys. -- AI does not change position size. -- AI does not override exits. +- ML model scores do not block buys. +- ML model scores do not change position size. +- ML model scores do not override exits. - Real-cash trading is not ready until fill, unfilled-order, and partial-fill handling is hardened. +Current operational notes: +- On 2026-06-04, duplicate morning execution happened before the `/morning` instruction fix. The next scheduled morning run should show one context run and one `scripts/start_bot.py` startup. +- KIS rate limits can still happen when multiple scripts/processes call KIS concurrently. +- The 2026-06-03 holiday training run logged a failure at the holiday-check step instead of a clean skip; inspect before relying on holiday automation noise level. +- Keep secrets out of tracked files and remote URLs. Prefer environment variables for Discord webhooks and credentials. + Daily schedule: | Time | Task | Purpose | |---|---|---| -| 08:15 | `StockBot_Morning` | Run `/morning`, build context, start bot | +| 08:15 | `StockBot_Morning` | Run `/morning`, build context, then `scripts/start_bot.py` starts exactly one bot | | 09:00-15:10 | `StockBot_Watchdog` | Check/restart bot every 5 minutes | | 11:20 | `StockBot_Midday` | Midday review and context update | | 15:30 | `StockBot_Evening` | Daily review and proposal report | @@ -91,9 +114,12 @@ Useful commands: python -m pip install -r requirements.txt powershell -ExecutionPolicy Bypass -File scripts\install_dependencies.ps1 powershell -ExecutionPolicy Bypass -File scripts\setup_scheduler.ps1 +python scripts\start_bot.py powershell -ExecutionPolicy Bypass -File scripts\run_training_pipeline.ps1 python scripts\export_training_dataset.py python scripts\train_ai_model.py +Get-Content logs\morning.log -Tail 80 +Get-Content logs\stockbot.log -Tail 80 ``` Dependency portability: