[2026-06-04] 문서 역할 재정리
This commit is contained in:
@@ -1,338 +1,302 @@
|
||||
# StockBot v3.0 - Claude Code 운영 가이드
|
||||
# StockBot v3.0 - Claude Code Operating Guide
|
||||
|
||||
> 최종 수정: 2026-06-04
|
||||
> 인프라: 로컬 Windows → Synology NAS Docker 이전 예정
|
||||
> 현재 모드: 모의투자 (KIS_MOCK=true, DRY_RUN=true)
|
||||
> Last updated: 2026-06-04
|
||||
> Runtime: local Windows now, planned Synology NAS Docker migration later
|
||||
> Current mode: paper trading / dry run (`KIS_MOCK=true`, `DRY_RUN=true`)
|
||||
|
||||
## Current safety policy
|
||||
This file is written for Claude Code. Keep it operational, explicit, and easy
|
||||
for an agent to follow. Human-facing project background belongs in `README.md`.
|
||||
|
||||
- AI is for market review and proposals only; code decides entries and exits.
|
||||
- Evening Claude must not edit `app/config.py` or execution/strategy/risk code directly.
|
||||
- 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.
|
||||
## Agent Role
|
||||
|
||||
## Current implementation status - 2026-06-04
|
||||
- When working alone: analyze, plan, implement, verify, and self-review.
|
||||
- When collaborating with Codex: implement only the approved scope and provide
|
||||
Codex with the approved plan, relevant files, diff, test results, and
|
||||
acceptance criteria for review.
|
||||
- Do not ask Codex for the entire conversation history during collaboration.
|
||||
- Do not edit files that Codex is actively editing.
|
||||
- Limit review loops: one pass for small work, at most two passes for medium
|
||||
work. Split large work into phase gates.
|
||||
|
||||
- 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.
|
||||
## Solo Workflow
|
||||
|
||||
1. Analyze the request and classify scope: small, medium, or large.
|
||||
2. Write an explicit plan before implementation.
|
||||
3. Implement one file at a time and keep the scope tight.
|
||||
4. Run focused verification.
|
||||
5. Perform the veteran self-review below.
|
||||
6. If the score is below 90, fix the highest-leverage issues and review again.
|
||||
|
||||
Use this exact self-review format:
|
||||
|
||||
```text
|
||||
Veteran role: <relevant expert role>
|
||||
Overall score: <0-100>
|
||||
Decision: PASS | FAIL
|
||||
|
||||
Category scores:
|
||||
- Correctness and requirement fit: <score>/30 - <reason>
|
||||
- Safety, security, and failure handling: <score>/20 - <reason>
|
||||
- Maintainability and architecture fit: <score>/20 - <reason>
|
||||
- Testability and verification: <score>/15 - <reason>
|
||||
- Scope control and operational readiness: <score>/10 - <reason>
|
||||
- Clarity of handoff and reviewer confidence: <score>/5 - <reason>
|
||||
|
||||
Blocking issues preventing 90+:
|
||||
- <issue>
|
||||
|
||||
Highest-leverage fixes:
|
||||
- <fix>
|
||||
```
|
||||
|
||||
## Safety Policy
|
||||
|
||||
- AI is for market review, context generation, and proposals only.
|
||||
- The code decides entries, exits, risk gates, and order behavior.
|
||||
- Runtime ML model scores are observation-only. They may be logged and stored,
|
||||
but must not block buys, resize positions, or override exits unless explicitly
|
||||
approved later.
|
||||
- Evening review must not directly edit `app/config.py`, `app/execution/`,
|
||||
`app/strategy/`, or `app/risk/`. Write proposal reports instead.
|
||||
- Strategy parameter changes must be written to
|
||||
`reports/proposals/YYYY-MM-DD_strategy_proposal.md` with evidence and manual
|
||||
approval requirements.
|
||||
- `FORCE_EXIT = "14:50"` is immutable.
|
||||
- Stop-loss checks must remain higher priority than profit-taking checks.
|
||||
- Real-cash trading is not approved yet.
|
||||
|
||||
## Current Implementation Status
|
||||
|
||||
- Current mode is paper trading / dry-run focused.
|
||||
- Approved strategy values:
|
||||
- `ENTRY_START = "09:20"`
|
||||
- `MAX_HOLD_MIN = 90`
|
||||
- `FORCE_EXIT = "14:50"` unchanged
|
||||
- `avoid_sectors` filtering is active at runtime. `main.py` passes sector
|
||||
context into `check_entry()`.
|
||||
- Sector handling keeps a `ticker_sectors` cache 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:
|
||||
- `TIME` and `FORCE` cooldown is based on final exit time, not entry time.
|
||||
- Final `TP1`/`TP2` exits block same-day re-entry for that ticker.
|
||||
- Re-entry control state is restored from today's DB rows after restart.
|
||||
- Duplicate bot 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/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.
|
||||
- `.claude/commands/morning.md` must not call `/start-bot` or
|
||||
`scripts/start_bot.py`.
|
||||
- KIS stability hardening is active:
|
||||
- Mode-specific request spacing in `KISClient` (`mock` more conservative than `real`).
|
||||
- Mode-specific request spacing in `KISClient`.
|
||||
- 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`.
|
||||
- External data collection:
|
||||
- Daily market features: `scripts/collect_daily_features.py` with KIS fallback when pykrx fails.
|
||||
- KIS minute bars: `scripts/collect_minute_data.py`, default ETF/ETN exclusion, multi-window collection from 09:30 to 14:00.
|
||||
- External dataset builder: `scripts/build_external_training_dataset.py`, using prior daily OHLCV for breakout targets.
|
||||
- ML engine:
|
||||
- DRY_RUN buy/sell paths can reuse the already-read quote as the simulated
|
||||
fill price to reduce extra API calls.
|
||||
- Daily summary has a duplicate guard; Discord settlement-send failures are
|
||||
logged without crashing settlement.
|
||||
- Data layer:
|
||||
- `entry_snapshots` are active.
|
||||
- `post_entry_snapshots` sample 60s, 180s, 300s, and 600s after entry.
|
||||
- Bot data export: `scripts/export_training_dataset.py`.
|
||||
- External data and ML:
|
||||
- Daily features: `scripts/collect_daily_features.py`, with KIS fallback when
|
||||
pykrx fails.
|
||||
- KIS minute bars: `scripts/collect_minute_data.py`, ETF/ETN excluded by
|
||||
default, multi-window collection from 09:30 to 14:00.
|
||||
- External dataset builder: `scripts/build_external_training_dataset.py`.
|
||||
- Training: `scripts/train_ai_model.py`.
|
||||
- Model output: `models/scalping_model.joblib`.
|
||||
- Metrics output: `models/scalping_model.metrics.json`.
|
||||
- Runtime loader: `app/ml/predictor.py`.
|
||||
- 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`; 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.
|
||||
- Latest successful training run: 2026-06-02 18:36.
|
||||
- Latest rows: 5,773 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.
|
||||
- Latest daily review/proposal files exist through 2026-06-02.
|
||||
- 2026-06-03 was skipped as a market holiday.
|
||||
|
||||
## Current operational risks - 2026-06-04
|
||||
## Current Risks
|
||||
|
||||
- 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.
|
||||
- The ML model is observation-only and still dominated by external pretraining
|
||||
rows; bot-trade labels are only 53 rows.
|
||||
- KIS minute data is verified for same-day windows, but historical depth and
|
||||
ticker coverage are 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.
|
||||
- pykrx daily feature collection can fail for same-day data; KIS fallback is
|
||||
active.
|
||||
- KIS rate limits can still happen if multiple scripts or processes call KIS at
|
||||
the same time.
|
||||
- The 2026-06-03 holiday training run logged a failure at the holiday-check
|
||||
step instead of a clean skip. Inspect this before relying on holiday
|
||||
automation noise level.
|
||||
- The 2026-06-04 morning duplicate execution happened before the `/morning`
|
||||
instruction fix. The next scheduled morning run should be checked for exactly
|
||||
one context generation 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 needed: keep webhooks, credentials, tokens, and remote
|
||||
credentials out of tracked files and remote URLs.
|
||||
- Older logs contain encoding damage. New operational notes should stay ASCII
|
||||
unless the target file intentionally uses another encoding.
|
||||
|
||||
---
|
||||
## Automation Flow
|
||||
|
||||
## 프로젝트 개요
|
||||
```text
|
||||
08:15 StockBot_Morning -> scripts/run_morning.ps1 -> /morning
|
||||
Build data/daily_context.json.
|
||||
After /morning exits, run_morning.ps1 calls python scripts/start_bot.py.
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| 목표 | KIS API 기반 한국 주식 단타 자동매매 |
|
||||
| 전략 | 변동성 돌파 (K=0.5) |
|
||||
| 언어 | Python 3.11 |
|
||||
| DB | SQLite (data/stockbot.db) |
|
||||
| 알림 | Discord Webhook (거래 알림 + 코드 변경 알림 채널 분리) |
|
||||
| AI | Claude Code headless (`claude -p "/커맨드" --dangerously-skip-permissions`) |
|
||||
| 코드 관리 | Gitea (NAS) — 파일 수정 후 확인 없이 자동 commit + push |
|
||||
|
||||
---
|
||||
|
||||
## Claude Code 권한 및 자동화 설정
|
||||
|
||||
- Claude 권한은 `.claude/settings.json`에서 관리한다.
|
||||
- Codex 연동 환경변수/훅은 `.codex/config.toml`, `.codex/hooks.json`에서 관리한다.
|
||||
- 파일 수정 완료 후 확인 없이 커밋 + `git push origin master`까지 수행한다.
|
||||
- 단, `.env`, 실행 중 생성 파일, 사용자 작업 중 파일은 커밋하지 않는다.
|
||||
- 인코딩: `PYTHONUTF8=1`, `PYTHONIOENCODING=utf-8` 환경변수 설정
|
||||
|
||||
---
|
||||
|
||||
## 핵심 설계 원칙 (절대 불변)
|
||||
|
||||
1. **14:50 강제 청산** — 하드코딩, 예외 없음
|
||||
2. **손절 우선** — AI 판단과 무관하게 손절 룰 항상 우선순위 1위
|
||||
3. **AI 역할 분리** — Claude Code는 장 전 분석 + 장 후 피드백만, 실시간 매매 개입 불가
|
||||
4. **검증 순서** — 모의투자 3개월 → 조건 충족 → 실거래
|
||||
|
||||
---
|
||||
|
||||
## 하루 자동화 흐름
|
||||
|
||||
```
|
||||
08:15 StockBot_Morning → run_morning.ps1 → claude /morning
|
||||
RSS+네이버 뉴스+KIS 수급 분석 → daily_context.json
|
||||
/morning 종료 후 run_morning.ps1이 python scripts/start_bot.py 호출
|
||||
08:30 봇이 daily_context.json 로드 → Discord 전송 → 유니버스 30종목 확정
|
||||
08:50 목표가 계산
|
||||
09:00 아침 세션 시작 (변동성 돌파 신호 + AI 필터)
|
||||
B안: 연속 손절 시 포지션 크기 자동 축소 (0회→1.0× / 1회→0.7× / 2회→0.5× / 3+→0.3×)
|
||||
11:00 midday_context.json 미로드 시 신규 진입 일시 중단
|
||||
11:20 StockBot_Midday → run_midday.ps1 → claude /midday
|
||||
오전 결과+시장 스냅샷 수집 → midday_context.json 저장
|
||||
파일 생성 즉시 봇이 감지 → 점심 세션 자동 시작
|
||||
14:00 신규 진입 마감
|
||||
14:50 강제 전량 청산 (절대 불변)
|
||||
15:10 일일 결산 → Discord 전송
|
||||
15:30 StockBot_Evening → run_evening.ps1 → claude /evening
|
||||
결과 분석 + 리포트/제안서 저장
|
||||
08:30 Bot loads daily_context.json and builds the watch universe.
|
||||
08:50 Bot calculates volatility breakout targets.
|
||||
09:00 Morning trading session starts.
|
||||
11:00 New entries pause if midday_context.json has not loaded.
|
||||
11:20 StockBot_Midday -> scripts/run_midday.ps1 -> /midday
|
||||
Build data/midday_context.json; bot detects it and starts lunch controls.
|
||||
14:00 New entries stop; exits continue.
|
||||
14:50 Force exit all positions. This time is immutable.
|
||||
15:10 Daily settlement and Discord summary.
|
||||
15:30 StockBot_Evening -> scripts/run_evening.ps1 -> /evening
|
||||
Write daily report and proposal report when needed.
|
||||
16:00 StockBot_Training -> scripts/run_training_pipeline.ps1
|
||||
```
|
||||
|
||||
### 스케줄러 스크립트 주의사항 (scripts/run_*.ps1)
|
||||
- 경로: `$PROJECT = Split-Path -Parent $PSScriptRoot` (한글 경로 인코딩 문제 방지)
|
||||
- CLI 실행: `scripts/stockbot_env.ps1`의 `Resolve-StockBotClaude`가 `claude.cmd`를 우선 찾고 없으면 `codex.cmd`를 사용
|
||||
- 인코딩: `New-Object System.Text.UTF8Encoding $false` + UTF-8 BOM으로 저장
|
||||
- 봇 시작: `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`
|
||||
## Slash Command Responsibilities
|
||||
|
||||
---
|
||||
### `/morning`
|
||||
|
||||
## Claude Code 역할 상세
|
||||
1. Run `python app/ai/morning.py --print`.
|
||||
2. Analyze collected news, KIS flow, sectors, and ticker-specific news.
|
||||
3. Write `data/daily_context.json`.
|
||||
4. Send the morning Discord summary.
|
||||
5. Do not start the bot. Startup belongs only to `scripts/run_morning.ps1`.
|
||||
|
||||
### 장 전 분석 — `/morning` 슬래시 커맨드
|
||||
```
|
||||
1. python app/ai/morning.py --print (뉴스 크롤링 + KIS 수급 수집)
|
||||
2. Claude가 데이터 분석 → 시장 분위기/섹터/boosted_tickers 판단
|
||||
3. data/daily_context.json 저장
|
||||
4. Discord로 분석 요약 전송
|
||||
5. 여기서는 봇을 시작하지 않음. 봇 시작은 run_morning.ps1만 담당.
|
||||
### `/midday`
|
||||
|
||||
1. Run `python app/ai/midday.py --print`.
|
||||
2. Compare morning context with actual morning trades and market snapshot.
|
||||
3. Write `data/midday_context.json`.
|
||||
4. Send the midday Discord summary.
|
||||
|
||||
### `/evening`
|
||||
|
||||
1. Run `python app/ai/evening.py --print`.
|
||||
2. Review trades, win rate, PnL, fees, exit distribution, overtrading, AI
|
||||
filter quality, and execution quality.
|
||||
3. Write `reports/daily/YYYY-MM-DD.md`.
|
||||
4. If a strategy change is justified, write
|
||||
`reports/proposals/YYYY-MM-DD_strategy_proposal.md`.
|
||||
5. Do not directly edit runtime strategy/config/risk/execution code during
|
||||
evening review.
|
||||
6. Check live-readiness criteria.
|
||||
7. Send a concise Discord summary.
|
||||
|
||||
### `/start-bot`
|
||||
|
||||
1. Run `python scripts/start_bot.py`.
|
||||
2. The script stops existing PID-file and scanned `app/main.py` processes.
|
||||
3. It starts exactly one detached `app/main.py` process.
|
||||
4. It writes `logs/bot.pid` and sends the Discord start notification.
|
||||
|
||||
## Important Files
|
||||
|
||||
```text
|
||||
app/main.py Main trading loop and runtime orchestration
|
||||
app/config.py Strategy parameters
|
||||
app/strategy/volatility_breakout.py Entry/exit signal logic
|
||||
app/risk/manager.py L1-L5 risk controls and L3-B sizing
|
||||
app/execution/kis_client.py KIS REST/WebSocket wrapper
|
||||
app/execution/order_executor.py Order execution and trade persistence
|
||||
app/db/models.py SQLite schema
|
||||
app/db/repository.py DB access helpers
|
||||
app/ai/morning.py Morning data collection
|
||||
app/ai/midday.py Midday data collection
|
||||
app/ai/evening.py Evening data collection
|
||||
scripts/start_bot.py Deterministic single-bot startup
|
||||
scripts/run_morning.ps1 Scheduler morning job
|
||||
scripts/run_midday.ps1 Scheduler midday job
|
||||
scripts/run_evening.ps1 Scheduler evening job
|
||||
scripts/run_training_pipeline.ps1 Training pipeline
|
||||
```
|
||||
|
||||
### 장중 분석 — `/midday` 슬래시 커맨드
|
||||
```
|
||||
1. python app/ai/midday.py --print (오전 거래 결과 + 현재 시장 스냅샷 수집)
|
||||
2. 오전 daily_context 예측 vs 실제 결과 비교 분석
|
||||
3. 점심 세션 파라미터 결정 (진입 허용 여부, 포지션 배율, 섹터 업데이트)
|
||||
4. data/midday_context.json 저장 → 봇이 즉시 감지해 점심 세션 시작
|
||||
5. Discord로 장중 분석 전송
|
||||
```
|
||||
## Edit Boundaries
|
||||
|
||||
### 장 후 피드백 — `/evening` 슬래시 커맨드
|
||||
```
|
||||
1. python app/ai/evening.py --print (오늘 매매 내역 조회)
|
||||
2. 승률/손익/이상패턴 분석
|
||||
3. app/config.py 파라미터 조정 (문제 명확할 때만)
|
||||
4. reports/daily/날짜.md 저장
|
||||
5. 실전 전환 조건 5가지 체크
|
||||
6. Discord로 요약 전송
|
||||
```
|
||||
Freely editable when the task calls for it:
|
||||
|
||||
### 봇 시작 — `/start-bot` 슬래시 커맨드
|
||||
```
|
||||
1. python scripts/start_bot.py 실행
|
||||
2. PID 파일 + 프로세스 스캔으로 기존 app/main.py 종료
|
||||
3. app/main.py를 DETACHED_PROCESS로 백그라운드 시작
|
||||
4. logs/bot.pid 저장 + Discord "[모의투자] 자동매매 봇 시작" 알림
|
||||
```
|
||||
- `app/config.py`
|
||||
- `app/strategy/volatility_breakout.py`
|
||||
- `app/risk/manager.py`
|
||||
- `reports/`
|
||||
- Documentation files
|
||||
|
||||
---
|
||||
Requires explicit user approval:
|
||||
|
||||
## Discord 알림 구조
|
||||
- Structural changes to `app/main.py`
|
||||
- `app/execution/`
|
||||
- `app/db/`
|
||||
- Database schema changes
|
||||
- Real-cash trading behavior
|
||||
|
||||
| 채널 | 내용 | 발신 |
|
||||
|------|------|------|
|
||||
| 거래 알림 | 매수/매도/손절/결산 | `app/monitor/notifier.py` |
|
||||
| 코드 변경 | 커밋 내용 + Push 완료 여부 | `.claude/discord_notify.py` (Stop 훅, `.codex/hooks.json`에서도 호출) |
|
||||
Never edit or commit:
|
||||
|
||||
- 코드 변경 알림: **커밋이 있을 때만** 발송 (스케줄러 태스크 등 노이즈 없음)
|
||||
- Discord 요청 시 반드시 `User-Agent: DiscordBot (stockbot, 1.0)` 헤더 포함 (Cloudflare 차단 방지)
|
||||
- `.env`
|
||||
- token files
|
||||
- runtime DB files
|
||||
- runtime logs
|
||||
- `logs/stockbot.lock`
|
||||
- files the user says they are currently editing
|
||||
|
||||
---
|
||||
Never change:
|
||||
|
||||
## 파일 구조
|
||||
- `FORCE_EXIT = "14:50"`
|
||||
- stop-loss priority over profit-taking
|
||||
|
||||
```
|
||||
stockbot_v3/
|
||||
├── CLAUDE.md
|
||||
├── AGENTS.md
|
||||
├── .env ← API 키 (Git 절대 제외)
|
||||
├── .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 ← 전략 파라미터 (수정 가능)
|
||||
│ ├── ai/
|
||||
│ │ ├── morning.py ← 장 전 데이터 수집
|
||||
│ │ ├── midday.py ← 장중 데이터 수집
|
||||
│ │ └── evening.py ← 장 후 데이터 수집
|
||||
│ ├── strategy/
|
||||
│ │ └── volatility_breakout.py ← 전략 로직 (수정 가능)
|
||||
│ ├── execution/
|
||||
│ │ ├── kis_client.py ← KIS API 래퍼 (승인 필요)
|
||||
│ │ └── order_executor.py ← 주문 실행 (승인 필요)
|
||||
│ ├── risk/
|
||||
│ │ └── manager.py ← 리스크 관리 (수정 가능)
|
||||
│ ├── monitor/
|
||||
│ │ └── notifier.py ← Discord Webhook
|
||||
│ └── db/
|
||||
│ ├── models.py ← SQLite 스키마 (승인 필요)
|
||||
│ └── repository.py ← DB 접근 (승인 필요)
|
||||
├── scripts/
|
||||
│ ├── run_bot.ps1 ← 스케줄러용 봇 시작
|
||||
│ ├── 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/ ← 매일 자동 생성
|
||||
│ └── live_ready/ ← 실전 전환 조건 충족 시 생성
|
||||
├── data/
|
||||
│ ├── stockbot.db
|
||||
│ ├── daily_context.json ← 매일 /morning이 갱신, 봇이 08:30에 로드
|
||||
│ ├── midday_context.json ← 매일 /midday가 갱신, 봇이 파일 감지 즉시 로드
|
||||
│ ├── news/
|
||||
│ └── market/
|
||||
└── logs/
|
||||
├── stockbot.log ← 봇 메인 로그 (UTF-8)
|
||||
├── bot_stderr.log ← start_bot.py가 연결한 봇 stdout/stderr
|
||||
├── bot.pid ← 현재 봇 PID
|
||||
├── stockbot.lock ← 단일 실행 lock (실행 중 생성)
|
||||
├── morning.log ← /morning 실행 로그
|
||||
├── midday.log ← /midday 실행 로그
|
||||
├── evening.log ← /evening 실행 로그
|
||||
└── training.log ← 학습 파이프라인 로그
|
||||
```
|
||||
## Git Rules
|
||||
|
||||
---
|
||||
- Branch: `master`.
|
||||
- Remote: `origin` on the NAS Gitea server.
|
||||
- After file edits, commit and push to `origin master` without asking again,
|
||||
unless the user says not to.
|
||||
- Commit message format: `[YYYY-MM-DD] concise Korean or English summary`.
|
||||
- Stage only the intended files. Do not include `.env`, runtime logs, lock files,
|
||||
token files, DB files, or user-in-progress data files.
|
||||
|
||||
## 수정 범위
|
||||
## Risk Controls
|
||||
|
||||
### 자유롭게 수정 가능
|
||||
- `app/config.py` — 전략 파라미터 (TP1_PCT, TP2_PCT, SL_PCT, STRATEGY_K 등)
|
||||
- `app/strategy/volatility_breakout.py` — 전략 로직
|
||||
- `app/risk/manager.py` — 리스크 기준값 (L1~L5)
|
||||
- `app/ai/daily_context.json` — 매일 장 전 생성
|
||||
- `reports/` — 리포트 생성/저장
|
||||
| Level | Condition | Action |
|
||||
|---|---|---|
|
||||
| L1 | Single trade hits stop-loss | Exit immediately |
|
||||
| L2 | Daily loss reaches -3% | Stop new entries for the day |
|
||||
| L3-B | Consecutive stop-losses | Reduce position size, no full stop |
|
||||
| L4 | Weekly loss reaches -7% | Stop until weekend review |
|
||||
| L5 | Monthly loss reaches -15% | Retire strategy and review |
|
||||
|
||||
주의: 장후 자동 리뷰(`/evening`)에서는 파라미터를 직접 수정하지 않고 `reports/proposals/YYYY-MM-DD_strategy_proposal.md`에 제안서로 남긴다.
|
||||
L3-B sizing:
|
||||
|
||||
### 승인 필요 (사용자 확인 후 수정)
|
||||
- `app/main.py` — 구조 변경, 스케줄 변경
|
||||
- `app/execution/` — 주문 로직 변경
|
||||
- `app/db/` — 스키마 변경
|
||||
| Consecutive stop-loss count | Position multiplier |
|
||||
|---|---|
|
||||
| 0 | 1.0x |
|
||||
| 1 | 0.7x |
|
||||
| 2 | 0.5x |
|
||||
| 3+ | 0.3x |
|
||||
|
||||
### 절대 금지
|
||||
- `FORCE_EXIT = "14:50"` 변경
|
||||
- 손절을 익절보다 후순위로 변경
|
||||
- `.env` 파일 직접 수정 (KIS_MOCK, DRY_RUN 포함)
|
||||
- `.env` Git 커밋
|
||||
## Live-Cash Readiness
|
||||
|
||||
---
|
||||
All conditions must pass before real-cash mode:
|
||||
|
||||
## Git 규칙
|
||||
- At least 30 trading days of operation.
|
||||
- Recent 30-day win rate above 48%.
|
||||
- Recent 30-day MDD better than -10%.
|
||||
- Recent 30-day Sharpe above 1.0.
|
||||
- L3-B minimum multiplier events no more than twice per month.
|
||||
|
||||
- branch: `master` / remote: `origin` (Gitea NAS)
|
||||
- 파일 수정 후 **자동으로** 커밋 + `git push origin master`
|
||||
- 단, `.env`, 실행 중 생성 파일(`logs/stockbot.lock`, `logs/bot.pid`), 사용자가 수정 중인 데이터 파일은 커밋하지 않는다.
|
||||
- 커밋 메시지: `[날짜] 변경내용 요약`
|
||||
- `.env`는 절대 커밋 금지
|
||||
If all pass, create `reports/live_ready/YYYY-MM-DD_READY.md` and send Discord
|
||||
notification. Switching to real-cash mode requires manual `.env` changes:
|
||||
`KIS_MOCK=false`, `DRY_RUN=false`.
|
||||
|
||||
---
|
||||
## Next Checks
|
||||
|
||||
## 리스크 관리 (L1~L5)
|
||||
|
||||
| 레벨 | 조건 | 동작 | Discord |
|
||||
|------|------|------|---------|
|
||||
| L1 | 1회 -1.5% | 즉시 손절 | [손절] |
|
||||
| L2 | 일일 -3% | 당일 신규 진입 중단 | [경고] |
|
||||
| L3-B | 연속 손절 | 포지션 크기 단계 축소 (전면 중단 없음) | [경고] |
|
||||
| L4 | 주간 -7% | 주말까지 중단 | [경고] |
|
||||
| L5 | 월간 -15% | 전략 폐기 + 재검토 | [긴급] |
|
||||
|
||||
**L3-B 포지션 배율** (익절 시 한 단계 회복):
|
||||
|
||||
| 연속 손절 | 포지션 크기 |
|
||||
|-----------|------------|
|
||||
| 0회 | 1.0× (정상) |
|
||||
| 1회 | 0.7× |
|
||||
| 2회 | 0.5× |
|
||||
| 3회+ | 0.3× (최소) |
|
||||
|
||||
---
|
||||
|
||||
## 실전 전환 조건 (claude_evening 자동 체크)
|
||||
|
||||
| 조건 | 기준 |
|
||||
|------|------|
|
||||
| 누적 운영 | 30거래일 이상 |
|
||||
| 승률 | 최근 30일 > 48% |
|
||||
| MDD | 최근 30일 < -10% |
|
||||
| 샤프지수 | 최근 30일 > 1.0 |
|
||||
| L3-B 최소배율(0.3×) 도달 | 월 2회 이하 |
|
||||
|
||||
전부 충족 시 → `reports/live_ready/날짜_READY.md` 생성 + Discord 🚀 알림
|
||||
전환 방법: `.env`에서 `KIS_MOCK=false`, `DRY_RUN=false` 로 변경
|
||||
|
||||
---
|
||||
|
||||
## 운영 모드
|
||||
|
||||
| KIS_MOCK | DRY_RUN | 동작 |
|
||||
|----------|---------|------|
|
||||
| true | true | 신호 확인만 ← **현재** |
|
||||
| true | false | 모의투자 실주문 |
|
||||
| false | false | 실거래 |
|
||||
|
||||
---
|
||||
|
||||
## 다음 단계
|
||||
|
||||
- [ ] WebSocket 전환 — REST 폴링 → KIS WebSocket 실시간 시세
|
||||
- [ ] `/morning` 중복 시작 수정 후 다음 장전 자동 실행에서 단일 실행 여부 확인
|
||||
- [ ] 휴장일 training pipeline이 실패 로그 대신 정상 skip으로 끝나는지 확인/수정
|
||||
- [ ] Discord webhook/remote credential 환경변수화 및 노출 이력 회수 검토
|
||||
- [ ] NAS Docker 이전 (개발 완료 후 `git push` → NAS `git pull` → `docker-compose up -d`)
|
||||
- Verify the next morning run has exactly one `/morning` context generation and
|
||||
one `scripts/start_bot.py` startup.
|
||||
- Fix the holiday training pipeline so market holidays end as clean skips.
|
||||
- Move tracked webhook/credential material into environment variables and rotate
|
||||
anything exposed.
|
||||
- Continue WebSocket migration planning.
|
||||
- Continue NAS Docker migration planning.
|
||||
|
||||
Reference in New Issue
Block a user