12 KiB
12 KiB
StockBot v3.0 - Claude Code Operating Guide
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)
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.
Agent Role
- 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.
Solo Workflow
- Analyze the request and classify scope: small, medium, or large.
- Write an explicit plan before implementation.
- Implement one file at a time and keep the scope tight.
- Run focused verification.
- Perform the veteran self-review below.
- If the score is below 90, fix the highest-leverage issues and review again.
Use this exact self-review format:
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/, orapp/risk/. Write proposal reports instead. - Strategy parameter changes must be written to
reports/proposals/YYYY-MM-DD_strategy_proposal.mdwith 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 = 90FORCE_EXIT = "14:50"unchanged
avoid_sectorsfiltering is active at runtime.main.pypasses sector context intocheck_entry().- Sector handling keeps a
ticker_sectorscache and uses name-based hints for known avoid-sector cases. - Re-entry controls are active:
TIMEandFORCEcooldown is based on final exit time, not entry time.- Final
TP1/TP2exits block same-day re-entry for that ticker. - Re-entry control state is restored from today's DB rows after restart.
- SL cascade halt is active:
SL_CASCADE_HALT_THRESHOLD = 5SL_CASCADE_WINDOW_MIN = 60- New entries stop when the threshold is reached; existing positions keep normal exit handling.
- Duplicate bot execution guards are active:
app/main.pyusesSingleInstanceLockonlogs/stockbot.lock.scripts/start_bot.pystops the PID-file process and scans for existingapp/main.pyprocesses before starting one new bot.scripts/run_morning.ps1is the only owner of post-morning bot startup..claude/commands/morning.mdmust not call/start-botorscripts/start_bot.py.
- KIS stability hardening is active:
- 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.
- Mode-specific request spacing in
- Daily summary has a duplicate guard; Discord settlement-send failures are logged without crashing settlement.
- Data layer:
entry_snapshotsare active.post_entry_snapshotssample 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. - Runtime loader:
app/ml/predictor.py. - Latest successful training run: 2026-06-02 18:36.
- Latest rows: 5,773 total (
external_training_dataset.csv5,720 + bot dataset 53). - Latest metrics:
label_stop_lossROC-AUC 0.896,label_winROC-AUC 0.715.
- Daily features:
- Latest daily review/proposal files exist through 2026-06-02.
- 2026-06-03 was skipped as a market holiday.
Current Risks
- 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 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
/morninginstruction fix. The next scheduled morning run should be checked for exactly one context generation and onestart_bot.pystartup. - 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
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.
08:30 Bot loads daily_context.json and builds the watch universe.
08:50 Bot calculates volatility breakout targets. If restarted after 08:50,
the bot recalculates targets immediately; open=0 is ignored.
09:00 Morning trading session starts.
09:00-15:05 StockBot_Watchdog checks bot liveness every 5 minutes.
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.
Watchdog must not restart the bot at or after 15:10.
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
Slash Command Responsibilities
/morning
- Run
python app/ai/morning.py --print. - Analyze collected news, KIS flow, sectors, and ticker-specific news.
- Write
data/daily_context.json. - Send the morning Discord summary.
- Do not start the bot. Startup belongs only to
scripts/run_morning.ps1.
/midday
- Run
python app/ai/midday.py --print. - Compare morning context with actual morning trades and market snapshot.
- Write
data/midday_context.json. - Send the midday Discord summary.
/evening
- Run
python app/ai/evening.py --print. - Review trades, win rate, PnL, fees, exit distribution, overtrading, AI filter quality, and execution quality.
- Write
reports/daily/YYYY-MM-DD.md. - If a strategy change is justified, write
reports/proposals/YYYY-MM-DD_strategy_proposal.md. - Do not directly edit runtime strategy/config/risk/execution code during evening review.
- Check live-readiness criteria.
- Send a concise Discord summary.
/start-bot
- Run
python scripts/start_bot.py. - The script stops existing PID-file and scanned
app/main.pyprocesses. - It starts exactly one detached
app/main.pyprocess. - It writes
logs/bot.pidand sends the Discord start notification.
Important Files
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
Edit Boundaries
Freely editable when the task calls for it:
app/config.pyapp/strategy/volatility_breakout.pyapp/risk/manager.pyreports/- Documentation files
Requires explicit user approval:
- Structural changes to
app/main.py app/execution/app/db/- Database schema changes
- Real-cash trading behavior
Never edit or commit:
.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
Git Rules
- Branch:
master. - Remote:
originon the NAS Gitea server. - After file edits, commit and push to
origin masterwithout 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
| 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 |
L3-B sizing:
| Consecutive stop-loss count | Position multiplier |
|---|---|
| 0 | 1.0x |
| 1 | 0.7x |
| 2 | 0.5x |
| 3+ | 0.3x |
Live-Cash Readiness
All conditions must pass before real-cash mode:
- 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.
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
- Verify the next morning run has exactly one
/morningcontext generation and onescripts/start_bot.pystartup. - 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.