Files
Stock-trading-programming/CLAUDE.md
T

16 KiB
Raw Blame History

StockBot v3.0 - Claude Code 운영 가이드

최종 수정: 2026-06-04 인프라: 로컬 Windows → Synology NAS Docker 이전 예정
현재 모드: 모의투자 (KIS_MOCK=true, DRY_RUN=true)

Current safety policy

  • 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.

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.
  • 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:
    • 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.

Current operational risks - 2026-06-04

  • 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.

프로젝트 개요

항목 내용
목표 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
         결과 분석 + 리포트/제안서 저장

스케줄러 스크립트 주의사항 (scripts/run_*.ps1)

  • 경로: $PROJECT = Split-Path -Parent $PSScriptRoot (한글 경로 인코딩 문제 방지)
  • CLI 실행: scripts/stockbot_env.ps1Resolve-StockBotClaudeclaude.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

Claude Code 역할 상세

장 전 분석 — /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. python app/ai/midday.py --print  (오전 거래 결과 + 현재 시장 스냅샷 수집)
2. 오전 daily_context 예측 vs 실제 결과 비교 분석
3. 점심 세션 파라미터 결정 (진입 허용 여부, 포지션 배율, 섹터 업데이트)
4. data/midday_context.json 저장 → 봇이 즉시 감지해 점심 세션 시작
5. Discord로 장중 분석 전송

장 후 피드백 — /evening 슬래시 커맨드

1. python app/ai/evening.py --print  (오늘 매매 내역 조회)
2. 승률/손익/이상패턴 분석
3. app/config.py 파라미터 조정 (문제 명확할 때만)
4. reports/daily/날짜.md 저장
5. 실전 전환 조건 5가지 체크
6. Discord로 요약 전송

봇 시작 — /start-bot 슬래시 커맨드

1. python scripts/start_bot.py 실행
2. PID 파일 + 프로세스 스캔으로 기존 app/main.py 종료
3. app/main.py를 DETACHED_PROCESS로 백그라운드 시작
4. logs/bot.pid 저장 + Discord "[모의투자] 자동매매 봇 시작" 알림

Discord 알림 구조

채널 내용 발신
거래 알림 매수/매도/손절/결산 app/monitor/notifier.py
코드 변경 커밋 내용 + Push 완료 여부 .claude/discord_notify.py (Stop 훅, .codex/hooks.json에서도 호출)
  • 코드 변경 알림: 커밋이 있을 때만 발송 (스케줄러 태스크 등 노이즈 없음)
  • Discord 요청 시 반드시 User-Agent: DiscordBot (stockbot, 1.0) 헤더 포함 (Cloudflare 차단 방지)

파일 구조

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            ← 학습 파이프라인 로그

수정 범위

자유롭게 수정 가능

  • 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/ — 리포트 생성/저장

주의: 장후 자동 리뷰(/evening)에서는 파라미터를 직접 수정하지 않고 reports/proposals/YYYY-MM-DD_strategy_proposal.md에 제안서로 남긴다.

승인 필요 (사용자 확인 후 수정)

  • app/main.py — 구조 변경, 스케줄 변경
  • app/execution/ — 주문 로직 변경
  • app/db/ — 스키마 변경

절대 금지

  • FORCE_EXIT = "14:50" 변경
  • 손절을 익절보다 후순위로 변경
  • .env 파일 직접 수정 (KIS_MOCK, DRY_RUN 포함)
  • .env Git 커밋

Git 규칙

  • branch: master / remote: origin (Gitea NAS)
  • 파일 수정 후 자동으로 커밋 + git push origin master
  • 단, .env, 실행 중 생성 파일(logs/stockbot.lock, logs/bot.pid), 사용자가 수정 중인 데이터 파일은 커밋하지 않는다.
  • 커밋 메시지: [날짜] 변경내용 요약
  • .env는 절대 커밋 금지

리스크 관리 (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 pulldocker-compose up -d)