311 lines
12 KiB
Markdown
311 lines
12 KiB
Markdown
# 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
|
|
|
|
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` 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.
|
|
- SL cascade halt is active:
|
|
- `SL_CASCADE_HALT_THRESHOLD = 5`
|
|
- `SL_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.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`.
|
|
- 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.
|
|
- 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`.
|
|
- Runtime loader: `app/ml/predictor.py`.
|
|
- 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 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 `/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.
|
|
|
|
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`
|
|
|
|
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`.
|
|
|
|
### `/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
|
|
```
|
|
|
|
## Edit Boundaries
|
|
|
|
Freely editable when the task calls for it:
|
|
|
|
- `app/config.py`
|
|
- `app/strategy/volatility_breakout.py`
|
|
- `app/risk/manager.py`
|
|
- `reports/`
|
|
- 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: `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
|
|
|
|
| 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 `/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.
|