Skip to content

easygap/quant_trader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

966 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

QUANT TRADER

Python Market Mode Focus

๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŠธ๋ ˆ์ด๋”ฉ์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋งŒ๋“  Python ์ž๋™๋งค๋งค ์‹คํ—˜์‹ค์ž…๋‹ˆ๋‹ค. ์ง€ํ‘œยทํŽ€๋”๋ฉ˜ํ„ธ ๊ธฐ๋ฐ˜ ์‹ ํ˜ธ ์ƒ์„ฑ๋ถ€ํ„ฐ ๋ฐฑํ…Œ์ŠคํŠธ, ๋ชจ์˜ํˆฌ์ž, ๋ฆฌ์Šคํฌ ๊ด€๋ฆฌ, ์šด์˜ ๋Œ€์‹œ๋ณด๋“œ, KIS API ์—ฐ๋™๊นŒ์ง€ ํ•œ ์ €์žฅ์†Œ์—์„œ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ๋Š” ํ•™์Šตยท์—ฐ๊ตฌ์šฉ์ž…๋‹ˆ๋‹ค. ํˆฌ์ž ์กฐ์–ธ์ด ์•„๋‹ˆ๋ฉฐ, ์‹ค์ „ ์ฃผ๋ฌธ ๊ฒฝ๋กœ๋Š” ์—ฌ๋Ÿฌ fail-closed gate๋ฅผ ํ†ต๊ณผํ•ด์•ผ๋งŒ ์—ด๋ฆฌ๋„๋ก ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค.

Why This Repo Exists

์ž๋™๋งค๋งค ํ”„๋กœ์ ํŠธ๋Š” "์ˆ˜์ต๋ฅ  ๊ทธ๋ž˜ํ”„"๋ณด๋‹ค ์šด์˜ ์•ˆ์ „์„ฑ์ด ๋จผ์ €๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. quant_trader๋Š” ์ „๋žต์„ ๋ฐ”๋กœ ์‹ค๊ณ„์ขŒ๋กœ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์•„๋ž˜ ํ๋ฆ„์„ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.

  1. ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘๊ณผ ์ง€ํ‘œ ๊ณ„์‚ฐ
  2. ๋น„์šฉยท์Šฌ๋ฆฌํ”ผ์ง€ยทlook-ahead guard๊ฐ€ ๋“ค์–ด๊ฐ„ ๋ฐฑํ…Œ์ŠคํŠธ
  3. paper evidence์™€ runtime health ์ถ•์ 
  4. promotion gate ๊ฒ€์ฆ
  5. live ์‹œ์ž‘ ์ „ KIS ์—ฐ๊ฒฐ, ์ž”๊ณ  ๋™๊ธฐํ™”, current blockers ์žฌํ™•์ธ

Highlights

  • ํ•œ๊ตญ ์ฃผ์‹ ์ค‘์‹ฌ ๋ฐฑํ…Œ์ŠคํŠธ, ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ, ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ
  • scoring, mean reversion, trend following, fundamental factor, relative strength rotation ์ „๋žต
  • paper trading runtime state machine๊ณผ 60์˜์—…์ผ evidence ๊ธฐ๋ฐ˜ promotion workflow
  • KIS REST/WebSocket ์—ฐ๋™, ์ฃผ๋ฌธ ์ค‘๋ณต ๋ฐฉ์ง€, ๋ฏธ์ฒด๊ฒฐ reconcile, emergency liquidation guard
  • Discord ์•Œ๋ฆผ, SQLite ๋ฐฑ์—…, web dashboard, operator health check
  • pytest ๊ธฐ๋ฐ˜ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ์™€ ๋‹ค์–‘ํ•œ research sweep ๋„๊ตฌ

Quick Start

python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt

# ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‹คํ–‰ ๋ชจ๋“œ ๋ณด๊ธฐ
python main.py --mode guide

# ๋‹จ์ผ ์ข…๋ชฉ ๋ฐฑํ…Œ์ŠคํŠธ
python main.py --mode backtest --strategy scoring --symbol 005930

# ์šด์˜ ํ—ฌ์Šค ์ ๊ฒ€
python main.py --mode health

# ํ…Œ์ŠคํŠธ
pytest tests/ -q

Good First Reads

๋ฌธ์„œ ๋‚ด์šฉ
docs/PROFITABILITY_FINDINGS.md ์ˆ˜์ต์„ฑ ์ •์ง ์ ๊ฒ€๊ณผ ํ˜„์žฌ ๊ฒฐ๋ก 
docs/BASKET_PAPER_EVALUATION.md ๋ฐ”์Šค์ผ“ paperโ†’live ์Šน๊ฒฉ ๊ธฐ์ค€
docs/BASKET_LIVE_RUNBOOK.md ๋ฐ”์Šค์ผ“ live ์ „ํ™˜ ์ ˆ์ฐจ
docs/PROJECT_GUIDE.md ํŒŒ์ผ ๊ตฌ์กฐ์™€ ์‹คํ–‰ ํ๋ฆ„
quant_trader_design.md ์•„ํ‚คํ…์ฒ˜์™€ ์ „๋žต ์„ค๊ณ„

English Summary

quant_trader is a Python research project for risk-first algorithmic trading on Korean equities. It includes backtesting, paper trading, strategy validation, KIS API integration, portfolio rebalancing, operational health checks, and live-trading gates that fail closed unless the evidence package is current and consistent.

ํ˜„์žฌ ์ƒํƒœ (2026-06-10):

  • ๋ฐ”์Šค์ผ“ paper ์šด์˜ ๊ฐœ์‹œ: kr_diversified_hold(๋ถ„์‚ฐ ๋Œ€ํ˜•์ฃผ buy&hold, ์ฃผ์‹ 80%/ํ˜„๊ธˆ 20%) enabled โ€” ์ผ์ผ ์ž๋™ ์‚ฌ์ดํด(๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ โ†’ NAV ์Šค๋ƒ…์ƒท โ†’ DB ๋ฐฑ์—… โ†’ ์Šน๊ฒฉ ์ง„ํ–‰๋ฅ  ๋ณด๊ณ )๋กœ 60์˜์—…์ผ ํŠธ๋ž™๋ ˆ์ฝ”๋“œ ์ถ•์  ์ค‘. --mode health๊ฐ€ ์‚ฌ์ดํด ๋Š๊น€(์Šค๋ƒ…์ƒท 4์ผ+)์„ ์ž๋™ ๊ฒฝ๊ณ 
  • paperโ†’live ์Šน๊ฒฉ ๊ธฐ์ค€ ์ •์˜(docs/BASKET_PAPER_EVALUATION.md): 60์˜์—…์ผยท์Šค๋ƒ…์ƒท ์ปค๋ฒ„๋ฆฌ์ง€ โ‰ฅ95%ยทdead-letter 0๊ฑดยท๋น„์šฉ ๋“œ๋ž˜๊ทธ โ‰ค1%/๋…„. ๋ฒ ํƒ€ ์ „๋žต์ด๋ฏ€๋กœ "์‹œ์žฅ ์ดˆ๊ณผ์ˆ˜์ต"์€ ๊ธฐ์ค€์ด ์•„๋‹˜. tools/basket_paper_evaluation.py๋กœ ์ž๋™ ํŒ์ •(WAIT/PASS_CANDIDATE/FAIL_REVIEW)
  • ๋ฐ”์Šค์ผ“ ์ „์šฉ live gate ๋ถ„๊ธฐ: ๊ธฐ์กด ๊ฒŒ์ดํŠธ๊ฐ€ ๋ฐ”์Šค์ผ“์— ์‹ ํ˜ธ ์ „๋žต์šฉ canonical promotion(๋ฒค์น˜๋งˆํฌ ์ดˆ๊ณผ์ˆ˜์ต ํฌํ•จ)์„ ์š”๊ตฌํ•ด ์˜๊ตฌ ํ†ต๊ณผ ๋ถˆ๊ฐ€์˜€๋˜ ํ•จ์ • ํ•ด์†Œ โ€” paper ํ‰๊ฐ€ PASS_CANDIDATE ๊ธฐ๋ฐ˜์œผ๋กœ ์‹ค์ œ๋กœ ์—ด๋ฆฌ๋Š” ๊ฒฝ๋กœ ํ™•๋ฆฝ. ์ „ํ™˜ ์ ˆ์ฐจ๋Š” docs/BASKET_LIVE_RUNBOOK.md(๋ชจ์˜์„œ๋ฒ„ ๋ฆฌํ—ˆ์„ค โ†’ ์‹ค๊ณ„์ขŒ ์†Œ์•ก โ†’ ๋ชฉํ‘œ ์ž๋ณธ)
  • live ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์‹คํ–‰ ๊ฐ€๋Šฅํ™”: BUY๊ฐ€ "paper-only" ์ฐจ๋‹จ์œผ๋กœ ํ•ญ์ƒ ์‹คํŒจํ•ด SELL-only ํ˜„๊ธˆํ™”๊ฐ€ ๋˜๋˜ ๋ฒ„๊ทธ ์ˆ˜์ •(์ผ๋ฐ˜ ๋งค์ˆ˜์™€ ๋™์ผํ•œ ์ง‘ํ–‰ ์•ˆ์ „์žฅ์น˜ + live gate ๊ฒ€์‚ฌ ์Šน๊ณ„), ํšŒ์ „์œจ ์˜ˆ์‚ฐ SELL ์šฐ์„ ยท๋ถ€๋ถ„ ์‹คํ–‰, KIS ์ž”๊ณ  ๋ฏธํ™•์ธ ์‹œ ์‚ฌ์ด์ง• fail-closed
  • ์ฃผ๋ฌธ ์‘๋‹ต ์œ ์‹ค ์‹œ ์žฌ์‹œ๋„ ๋ž˜ํผ๊ฐ€ ์žฌ์ „์†กํ•˜๋˜ ์ž”์—ฌ ๊ตฌ๋ฉ ํ์‡„(KISOrderResponseUnknown โ†’ reconcile ๋Œ€๊ธฐ), ์†์ ˆ๊ฐ€ ํ•˜ํ•œ ํด๋žจํ”„, ํžˆ์Šคํ„ฐ๋ฆฌ์‹œ์Šค SELL ํ•ด์ œ ๋ถ€ํ˜ธ ์ˆ˜์ •, ๋‚ด์žฅ ์ง€ํ‘œ ํด๋ฐฑ pandas-ta ํŒจ๋ฆฌํ‹ฐ(RSI ~12pt ์˜ค์ฐจ ์ •์ •)
  • ํŠธ๋ž™๋ ˆ์ฝ”๋“œ ๋„๊ตฌ๊ฐ€ ํ˜„๊ธˆ ๋ฐฐ๋ถ„(target_stock_weightยทmin_cash_ratio)์„ ๋ฌด์‹œํ•ด ์ˆ˜์ตยทMDD๋ฅผ ๊ณผ๋Œ€ ๋ณด๊ณ ํ•˜๋˜ ๋ฌธ์ œ ์ •์ • โ€” ๋ฐฐํฌ ๋ฐ”์Šค์ผ“ ์ •์ง ์ˆ˜์น˜(2021-12~2026-06): CAGR +26.9%, Sharpe 1.09, MDD โˆ’21.4%
  • ์ธ์ž ์—†์ด ์‹คํ–‰ ์‹œ ๋ฐฑํ…Œ์ŠคํŠธ ์ž๋™์‹คํ–‰ ๋Œ€์‹  ์‚ฌ์šฉ ๊ฐ€์ด๋“œ ์ถœ๋ ฅ(--mode guide), ์šด์˜ ๋ฌธ์„œ v6.1 ๊ฐฑ์‹ 

์ด์ „ ์ƒํƒœ (2026-06-01):

  • ์ ๋Œ€์  ์ฝ”๋“œ ๊ฐ์‚ฌ๋กœ ์‹ค๊ฑฐ๋ž˜ ์•ˆ์ „ ๋ฒ„๊ทธ ์ •๋ฆฌ: KIS ์ฃผ๋ฌธ์ด ์‘๋‹ต ์œ ์‹ค ์‹œ ์žฌ์ „์†ก๋ผ ์ด์ค‘ ์ฒด๊ฒฐ๋˜๋˜ ๊ฒฝ๋กœ๋ฅผ idempotent=False๋กœ ์ฐจ๋‹จ(์ตœ๋Œ€ 1ํšŒ ์ œ์ถœ), ์„œํ‚ท ๋ธŒ๋ ˆ์ด์ปค ์žฌ์‹œ๋„ ๋ฃจํ”„ ๋‚ด ์žฌํ™•์ธ, 429 Retry-After HTTP-date ํฌ๋ž˜์‹œ ๊ฐ€๋“œ
  • ๋ถ€๋ถ„ ์ต์ ˆ์ด ๋งค ๋ชจ๋‹ˆํ„ฐ๋ง ์‚ฌ์ดํด๋งˆ๋‹ค ์žฌ๋ฐœ๋™๋˜๋˜ ๋ฒ„๊ทธ ์ˆ˜์ •(Position.partial_tp_done ์˜์†ํ™”), ์Šค์ผ€์ค„๋Ÿฌ ์ง„์ž… ์˜ˆ์™ธ ์‹œ ์†์ ˆ/์ต์ ˆ ์Šคํ‚ต ๋ฐฉ์ง€, ์ผ์ผ ์†์‹ค ํ•œ๋„ ๊ธฐ์ค€๊ฐ’์— ๋‹น์ผ ์Šค๋ƒ…์ƒท ์‚ฌ์šฉ ์ฐจ๋‹จ
  • ๋ผ์ด๋ธŒ ๊ฒŒ์ดํŠธ fail-closed ๋ณด๊ฐ•: NaN/Inf ์ง€ํ‘œ๊ฐ€ ์ž„๊ณ„๊ฐ’ ๋น„๊ต๋ฅผ ํ†ต๊ณผํ•˜๋˜ ๊ตฌ๋ฉ์„ ๋ง‰์•„(_as_float ๋น„์œ ํ•œ๊ฐ’ โ†’ None) ์†์ƒ๋œ ์ง€ํ‘œ๋กœ ๋ผ์ด๋ธŒ ์Šน๊ฒฉ๋˜๋Š” ๊ฒƒ์„ ์ฐจ๋‹จ
  • ์ˆ˜์ต์„ฑ ๊ฒ€์ฆ ์ •์งํ™”: canonical ์œ ๋‹ˆ๋ฒ„์Šค ์ƒ์กด์ž ํŽธํ–ฅ ์ฐจ๋‹จ + Deflated/Probabilistic Sharpe + ์ง„์งœ OOS holdout(--oos-holdout-split)๋กœ ๋‹ค์ค‘๊ฒ€์ •ยท์„ ํƒ ๊ณผ์ ํ•ฉ ๋…ธ์ถœ
  • ์ง€ํ‘œ ์—”์ง„ ADX +DI/-DI ๋งคํ•‘ ์˜ค๋ฅ˜, ๋ฐฑํ…Œ์ŠคํŠธ gross_return ๋น„์šฉ ํ™˜์› ์˜ค๋ฅ˜, ๊ฑฐ๋ž˜๋Ÿ‰๋น„์œจ inf ๊ฐ€๋“œ ์ˆ˜์ •

์ด์ „ ์ƒํƒœ (2026-05-14):

  • GitHub ์›๊ฒฉ ๋ธŒ๋žœ์น˜ ์ •๋ฆฌ ์™„๋ฃŒ: ์™„๋ฃŒ ๋ธŒ๋žœ์น˜ ์‚ญ์ œ, ํ™œ์„ฑ PR ๋ธŒ๋žœ์น˜๋งŒ ์œ ์ง€
  • 60์˜์—…์ผ Paper ์‹คํ—˜ freeze pack ๋ณ‘ํ•ฉ: reports/experiment_freeze_pack.md, ์ผ/์ฃผ๊ฐ„ ops checklist, stop condition ๋ฌธ์„œ ์ถ”๊ฐ€
  • Paper Evidence ๋Ÿฐํƒ€์ž„: v2 ์ผ๋ณ„ ์ž๋™ ์ˆ˜์ง‘ โ†’ benchmark finalization โ†’ ๋‚ ์งœ์ˆœ canonical evidence โ†’ promotion package โ†’ launch readiness
  • Paper Runtime State Machine: normal/degraded/frozen/blocked_insufficient_evidence ์ƒํƒœ ์ž๋™ ์ „ํ™˜ + allowed_actions ์ œ์–ด
  • Paper ์šด์˜ CLI๋Š” pilot ์ œ์–ด/๋Ÿฐํƒ€์ž„ ์ƒํƒœ ์•ก์…˜ ์˜ต์…˜์„ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜๋งŒ ๋ฐ›๋„๋ก ์ •๋ฆฌ๋˜์–ด, ์ƒ์ถฉ ์•ก์…˜ ๋™์‹œ ์ง€์ • ์‹œ ์ƒํƒœ ๋ณ€๊ฒฝ ์ „์— fail-closed๋กœ ์ข…๋ฃŒ
  • Paper Pilot Authorization: blocked ์ƒํƒœ์—์„œ๋„ ์ œํ•œ์  real paper ๊ฐ€๋Šฅ (์ˆ˜๋™ ์Šน์ธ + ๋ฆฌ์Šคํฌ ์บก + fail-closed/audited entry guard)
  • Paper ์‹ ๊ทœ ์ง„์ž… ์‹คํ–‰ ๊ฒฝ๊ณ„ fail-closed: preflight ์ƒํƒœ ๋ˆ„๋ฝ/์†์ƒ ๋˜๋Š” runtime ์กฐํšŒ ์‹คํŒจ ์‹œ BUY ์ œ์ถœ ์ „ ์ฐจ๋‹จ, SELL ์ฒญ์‚ฐ์€ ์œ ์ง€
  • Paper ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ BUY ์‹คํ–‰์€ ์‹ค์ œ ์กด์žฌํ•˜๋Š” ํฌํŠธํด๋ฆฌ์˜ค ์ž๋ณธ/ํ˜„๊ธˆ ์กฐํšŒ API๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ณ ์ •๋˜์–ด ์ฃผ๋ฌธ ์‹คํ–‰ ์ „ ๋‹จ๊ณ„ ์˜ค๋ฅ˜๋ฅผ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋กœ ์ฐจ๋‹จ
  • --mode paper ๋‹จ๋ฐœ ์‹คํ–‰์€ ์„ค์ • ํŒŒ์ผ์˜ trading.mode=live๊ฐ€ ๋‚จ์•„ ์žˆ์–ด๋„ ํ•ด๋‹น ์‹คํ–‰์„ paper๋กœ ๊ณ ์ •ํ•ด ์‹ค์ฃผ๋ฌธ ๊ฒฝ๋กœ ์ง„์ž…์„ ์ฐจ๋‹จ
  • ์žฅ์ค‘ auto-entry ํ›„๋ณด๋Š” ์ฃผ๋ฌธ ์ง์ „ ํ˜„์žฌ ๋ฐ์ดํ„ฐ๋กœ BUY ์‹œ๊ทธ๋„์„ ์žฌ๊ฒ€์ฆํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ/API/์ „๋žต ๊ณ„์‚ฐ ์˜ค๋ฅ˜๋กœ ์žฌ๊ฒ€์ฆ์— ์‹คํŒจํ•˜๋ฉด ํ•ด๋‹น ๋ฃจํ”„ ์ฃผ๋ฌธ์„ ๋ณด๋ฅ˜ํ•˜๊ณ  ํ›„๋ณด๋ฅผ ๋‹ค์Œ ๋ฃจํ”„๋กœ ๋„˜๊น€
  • QUANT_AUTO_ENTRY ํ•ด์„ ๋‹จ์ผํ™”: YAML hash์™€ resolved hash๋ฅผ ๋ถ„๋ฆฌํ•ด ์‹คํ—˜ ์„ค์ • drift ๊ฐ์ง€
  • Research sweep: ๊ธฐ์กด top-20 all-family ํ›„๋ณด ์žฌ๊ฒ€์ฆ๋„ NO_ALPHA_CANDIDATE; pullback, benchmark-relative momentum, risk-budget, cash-switch, benchmark-aware rotation, target-weight top-N rotation/score-floor ํ›„๋ณด๊ตฐ๊ณผ exposure-matched benchmark ์ง„๋‹จ์„ research-only๋กœ ์ถ”๊ฐ€
  • target-weight ๋ฆฌ์Šคํฌ ์™„ํ™” top-200 sweep: ์ตœ์ƒ์œ„ tolerance ํ›„๋ณด๋„ ์ˆ˜์ต/์ดˆ๊ณผ์ˆ˜์ต์€ ๊ฐœ์„ ๋์ง€๋งŒ MDDยทํšŒ์ „์œจ ๊ฒŒ์ดํŠธ ๋ฏธํ†ต๊ณผ๋กœ ์ „ ํ›„๋ณด paper_only
  • target-weight ์ €ํšŒ์ „ top-200 sweep: ๊ฒฉ์›”/๋ถ„๊ธฐ ํ›„๋ณด๊ฐ€ ํšŒ์ „์œจ์€ ๋‚ฎ์ท„์ง€๋งŒ benchmark excess Sharpe์™€ MDD ๊ฒŒ์ดํŠธ ๋ฏธํ†ต๊ณผ๋กœ NO_ALPHA_CANDIDATE
  • target-weight ๋ณ€๋™์„ฑ ํƒ€๊นƒ top-200 sweep: ์ตœ์ƒ์œ„ ํ›„๋ณด๋Š” ์ดˆ๊ณผ์ˆ˜์ต์ด ์–‘์ˆ˜์˜€์ง€๋งŒ ์ „ ํ›„๋ณด๊ฐ€ MDD ๊ฒŒ์ดํŠธ ๋ฏธํ†ต๊ณผ๋กœ KEEP_RESEARCH_ONLY
  • target-weight ๋ฆฌ์Šคํฌ ํŽ˜๋„ํ‹ฐ ๋žญํ‚น top-200 sweep: ์ˆ˜์ตยท์ดˆ๊ณผ์ˆ˜์ต์€ ๊ฐœ์„ ๋์ง€๋งŒ MDDยทํšŒ์ „์œจ ๊ฒŒ์ดํŠธ ๋ฏธํ†ต๊ณผ๋กœ KEEP_RESEARCH_ONLY
  • target-weight ์†์‹ค๋ฐฉ์–ด top-200 sweep: pdd8/floor25/cooldown1 ํ›„๋ณด๊ฐ€ MDD -19.56%, turnover/year 296.4%๋กœ ๊ฐœ์„ ๋˜์–ด research sweep ๊ธฐ์ค€ RUN_CANONICAL_EVALUATION
  • target-weight ์†์‹ค๋ฐฉ์–ด canonical ํ‰๊ฐ€: pdd8 ํ›„๋ณด๋Š” benchmark excess -6.46%p, exp75 ์›๋ณธ/tol3 ํ›„๋ณด๋Š” turnover/year 1026.3%/1009.0%, exp75 tol4 ํ›„๋ณด๋Š” turnover/year 986.5%๋กœ ํšŒ์ „์œจ์€ ํ†ต๊ณผํ–ˆ์ง€๋งŒ MDD -20.25%๋ผ ๋ชจ๋‘ paper_only; tol4 guard-only, rank-risk ๊ฐ•ํ™”, sector cap 2, corrcap85, corrpen ํ›„๋ณด๋„ canonical ์‹ ๊ทœ ์Šน๊ฒฉ ์—†์Œ. ์†์‹ค ํ›„ ์žฌ์ง„์ž… ์ œํ•œ ํ›„๋ณด๋Š” top-200์—์„œ MDD ์•…ํ™”๋กœ canonical ์ œ์™ธ. ๊ธฐ์กด risk-overlay ํ›„๋ณด๋งŒ provisional ์œ ์ง€
  • target-weight ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐ canonical ํ‰๊ฐ€: top-200์—์„œ๋Š” ํ›„๋ณด 2๊ฐœ๊ฐ€ ํ†ต๊ณผํ–ˆ์ง€๋งŒ canonical top-20์—์„œ๋Š” MDD -20.82%/-20.89%๋กœ paper_only; ์ดˆ๊ณผ์ˆ˜์ตยทํšŒ์ „์œจ์€ ๊ฐœ์„ ๋์œผ๋‚˜ live/paper ์‹ ๊ทœ ์ „ํ™˜์€ ๊ธˆ์ง€
  • target-weight ํฌ์ง€์…˜ ์†์‹ค ๊ฐ์‚ฐ canonical ํ‰๊ฐ€: tol5+sectorcap2+posloss8 ํ›„๋ณด๊ฐ€ return +198.15%, MDD -17.18%, turnover/year 993.9%๋กœ ์‹ ๊ทœ provisional_paper_candidate; pilot plan์€ rank penalty/sector cap/ํฌ์ง€์…˜ ์†์‹ค ๊ฐ์‚ฐ๊ณผ paper evidence ๊ธฐ๋ฐ˜ portfolio drawdown guard ์ƒํƒœ๋ฅผ ์žฌํ˜„ํ•˜๋ฉฐ, ๋ช…์‹œ ์ƒํƒœ๊ฐ€ ์—†์œผ๋ฉด fail-closed ์ฐจ๋‹จ
  • scoring: paper_only (๊ด€์ฐฐ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ Sharpe/PF/WF ์•ˆ์ •์„ฑ ๋ฏธ๋‹ฌ)
  • rotation: provisional_paper_candidate (risk-adjusted ๊ธฐ์ค€ ํ†ต๊ณผ, live alpha๋Š” ๋ฏธํ™•์ธ)
  • target-weight risk overlay ํ›„๋ณด: canonical bundle ๊ธฐ์ค€ provisional_paper_candidate + ์ „์šฉ paper/pilot adapter/shadow proof, ์œ ๋™์„ฑ/๋น„์šฉ pre-trade/pilot ์Šน์ธ/์‹คํ–‰์ผ/์žฅ ์‹œ๊ฐ„/๊ฐ€๊ฒฉ ์ตœ์‹ ์„ฑ guard ์ถ”๊ฐ€. ๋ฆฌ์„œ์น˜ ๋ฐฑํ…Œ์ŠคํŠธ๋Š” ์ง์ „ ๊ฑฐ๋ž˜์ผ ์ ์ˆ˜ โ†’ ๋‹ค์Œ ๊ฑฐ๋ž˜์ผ ์‹œ๊ฐ€ ์ฒด๊ฒฐ โ†’ ์ข…๊ฐ€ ํ‰๊ฐ€ ๊ธฐ์ค€์œผ๋กœ ๋ณด์ˆ˜ํ™”ํ–ˆ์œผ๋ฉฐ, ๊ธฐ์กด target-weight research artifact๋Š” execution price mode ํ™•์ธ ๋˜๋Š” ์žฌ์ƒ์„ฑ ํ›„ ์‚ฌ์šฉ (live ๋ฏธ์—ฐ๊ฒฐ)
  • target-weight capped pilot readiness: audit ์‹œ์ž‘ ์‹œ paper preflight๋ฅผ ๋จผ์ € ๊ฐฑ์‹ ํ•˜๊ณ , Discord webhook ๋ˆ„๋ฝ ๋˜๋Š” notifier ๋น„์ •์ƒ ์ƒํƒœ๋Š” ์ฃผ๋ฌธ ์ „ BLOCKED๋กœ ํ™•์ •
  • live ๋ณด๋ฅ˜ ์ฃผ๋ฌธ ๋ณต๊ตฌ๋Š” KIS ๋ฏธ์ฒด๊ฒฐ ๋ชฉ๋ก์—์„œ ์‚ฌ๋ผ์ง„ ์ฃผ๋ฌธ๋„ ์ฒด๊ฒฐ ์ƒ์„ธ๊ฐ€ ํ™•์ธ๋  ๋•Œ๋งŒ RECONCILED๋กœ ๋‹ซ๊ณ , ์กฐํšŒ ์‹คํŒจ/๋ถˆ๋ช…ํ™• ์ƒํƒœ๋Š” ์—ด๋ฆฐ ์ฃผ๋ฌธ๊ณผ ์ค‘๋ณต ์ฐจ๋‹จ์„ ์œ ์ง€
  • live ์ฒด๊ฒฐ ์กฐํšŒ๋Š” ์ฃผ๋ฌธ๋ฒˆํ˜ธ๊ฐ€ ํ˜„์žฌ ์ฃผ๋ฌธ๊ณผ ์ผ์น˜ํ•˜๋Š” ์ฒด๊ฒฐ row๋งŒ ํ™•์ • ์ฒด๊ฒฐ๋กœ ์ธ์ •
  • KIS Circuit Breaker๋Š” ์žฅ์•  ํ›„ HALF_OPEN ๋ณต๊ตฌ ์ƒํƒœ์—์„œ ๋‹จ์ผ probe๋งŒ ํ—ˆ์šฉํ•˜๊ณ  ๊ฒฐ๊ณผ ํ™•์ธ ์ „ ์ถ”๊ฐ€ ์š”์ฒญ์„ ์ฐจ๋‹จ
  • ์‹ ๊ทœ BUY ์ฃผ๋ฌธ ์ง์ „ ์œ ๋™์„ฑ ์žฌ๊ฒ€์ฆ์€ ํ‰๊ท  ๊ฑฐ๋ž˜๋Ÿ‰ ๋ˆ„๋ฝ/0๋„ fail-closed๋กœ ์ฐจ๋‹จํ•ด ์†Œํ˜•์ฃผยท๋ฐ์ดํ„ฐ ๊ณต๋ฐฑ ์ฃผ๋ฌธ์„ ๋ง‰์Œ
  • ์‹œ์žฅ ๊ตญ๋ฉด ํ•„ํ„ฐ๊ฐ€ ์ผœ์ ธ ์žˆ๋Š”๋ฐ ์ง€์ˆ˜ ๋ฐ์ดํ„ฐ ์กฐํšŒยทMA ๊ณ„์‚ฐ์ด ๋ถˆ๋ช…ํ™•ํ•˜๋ฉด unknown ๊ตญ๋ฉด์œผ๋กœ ์‹ ๊ทœ BUY๋ฅผ ์ฐจ๋‹จ
  • ๊ฐญ์—… ์ถ”๊ฒฉ๋งค์ˆ˜ ๋ฐฉ์ง€ ๊ฐ€๋“œ๋Š” ์ตœ๊ทผ ๊ฐ€๊ฒฉ ์กฐํšŒ ์‹คํŒจยท๋ฐ์ดํ„ฐ ๋ถ€์กฑ๋„ ์‹ ๊ทœ BUY ์ฐจ๋‹จ์œผ๋กœ ์ฒ˜๋ฆฌ
  • ์ƒ๊ด€๊ด€๊ณ„ ๋ฆฌ์Šคํฌ ํ™•์ธ์€ ๊ฐ€๊ฒฉ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹คํŒจยท๋ถ€์กฑ ์‹œ ์‹ ๊ทœ BUY๋ฅผ ์ฐจ๋‹จ
  • ์—…์ข… ๋น„์ค‘ cap์€ ์„นํ„ฐ ๋งต ์กฐํšŒ ์‹คํŒจยท๋งคํ•‘ ๋ˆ„๋ฝ ์‹œ ์‹ ๊ทœ BUY๋ฅผ ์ฐจ๋‹จ
  • ์ฃผ๋ฌธ/exit ํŒ๋‹จ ๊ฐ€๊ฒฉ์ด 0ยทNaNยท๋ˆ„๋ฝ์ด๋ฉด BUY/SELL ์ œ์ถœ๊ณผ ์†์ ˆ/์ต์ ˆ/๋ธ”๋ž™์Šค์™„ ํŒ๋‹จ์„ ๋ณด๋ฅ˜ํ•˜๊ณ  ์ฐจ๋‹จ ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋ก
  • live ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์ฃผ๋ฌธ์€ CLI์™€ ์Šค์ผ€์ค„๋Ÿฌ ์ž๋™ ์ฒดํฌ ๋ชจ๋‘ ๋ฐ”์Šค์ผ“๋ณ„ basket_rebalance:<basket> canonical live gate/account/order tag ์ผ์น˜ ์—†์ด๋Š” ์‹คํ–‰ ์ฐจ๋‹จ
  • manual paper evidence single-day/backfill/finalize๋Š” backfill provenance๋กœ ๊ธฐ๋ก๋˜์–ด ์Šน๊ฒฉ ์ฆ๊ฑฐ์—์„œ ์ œ์™ธ
  • shadow bootstrap collect/finalize๋Š” shadow_bootstrap provenance๋กœ ๊ธฐ๋ก๋˜์–ด ์ฃผ๋ฌธ ๊ธฐ๋ฐ˜ ์Šน๊ฒฉ ์ฆ๊ฑฐ์™€ ๋ถ„๋ฆฌ
  • live candidate: ์—†์Œ. --force-live ์ œ๊ฑฐ, hard gate ์šฐํšŒ ๋ถˆ๊ฐ€

์ฃผ์š” ๊ธฐ๋Šฅ

  • ๋ฐฑํ…Œ์ŠคํŠธ / ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ / ๋ฉ€ํ‹ฐ์ „๋žต sleeve ๋น„๊ต
  • ๋ชจ์˜ํˆฌ์ž / ์‹ค์ „ ๋งค๋งค
  • ์ „๋žต ๊ฒ€์ฆ / ์„ฑ๊ณผ ๋น„๊ต / ํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™”
  • ์Šค์ฝ”์–ด๋ง / ํ‰๊ท ํšŒ๊ท€ / ์ถ”์„ธ์ถ”์ข… / ํŽ€๋”๋ฉ˜ํ„ธ / ์•™์ƒ๋ธ” ์ „๋žต
  • ๊ฑฐ๋ž˜๋Ÿ‰ ๋ŒํŒŒ(C-4) / ์ƒ๋Œ€๊ฐ•๋„ ํšŒ์ „(C-5) / 2-sleeve ํฌํŠธํด๋ฆฌ์˜ค (BV50/R50 Paper ๊ฐ€๋™ ์ค‘)
  • Paper Evidence ์ž๋™ ์ˆ˜์ง‘ / Runtime State Machine / Pilot Authorization / Launch Readiness
  • ๋ฆฌ์Šคํฌ ๊ด€๋ฆฌ, ์•Œ๋ฆผ, ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ, ์›น ๋Œ€์‹œ๋ณด๋“œ

์‚ฌ์šฉ ํ™˜๊ฒฝ

  • Python 3.11 ~ 3.12

์„ค์น˜

pip install -r requirements.txt

์„ค์ •

์‹คํ–‰ ์ „์— ์„ค์ • ํŒŒ์ผ๊ณผ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ๋จผ์ € ์ค€๋น„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • config/settings.yaml.example โ†’ config/settings.yaml
  • .env.example ์ฐธ๊ณ  ํ›„ .env ์ž‘์„ฑ
  • target-weight capped paper pilot์€ Discord webhook์ด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. .env์˜ DISCORD_WEBHOOK_URL์„ ์ฑ„์šฐ๊ณ  config/settings.yaml์˜ discord.enabled: true๋ฅผ ์œ ์ง€ํ•˜์„ธ์š”.
  • config/holidays.yaml์€ ํ•„์š” ์‹œ ๊ฐฑ์‹  ๊ฐ€๋Šฅ
  • ๋ฏธ๊ตญ ํœด์žฅ์ผ์ด ํ•„์š”ํ•˜๋ฉด config/us_holidays.yaml ์ถ”๊ฐ€

Paper schedule์€ ๊ธฐ๋ณธ์ ์œผ๋กœ signal-only์ž…๋‹ˆ๋‹ค. DB ๋ชจ์˜ ์ฃผ๋ฌธ๊นŒ์ง€ ์‹คํ–‰ํ•˜๋Š” full paper๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ๋งŒ ์ผญ๋‹ˆ๋‹ค.

QUANT_AUTO_ENTRY=true python main.py --mode schedule --strategy scoring

trading.auto_entry์˜ YAML ๊ธฐ๋ณธ๊ฐ’์€ false๋กœ ๋‘๊ณ , 60์˜์—…์ผ ์‹คํ—˜์—์„œ๋Š” QUANT_AUTO_ENTRY์— ๋”ฐ๋ผ resolved hash๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. live ๋ชจ๋“œ๋Š” ๋ณ„๋„ hard gate๋ฅผ ํ†ต๊ณผํ•ด์•ผ ํ•˜๋ฉฐ, ํ™˜๊ฒฝ๋ณ€์ˆ˜๋งŒ์œผ๋กœ ์‹ค์ „ ์ฃผ๋ฌธ์„ ์—ด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์‹คํ–‰

# ๋‹จ์ผ ์ข…๋ชฉ ๋ฐฑํ…Œ์ŠคํŠธ
python main.py --mode backtest --strategy scoring --symbol 005930

# ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ (gap/์–ด๋‹/BlackSwan guard ํฌํ•จ)
python main.py --mode portfolio_backtest --strategy scoring --symbols 005930,000660 --start 2023-01-01 --end 2024-12-31

# ๊ฑฐ๋ž˜๋Ÿ‰ ๋ŒํŒŒ ์ „๋žต (C-4) ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ
python main.py --mode portfolio_backtest --strategy breakout_volume --symbols 005930,000660,035720,051910 --start 2024-01-01 --end 2025-12-31

# ๋ฉ€ํ‹ฐ์ „๋žต sleeve ๋น„์ค‘ ์Šค์œ• (C-5)
python scripts/c5_weight_sweep.py

# paper trading ์›”๊ฐ„ ๋ฆฌํฌํŠธ (BV50/R50 guardrail ๋ชจ๋‹ˆํ„ฐ๋ง)
python scripts/c5_paper_monthly_report.py

# paper trading ํŠน์ • ๊ธฐ๊ฐ„ ๋ฆฌํฌํŠธ
python scripts/c5_paper_monthly_report.py 2026-04-01 2026-04-02

# ๋ชจ์˜ํˆฌ์ž
python main.py --mode paper --strategy scoring

# ๋ชจ์˜ ์Šค์ผ€์ค„ ๋ฃจํ”„
python main.py --mode schedule --strategy scoring

# full paper ์Šค์ผ€์ค„ ๋ฃจํ”„ (DB ๋ชจ์˜ ์ฃผ๋ฌธ ์‹คํ–‰)
QUANT_AUTO_ENTRY=true python main.py --mode schedule --strategy scoring

# Paper ์šด์˜ preflight / launch readiness
python tools/paper_preflight.py --strategy scoring --with-pilot-check
python tools/paper_launch_readiness.py --strategy scoring --generate-runbook

# Target-weight capped pilot preflight / readiness audit
python tools/paper_preflight.py --strategy target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_tol5_sectorcap2_posloss8_frac50_pdd10_floor40_cd1 --with-pilot-check
python tools/target_weight_rotation_pilot.py --candidate-id target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_tol5_sectorcap2_posloss8_frac50_pdd10_floor40_cd1 --readiness-audit --allow-rerun

# Paper evidence pipeline
python tools/run_paper_evidence_pipeline.py --strategy scoring --finalize --date YYYY-MM-DD
python tools/run_paper_evidence_pipeline.py --strategy scoring --generate-package

# ์‹ค์ „ ๋งค๋งค (ํ˜„์žฌ ๋ชจ๋“  ์ „๋žต์ด live ์ฐจ๋‹จ ์ƒํƒœ โ€” live_candidate ์Šน๊ฒฉ ์ „๊นŒ์ง€ ์‹คํ–‰ ๋ถˆ๊ฐ€)
# python main.py --mode live --strategy scoring --confirm-live

# ์ „๋žต ๊ฒ€์ฆ
python main.py --mode validate --strategy scoring --symbol 005930 --validation-years 5

# ์„ฑ๊ณผ ๋น„๊ต
python main.py --mode compare --start 2025-01-01 --end 2025-03-19 --strategy scoring

# ํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™”
python main.py --mode optimize --strategy scoring --include-weights --auto-correlation

# ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ
python main.py --mode rebalance
python main.py --mode rebalance --dry-run
# config๊ฐ€ live์ผ ๋•Œ ์‹ค์ œ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์ฃผ๋ฌธ์€ ENABLE_LIVE_TRADING=true + --confirm-live + live gate ํ†ต๊ณผ ํ•„์š”

# ์›น ๋Œ€์‹œ๋ณด๋“œ
python main.py --mode dashboard
# ๊ธฐ๋ณธ ๋ฐ”์ธ๋“œ๋Š” http://127.0.0.1:8080 ์ž…๋‹ˆ๋‹ค.
# ์™ธ๋ถ€ ๊ณต๊ฐœ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งŒ ์ธ์ฆ/reverse proxy ๊ตฌ์„ฑ ํ›„ --dashboard-host 0.0.0.0 ์„ ๋ช…์‹œํ•˜์„ธ์š”.

# ์šด์˜ ํ†ตํ•ฉ ํ—ฌ์Šค ์ ๊ฒ€ (์ „ ์ „๋žต runtime + current_blockers ํ•œ๋ˆˆ์—)
python main.py --mode health
# ์ข…๋ฃŒ์ฝ”๋“œ 0=OK / 1=ATTENTION / 2=BLOCKED โ€” ๋ชจ๋‹ˆํ„ฐ๋ง ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ถ„๊ธฐ ๊ฐ€๋Šฅ.
# ์ฃผ์˜: verdict๋Š” '์šด์˜ ๊ฑด๊ฐ•' ๊ธฐ์ค€์ด๋‹ค. live ์Šน๊ฒฉ ๊ฒŒ์ดํŠธ์˜ NO-GO(live ํ›„๋ณด ์—†์Œ โ€”
# ์—ฐ๊ตฌ ๊ฒฐ๋ก ์ƒ ์ •์ƒ ์ƒํƒœ)๋Š” BLOCKED๋กœ ํ•ฉ์‚ฐํ•˜์ง€ ์•Š๊ณ  ํ—ค๋“œ๋ผ์ธ ๋ผ๋ฒจ๋กœ๋งŒ ๋ณด๊ณ ํ•œ๋‹ค.
# ๊ฒŒ์ดํŠธ artifact์˜ ์žฅ์• ์„ฑ ์‹ ํ˜ธ(๋ถ€์žฌ/stale/ํ‘œ๊ธฐ ๋ถˆ์ผ์น˜)๋Š” ATTENTION(1)์œผ๋กœ ๊ฐ•๋“ฑ๋œ๋‹ค.
# ๊ฐ™์€ ์ ๊ฒ€์„ tools/paper_runtime_status.py --health (--json) ์œผ๋กœ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ํœด์žฅ์ผ ๊ฐฑ์‹ 
python main.py --update-holidays

Full paper ์‹ ๊ทœ BUY๋Š” reports/paper_runtime/preflight_status_{strategy}.json์ด ์กด์žฌํ•˜๊ณ , runtime state ์กฐํšŒ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉฐ, entry ํ—ˆ์šฉ ๋˜๋Š” ํ˜„์žฌ pilot authorization์ด ์žฌ๊ฒ€์ฆ๋  ๋•Œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. preflight ๋ˆ„๋ฝ/์†์ƒ, runtime ์กฐํšŒ ์‹คํŒจ, critical fail์€ ์ฃผ๋ฌธ ์ƒ์„ฑ ์ „ ์ฐจ๋‹จ๋˜๋ฉฐ ๊ธฐ์กด ํฌ์ง€์…˜ SELL ์ฒญ์‚ฐ์€ ์ฐจ๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. python main.py --mode paper๋Š” ์„ค์ • ํŒŒ์ผ์— trading.mode: live๊ฐ€ ๋‚จ์•„ ์žˆ์–ด๋„ ํ•ด๋‹น ์‹คํ–‰์„ paper๋กœ ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ์˜ํˆฌ์ž ๋ช…๋ น์ด ์„ค์ • ์ž”์žฌ ๋•Œ๋ฌธ์— ์‹ค์ „ ์ฃผ๋ฌธ ์‹คํ–‰๊ธฐ๋กœ ์ดˆ๊ธฐํ™”๋˜๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•œ ์•ˆ์ „์žฅ์น˜์ž…๋‹ˆ๋‹ค. ์žฅ์ „/์žฅ์ค‘ auto-entry ํ›„๋ณด๋Š” ์ฃผ๋ฌธ ์ œ์ถœ ์ง์ „์— ์ตœ์‹  OHLCV์™€ ์ „๋žต ์‹ ํ˜ธ๋กœ ๋‹ค์‹œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์žฌ์กฐํšŒ ๋˜๋Š” ์‹ ํ˜ธ ๊ณ„์‚ฐ์ด ์‹คํŒจํ•˜๋ฉด stale ํ›„๋ณด๋กœ ๋งค์ˆ˜ํ•˜์ง€ ์•Š๊ณ  ENTRY_REVALIDATION_BLOCK ์ด๋ฒคํŠธ๋ฅผ ๋‚จ๊ธด ๋’ค ํ›„๋ณด๋ฅผ ๋‹ค์Œ ๋ฃจํ”„๊นŒ์ง€ ๋ณด๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.

Target-weight capped pilot์˜ --readiness-audit๋Š” ์ฃผ๋ฌธ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํŒ์ •ํ•˜๊ธฐ ์ „์— paper_preflight๋ฅผ ๋จผ์ € ๊ฐฑ์‹ ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ preflight_refresh artifact์— ๋‚จ๊น๋‹ˆ๋‹ค. notifier: Discord webhook ๋ฏธ์„ค์ • ๋˜๋Š” notifier health ๋น„์ •์ƒ ์ƒํƒœ๊ฐ€ ๋‚˜์˜ค๋ฉด pilot authorization์ด๋‚˜ cap์ด ๋งž์•„๋„ ์‹คํ–‰ ์ „ BLOCKED๋กœ ์œ ์ง€๋˜๋ฏ€๋กœ, .env์˜ DISCORD_WEBHOOK_URL ์„ค์ • ํ›„ preflight์™€ readiness audit์„ ๋‹ค์‹œ ๋Œ๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ „ ๋งค๋งค๋Š” ENABLE_LIVE_TRADING=true + --confirm-live + ์ „๋žต ์ƒํƒœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์˜ live_candidate ํ—ˆ์šฉ + ํ˜„์žฌ commit/config์™€ ์ผ์น˜ํ•˜๋Š” canonical promotion bundle + reports/current_blockers.json์˜ go_live=true ๋ฐ live_candidates ํฌํ•จ + ๋‚ด๋ถ€ strategy๊ฐ€ ํ˜„์žฌ ์ „๋žต๋ช…๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜๋Š” ELIGIBLE paper evidence package๊ฐ€ ๋ชจ๋‘ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์šด์˜์ž๊ฐ€ ์ „๋žต ์ƒํƒœ๋ฅผ live ๋ฏธํ—ˆ์šฉ์œผ๋กœ ๋‚ฎ์ถ”๊ฑฐ๋‚˜ current blockers๊ฐ€ ์ตœ์‹  promotion blocker summary์™€ ๋งž์ง€ ์•Š์œผ๋ฉด canonical live gate๊ฐ€ ํ†ต๊ณผํ•ด๋„ ์‹ค์ „ ์‹œ์ž‘์€ fail-closed๋กœ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. promotion engine๊ณผ live gate๋Š” same-universe/cash-adjusted paper excess๊ฐ€ ๋ชจ๋‘ ์–‘์ˆ˜์ธ์ง€ ํ™•์ธํ•˜๋ฉฐ, live gate๋Š” promotion_result.json ํ‘œ๊ธฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฏฟ์ง€ ์•Š๊ณ  ๊ฐ™์€ ์‚ฐ์ถœ๋ฌผ๊ณผ evidence๋ฅผ ์Šน๊ฒฉ ์—”์ง„์œผ๋กœ ์žฌ๊ณ„์‚ฐํ•ด ํ˜„์žฌ ๊ทœ์น™์—์„œ๋„ live_candidate์ธ์ง€ ๋‹ค์‹œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. paper evidence package๋Š” package payload hash์™€ ์›๋ณธ daily evidence JSONL์˜ source record hash๋„ ์žฌ๊ฒ€์ฆํ•˜๋ฏ€๋กœ ํŒจํ‚ค์ง€ ์š”์•ฝ๊ฐ’์ด๋‚˜ ์›๋ณธ record๊ฐ€ ๋”ฐ๋กœ ๋ฐ”๋€Œ๋ฉด live gate๊ฐ€ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. live ์Šค์ผ€์ค„๋Ÿฌ ์‹œ์ž‘ ์ „ KIS ์—ฐ๊ฒฐ ๊ฒ€์ฆ๊ณผ KISโ†”DB ์ž”๊ณ  ๋™๊ธฐํ™”๋„ ๋ฐ˜๋“œ์‹œ ํ†ต๊ณผํ•ด์•ผ ํ•˜๋ฉฐ, ์‹คํŒจํ•˜๋ฉด ๊ฒฝ๊ณ ๋กœ ๋„˜๊ธฐ์ง€ ์•Š๊ณ  ์‹œ์ž‘์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ OrderExecutor๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ด live BUY๋ฅผ ํ˜ธ์ถœํ•ด๋„ live_gate_validated=True๋กœ ์ƒ์„ฑ๋œ ์‹คํ–‰ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹ˆ๋ฉด KIS ์ฃผ๋ฌธ ์ œ์ถœ ์ „์— ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. live ์ฃผ๋ฌธ ์ „ ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ ์‹คํŒจ๋Š” ๋ฏธ์ฒด๊ฒฐ ์—†์Œ์œผ๋กœ ํ•ด์„ํ•˜์ง€ ์•Š๊ณ  ์ค‘๋ณต ์ฃผ๋ฌธ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์ฐจ๋‹จํ•˜๋ฉฐ, live ๊ธด๊ธ‰ ์ฒญ์‚ฐ๋„ KIS ํ˜„์žฌ๊ฐ€๊ฐ€ ๊ฒ€์ฆ๋˜์ง€ ์•Š์œผ๋ฉด ํ‰๊ท ๋‹จ๊ฐ€ ์ง€์ •๊ฐ€ fallback ๋งค๋„๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ˆ˜๋™ single-day/backfill/finalize evidence CLI๋Š” ์šด์˜ ๋ณด์ •ยทํ’ˆ์งˆ ์ ๊ฒ€ ์šฉ๋„์ด๋ฉฐ backfill provenance๋กœ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ scheduler/pilot ์„ธ์…˜์—์„œ ์ˆ˜์ง‘๋œ real_paper/pilot_paper record๋งŒ ์Šน๊ฒฉ ์ฆ๊ฑฐ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Shadow bootstrap collect/finalize CLI๋„ ์ฃผ๋ฌธ ์ œ์ถœ ์—†์ด shadow_bootstrap provenance๋กœ ๊ธฐ๋ก๋˜๋ฉฐ, ๋นˆ ์ด์ „์ผ์„ finalizeํ•˜๋ฉด์„œ ์ƒˆ record๊ฐ€ ์ƒ์„ฑ๋˜์–ด๋„ ์Šน๊ฒฉ ์ฆ๊ฑฐ๋กœ ๊ณ„์‚ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ชจ๋“  ์ „๋žต์€ provisional_paper_candidate ๋˜๋Š” disabled ์ƒํƒœ์ด๋ฉฐ, live ๋ชจ๋“œ๋Š” ์ฐจ๋‹จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
reports/approved_strategies.json์™€ ์˜ค๋ž˜๋œ validation_walkforward_*.json ํŒŒ์ผ์€ ๋” ์ด์ƒ live ๊ทผ๊ฑฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. --force-live ํ”Œ๋ž˜๊ทธ๋Š” ์ œ๊ฑฐ๋˜์—ˆ์œผ๋ฉฐ, ์–ด๋–ค ์กฐํ•ฉ์œผ๋กœ๋„ hard gate๋ฅผ ์šฐํšŒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. legacy approved_strategies.json๊ฐ€ ๊นจ์ ธ ์žˆ๊ฑฐ๋‚˜ ์Šคํ‚ค๋งˆ๊ฐ€ ๋งž์ง€ ์•Š์œผ๋ฉด paper runtime๋„ fail-closed๋กœ ์‹ ๊ทœ entry/shadow ์ˆ˜์ง‘์„ ๋‹ซ๊ณ  exit/finalize ๊ฐ™์€ ์•ˆ์ „ ์ž‘์—…๋งŒ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌ์Šคํฌ ๊ด€๋ฆฌ

๊ธฐ๋ณธ์ ์ธ ์•ˆ์ „์žฅ์น˜๋Š” ๋„ฃ์–ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

  • look-ahead ์™„ํ™” ๋ฐฑํ…Œ์ŠคํŠธ
  • ํฌ์ง€์…˜ ์ˆ˜ / ์ž๊ธˆ ๋น„์ค‘ ์ œํ•œ
  • ๋ฏธ์ฒด๊ฒฐ / ์ค‘๋ณต ์ฃผ๋ฌธ ๋ฐฉ์ง€ (live ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ ์‹คํŒจ ์‹œ ์ฃผ๋ฌธ ๋ณด๋ฅ˜, ํ˜ธํ™˜ bool API๋„ ๋ฏธ์ฒด๊ฒฐ ์žˆ์Œ์œผ๋กœ fail-closed)
  • ์‹ ๊ทœ BUY ์ฃผ๋ฌธ ์ง์ „ ํ‰๊ท  ๊ฑฐ๋ž˜๋Ÿ‰ ๋ˆ„๋ฝ ๋˜๋Š” ๊ฑฐ๋ž˜๋Œ€๊ธˆ ํ•˜ํ•œ ๋ฏธ๋‹ฌ ์‹œ ์ฐจ๋‹จ
  • ๊ฐญ ๋ฆฌ์Šคํฌ ํ™•์ธ์šฉ ์ตœ๊ทผ ๊ฐ€๊ฒฉ ์กฐํšŒ ์‹คํŒจ ๋˜๋Š” ๋ฐ์ดํ„ฐ ๋ถ€์กฑ ์‹œ ์‹ ๊ทœ BUY ์ฐจ๋‹จ
  • ์ƒ๊ด€๊ด€๊ณ„ ๋ฆฌ์Šคํฌ ํ™•์ธ์šฉ ๊ฐ€๊ฒฉ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹คํŒจ ๋˜๋Š” ๋ณด์œ  ์ข…๋ชฉ ๋ฐ์ดํ„ฐ ๋ถ€์กฑ ์‹œ ์‹ ๊ทœ BUY ์ฐจ๋‹จ
  • ์—…์ข… ๋น„์ค‘ cap ํ™•์ธ์šฉ ์„นํ„ฐ ๋งต ์กฐํšŒ ์‹คํŒจ ๋˜๋Š” ๋Œ€์ƒ/๋ณด์œ  ์ข…๋ชฉ ๋งคํ•‘ ๋ˆ„๋ฝ ์‹œ ์‹ ๊ทœ BUY ์ฐจ๋‹จ
  • ์ฃผ๋ฌธ/์†์ ˆ/์ต์ ˆ/๋ธ”๋ž™์Šค์™„ ํŒ๋‹จ์šฉ ํ˜„์žฌ๊ฐ€๊ฐ€ ์—†๊ฑฐ๋‚˜ 0/NaN์ด๋ฉด ์ฃผ๋ฌธยท์ฒญ์‚ฐ ํŒ๋‹จ ๋ณด๋ฅ˜ ๋ฐ PRICE_DATA_BLOCK ๊ธฐ๋ก
  • live ์ฃผ๋ฌธ ์ฒด๊ฒฐ ํ™•์ธ ์ „ DB ๊ฑฐ๋ž˜ยทํฌ์ง€์…˜ ๋ฐ˜์˜ ๋ณด๋ฅ˜
  • live ์ฒด๊ฒฐ ์กฐํšŒ ๊ฒฐ๊ณผ์˜ ์ฃผ๋ฌธ๋ฒˆํ˜ธ๊ฐ€ ํ˜„์žฌ ์ฃผ๋ฌธ๊ณผ ๋‹ค๋ฅด๋ฉด DB ๊ฑฐ๋ž˜ยทํฌ์ง€์…˜ ๋ฐ˜์˜ ๋ณด๋ฅ˜
  • live ์žฌ์‹œ์ž‘ ์‹œ ๋ธŒ๋กœ์ปค ๋ฏธ์ฒด๊ฒฐ ๋ชฉ๋ก์—์„œ ์‚ฌ๋ผ์ง„ ๋ณด๋ฅ˜ ์ฃผ๋ฌธ๋„ ์ฒด๊ฒฐ ์ƒ์„ธ ํ™•์ธ ์ „์—๋Š” ์—ด๋ฆฐ ์ฃผ๋ฌธ์œผ๋กœ ์œ ์ง€
  • live ์‹œ์ž‘ ์ „ KIS ์—ฐ๊ฒฐ / ์ž”๊ณ  ๋™๊ธฐํ™” ์‹คํŒจ ์‹œ ์Šค์ผ€์ค„๋Ÿฌ ์‹œ์ž‘ ์ฐจ๋‹จ
  • paper evidence package payload hash / source record hash ๋ถˆ์ผ์น˜ ์‹œ live gate ์ฐจ๋‹จ, --check-only๋Š” invalid package๋ฅผ ๊ตฌ์กฐํ™”๋œ WARN์œผ๋กœ ๋…ธ์ถœํ•˜๊ณ  --paper-evidence-quarantine-invalid๋กœ ์šด์˜ ์ž…๋ ฅ ๊ฒฝ๋กœ ๋ฐ–์— ๊ฒฉ๋ฆฌ ๊ฐ€๋Šฅ
  • live ์‹ ๊ทœ BUY๋Š” gate ํ†ต๊ณผ ์ƒํƒœ๊ฐ€ ์ „๋‹ฌ๋œ OrderExecutor์—์„œ๋งŒ KIS ์ฃผ๋ฌธ ์ œ์ถœ ํ—ˆ์šฉ
  • live ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์ฃผ๋ฌธ์€ CLI ์šด์˜์ž ํ™•์ธ ๋˜๋Š” live ์Šค์ผ€์ค„๋Ÿฌ ๊ฒ€์ฆ ์ƒํƒœ์—์„œ ๋ฐ”์Šค์ผ“๋ณ„ canonical live gate, account_key/order strategy tag ์ผ์น˜, KISโ†”DB ํฌ์ง€์…˜ ๋™๊ธฐํ™” ํ†ต๊ณผ ํ›„์—๋งŒ ์‹คํ–‰
  • auto-entry ํ›„๋ณด ์‹œ๊ทธ๋„ ์žฌ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ์‹ ๊ทœ BUY ๋ณด๋ฅ˜
  • live ๊ธด๊ธ‰ ์ฒญ์‚ฐ ์ „ KIS-only ๋ณด์œ  ํฌ์ง€์…˜์„ DB์— ๋จผ์ € ๋ฐ˜์˜
  • live ๊ธด๊ธ‰ ์ฒญ์‚ฐ ํ˜„์žฌ๊ฐ€ ์กฐํšŒ ์‹คํŒจ ์‹œ ํ‰๊ท ๋‹จ๊ฐ€ ์ง€์ •๊ฐ€ fallback ๋งค๋„ ์ฐจ๋‹จ
  • HTTP ๊ธด๊ธ‰ ์ฒญ์‚ฐ ํŠธ๋ฆฌ๊ฑฐ live ์‹คํ–‰์€ ๋ณ„๋„ ํ™•์ธ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์—†์ด๋Š” ์ฐจ๋‹จ
  • HTTP ๊ธด๊ธ‰ ์ฒญ์‚ฐ์€ ๊ฐœ๋ณ„ ๋งค๋„ ์‹คํŒจ๊ฐ€ ์žˆ์œผ๋ฉด ์‹คํŒจ ์‘๋‹ต์œผ๋กœ ๋…ธ์ถœ
  • HTTP ๊ธด๊ธ‰ ์ฒญ์‚ฐ ์‹คํ–‰์€ POST ์ „์šฉ์ด๋ฉฐ query token ์ธ์ฆ์€ ๊ธฐ๋ณธ ๋น„ํ™œ์„ฑ
  • HTTP ๊ธด๊ธ‰ ์ฒญ์‚ฐ ์„œ๋ฒ„๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 127.0.0.1์—๋งŒ ๋ฐ”์ธ๋“œ
  • HTTP ๊ธด๊ธ‰ ์ฒญ์‚ฐ ํ† ํฐ์€ ๊ธฐ๋ณธ ์ตœ์†Œ 16์ž์™€ placeholder ์ฐจ๋‹จ ๊ฒ€์ฆ ์ ์šฉ
  • ๊ธด๊ธ‰ ์ฒญ์‚ฐ ๊ฒฐ๊ณผ๋Š” ์„ฑ๊ณต/์‹คํŒจ summary๋ฅผ ํ†ตํ•ฉ ์•Œ๋ฆผ์œผ๋กœ ์ „ํŒŒ
  • paper/live ํ˜„๊ธˆ ์ •์‚ฐ์€ ์‹ค์ œ ์ฒด๊ฒฐ๊ฐ€ ๊ธฐ์ค€์ด๋ฉฐ ์Šฌ๋ฆฌํ”ผ์ง€๋ฅผ ํ˜„๊ธˆ ํ๋ฆ„์—์„œ ์ค‘๋ณต ์ฐจ๊ฐํ•˜์ง€ ์•Š์Œ
  • ์„ฑ๊ณผ ์—ดํ™” ์‹œ ์ง„์ž… ์ œํ•œ
  • ์‹œ์žฅ ๊ตญ๋ฉด / ๋ธ”๋ž™์Šค์™„ ๋Œ€์‘
  • ๋‹จ์ผ์ข…๋ชฉ/ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ gap/์–ด๋‹/BlackSwan ์ด๋ฒคํŠธ guard
  • ๋ฐฑํ…Œ์ŠคํŠธ / research sweep universe 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Œ€๊ธˆ ์‚ฌ์ „ ํ•„ํ„ฐ
  • DB ๋ฐฑ์—… / ์ž”๊ณ  ํฌ๋กœ์Šค์ฒดํฌ / ๊ธด๊ธ‰ ์ฒญ์‚ฐ
  • ์•Œ๋ฆผ ์ฑ„๋„ fallback

์„ธ๋ถ€ ์„ค์ •์€ config/risk_params.yaml, config/strategies.yaml, config/settings.yaml์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ

pytest tests/ -q

์™ธ๋ถ€ API๋‚˜ ์›น์†Œ์ผ“์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ๋ชจํ‚นํ•ด์„œ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

  • config/ โ€” ์„ค์ •
  • core/ โ€” ๋ฐ์ดํ„ฐ, ์ง€ํ‘œ, ์‹ ํ˜ธ, ๋ฆฌ์Šคํฌ, ์ฃผ๋ฌธ, ์Šค์ผ€์ค„๋Ÿฌ, ์•Œ๋ฆผ, paper evidence/runtime/pilot/preflight
  • strategies/ โ€” ์ „๋žต (scoring, breakout_volume, relative_strength_rotation ๋“ฑ)
  • scripts/ โ€” ๊ฒ€์ฆ ์Šคํฌ๋ฆฝํŠธ (C-4 OOS, C-5 sleeve ๋น„๊ต/๋น„์ค‘ ์Šค์œ•/ํ•„ํ„ฐ ํ…Œ์ŠคํŠธ/rolling WF/paper ๋ฆฌํฌํŠธ)
  • tools/ โ€” Paper ์šด์˜ ๋„๊ตฌ์™€ research sweep (evidence pipeline, pilot control, bootstrap, preflight, launch readiness, candidate sweep, target-weight pilot)
  • api/ โ€” KIS RESTยท์›น์†Œ์ผ“
  • backtest/ โ€” ๋ฐฑํ…Œ์ŠคํŠธ, ๊ฒ€์ฆ, ์ตœ์ ํ™”, ๋น„๊ต
  • database/ โ€” ๋ชจ๋ธยท๋ฐฑ์—…
  • monitoring/ โ€” ๋กœ๊น…, ์•Œ๋ฆผ, ๋Œ€์‹œ๋ณด๋“œ, ์ฒญ์‚ฐ ํŠธ๋ฆฌ๊ฑฐ
  • tests/ โ€” ํ…Œ์ŠคํŠธ
  • docs/ โ€” ๋ฌธ์„œ
  • deploy/ โ€” (์„ ํƒ) Oracle Cloud ARM ์„œ๋ฒ„ ์ƒ์‹œ ๊ตฌ๋™(systemd, logrotate)

๋ฌธ์„œ

๋ฌธ์„œ ๋‚ด์šฉ
docs/PROFITABILITY_FINDINGS.md ์ˆ˜์ต์„ฑ ์ •์ง ์ ๊ฒ€ (๋จผ์ € ์ฝ์„ ๊ฒƒ) โ€” ๋Šฅ๋™ alpha๋Š” ์—†์Œ, ๋ถ„์‚ฐ ๋Œ€ํ˜•์ฃผ buy&hold๊ฐ€ ํ˜„์‹ค์  ๊ณ ์ˆ˜์ต ๊ฒฝ๋กœ
docs/PAPER_TO_LIVE_RUNBOOK.md Paperโ†’Live ๊ฒ€์ฆ๋œ ์šด์˜ ๊ฒฝ๋กœ + ์ •์งํ•œ caveat
docs/PROJECT_GUIDE.md ํŒŒ์ผ ์—ญํ• , ๋ชจ๋“œ๋ณ„ ํ๋ฆ„, ์„ค์ • ์š”์•ฝ, ์‹ค์ „ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
quant_trader_design.md ์•„ํ‚คํ…์ฒ˜, ์ง€ํ‘œยท์ „๋žตยท๋ฆฌ์Šคํฌ ์„ค๊ณ„, ๊ฒ€์ฆ ๊ด€์ , ๋กœ๋“œ๋งต
BACKTEST_IMPROVEMENT.md ๋ฐฑํ…Œ์ŠคํŠธ ์‹ ๋ขฐ์„ฑ ๊ฐœ์„  ๋‚ด์—ญ, ์•Œ๋ ค์ง„ ํ•œ๊ณ„, ์ถ”๊ฐ€ ๊ณผ์ œ
deploy/README.md Oracle Cloud Free Tier ARM ๋ฐฐํฌยทsystemd ์ƒ์‹œ ๊ตฌ๋™ ๊ฐ€์ด๋“œ
reports/strategy_promotion_policy.md ์ „๋žต ์Šน๊ฒฉ ์ •๋Ÿ‰ ๊ธฐ์ค€ํ‘œ
reports/live_gate_policy.md Live ์ง„์ž… canonical/evidence hard gate
reports/paper_runbook.md Paper Trading ์šด์˜ ๊ฐ€์ด๋“œ
reports/experiment_freeze_pack.md 60์˜์—…์ผ Paper ์‹คํ—˜ ๋™๊ฒฐ ๊ธฐ์ค€, hash, ์‹คํ–‰ ๋ชจ๋“œ
reports/daily_ops_checklist.md ์ผ์ผ Paper ์šด์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
reports/weekly_ops_checklist.md ์ฃผ๊ฐ„ Paper ์šด์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
reports/experiment_stop_conditions.md ์‹คํ—˜ ์ค‘๋‹จยท๋™๊ฒฐยท์žฌ๊ฐœ ์กฐ๊ฑด

์ „๋žต ์ƒํƒœ

์Šน๊ฒฉ ๊ทœ์น™ v3 โ€” core/promotion_engine.py์—์„œ metrics ๊ธฐ๋ฐ˜ ์ž๋™ ํŒ์ •. tools/evaluate_and_promote.py --canonical๋กœ ์žฌํ˜„ํ•˜๋ฉฐ, canonical ํ‰๊ฐ€ ์‚ฐ์ถœ๋ฌผ์—๋Š” ์ข…๋ชฉ๊ตฐ ๊ตฌ์„ฑ, ๋ฐ์ดํ„ฐ ๋ฒ”์œ„, ์ˆ˜์ง‘ ์˜ค๋ฅ˜๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋งŒ๋“  data_snapshot_hash๋ฅผ ๋‚จ๊ธด๋‹ค. live gate์™€ ์Šน๊ฒฉ ์‚ฐ์ถœ๋ฌผ ๋กœ๋”๋Š” ์ด ํ•ด์‹œ, ๋ฐ์ดํ„ฐ ๋ฒ”์œ„, ์ˆ˜์ง‘ ์˜ค๋ฅ˜, ํ‰๊ฐ€ ์‹คํŒจ ์ƒํƒœ๋ฅผ ๋‹ค์‹œ ๊ฒ€์ฆํ•˜๊ณ , live ์ง„์ž… ์ง์ „์— promotion engine ํŒ์ •์„ ์žฌ๊ณ„์‚ฐํ•ด ์†์ƒ๋˜๊ฑฐ๋‚˜ ํ˜„์žฌ ๊ทœ์น™๊ณผ ์–ด๊ธ‹๋‚œ ์‚ฐ์ถœ๋ฌผ ์‚ฌ์šฉ์„ ์ฐจ๋‹จํ•œ๋‹ค. Research candidate sweep โ€” tools/research_candidate_sweep.py --quick --candidate-family all๋กœ promotion๊ณผ ๋ถ„๋ฆฌ๋œ rotation/momentum/breakout/pullback/benchmark-relative/risk-budget/cash-switch/benchmark-aware rotation/target-weight top-N rotation ํ›„๋ณด ๋žญํ‚น artifact๋ฅผ ์ƒ์„ฑ. Raw EW B&H gate๋Š” ์œ ์ง€ํ•˜๋˜, defensive/cash-heavy ํ›„๋ณด ํ•ด์„์„ ์œ„ํ•ด ํ‰๊ท  ๋…ธ์ถœ๋ฅ ๊ณผ exposure-matched B&H excess๋„ ์ง„๋‹จ๊ฐ’์œผ๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋ฒค์น˜๋งˆํฌ universe ์ผ๋ถ€ ์ข…๋ชฉ์ด๋ผ๋„ OHLCV ์ˆ˜์ง‘ยท๊ธฐ๊ฐ„ ๊ฒ€์ฆ์— ์‹คํŒจํ•˜๋ฉด INSUFFICIENT_BENCHMARK_DATA๋กœ fail-closed ์ฐจ๋‹จํ•˜๊ณ , ๊ฒฐ์ธก ์ข…๋ชฉ๊ณผ ์ปค๋ฒ„๋ฆฌ์ง€ ๋น„์œจ์„ artifact/Markdown์— ๋‚จ๊น๋‹ˆ๋‹ค. --top-n 200์ฒ˜๋Ÿผ ๋„“์€ ์œ ๋‹ˆ๋ฒ„์Šค ๊ฒ€์ฆ์„ ์š”์ฒญํ•˜๋ฉด ๊ธฐ๋ณธ ํ›„๋ณด ์Šค์บ” ๋ฒ”์œ„๋ฅผ max(100, top_n*2)๋กœ ๋„“ํžˆ๋ฉฐ, ํ•„์š” ์‹œ --universe-scan-limit์œผ๋กœ ๋ช…์‹œ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด best ํ›„๋ณด๋งŒ ๋น ๋ฅด๊ฒŒ ์žฌ๊ฒ€์ฆํ•  ๋•Œ๋Š” --candidate-id๋ฅผ ๋ฐ˜๋ณต ๋˜๋Š” ์‰ผํ‘œ ๊ตฌ๋ถ„์œผ๋กœ ๋„˜๊ฒจ ์„ ํƒํ•œ ํ›„๋ณด๋งŒ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. top-200 follow-up์ฒ˜๋Ÿผ MDD/ํšŒ์ „์œจ ์™„ํ™” ํ›„๋ณด๋งŒ ๋น„๊ตํ•  ๋•Œ๋Š” --candidate-family target_weight_risk_relief๋กœ risk-off/tolerance/exposure ์ถ•์†Œ ํ›„๋ณด๊ตฐ์„ ๋ฐ”๋กœ ์‹คํ–‰ํ•˜๊ณ , ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ๋นˆ๋„ ์™„ํ™” ํ›„๋ณด๋งŒ ๋ณผ ๋•Œ๋Š” --candidate-family target_weight_turnover_relief๋กœ ๊ฒฉ์›”/๋ถ„๊ธฐ ํ›„๋ณด๊ตฐ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์†์‹ค ๊ตฌ๊ฐ„ ๋…ธ์ถœ์„ ๋” ์ง์ ‘ ๋‚ฎ์ถ”๋Š” ํ›„๋ณด๋Š” --candidate-family target_weight_volatility_target๋กœ benchmark ์‹คํ˜„ ๋ณ€๋™์„ฑ ํƒ€๊นƒ๊ณผ ๋‚™ํญ floor๋ฅผ ์ ์šฉํ•ด ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ์ข…๋ชฉ ์„ ํƒ ์ž์ฒด๋ฅผ ๋ณด์ˆ˜ํ™”ํ•˜๋Š” ํ›„์† ๋น„๊ต๋Š” --candidate-family target_weight_downside_rank_relief๋กœ ๋‚™ํญยทํ•˜๋ฐฉ๋ณ€๋™์„ฑ ํŽ˜๋„ํ‹ฐ๋ฅผ ๋žญํ‚น ์ ์ˆ˜์— ๋ฐ˜์˜ํ•ด ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ๋žญํ‚น ํŽ˜๋„ํ‹ฐ ๊ธฐ๋ฐ˜ ํ›„๋ณด์˜ ๊ต์ฒด ๋นˆ๋„๋ฅผ ์ค„์ด๋Š” ํ›„์† ๋น„๊ต๋Š” --candidate-family target_weight_churn_relief๋กœ ๊ฒฉ์›” ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ๊ณผ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ๋‹น ์‹ ๊ทœ ํŽธ์ž… ์ˆ˜ ์ƒํ•œ(max_new_targets_per_rebalance)์„ ๊ฒฐํ•ฉํ•ด ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ํฌํŠธํด๋ฆฌ์˜ค ์†์‹ค ๊ตฌ๊ฐ„ ์ž์ฒด๋ฅผ ์ค„์ด๋Š” ํ›„์† ๋น„๊ต๋Š” --candidate-family target_weight_drawdown_guard๋กœ ์ง์ „ ํ‰๊ฐ€ NAV ๊ธฐ๋ฐ˜ drawdown guard์™€ ์žฌ์ง„์ž… cooldown์„ ๊ฒฐํ•ฉํ•ด ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ์„ ์ • ์ข…๋ชฉ์˜ ๋ชฉํ‘œ ๊ธˆ์•ก ์ž์ฒด๋ฅผ ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐํ˜•์œผ๋กœ ์กฐ์ •ํ•˜๋Š” ํ›„์† ๋น„๊ต๋Š” --candidate-family target_weight_volatility_budget๋กœ ์—ญ๋ณ€๋™์„ฑ sleeve weighting์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. target-weight ํ›„๋ณด ํ‰๊ฐ€๋Š” ๊ฐ™์€ sweep ์•ˆ์—์„œ OHLCV fetch cache๋ฅผ ๊ณต์œ ํ•ด ๋™์ผ ์ข…๋ชฉยท๊ธฐ๊ฐ„ ๋ฐ˜๋ณต ์ˆ˜์ง‘์„ ์ค„์ด๊ณ , cache hit/unique fetch ์ง„๋‹จ๊ฐ’์„ artifact์™€ Markdown์— ๋‚จ๊น๋‹ˆ๋‹ค. sweep artifact์™€ Markdown์—๋Š” ์„ ํƒ ๋ฐฉ์‹, ์š”์ฒญ top-N, ์Šค์บ” ํ•œ๋„, ํ›„๋ณด ํ•„ํ„ฐ, ์œ ๋™์„ฑ ํ•„ํ„ฐ ์ „ํ›„ ์ข…๋ชฉ ์ˆ˜, ํ›„๋ณด๋ณ„ ํƒˆ๋ฝ ์‚ฌ์œ ์™€ ๋ฐ˜๋ณต ๋ณ‘๋ชฉ ์š”์•ฝ์„ ๋‚จ๊ฒจ ์‹ค์ œ ๊ฒ€์ฆ ๋ฒ”์œ„์™€ ๊ฒŒ์ดํŠธ ๋ณ‘๋ชฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. target-weight ํ›„๋ณด๋Š” min_score_floor_pct๋กœ ์•ฝํ•œ ์ดˆ๊ณผ ๋ชจ๋ฉ˜ํ…€ ์Šฌ๋กฏ์„ ํ˜„๊ธˆ์œผ๋กœ ๋‚จ๊ธฐ๊ณ , hold_rank_buffer์™€ max_new_targets_per_rebalance๋กœ ๋žญํ‚น ํ”๋“ค๋ฆผ์— ๋”ฐ๋ฅธ ๋ถˆํ•„์š”ํ•œ ๊ต์ฒด์™€ ์‹ ๊ทœ ํŽธ์ž… ์ˆ˜๋ฅผ ์ค„์ด๋ฉฐ, target_allocation_mode=inverse_volatility๋กœ ์„ ํƒ ์ข…๋ชฉ๋ณ„ ๋ชฉํ‘œ ๊ธˆ์•ก์„ rolling ๋ณ€๋™์„ฑ์˜ ์—ญ์ˆ˜ ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆ„๊ณ , portfolio_drawdown_guard_trigger_pct/portfolio_drawdown_guard_exposure/portfolio_drawdown_guard_cooldown_rebalances๋กœ ํฌํŠธํด๋ฆฌ์˜ค ๋‚™ํญ ํ›„ ๋ชฉํ‘œ ๋…ธ์ถœ๊ณผ ์žฌ์ง„์ž… ์†๋„๋ฅผ ์ œํ•œํ•˜๊ณ , market_exposure_mode=benchmark_risk๋กœ KS11 SMA/๋‚™ํญ/๋ณ€๋™์„ฑ risk-off ๊ตฌ๊ฐ„์˜ ๋ถ€๋ถ„ ๋…ธ์ถœ ์ถ•์†Œ๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. canonical risk-overlay ํ›„๋ณด์—๋Š” target_tolerance_pct=3/5 turnover-aware ๋ณ€ํ˜•๋„ ํฌํ•จํ•ด ์ž‘์€ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์ƒ๋žต์ด ๋น„์šฉ๊ณผ ์„ฑ๊ณผ์— ์ฃผ๋Š” ์˜ํ–ฅ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. target-weight ๋ฆฌ์„œ์น˜ ๋ฐฑํ…Œ์ŠคํŠธ๋Š” ์ง์ „ ๊ฑฐ๋ž˜์ผ ์ ์ˆ˜๋กœ ๋‹ค์Œ ๊ฑฐ๋ž˜์ผ ์‹œ๊ฐ€์— ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑํ•˜๊ณ  ์ผ๋ง ํ‰๊ฐ€๋Š” ์ข…๊ฐ€๋กœ ํ•˜๋ฉฐ, ์ „์ผ ๊ธฐ์ค€ 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Ÿ‰์„ ๋น„์šฉ ๊ณ„์‚ฐ์— ๋„˜๊ฒจ ๋™์  ์Šฌ๋ฆฌํ”ผ์ง€์™€ participation ์ง„๋‹จ๊ฐ’์„ ๋‚จ๊น๋‹ˆ๋‹ค. Paper Evidence ์ฒด๊ณ„ โ€” core/paper_evidence.py v2 ์ผ๋ณ„ 22๊ฐœ ์ง€ํ‘œ ์ž๋™ ์ˆ˜์ง‘, core/paper_runtime.py entry gate, core/paper_pilot.py launch readiness/pilot auth ํŒ์ •. scheduler๋Š” v2 collector๋งŒ canonical ์ฆ๊ฑฐ๋กœ ๊ธฐ๋กํ•˜๋ฉฐ, legacy core/evidence_collector.py๋Š” import ํ˜ธํ™˜์šฉ deprecated no-op์ž…๋‹ˆ๋‹ค. ์Šน๊ฒฉ ํŒจํ‚ค์ง€๋Š” execution_backed=True์™€ real_paper/pilot_paper ์ถœ์ฒ˜๊ฐ€ ๋ช…์‹œ๋œ ๊ธฐ๋ก๋งŒ ์Šน๊ฒฉ ์ฆ๊ฑฐ๋กœ ์ธ์ •ํ•˜๊ณ , ํŒจํ‚ค์ง€ ๋‚ด๋ถ€ strategy๊ฐ€ ํ˜„์žฌ ์ „๋žต๋ช…๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์Šน๊ฒฉ/๋ผ์ด๋ธŒ ์ฆ๊ฑฐ๋กœ ์“ฐ์ง€ ์•Š์•„ ์˜ˆ์ „ ํ˜•์‹ยท์ˆ˜์ž‘์—… ๊ธฐ๋ก ์˜ค์—ผ์„ ์ฐจ๋‹จํ•œ๋‹ค.

2026-04-29 all-family quick sweep: 5์ข…๋ชฉ(005930,000660,035720,051910,068270)์—์„œ rotation/momentum/breakout ํ›„๋ณด 14๊ฐœ๋ฅผ ๋น„๊ตํ–ˆ์ง€๋งŒ ๋ชจ๋‘ benchmark excess return/Sharpe๋ฅผ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•ด NO_ALPHA_CANDIDATE๋กœ ํŒ์ •. ์ด ๊ฒฐ๊ณผ๋งŒ์œผ๋กœ canonical promotion์ด๋‚˜ paper/live ์Šน๊ฒฉ์€ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2026-04-30 top-20 all-family quick sweep: canonical liquidity universe 20์ข…๋ชฉ์—์„œ ๋™์ผ ํ›„๋ณด 14๊ฐœ๋ฅผ ์žฌ๊ฒ€์ฆํ–ˆ์ง€๋งŒ NO_ALPHA_CANDIDATE ์œ ์ง€. best=momentum_factor_120d๋Š” return +118.56%, Sharpe 0.79์˜€์œผ๋‚˜ benchmark excess=-30.83%p, MDD=-40.08%๋กœ ์Šน๊ฒฉ ๋ถˆ๊ฐ€. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋‹จ์ˆœ ํ›„๋ณด ํ™•์žฅ์ด ์•„๋‹ˆ๋ผ benchmark๋ฅผ ์ด๊ธฐ๋Š” ์ƒˆ๋กœ์šด alpha ํ›„๋ณด๊ตฐ ์„ค๊ณ„๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

2026-04-30 follow-up: ๊ธฐ์กด ์ „๋žต ์ค‘ ์™ธ๋ถ€ ์žฌ๋ฌด ๋ฐ์ดํ„ฐ ์˜์กด์ด ์—†๋Š” trend_pullback์„ pullback candidate family๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ์กด ์‹คํŒจ ์›์ธ(์ ˆ๋Œ€์ˆ˜์ต์€ ๋†’์ง€๋งŒ benchmark์— ๋’ค์ฒ˜์ง)์„ ์ง์ ‘ ๊ฒจ๋ƒฅํ•˜๊ธฐ ์œ„ํ•ด momentum_factor์— KS11 ๋Œ€๋น„ ์ดˆ๊ณผ ๋ชจ๋ฉ˜ํ…€/๋ณ€๋™์„ฑ ๊ฒŒ์ดํŠธ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ  benchmark_relative candidate family๋กœ ๋…ธ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. all sweep์€ ์ด์ œ rotation/momentum/breakout/pullback/benchmark-relative ํ›„๋ณด๊ตฐ์„ ํ•จ๊ป˜ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

2026-04-30 5-symbol smoke sweep: ์‹ ๊ทœ benchmark_relative 3๊ฐœ์™€ pullback 4๊ฐœ ๋ชจ๋‘ NO_ALPHA_CANDIDATE. best=benchmark_relative_momentum_60d return +4.13%, excess=-169.50%p; best pullback=trend_pullback_aggressive return +3.04%, excess=-170.59%p. ๋‘ ํ›„๋ณด๊ตฐ์€ ๊ณ„์† research-only์ž…๋‹ˆ๋‹ค.

2026-04-30 follow-up: ์‹ ํ˜ธ ํ•„ํ„ฐ๋งŒ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉํ–ฅ์ด ์•ฝํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•ด risk_budget candidate family๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋™์ผ ์‹ ํ˜ธ๋ฅผ ์ง‘์ค‘ํ˜•/๊ท ํ˜•ํ˜•/๋ฐฉ์–ดํ˜• exposure budget์œผ๋กœ ๋‚˜๋ˆ  ํ‰๊ฐ€ํ•˜๊ณ , ๊ฐ ํ›„๋ณด artifact์— ์ ์šฉ๋œ diversification ์„ค์ •์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

2026-04-30 risk-budget smoke sweep: 5์ข…๋ชฉ ๊ธฐ์ค€ NO_ALPHA_CANDIDATE. best return=risk_budget_momentum_120d_concentrated +11.40%, excess=-162.23%p, MDD=-32.28%; best risk-adjusted=risk_budget_rotation_slow_defensive +10.91%, excess=-162.72%p, MDD=-6.41%. ๋ฐฉ์–ดํ˜• exposure๋Š” ๋‚™ํญ์„ ์ค„์˜€์ง€๋งŒ alpha ์ž์ฒด๋Š” ์•„์ง ์—†์Šต๋‹ˆ๋‹ค.

2026-04-30 follow-up: ๋ฐฉ์–ดํ˜• exposure๋งŒ์œผ๋กœ benchmark๋ฅผ ์ด๊ธฐ์ง€ ๋ชปํ•ด relative_strength_rotation์— market_filter_exit ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ  cash_switch candidate family๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. KS11์ด ์ด๋™ํ‰๊ท  ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ€๋ฉด ์‹ ๊ทœ ์ง„์ž… ์ฐจ๋‹จ์„ ๋„˜์–ด ๊ธฐ์กด ํฌ์ง€์…˜๋„ ํ˜„๊ธˆํ™”ํ•˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

2026-04-30 cash-switch smoke sweep: 5์ข…๋ชฉ ๊ธฐ์ค€ NO_ALPHA_CANDIDATE. best=cash_switch_rotation_slow_defensive return +1.87%, excess=-171.76%p, Sharpe=-0.40, MDD=-11.78%. ํ˜„๊ธˆ ์ „ํ™˜์€ ์†์‹ค ๋ฐฉ์–ด์—๋Š” ์ผ๋ถ€ ์œ ํšจํ–ˆ์ง€๋งŒ benchmark ๋Œ€๋น„ alpha๋Š” ๋งŒ๋“ค์ง€ ๋ชปํ•ด research-only๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

2026-04-30 follow-up: research_candidate_sweep์— exposure-matched benchmark diagnostics๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. cash-switch ํ›„๋ณด์˜ ํ‰๊ท  ๋…ธ์ถœ์€ 8.410.0%์— ๋ถˆ๊ณผํ–ˆ๊ณ  exposure-matched excess๋„ -7.87%p-0.36%p๋กœ ์Œ์ˆ˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ‰ raw benchmark gap์€ ๋‚ฎ์€ ๋…ธ์ถœ ์˜ํ–ฅ์ด ํฌ์ง€๋งŒ, ๊ฐ™์€ ๋…ธ์ถœ๋กœ ๋น„๊ตํ•ด๋„ ์‹ ํ˜ธ edge๊ฐ€ ์•„์ง ์—†์–ด ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋‹จ์ˆœ ํ˜„๊ธˆํ™”๋ณด๋‹ค benchmark-aware ๋žญํ‚น/๋ถ€๋ถ„ ํ—ค์ง€/๋…ธ์ถœ ์œ ์ง€ํ˜• alpha ์„ค๊ณ„๊ฐ€ ์šฐ์„ ์ž…๋‹ˆ๋‹ค.

2026-04-30 follow-up: relative_strength_rotation์— benchmark-aware ranked mode๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. score_mode=benchmark_excess๋Š” ์ข…๋ชฉ 60/120d ๋ณตํ•ฉ ๋ชจ๋ฉ˜ํ…€์—์„œ KS11 ๋ณตํ•ฉ ๋ชจ๋ฉ˜ํ…€์„ ์ฐจ๊ฐํ•ด ๋žญํ‚นํ•˜๊ณ , rank_entry_mode=dense_ranked/exit_rebalance_mode=score_floor๋กœ ์ ˆ๋Œ€ ์ถ”์„ธ ํ•„ํ„ฐ ๋•Œ๋ฌธ์— ๊ณผ๋„ํ•˜๊ฒŒ ํ˜„๊ธˆํ™”๋˜๋Š” ๋ฌธ์ œ๋ฅผ research-only๋กœ ๋ถ„๋ฆฌ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

2026-05-08 follow-up: backtest/portfolio_backtester.py์—๋„ gap-up ์‹ ๊ทœ ๋งค์ˆ˜ ์ฐจ๋‹จ, gap-down GAP_DOWN ์ฒญ์‚ฐ, ์–ด๋‹ ์œˆ๋„์šฐ ์‹ ๊ทœ ๋งค์ˆ˜ ์ฐจ๋‹จ, BlackSwan ์ฒญ์‚ฐยท์ฟจ๋‹ค์šดยทrecovery ์‚ฌ์ด์ง•์„ ๋ฐ˜์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ผ์ข…๋ชฉ/ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ™์€ ๋ฆฌ์Šคํฌ ์ด๋ฒคํŠธ ์ „์ œ๋กœ ๋น„๊ต๋˜๋„๋ก gap_*, earnings_*, blackswan_* ์ง„๋‹จ ์นด์šดํ„ฐ์™€ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ณด๊ฐ•ํ–ˆ์Šต๋‹ˆ๋‹ค.

2026-05-08 follow-up: WatchlistManager.liquidity_filter_report()๋ฅผ ๊ณตํ†ต ์ง„๋‹จ API๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ์™€ tools/research_candidate_sweep.py๊ฐ€ ํ‰๊ฐ€ ์‹œ์ž‘์ผ ๊ธฐ์ค€ 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Œ€๊ธˆ ํ•˜ํ•œ ๋ฏธ๋งŒ ๋˜๋Š” strict ๋ชจ๋“œ ๋ฐ์ดํ„ฐ ๋ˆ„๋ฝ ์ข…๋ชฉ์„ universe์—์„œ ๋จผ์ € ์ œ์™ธํ•˜๋„๋ก ๋ณด๊ฐ•ํ–ˆ์Šต๋‹ˆ๋‹ค. research artifact์—๋Š” ์ž…๋ ฅ universe, ํ•„ํ„ฐ ํ†ต๊ณผ universe, ์ œ์™ธ ์ข…๋ชฉ/์‚ฌ์œ ๊ฐ€ ํ•จ๊ป˜ ๋‚จ์Šต๋‹ˆ๋‹ค.

2026-05-08 follow-up: PortfolioBacktester๋„ ๋‹จ์ผ์ข…๋ชฉ ๋ฐฑํ…Œ์Šคํ„ฐ์ฒ˜๋Ÿผ ์ข…๋ชฉ๋ณ„ 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Ÿ‰์„ RiskManager.calculate_transaction_costs()์— ์ „๋‹ฌํ•ด ๋™์  ์Šฌ๋ฆฌํ”ผ์ง€ ๋ฐฐ์ˆ˜๋ฅผ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ํฌํŠธํด๋ฆฌ์˜ค ๊ฑฐ๋ž˜ ๊ธฐ๋ก์—๋Š” participation_rate, slippage_multiplier, slippage_cost๊ฐ€ ๋‚จ์•„ ๊ฑฐ๋ž˜๋น„์šฉ ๊ณผ์†Œ์ถ”์ •์„ ์ ๊ฒ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2026-05-12 follow-up: ๋‹จ์ผ/ํฌํŠธํด๋ฆฌ์˜ค ๋ฐฑํ…Œ์ŠคํŠธ ๋ฆฌํฌํŠธ์— ๋น„์šฉ ์ „/ํ›„ ์„ฑ๊ณผ ๋น„๊ต๋ฅผ ์ž๋™ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. backtest.cost_impact๊ฐ€ ์ˆ˜์ˆ˜๋ฃŒยท์„ธ๊ธˆยท์Šฌ๋ฆฌํ”ผ์ง€๋ฅผ ํ‘œ์ค€ ์ง‘๊ณ„ํ•ด ๋น„์šฉ ์ฐจ๊ฐ ์ „ ์ถ”์ • ์ˆ˜์ต๋ฅ , ๋น„์šฉ ๋“œ๋ž˜๊ทธ(bp), ๋น„์šฉ/์ˆœ์†์ต, cost impact status๋ฅผ ๋‚จ๊ธฐ๋ฉฐ, ๋น„์šฉ ๋•Œ๋ฌธ์— gross profit์ด net loss๋กœ ๋’ค์ง‘ํžˆ๊ฑฐ๋‚˜ ๋น„์šฉ์ด ์ˆœ์ด์ต์„ ์ดˆ๊ณผํ•˜๋ฉด ์šด์˜ ๊ฒ€ํ†  ์‹ ํ˜ธ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

2026-05-08 follow-up: tools/research_candidate_sweep.py์˜ target-weight ๋ฆฌ์„œ์น˜ ๋ฐฑํ…Œ์ŠคํŠธ๋„ OHLCV volume์œผ๋กœ ์ข…๋ชฉ๋ณ„ 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Ÿ‰์„ ๊ณ„์‚ฐํ•ด ๋งค์ˆ˜ยท๋งค๋„ ๋น„์šฉ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. target-weight trade์™€ metrics์—๋Š” avg_daily_volume, participation_rate, slippage_multiplier, slippage_cost_total์ด ๋‚จ์•„ high-turnover ํ›„๋ณด์˜ ๋น„์šฉ ๊ณผ์†Œ์ถ”์ •์„ ๋” ๋นจ๋ฆฌ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2026-05-12 follow-up: target-weight research sweep์— canonical risk-overlay ํ›„๋ณด์˜ target_tolerance_pct=3/5 ๋ณ€ํ˜•์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์„œ์น˜ metrics์—๋Š” rebalance_tolerance_pct, rebalance_tolerance_skipped_trades, rebalance_tolerance_skipped_notional์„ ๋‚จ๊ฒจ ๋„“์€ tolerance๊ฐ€ ์‹ค์ œ๋กœ turnover๋ฅผ ์ค„์˜€๋Š”์ง€ artifact์—์„œ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2026-05-08 follow-up: research_candidate_sweep์˜ EW B&H ๋ฒค์น˜๋งˆํฌ๊ฐ€ ์ผ๋ถ€ ์ข…๋ชฉ ๊ฒฐ์ธก ์ƒํƒœ์—์„œ ์ „์ฒด capital ๋Œ€๋น„ ๋‚ฎ๊ฒŒ ๊ณ„์‚ฐ๋˜์–ด ํ›„๋ณด ์ดˆ๊ณผ์ˆ˜์ต์ด ๊ณผ๋Œ€ํ‰๊ฐ€๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์ฐจ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฒค์น˜๋งˆํฌ ์ž…๋ ฅ universe ์ „์ฒด๊ฐ€ ์ˆ˜์ง‘ยท๊ฒ€์ฆ๋˜์ง€ ์•Š์œผ๋ฉด excess gate์™€ decision action์€ INSUFFICIENT_BENCHMARK_DATA๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค.

2026-05-08 follow-up: OrderExecutor live BUY/SELL์€ ์ฃผ๋ฌธ ACK ์ดํ›„ ์ฒด๊ฒฐ๊ฐ€ยท์ฒด๊ฒฐ์ˆ˜๋Ÿ‰ ํ™•์ธ์ด ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋ถ€๋ถ„์ฒด๊ฒฐ๋งŒ ํ™•์ธ๋˜๋ฉด ๋” ์ด์ƒ ์˜ˆ์ƒ๊ฐ€ ๊ธฐ์ค€ ์ „๋Ÿ‰ FILLED๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋•Œ success=False๋Š” ๋ธŒ๋กœ์ปค ์ฃผ๋ฌธ ๋ถ€์žฌ๊ฐ€ ์•„๋‹ˆ๋ผ order_pending=True/requires_reconcile=True์ธ ์žฅ๋ถ€ ๋ฐ˜์˜ ๋ณด๋ฅ˜ ์ƒํƒœ์ด๋ฉฐ, KIS ์ž”๊ณ  ๋Œ€์กฐ ์ „ DB ํฌ์ง€์…˜ยท๊ฑฐ๋ž˜ ๊ธฐ๋ก ์˜ค์—ผ์„ ๋ง‰์Šต๋‹ˆ๋‹ค.

2026-05-11 follow-up: paper BUY ์ˆ˜๋Ÿ‰ยท์†์ ˆยท์ต์ ˆยทํŠธ๋ ˆ์ผ๋ง ๊ธฐ์ค€์„ ์˜ˆ์ƒ ์ฒด๊ฒฐ๊ฐ€๋กœ ๋ณด์ˆ˜ํ™”ํ•˜๊ณ , paper SELL๋„ ๋งค์ˆ˜์ฒ˜๋Ÿผ ๋ชจ๋ธ ์Šฌ๋ฆฌํ”ผ์ง€๋ฅผ ์ฒด๊ฒฐ๊ฐ€์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. TradeHistory.price๋Š” ์‹ค์ œ ์ฒด๊ฒฐ๊ฐ€๋กœ ๋ณด๊ณ , get_trade_cash_summary()๋Š” ์Šฌ๋ฆฌํ”ผ์ง€๋ฅผ ์ง„๋‹จ๊ฐ’์œผ๋กœ ์ง‘๊ณ„ํ•˜๋˜ ํ˜„๊ธˆ ํ๋ฆ„์—์„œ๋Š” ์ˆ˜์ˆ˜๋ฃŒยท์„ธ๊ธˆ๋งŒ ๋ณ„๋„ ์ฐจ๊ฐํ•ด ์ฒด๊ฒฐ๊ฐ€์— ์ด๋ฏธ ๋“ค์–ด๊ฐ„ ๋น„์šฉ์ด ์ค‘๋ณต ๋ฐ˜์˜๋˜์ง€ ์•Š๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

2026-05-08 follow-up: KIS ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ ์‹คํŒจ๋ฅผ ๋” ์ด์ƒ โ€œ๋ฏธ์ฒด๊ฒฐ ์—†์Œโ€์œผ๋กœ ํ•ด์„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. live BUY/SELL์€ ์ฃผ๋ฌธ ์ „ ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์‘๋‹ต ํ˜•์‹์ด ๋ถˆ๋ช…ํ™•ํ•˜๋ฉด live_unfilled_check.checked=False๋กœ ์ฃผ๋ฌธ์„ ๋ณด๋ฅ˜ํ•˜๊ณ , ์žฌ์‹œ์ž‘ ๋ณต๊ตฌ์—์„œ๋„ KIS ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ ์‹คํŒจ๋ฅผ ๋ณ„๋„ critical ์•Œ๋ฆผ์œผ๋กœ ๋“œ๋Ÿฌ๋ƒ…๋‹ˆ๋‹ค.

2026-05-14 follow-up: ํ˜ธํ™˜์šฉ has_unfilled_orders()๋„ ๋ฏธ์ฒด๊ฒฐ ์กฐํšŒ ์‹คํŒจ๋ฅผ False๋กœ ๊ฐ์ถ”์ง€ ์•Š๊ณ  ๋ฏธ์ฒด๊ฒฐ ์žˆ์Œ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. live ์‹ ๊ทœ ์ฃผ๋ฌธ์ด ์ƒํƒœํ˜• API๋ฅผ ์šฐํšŒํ•˜๋Š” ๋ ˆ๊ฑฐ์‹œ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์™€๋„ ์ค‘๋ณต ์ฃผ๋ฌธ ์œ„ํ—˜์€ fail-closed๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

2026-05-14 follow-up: OrderExecutor live BUY ์ง์ ‘ ํ˜ธ์ถœ ์šฐํšŒ๋ฅผ ๋ง‰์•˜์Šต๋‹ˆ๋‹ค. run_live_trading() ๋˜๋Š” live ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์ฒ˜๋Ÿผ readiness gate๋ฅผ ํ†ต๊ณผํ•œ ๊ฒฝ๋กœ๋งŒ live_gate_validated=True๋ฅผ ์ „๋‹ฌํ•˜๋ฉฐ, ๊ธฐ๋ณธ๊ฐ’์€ fail-closed๋ผ ์ˆ˜๋™ ์Šคํฌ๋ฆฝํŠธ/์ฝ˜์†”์—์„œ executor๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด๋„ ์‹ ๊ทœ BUY๋Š” KIS ์ฃผ๋ฌธ ์ „์— ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. SELL์€ ๊ธด๊ธ‰ ์ฒญ์‚ฐ ์•ˆ์ „์„ฑ์„ ์œ„ํ•ด ๊ธฐ์กด ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

2026-05-14 follow-up: ๋ฐ”์Šค์ผ“ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ paper BUY ์‹คํ–‰ ๊ฒฝ๋กœ๋ฅผ ๋ณต๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค. BasketRebalancer.execute()๊ฐ€ ์—†๋Š” ํฌํŠธํด๋ฆฌ์˜ค ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋˜ ๋ถ€๋ถ„์„ get_current_capital()/get_available_cash() ๊ธฐ์ค€์œผ๋กœ ์ •๋ฆฌํ–ˆ๊ณ , ์‹ค์ œ ์ฃผ๋ฌธ ์‹คํ–‰ ์ „ ์ž๋ณธยทํ˜„๊ธˆ ๊ฐ’์ด OrderExecutor.execute_buy_quantity()์— ์ „๋‹ฌ๋˜๋Š”์ง€ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋กœ ๊ณ ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

2026-05-14 follow-up: ์‹œ์žฅ ๊ตญ๋ฉด ํ•„ํ„ฐ๋ฅผ fail-closed๋กœ ๋ณด๊ฐ•ํ–ˆ์Šต๋‹ˆ๋‹ค. market_regime_filter=true ์ƒํƒœ์—์„œ ์ง€์ˆ˜ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹คํŒจ, ๋นˆ ๋ฐ์ดํ„ฐ, MA ๊ณ„์‚ฐ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋” ์ด์ƒ bullish ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋„˜๊ธฐ์ง€ ์•Š๊ณ  regime=unknown, allow_buys=false, position_scale=0.0์œผ๋กœ ์‹ ๊ทœ BUY๋ฅผ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ง์ ‘ OrderExecutor.execute_buy()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ๋กœ๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์œผ๋ฉด ์ฃผ๋ฌธ ์ „ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.

2026-05-14 follow-up: KIS Circuit Breaker์˜ HALF_OPEN ๋ณต๊ตฌ ์ƒํƒœ๋ฅผ ๋‹จ์ผ probe ๋ฐฉ์‹์œผ๋กœ ์ œํ•œํ–ˆ์Šต๋‹ˆ๋‹ค. OPEN ์ฟจ๋‹ค์šด ํ›„ ์ฒซ ์š”์ฒญ ํ•˜๋‚˜๋งŒ ํ†ต๊ณผ์‹œํ‚ค๊ณ , on_success() ๋˜๋Š” on_failure()๊ฐ€ ๋“ค์–ด์˜ค๊ธฐ ์ „๊นŒ์ง€ ์ถ”๊ฐ€ ์š”์ฒญ์€ ์ฐจ๋‹จํ•ด ์žฅ์•  ํšŒ๋ณต ์งํ›„ ์š”์ฒญ์ด ํ•œ๊บผ๋ฒˆ์— ํ’€๋ฆฌ์ง€ ์•Š๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

2026-05-14 follow-up: paper promotion evidence package์— package_integrity.payload_hash์™€ source_records.records_hash๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. live gate๋Š” ํŒจํ‚ค์ง€ payload hash, ์›๋ณธ daily evidence JSONL์—์„œ ์žฌ๊ณ„์‚ฐํ•œ source record hash, record count/date ๋ฒ”์œ„๋ฅผ ๋ชจ๋‘ ๋น„๊ตํ•ด ํŒจํ‚ค์ง€ ์š”์•ฝ๊ฐ’๊ณผ ์›๋ณธ evidence๊ฐ€ ๋”ฐ๋กœ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ live ์ „ํ™˜ ๊ทผ๊ฑฐ๋กœ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2026-05-14 follow-up: live ๊ธด๊ธ‰ ์ฒญ์‚ฐ์€ KIS ํ˜„์žฌ๊ฐ€๊ฐ€ ์—†๊ฑฐ๋‚˜ 0 ์ดํ•˜์ด๋ฉด ํ•ด๋‹น ์ข…๋ชฉ์„ ์‹คํŒจ ์ƒ์„ธ๋กœ ๊ธฐ๋กํ•˜๊ณ  execute_sell์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ‰๊ท ๋‹จ๊ฐ€๋ฅผ ํ˜„์žฌ ์‹œ์žฅ๊ฐ€์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•œ ์ง€์ •๊ฐ€ ๋งค๋„ fallback์„ ๋ง‰์•„ ๊ธ‰๋ฝ์žฅ ๋ฏธ์ฒด๊ฒฐ ์œ„ํ—˜์„ ์šด์˜ ์•Œ๋ฆผ์œผ๋กœ ๋“œ๋Ÿฌ๋ƒ…๋‹ˆ๋‹ค.

2026-05-08 follow-up: target-weight ๋ฆฌ์„œ์น˜ ๋ฐฑํ…Œ์ŠคํŠธ์˜ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์ฒด๊ฒฐ ๊ธฐ์ค€์„ ๋‹น์ผ ์ข…๊ฐ€์—์„œ ๋‹ค์Œ ๊ฑฐ๋ž˜์ผ ์‹œ๊ฐ€๋กœ ๋ณด์ˆ˜ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋žญํ‚น๊ณผ risk-off ํŒ๋‹จ์€ ์ง์ „ ๊ฑฐ๋ž˜์ผ ์ข…๊ฐ€๊นŒ์ง€๋งŒ ์‚ฌ์šฉํ•˜๊ณ , ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์ฒด๊ฒฐ์€ ํ•ด๋‹น ๊ฑฐ๋ž˜์ผ ์›๋ณธ open, ์ผ๋ง ํ‰๊ฐ€๋Š” close๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์‹ ๊ทœ top-N ๋งค์ˆ˜ ํ›„๋ณด์˜ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์ผ open์ด ๋ˆ„๋ฝ๋˜๋ฉด target_weight_research_execution_price_missing์œผ๋กœ ์ค‘๋‹จํ•˜๊ณ , ์ด๋ฏธ ๋ณด์œ ํ•œ ์ข…๋ชฉ์˜ open์ด ์—†์œผ๋ฉด ํ•ด๋‹น ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์„ ๊ฑฐ๋ž˜ ์—†์ด skip ์ง„๋‹จ์œผ๋กœ ๋‚จ๊น๋‹ˆ๋‹ค. ๋™์  ์Šฌ๋ฆฌํ”ผ์ง€์˜ 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Ÿ‰๋„ ๋‹น์ผ ๊ฑฐ๋ž˜๋Ÿ‰์„ ํฌํ•จํ•˜์ง€ ์•Š๋„๋ก 1๊ฑฐ๋ž˜์ผ ์ง€์—ฐํ•ฉ๋‹ˆ๋‹ค.

2026-04-30 benchmark-aware rotation smoke sweep: 5์ข…๋ชฉ ๊ธฐ์ค€ NO_ALPHA_CANDIDATE. best=benchmark_aware_rotation_60_120_balanced return=+21.65%, Sharpe=0.50, avg exposure=24.1%์˜€์ง€๋งŒ raw excess=-151.98%p, exposure-matched excess=-16.05%p๋ผ promotion ๋ฏธ์ง„ํ–‰. fast 40_100_dense๋Š” exposure-matched excess=+2.04%p์˜€์œผ๋‚˜ raw excess=-163.35%p๋ผ ๋‹ค์Œ ์—ฐ๊ตฌ ํžŒํŠธ๋กœ๋งŒ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฐฉํ–ฅ์€ sparse BUY/SELL ์‹ ํ˜ธ๋ฅผ ๋„˜์–ด monthly top-N ๋ชฉํ‘œ๋น„์ค‘ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์„ ๋ณ„๋„ ๋ฐฑํ…Œ์Šคํ„ฐ๋กœ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

2026-04-30 target-weight top-N rotation smoke sweep: 5์ข…๋ชฉ ๊ธฐ์ค€ NO_ALPHA_CANDIDATE. best=target_weight_rotation_top3_40_100_excess return=+128.44%, Sharpe=1.13, avg exposure=85.3%๋กœ ๋…ธ์ถœ ๋ถ€์กฑ ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ raw excess=-45.19%p, exposure-matched excess=-14.82%p๋ผ promotion ๋ฏธ์ง„ํ–‰. ์ด ๊ฒฐ๊ณผ๋Š” sparse ์‹ ํ˜ธ๊ฐ€ ๋ณ‘๋ชฉ์ด์—ˆ์Œ์„ ํ™•์ธํ–ˆ์ง€๋งŒ, ๋™์ผ ์œ ๋‹ˆ๋ฒ„์Šค B&H๋ฅผ ์ด๊ธฐ๋Š” alpha๋Š” ์•„์ง ์•„๋‹ˆ๋ผ์„œ ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋” ๋„“์€ ์œ ๋‹ˆ๋ฒ„์Šค์™€ ๋ถ€๋ถ„ hedge/์ƒ๋Œ€๊ฐ•๋„ ํ•„ํ„ฐ ๊ฐœ์„ ์ž…๋‹ˆ๋‹ค.

2026-04-30 canonical top-20 target-weight full sweep: ๊ธฐ์กด target_weight_rotation_top5_60_120_floor0_hold3๋Š” return=+278.57%, raw excess=+129.18%p, exposure-matched excess=+150.88%p, Sharpe=1.65, WF positive/Sh+ 100%, turnover/year=807.8%์˜€์ง€๋งŒ MDD=-28.25%๋กœ paper_only. benchmark-risk overlay ์ถ”๊ฐ€ ํ›„ best=target_weight_rotation_top5_60_120_floor0_hold3_risk60_35๋Š” return=+210.24%, raw excess=+60.85%p, exposure-matched excess=+130.96%p, Sharpe=1.60, PF=5.73, MDD=-19.24%, turnover/year=858.0%, WF positive/Sh+ 100%, risk-off rebalance=38.9%๋กœ ์ฒ˜์Œ provisional_paper_candidate์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํ›„์†์œผ๋กœ tools/evaluate_and_promote.py --canonical์ด ์ด ํ›„๋ณด๋ฅผ canonical promotion bundle์— ์žฌํ˜„ํ•˜๋„๋ก ์—ฐ๊ฒฐํ–ˆ๊ณ , promotion_result.json์—์„œ๋„ ๋™์ผ ํ›„๋ณด๊ฐ€ provisional_paper_candidate๋กœ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ tools/target_weight_rotation_pilot.py๊ฐ€ portfolio-level ๋ชฉํ‘œ๋น„์ค‘ plan์„ ๋งŒ๋“ค๊ณ  pilot cap์„ ๊ฒ€์ฆํ•œ ๋’ค paper-only exact-quantity ์ฃผ๋ฌธ์„ ๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. dry-run์€ --record-shadow-evidence๋กœ non-promotable shadow_bootstrap evidence๋ฅผ ๋‚จ๊ธฐ๊ณ , ๊ฐ™์€ ์‹คํ–‰์—์„œ launch readiness JSON/MD์™€ pilot runbook์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. session artifact์—๋Š” ๊ธฐ๋ณธ cap preview, plan ๊ธฐ๋ฐ˜ ์ตœ์†Œ/์ถ”์ฒœ pilot cap, enable ๋ช…๋ น, launch artifact ๊ฒฝ๋กœ๊ฐ€ ํ•จ๊ป˜ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. live ์ž๋™์šด์˜์€ ์—ฌ์ „ํžˆ ๊ธˆ์ง€์ž…๋‹ˆ๋‹ค.

2026-05-11 follow-up: target-weight canonical์„ next-open ์ฒด๊ฒฐ๊ณผ ๊ฒฐ์ธก ์ง„๋‹จ ๊ธฐ์ค€์œผ๋กœ ์žฌ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. target_weight_rotation_top5_60_120_floor0_hold3_risk60_35๋Š” return=+171.20%, PF=4.24, Sharpe=1.41, MDD=-19.90%, WF positive=100%, WF Sharpe+=83.3%๋กœ provisional_paper_candidate๋ฅผ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์‚ฐ์ถœ๋ฌผ์€ stale score ํ›„๋ณด 2๊ฐœ ์ œ์™ธ, held stale valuation 21์ผ, ๋ณด์œ  ์ข…๋ชฉ ์‹œ๊ฐ€ ๋ˆ„๋ฝ์— ๋”ฐ๋ฅธ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ skip 1ํšŒ๋ฅผ metrics์— ๋‚จ๊ธฐ๋ฏ€๋กœ paper pilot์—์„œ๋Š” ์ฒด๊ฒฐ ๊ฐ€๋Šฅ์„ฑ๊ณผ stale valuation ๋นˆ๋„๋ฅผ ํ•จ๊ป˜ ๊ฐ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2026-05-12 top-200 target-weight follow-up: --top-n 200 --candidate-id target_weight_rotation_top5_60_120_floor0_hold3_risk60_35 full sweep์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. canonical liquidity 200๊ฐœ ์ค‘ ์œ ๋™์„ฑ ํ•„ํ„ฐ ํ†ต๊ณผ 164๊ฐœ, benchmark coverage 100%์—์„œ return=+110.39%, raw excess=+78.50%p, exposure-matched excess=+90.25%p, Sharpe=0.85, PF=2.06, WF positive=83.3%, WF Sharpe+=100%์˜€์ง€๋งŒ MDD=-25.79%, turnover/year=1097.1%๋กœ provisional ๊ฒŒ์ดํŠธ๋ฅผ ๋„˜์ง€ ๋ชปํ•ด paper_only์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์ค€์œผ๋กœ alpha ์กด์žฌ ์—ฌ๋ถ€๋ณด๋‹ค drawdown๊ณผ turnover๋ฅผ ๋™์‹œ์— ๋‚ฎ์ถ”๋Š” ๋ฆฌ์Šคํฌ ์™„ํ™” ํ›„๋ณด๊ตฐ ๊ฒ€์ฆ์œผ๋กœ ์ด์–ด๊ฐ”์Šต๋‹ˆ๋‹ค.

2026-05-12 ๋ฆฌ์Šคํฌ ์™„ํ™” top-200 follow-up: --candidate-family target_weight_risk_relief --top-n 200 full sweep์—์„œ 10๊ฐœ ํ›„๋ณด๋ฅผ ๋น„๊ตํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ƒ์œ„ ํ›„๋ณด target_weight_rotation_top5_60_120_floor0_hold3_risk60_35_tol5๋Š” return=+125.61%, raw excess=+93.72%p, exposure-matched excess=+104.53%p, avg exposure=68.5%, Sharpe=0.91, PF=2.19, WF positive=83.3%, WF Sharpe+=100%๋กœ ๊ธฐ์กด ๋‹จ์ผ ํ›„๋ณด๋ณด๋‹ค ์ˆ˜์ต์„ฑ์€ ๊ฐœ์„ ๋์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ „์ฒด ํ›„๋ณด๊ฐ€ MDD -25.27%~-32.14%, turnover/year 1027.2%~1344.3% ๊ตฌ๊ฐ„์— ์žˆ์–ด mdd < -20์™€ turnover_per_year >= 1000 ๋ณ‘๋ชฉ์„ ๋„˜์ง€ ๋ชปํ–ˆ๊ณ , ํŒ์ •์€ KEEP_RESEARCH_ONLY์ž…๋‹ˆ๋‹ค. sweep data fetch cache๋Š” unique_fetches=1155, cache_hits=10395๋กœ ๋™์ž‘์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ๋นˆ๋„ ์ž์ฒด๋ฅผ ๋‚ฎ์ถ”๋Š” ๊ฒฉ์›”/๋ถ„๊ธฐ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ, ๋ณ€๋™์„ฑ ํƒ€๊นƒ, ๋‚™ํญ ์ฐจ๋‹จ, ํšŒ์ „์œจ ํŒจ๋„ํ‹ฐ ๋žญํ‚น์„ ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

2026-05-12 ์ €ํšŒ์ „ top-200 follow-up: --candidate-family target_weight_turnover_relief --top-n 200 full sweep์—์„œ ๊ฒฉ์›”/๋ถ„๊ธฐ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ํ›„๋ณด 6๊ฐœ๋ฅผ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. best=target_weight_rotation_top5_60_120_floor0_hold3_risk90_35_bimonthly๋Š” return=+85.72%, raw excess=+53.83%p, exposure-matched excess=+68.63%p, Sharpe=0.73, PF=1.86, turnover/year=616.7%์˜€์Šต๋‹ˆ๋‹ค. ๋ถ„๊ธฐ ํ›„๋ณด์˜ turnover/year๋Š” 456.1476.9%๊นŒ์ง€ ๋‚ด๋ ค๊ฐ”์ง€๋งŒ, ์ „ ํ›„๋ณด๊ฐ€ benchmark excess Sharpe<=0 ๋ฐ MDD -25.35%-35.12%๋กœ ๋ง‰ํ˜€ ํŒ์ •์€ NO_ALPHA_CANDIDATE์ž…๋‹ˆ๋‹ค. ์ฆ‰ ๋‹จ์ˆœ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ๋นˆ๋„ ์ถ•์†Œ๋Š” ํšŒ์ „์œจ ๋ณ‘๋ชฉ์€ ์™„ํ™”ํ•˜์ง€๋งŒ ์œ„ํ—˜์กฐ์ • alpha์™€ ๋‚™ํญ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ–ˆ๊ณ , ์ด ํŒ๋‹จ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€๋™์„ฑ ํƒ€๊นƒ๊ณผ ๋‚™ํญ ์ฐจ๋‹จ์„ ์‹ค์ œ ํฌ์ง€์…˜ ํฌ๊ธฐ ์‚ฐ์‹์— ๋„ฃ๋Š” ํ›„๋ณด๊ตฐ์„ ์ด์–ด์„œ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.

2026-05-12 ๋ณ€๋™์„ฑ ํƒ€๊นƒ top-200 follow-up: --candidate-family target_weight_volatility_target --top-n 200 full sweep์—์„œ benchmark ์‹คํ˜„ ๋ณ€๋™์„ฑ ํƒ€๊นƒ๊ณผ drawdown floor ํ›„๋ณด 6๊ฐœ๋ฅผ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. best=target_weight_rotation_top5_60_120_floor0_hold3_risk60_35_tol5_vol16_dd8_floor35๋Š” return=+105.18%, raw excess=+73.29%p, exposure-matched excess=+91.35%p, avg exposure=71.7%, Sharpe=0.81, PF=2.03, turnover/year=958.0%์˜€์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ „ ํ›„๋ณด๊ฐ€ MDD -24.26%~-31.04%๋กœ provisional MDD ๊ฒŒ์ดํŠธ๋ฅผ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ–ˆ๊ณ , 5๊ฐœ ํ›„๋ณด๋Š” benchmark excess Sharpe๋„ 0 ์ดํ•˜๋ผ ํŒ์ •์€ KEEP_RESEARCH_ONLY์ž…๋‹ˆ๋‹ค. ๋ณ€๋™์„ฑ ๊ธฐ๋ฐ˜ ๋…ธ์ถœ ์ถ•์†Œ๋งŒ์œผ๋กœ๋Š” ๋‚™ํญ ๋ณ‘๋ชฉ์ด ์ถฉ๋ถ„ํžˆ ํ’€๋ฆฌ์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋ชฉํ‘œ ๋…ธ์ถœ ์‚ฐ์‹๋ณด๋‹ค ์ข…๋ชฉ ์„ ๋ณ„ ๋žญํ‚น์— ๋‚™ํญยทํ•˜๋ฐฉ๋ณ€๋™์„ฑยท์ƒ๊ด€/์—…์ข… ์ง‘์ค‘ ํŽ˜๋„ํ‹ฐ๋ฅผ ๋„ฃ๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

2026-05-12 ๋ฆฌ์Šคํฌ ํŽ˜๋„ํ‹ฐ ๋žญํ‚น top-200 follow-up: --candidate-family target_weight_downside_rank_relief --top-n 200 full sweep์—์„œ ๋‚™ํญยทํ•˜๋ฐฉ๋ณ€๋™์„ฑ ํŽ˜๋„ํ‹ฐ ํ›„๋ณด 5๊ฐœ๋ฅผ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. best=target_weight_rotation_top5_60_120_floor0_hold3_risk60_35_tol5_rankrisk60๋Š” return=+132.51%, raw excess=+100.62%p, exposure-matched excess=+111.43%p, Sharpe=0.94, PF=2.21, WF positive/Sh+=100%๋กœ ๊ธฐ์กด ๋ฆฌ์Šคํฌ ์™„ํ™” ํ›„๋ณด๋ณด๋‹ค ์ˆ˜์ต์„ฑ์€ ๊ฐœ์„ ๋์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ „ ํ›„๋ณด๊ฐ€ MDD -25.20%~-33.07%, turnover/year 1143.8%~1366.0%๋กœ ๋ง‰ํ˜€ ํŒ์ •์€ KEEP_RESEARCH_ONLY์ž…๋‹ˆ๋‹ค. ์ฆ‰ downside rank penalty๋Š” alpha ํ›„๋ณด์„ฑ์„ ๊ฐ•ํ™”ํ–ˆ์ง€๋งŒ, ์ข…๋ชฉ ๊ต์ฒด ๋นˆ๋„๋ฅผ ๋‚ฎ์ถ”์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ์ด ๋žญํ‚น ํŽ˜๋„ํ‹ฐ๋ฅผ ๊ฒฉ์›” ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ, ๋” ๋„“์€ tolerance, ์›”๋ณ„ ์‹ ๊ทœ ํŽธ์ž… ์ˆ˜ ์ œํ•œ ๊ฐ™์€ churn control๊ณผ ๊ฒฐํ•ฉํ•˜๋Š” ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค.

2026-05-12 follow-up: target_weight_churn_relief ํ›„๋ณด๊ตฐ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง์ „ best์˜€๋˜ downside rank penalty ํ›„๋ณด๋ฅผ ๊ธฐ์ค€์œผ๋กœ max_new_targets_per_rebalance ์‹ ๊ทœ ํŽธ์ž… ์ƒํ•œ, ๊ฒฉ์›” ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ, ๋„“์€ tolerance ์กฐํ•ฉ์„ ๋ณ„๋„ family๋กœ ๋ถ„๋ฆฌํ•ด top-200 full sweep์—์„œ turnover/year์™€ MDD ๋ณ‘๋ชฉ์ด ์‹ค์ œ๋กœ ์™„ํ™”๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

2026-05-12 churn control top-200 follow-up: --candidate-family target_weight_churn_relief --top-n 200 full sweep์—์„œ ํ›„๋ณด 5๊ฐœ๋ฅผ ๊ฒ€์ฆํ–ˆ๊ณ  ํŒ์ •์€ KEEP_RESEARCH_ONLY์ž…๋‹ˆ๋‹ค. best=target_weight_rotation_top5_60_120_floor0_hold3_risk60_35_tol5_rankrisk60_maxnew2๋Š” return=+118.89%, raw excess=+87.00%p, exposure-matched excess=+97.61%p, Sharpe=0.89, PF=2.04, WF positive/Sh+=100%์˜€์ง€๋งŒ MDD=-26.95%, turnover/year=1034.2%๋กœ provisional ๊ฒŒ์ดํŠธ๋ฅผ ๋„˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. maxnew1๊ณผ ๊ฒฉ์›” ํ›„๋ณด๋Š” turnover/year๋ฅผ 423.0~674.4%๊นŒ์ง€ ๋‚ฎ์ท„์ง€๋งŒ benchmark excess Sharpe์™€ MDD๊ฐ€ ์•…ํ™”๋์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋‹จ์ˆœ ๊ต์ฒด ์ œํ•œ๋ณด๋‹ค ํฌํŠธํด๋ฆฌ์˜ค drawdown guard, ์žฌ์ง„์ž… cooldown, ์ƒ๊ด€/์—…์ข… ์ง‘์ค‘๋„ ํŽ˜๋„ํ‹ฐ์ฒ˜๋Ÿผ ์†์‹ค ๊ตฌ๊ฐ„ ์ž์ฒด๋ฅผ ์ค„์ด๋Š” ๊ตฌ์กฐ๊ฐ€ ์šฐ์„ ์ž…๋‹ˆ๋‹ค.

2026-05-12 follow-up: target_weight_drawdown_guard ํ›„๋ณด๊ตฐ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง์ „ ํ‰๊ฐ€ NAV ๊ธฐ์ค€ ํฌํŠธํด๋ฆฌ์˜ค ๋‚™ํญ์ด ์ž„๊ณ„๊ฐ’์„ ๋„˜์œผ๋ฉด ๋‹ค์Œ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ๋ชฉํ‘œ ๋…ธ์ถœ์„ floor๊นŒ์ง€ ๋‚ฎ์ถ”๊ณ , ํšŒ๋ณต ์งํ›„์—๋„ ์ง€์ • ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ํšŸ์ˆ˜๋งŒํผ cooldown์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๊ฒ€์ฆ์€ --candidate-family target_weight_drawdown_guard --top-n 200 full sweep์œผ๋กœ MDD๊ฐ€ ์‹ค์ œ๋กœ ๋‚ฎ์•„์ง€๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

2026-05-12 ์†์‹ค๋ฐฉ์–ด top-200 follow-up: --candidate-family target_weight_drawdown_guard --top-n 200 full sweep์—์„œ ํ›„๋ณด 5๊ฐœ๋ฅผ ๊ฒ€์ฆํ–ˆ๊ณ  ํŒ์ •์€ RUN_CANONICAL_EVALUATION์ž…๋‹ˆ๋‹ค. best=target_weight_rotation_top5_60_120_floor0_hold3_risk60_35_tol5_rankrisk60_pdd8_floor25_cd1๋Š” return=+99.53%, raw excess=+67.64%p, exposure-matched excess=+83.07%p, avg exposure=56.5%, Sharpe=1.02, PF=4.88, MDD=-19.56%, turnover/year=296.4%, WF positive/Sh+=66.7%์˜€์Šต๋‹ˆ๋‹ค. ํฌํŠธํด๋ฆฌ์˜ค guard๋Š” trigger 17ํšŒ, guard rebalance 20ํšŒ(74.1%)๋กœ ๋™์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ํ›„๋ณด target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_pdd10_floor40_cd1๋„ provisional ์กฐ๊ฑด์„ ํ†ต๊ณผํ–ˆ์ง€๋งŒ turnover/year=893.4%๋กœ ๋น„์šฉ ๋ฏผ๊ฐ๋„๊ฐ€ ๋” ํฝ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ 3๊ฐœ๋Š” MDD -20% ๋ฏธ๋งŒ ๋˜๋Š” benchmark excess Sharpe<=0๋กœ paper_only์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„๋Š” eligible 2๊ฐœ ํ›„๋ณด๋ฅผ canonical promotion evaluation์— ์˜ฌ๋ ค ๊ฐ™์€ ๊ธฐ์ค€์—์„œ ์žฌํ˜„์„ฑ์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ์ด artifact๋งŒ์œผ๋กœ paper/live ์ „ํ™˜์€ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2026-05-13 ์†์‹ค๋ฐฉ์–ด canonical follow-up: tools/evaluate_and_promote.py --canonical์— eligible 2๊ฐœ ์†์‹ค๋ฐฉ์–ด ํ›„๋ณด๋ฅผ ํฌํ•จํ•ด ์žฌํ‰๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด target_weight_rotation_top5_60_120_floor0_hold3_risk60_35๋Š” return=+171.20%, benchmark excess=+21.81%p, Sharpe=1.41, PF=4.24, MDD=-19.90%, turnover/year=794.0%, WF positive=100%, WF Sharpe+=83.3%๋กœ provisional_paper_candidate๋ฅผ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. pdd8/floor25 ํ›„๋ณด๋Š” return=+142.93%, Sharpe=1.43, PF=7.69, MDD=-15.89%, turnover/year=530.8%๋กœ ๋ฐฉ์–ด๋ ฅ์€ ์ข‹์•„์กŒ์ง€๋งŒ canonical benchmark excess=-6.46%p๋ผ paper_only์ž…๋‹ˆ๋‹ค. exp75/rankrisk90/pdd10/floor40 ํ›„๋ณด๋Š” return=+180.40%, benchmark excess=+31.01%p, Sharpe=1.49, PF=4.85, MDD=-19.24%, WF positive/Sh+=100%์˜€์ง€๋งŒ turnover/year=1026.3%๋กœ ๊ฒŒ์ดํŠธ๋ฅผ ๋„˜๊ฒจ paper_only์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” exp75 ๊ณ„์—ด์— tolerance ๋˜๋Š” ์‹ ๊ทœ ํŽธ์ž… ์ œํ•œ์„ ๊ฒฐํ•ฉํ•ด ์ดˆ๊ณผ์ˆ˜์ต๊ณผ WF ์•ˆ์ •์„ฑ์€ ์œ ์ง€ํ•˜๋ฉด์„œ turnover/year๋ฅผ 1000% ์•„๋ž˜๋กœ ๋‚ฎ์ถ”๋Š” ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค.

2026-05-13 exp75 ํšŒ์ „์œจ ์™„ํ™” follow-up: target_weight_drawdown_guard family์— exp75/rankrisk90/pdd10/floor40 ๊ธฐ๋ฐ˜ tol3, tol4, tol5, maxnew2, tol3_maxnew2 ๋ณ€ํ˜•์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. --candidate-family target_weight_drawdown_guard --top-n 200 ์žฌ๊ฒ€์ฆ์—์„œ๋Š” ํ›„๋ณด 10๊ฐœ ์ค‘ 4๊ฐœ๊ฐ€ canonical ํ‰๊ฐ€ ๋Œ€์ƒ์œผ๋กœ ๋‚จ์•˜๊ณ , ์ƒˆ tol4 ํ›„๋ณด๋Š” return=+81.19%, raw excess=+49.30%p, exposure-matched excess=+66.89%p, MDD=-19.33%, turnover/year=886.7%, WF positive/Sh+=100%๋กœ research ๊ธฐ์ค€์„ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. canonical ์žฌํ‰๊ฐ€์—์„œ๋Š” target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_tol4_pdd10_floor40_cd1๊ฐ€ return=+183.02%, benchmark excess=+33.63%p, Sharpe=1.50, PF=4.82, turnover/year=986.5%๋กœ ํšŒ์ „์œจ ๊ฒŒ์ดํŠธ๋Š” ํ†ต๊ณผํ–ˆ์ง€๋งŒ MDD=-20.25%๊ฐ€ -20% ์ œํ•œ์„ 0.25%p ์ดˆ๊ณผํ•ด paper_only์ž…๋‹ˆ๋‹ค. tol3๋Š” turnover/year=1009.0%, ์›๋ณธ์€ 1026.3%๋กœ ๊ฐ๊ฐ ํšŒ์ „์œจ ๋ฏธ๋‹ฌ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” tol4์˜ ๋‚ฎ์•„์ง„ ํšŒ์ „์œจ์„ ์œ ์ง€ํ•˜๋ฉด์„œ drawdown floor/cooldown ๋˜๋Š” ranking risk penalty๋ฅผ ๋” ๋ณด์ˆ˜ํ™”ํ•ด MDD๋ฅผ -20% ์•ˆ์ชฝ์œผ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๋ฐฉํ–ฅ์ด๋ฉฐ, ํ˜„์žฌ live/paper ์ „ํ™˜ ๋Œ€์ƒ์€ ๊ธฐ์กด risk-overlay ํ›„๋ณด๋งŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

2026-05-13 tol4 ๋‚™ํญ ์™„ํ™” follow-up: tol4 ๊ธฐ๋ฐ˜์œผ๋กœ pdd10_floor35_cd1, pdd8_floor40_cd1, pdd8_floor35_cd1, pdd10_floor40_cd2 ๋„ค ๋ณ€ํ˜•์„ ์ถ”๊ฐ€ํ•ด target_weight_drawdown_guard --top-n 200 full sweep์„ ๋‹ค์‹œ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ›„๋ณด 14๊ฐœ ์ค‘ ์‹ ๊ทœ ๋ณ€ํ˜•์€ canonical eligible์— ์ถ”๊ฐ€๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. pdd10_floor35๋Š” turnover/year=829.8%๋กœ ๋‚ฎ์•„์กŒ์ง€๋งŒ MDD=-20.20%, pdd8_floor35๋„ MDD=-20.20%๋ผ ์‹คํŒจํ–ˆ๊ณ , pdd8_floor40๊ณผ cooldown2๋Š” MDD/turnover๋Š” ํ†ต๊ณผ๊ถŒ์ด์—ˆ์ง€๋งŒ benchmark excess Sharpe<=0์œผ๋กœ ์ œ์™ธ๋์Šต๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ guard trigger/floor/cooldown๋งŒ ๋” ์กฐ์ด๋Š” ๋ฐฉ์‹์€ alpha ๋˜๋Š” MDD ์ค‘ ํ•˜๋‚˜๋ฅผ ์žƒ๊ธฐ ์‰ฌ์šฐ๋ฏ€๋กœ, ๋‹ค์Œ ํ›„๋ณด๋Š” ์ข…๋ชฉ ์„ ํƒ ๋‹จ๊ณ„์˜ downside rank penalty/์ƒ๊ด€ยท์—…์ข… ์ง‘์ค‘๋„ ํŽ˜๋„ํ‹ฐ๋‚˜ ๋น„์šฉ ๋ฏผ๊ฐ๋„ ๊ธฐ์ค€์„ ํ•จ๊ป˜ ์กฐ์ •ํ•˜๋Š” ์ชฝ์ด ์šฐ์„ ์ž…๋‹ˆ๋‹ค.

2026-05-13 rank-risk ๋ณด๊ฐ• follow-up: exp75 ๊ณ„์—ด์— rankrisk90_dd75, rankrisk120์„ ์ถ”๊ฐ€ํ•˜๊ณ  tol4+pdd10/floor40 guard์™€ ๊ฒฐํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. target_weight_drawdown_guard --top-n 200 ํ›„๋ณด 16๊ฐœ ์žฌ๊ฒ€์ฆ์—์„œ๋Š” rankrisk120_tol4๊ฐ€ return=+84.41%, raw excess=+52.52%p, MDD=-19.30%, turnover/year=919.4%, rankrisk90_dd75_tol4๊ฐ€ return=+82.56%, raw excess=+50.67%p, MDD=-19.54%, turnover/year=896.0%๋กœ ๊ธฐ์กด tol4๋ณด๋‹ค ์ข‹์•„์ ธ canonical ํ‰๊ฐ€ ๋Œ€์ƒ์— ํฌํ•จ๋์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ canonical top-20 ์žฌํ‰๊ฐ€์—์„œ๋Š” ๊ฐ๊ฐ return=+125.69%/+125.99%, turnover/year=927.9%/947.6%์˜€์ง€๋งŒ MDD=-20.74%/-20.76%์™€ benchmark excess=-23.70%p/-23.40%p๋กœ paper_only์ž…๋‹ˆ๋‹ค. ํŒจ๋„ํ‹ฐ ๊ฐ•๋„๋งŒ ํ‚ค์šฐ๋ฉด top-200์—์„œ๋Š” ์ข‹์•„์ ธ๋„ canonical ๋Œ€ํ˜•์ฃผ ๊ตฌ๊ฐ„ alpha๊ฐ€ ๊บพ์ด๋ฏ€๋กœ, ๋‹ค์Œ์€ sector/correlation cap์ฒ˜๋Ÿผ ๋ถ„์‚ฐ ์ œ์•ฝ์„ ์„ ํƒ ๋‹จ๊ณ„์— ์ง์ ‘ ๋„ฃ๋Š” ์ชฝ์„ ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

2026-05-13 sector cap follow-up: FDR KRX ๋ชฉ๋ก์— ์—…์ข… ์ปฌ๋Ÿผ์ด ์—†๋Š” ํ™˜๊ฒฝ์—์„œ๋„ get_sector_map()์ด KRX KIND ์ƒ์žฅ๋ฒ•์ธ ๋ชฉ๋ก(2,766๊ฐœ ์—…์ข… ๋งคํ•‘)์œผ๋กœ fallbackํ•˜๋„๋ก ๋ณด๊ฐ•ํ•˜๊ณ , target_weight_drawdown_guard --top-n 200์— sectorcap1/2 ํ›„๋ณด๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. sectorcap2๋Š” ์‹ค์ œ ์„นํ„ฐ ๋งต ์ ์šฉ ๊ธฐ์ค€์œผ๋กœ rankrisk120_tol4_sectorcap2 return=+85.49%, raw excess=+53.60%p, MDD=-19.94%, turnover/year=941.5%, rankrisk90_tol4_sectorcap2 return=+82.57%, raw excess=+50.68%p, MDD=-19.59%, turnover/year=909.3%๋กœ canonical ํ‰๊ฐ€ ๋Œ€์ƒ์— ํฌํ•จ๋์Šต๋‹ˆ๋‹ค. canonical top-20์—์„œ๋Š” rankrisk90_tol4_sectorcap2๊ฐ€ return=+185.39%, benchmark excess=+36.00%p, turnover/year=981.0%๋กœ ์›๋ณธ tol4๋ณด๋‹ค ์ข‹์•„์กŒ์ง€๋งŒ MDD=-20.22%๋ผ paper_only์ž…๋‹ˆ๋‹ค. rankrisk120_tol4_sectorcap2๋Š” sector cap ์ ์šฉ ํ›„์—๋„ canonical ๊ฒฐ๊ณผ๊ฐ€ ๊ธฐ์กด๊ณผ ๊ฐ™์•„ benchmark excess=-23.70%p, MDD=-20.74%๋กœ ์ œ์™ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ํ›„๋ณด๋Š” ์„นํ„ฐ ์ˆ˜๋Ÿ‰ cap๋งŒ์œผ๋กœ ๋ถ€์กฑํ•œ ๋‚™ํญ 0.22%p๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ƒ๊ด€๋„ cap, ์›”๋ณ„ ์†์‹ค ์ดํ›„ ์žฌ์ง„์ž… ์ œํ•œ, ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐํ˜• target selection์„ ๊ฒฐํ•ฉํ•˜๋Š” ์ชฝ์ž…๋‹ˆ๋‹ค.

2026-05-18 sector map cache follow-up: DataCollector.get_sector_map()์€ FDR/KRX KIND/pykrx ์—…์ข… ๋งคํ•‘์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ฝ์œผ๋ฉด reports/sector_map_cache.json์— schema v1 ์บ์‹œ๋ฅผ ์ €์žฅํ•˜๊ณ , ์‹ค์‹œ๊ฐ„ ์†Œ์Šค๊ฐ€ ๋ชจ๋‘ ๋น„์–ด ์žˆ์œผ๋ฉด ํ•ด๋‹น ์บ์‹œ๋ฅผ fallback์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  ์บ์‹œ๋Š” KRX KIND ๊ธฐ์ค€ 2,766๊ฐœ ์ข…๋ชฉ์ด๋ฉฐ, target-weight sector cap plan์€ ์บ์‹œ๊ฐ€ ์žˆ๋”๋ผ๋„ planning universe ์ „์ฒด ์„นํ„ฐ๊ฐ€ ๋งคํ•‘๋˜์ง€ ์•Š์œผ๋ฉด target_weight_sector_map_incomplete๋กœ fail-closed ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. KRX KIND๊ฐ€ ์šฐ์„ ์ฃผ ์„นํ„ฐ๋ฅผ ์ง์ ‘ ์ฃผ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” 005935 โ†’ 005930์ฒ˜๋Ÿผ ๊ฐ™์€ 5์ž๋ฆฌ stem์˜ ๋ณดํ†ต์ฃผ ์„นํ„ฐ๋ฅผ ์ถ”๋ก ํ•˜๊ณ  diagnostics์˜ sector_map_inferred_symbols์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. no-order --daily-ops-summary/--readiness-audit๋Š” sector map blocker๋ฟ ์•„๋‹ˆ๋ผ FDR/yfinance/KIS fallback ๋น„ํ™œ์„ฑํ™”๋กœ ์ธํ•œ ๊ฐ€๊ฒฉ ์ˆ˜์ง‘ ์‹คํŒจ๋„ traceback ๋Œ€์‹  BLOCKED failure artifact๋กœ ๋‚จ๊น๋‹ˆ๋‹ค.

2026-05-13 correlation cap follow-up: target selection ๋‹จ๊ณ„์— max_pairwise_correlation, correlation_lookback_days, correlation_min_periods๋ฅผ ์ถ”๊ฐ€ํ•ด ์ด๋ฏธ ์„ ํƒ๋œ ์ข…๋ชฉ๊ณผ์˜ ๊ณผ๊ฑฐ ์ˆ˜์ต๋ฅ  ์ƒ๊ด€์ด ์ž„๊ณ„๊ฐ’์„ ๋„˜๋Š” ํ›„๋ณด๋ฅผ ๊ฑด๋„ˆ๋›ฐ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. target_weight_drawdown_guard --top-n 200์—์„œ๋Š” corrcap85์™€ sectorcap2_corrcap85๊ฐ€ canonical ํ‰๊ฐ€ ๋Œ€์ƒ์— ํฌํ•จ๋๊ณ  ๊ด€์ธก ์ตœ๋Œ€ ์„ ํƒ ์ƒ๊ด€๋„๋Š” 0.8147๋กœ ์ œํ•œ๋์ง€๋งŒ, return/MDD/turnover๋Š” ๊ฐ๊ฐ ๊ธฐ์กด tol4 ๋ฐ sectorcap2์™€ ๋™์ผํ–ˆ์Šต๋‹ˆ๋‹ค. corrcap80์€ ๊ด€์ธก ์ƒ๊ด€๋„๋ฅผ 0.7675๊นŒ์ง€ ๋‚ฎ์ท„์ง€๋งŒ return=+70.22%, raw excess=+38.33%, MDD=-19.33%, turnover/year=908.3%์—์„œ benchmark excess Sharpe<=0์œผ๋กœ ์ œ์™ธ๋์Šต๋‹ˆ๋‹ค. canonical top-20์—์„œ๋„ corrcap85๋Š” MDD=-20.25%, sectorcap2_corrcap85๋Š” MDD=-20.22%๋กœ ๊ธฐ์กด ํ›„๋ณด์™€ ๊ฐ™์€ paper_only์ž…๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ 0.85 ๋‹จ์ˆœ pairwise cap์€ ๋„ˆ๋ฌด ๋А์Šจํ•˜๊ณ , 0.80 ๋‹จ๋… cap์€ alpha๋ฅผ ๊นŽ์œผ๋ฏ€๋กœ ๋‹ค์Œ์€ ์ƒ๊ด€๋„ penalty๋ฅผ ๋žญํ‚น ์ ์ˆ˜์— ์ง์ ‘ ์„ž๊ฑฐ๋‚˜ ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐ/์†์‹ค ํ›„ ์žฌ์ง„์ž… ์ œํ•œ๊ณผ ๊ฒฐํ•ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2026-05-13 correlation rank penalty follow-up: ๋‹จ์ˆœ hard cap ๋Œ€์‹  ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ์‹œ์ ์˜ score_row์— ํ‰๊ท  ์–‘์˜ ์ƒ๊ด€๋„ ๊ธฐ๋ฐ˜ correlation_rank_penalty_weight๋ฅผ ์ฐจ๊ฐํ•˜๋Š” ํ›„๋ณด๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. top-200 target_weight_drawdown_guard์—์„œ๋Š” sectorcap2_corrpen05๊ฐ€ return=+84.22%, raw excess=+52.33%p, MDD=-19.59%, turnover/year=912.5%, corrpen10์ด return=+83.50%, raw excess=+51.61%p, MDD=-19.96%, turnover/year=892.3%, corrpen05๊ฐ€ return=+82.82%, raw excess=+50.93%p, MDD=-19.33%, turnover/year=889.9%๋กœ ๋ชจ๋‘ canonical ํ›„๋ณด์— ํฌํ•จ๋์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ canonical top-20์—์„œ๋Š” corrpen05 return=+141.09%, benchmark excess=-8.30%p, MDD=-20.25%, corrpen10 return=+128.43%, benchmark excess=-20.96%p, MDD=-20.25%, sectorcap2_corrpen05 return=+143.11%, benchmark excess=-6.28%p, MDD=-20.22%๋กœ ๋ชจ๋‘ paper_only์ž…๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ ํ‰๊ท  ์ƒ๊ด€๋„ ์ ์ˆ˜ ์ฐจ๊ฐ์€ top-200์—์„œ๋Š” ๋ถ„์‚ฐ ๊ฐœ์„  ์‹ ํ˜ธ๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ ๋Œ€ํ˜•์ฃผ canonical alpha๋ฅผ ํฌ๊ฒŒ ๊นŽ์•„ ์šด์˜ ์Šน๊ฒฉ์—๋Š” ๋ถ€์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์ ์ˆ˜ ์ฐจ๊ฐ๋ณด๋‹ค ์†์‹ค ํ›„ ์žฌ์ง„์ž… ์ œํ•œ์ด๋‚˜ ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐํ˜• target selection์ฒ˜๋Ÿผ ๋‚™ํญ์„ ์ง์ ‘ ๊ฒจ๋ƒฅํ•˜๋Š” ์ œ์•ฝ์„ ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค.

2026-05-13 loss re-entry guard follow-up: ์ง์ „ ์‹คํ–‰ ๋ฆฌ๋ฐธ๋Ÿฐ์Šค ํ›„ ํ‰๊ฐ€ NAV ๋Œ€๋น„ ์†์‹ค๋ฅ ์ด loss_reentry_guard_trigger_pct๋ฅผ ๋„˜์œผ๋ฉด ์ง€์ • cooldown ๋™์•ˆ ์‹ ๊ทœ ํŽธ์ž… ์ˆ˜๋ฅผ loss_reentry_guard_max_new_targets๋กœ ๋‚ฎ์ถ”๋Š” ์˜ต์…˜์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. target_weight_drawdown_guard --top-n 200์— reentry4_maxnew0_cd1, reentry3_maxnew0_cd1, sectorcap2_reentry4_maxnew0_cd1 ํ›„๋ณด๋ฅผ ์ถ”๊ฐ€ํ–ˆ์ง€๋งŒ, ์†์‹ค ์งํ›„ ์ƒˆ ์ข…๋ชฉ ํŽธ์ž…์„ ๋ง‰๋Š” ๋ฐฉ์‹์€ ํšŒ์ „์œจ๋งŒ ๋‚ฎ์ถ”๊ณ  MDD๋ฅผ ์•…ํ™”์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. sectorcap2_reentry4๋Š” return=+84.68%, raw excess=+52.79%p, turnover/year=793.8%์˜€์ง€๋งŒ MDD=-22.34%, reentry4๋Š” return=+57.71%, MDD=-27.29%, reentry3์€ return=+28.93%, MDD=-35.30%๋กœ ๋ชจ๋‘ paper_only๋ผ canonical ํ‰๊ฐ€ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ณด์œ  ์ข…๋ชฉ ๊ณ ์ฐฉ์„ ๋งŒ๋“œ๋Š” ์‹ ๊ทœ ํŽธ์ž… ์ฐจ๋‹จ๋ณด๋‹ค, ์ข…๋ชฉ๋ณ„ ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐ์ด๋‚˜ ํฌ์ง€์…˜๋ณ„ ์†์ ˆ/๊ฐ์‚ฐ์ฒ˜๋Ÿผ ์†์‹ค ์›์ธ์„ ์ง์ ‘ ์ค„์ด๋Š” ์ œ์•ฝ์ด ์šฐ์„ ์ž…๋‹ˆ๋‹ค.

2026-05-13 position loss reduction follow-up: ์‹ ๊ทœ ํŽธ์ž…์„ ๋ง‰์•„ ์†์‹ค ์ข…๋ชฉ์„ ๊ณ ์ฐฉ์‹œํ‚ค๋Š” ๋Œ€์‹ , ์ง์ „ ํ™•์ • ์ข…๊ฐ€ ๊ธฐ์ค€ ๋ณด์œ  ์ข…๋ชฉ ์†์‹ค๋ฅ ์ด position_loss_reduce_trigger_pct๋ฅผ ๋„˜์œผ๋ฉด ๋‹ค์Œ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ๋ชฉํ‘œ ๊ธˆ์•ก์„ position_loss_reduce_target_fraction๊นŒ์ง€ ๊ฐ์‚ฐํ•˜๋Š” ์˜ต์…˜์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฐ ๋งค๋„๋Š” ๊ธฐ์กด ๋น„์šฉ/PnL/turnover ๊ฒฝ๋กœ๋ฅผ ๊ทธ๋Œ€๋กœ ํƒ€๋ฉฐ, ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ tolerance ๋•Œ๋ฌธ์— ์œ„ํ—˜ ๊ฐ์‚ฐ์ด ์ƒ๋žต๋˜์ง€ ์•Š๋„๋ก ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค๋ฐ์ดํ„ฐ target_weight_drawdown_guard --top-n 200 full sweep์—์„œ๋Š” sectorcap2_posloss8 ํ›„๋ณด๊ฐ€ return=+105.79%, raw excess=+73.90%p, MDD=-18.96%, Sharpe=1.00์œผ๋กœ ํ†ต๊ณผํ–ˆ์ง€๋งŒ canonical์—์„œ๋Š” turnover/year=1006.2%๋กœ paper_only์˜€์Šต๋‹ˆ๋‹ค. ํ›„์†์œผ๋กœ tol5๋ฅผ ๊ฒฐํ•ฉํ•˜์ž target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_tol5_sectorcap2_posloss8_frac50_pdd10_floor40_cd1๊ฐ€ top-200 return=+112.16%, raw excess=+80.27%p, MDD=-19.23%, Sharpe=1.04๋กœ ํ†ต๊ณผํ–ˆ๊ณ , canonical top-20์—์„œ๋„ return=+198.15%, benchmark excess=+48.76%p, Sharpe=1.57, PF=5.58, MDD=-17.18%, turnover/year=993.9%, WF positive/Sh+=100%๋กœ ์‹ ๊ทœ provisional_paper_candidate๊ฐ€ ๋์Šต๋‹ˆ๋‹ค. ๋‹จ live๋Š” ์—ฌ์ „ํžˆ 60์ผ paper evidence์™€ target-weight verified proof๊ฐ€ ์—†์–ด ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. core.target_weight_rotation.build_target_weight_plan()์€ paper/pilot plan์—์„œ๋„ rank_penalty_mode=downside_risk, max_targets_per_sector, position_loss_reduce_*, portfolio_drawdown_guard_*๋ฅผ ์ ์šฉํ•˜๊ณ , sector map ๋ˆ„๋ฝ ๋˜๋Š” drawdown guard ๋ช…์‹œ ์ƒํƒœ ๋ˆ„๋ฝ์€ fail-closed๋กœ ๋ง‰์Šต๋‹ˆ๋‹ค. pilot adapter๋Š” ๊ธฐ์กด paper evidence์˜ total NAV, peak, guard cooldown์„ ์ƒํƒœ๋กœ ๋ณต์›ํ•˜๋ฉฐ evidence snapshot์—๋„ guard ๊ฒฐ๊ณผ๋ฅผ ๋‚จ๊ฒจ ๋‹ค์Œ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์˜ cooldown์„ ์ด์–ด๊ฐ‘๋‹ˆ๋‹ค.

2026-05-13 volatility budget target selection follow-up: ์„ ํƒ ์ข…๋ชฉ์€ ์œ ์ง€ํ•˜๋˜ ๋ชฉํ‘œ ๊ธˆ์•ก์„ ๋™์ผ๊ฐ€์ค‘์ด ์•„๋‹ˆ๋ผ rolling ์‹คํ˜„ ๋ณ€๋™์„ฑ์˜ ์—ญ์ˆ˜๋กœ ๋ฐฐ๋ถ„ํ•˜๋Š” target_allocation_mode=inverse_volatility๋ฅผ target-weight research backtester์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. allocation_vol_lookback_days, allocation_vol_min_periods, allocation_vol_floor_pct, allocation_max_sleeve_weight_pct๋ฅผ artifact metrics์— ๋‚จ๊น๋‹ˆ๋‹ค. ์‹ค๋ฐ์ดํ„ฐ target_weight_volatility_budget --top-n 200 full sweep์—์„œ๋Š” canonical liquidity 200๊ฐœ ์ค‘ ์œ ๋™์„ฑ ํ†ต๊ณผ 164๊ฐœ, benchmark coverage 100%์—์„œ best=target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_tol4_pdd10_floor40_cd1_volbudget60_cap35๊ฐ€ return=+78.77%, raw excess=+46.88%p, exposure-matched excess=+63.79%p, avg exposure=55.2%, Sharpe=0.81, PF=1.96, MDD=-18.96%, trades=107๋กœ provisional_paper_candidate๊ฐ€ ๋์Šต๋‹ˆ๋‹ค. sectorcap2+volbudget60 ํ›„๋ณด๋„ return=+77.18%, raw excess=+45.29%p, MDD=-19.19%๋กœ ํ†ต๊ณผํ–ˆ๊ณ , volbudget90 ํ›„๋ณด๋Š” benchmark excess Sharpe<=0 ๋ณ‘๋ชฉ์ด๋ผ ์ œ์™ธํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ tools/evaluate_and_promote.py --canonical ์žฌํ‰๊ฐ€์—์„œ๋Š” volbudget60 ํ›„๋ณด๊ฐ€ return=+170.73%, benchmark excess=+21.34%p, Sharpe=1.44, PF=4.53, turnover/year=982.6%, WF positive/Sh+=100%์˜€์ง€๋งŒ MDD=-20.82%๋กœ paper_only์ž…๋‹ˆ๋‹ค. sectorcap2+volbudget60๋„ return=+173.80%, benchmark excess=+24.41%p, Sharpe=1.46, PF=4.68, turnover/year=978.1%, WF positive/Sh+=100%์˜€์ง€๋งŒ MDD=-20.89%๋ผ paper_only์ž…๋‹ˆ๋‹ค. ๋ณ€๋™์„ฑ ์˜ˆ์‚ฐ์€ ํšŒ์ „์œจ๊ณผ ์ดˆ๊ณผ์ˆ˜์ต์„ ์œ ์ง€ํ–ˆ์ง€๋งŒ ๋Œ€ํ˜•์ฃผ canonical MDD๊ฐ€ ๋” ์•…ํ™”๋์œผ๋ฏ€๋กœ paper/live ์ „ํ™˜ ๋Œ€์ƒ์€ ์•„๋‹ˆ๋ฉฐ, research-only ๋ฐฐ๋ถ„ ๋กœ์ง์ด๋ฏ€๋กœ ํ–ฅํ›„ ํ†ต๊ณผ ํ›„๋ณด๊ฐ€ ๋‹ค์‹œ ์ƒ๊ธฐ๋ฉด paper pilot ์ „ core.target_weight_rotation plan builder์— ๊ฐ™์€ ๋ฐฐ๋ถ„ ์‚ฐ์‹์„ ์ด์‹ํ•˜๊ณ  params_hash ์ผ์น˜๊นŒ์ง€ ๊ฒ€์ฆํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์—ฐ๊ตฌ๋Š” ๋ชฉํ‘œ๋น„์ค‘ ๋ฐฐ๋ถ„๋ณด๋‹ค ํฌ์ง€์…˜๋ณ„ ์†์‹ค ๊ฐ์‚ฐ ๋˜๋Š” ๋” ๋ณด์ˆ˜์ ์ธ drawdown guard๋ฅผ ๊ฒฐํ•ฉํ•ด MDD๋ฅผ -20% ์•ˆ์ชฝ์œผ๋กœ ์•ˆ์ •ํ™”ํ•˜๋Š” ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค.

2026-05-13 research empty-universe guard: canonical universe ๋ชฉ๋ก ์กฐํšŒ ์‹คํŒจ, ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์‹คํŒจ, strict ์œ ๋™์„ฑ ํ•„ํ„ฐ ๋•Œ๋ฌธ์— research universe๊ฐ€ 0๊ฐœ๊ฐ€ ๋˜๋ฉด ํ›„๋ณด๋ณ„ 0% ์„ฑ๊ณผ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  benchmark/candidate ํ‰๊ฐ€๋ฅผ ๊ฑด๋„ˆ๋›ฐ๋„๋ก ๋ณด๊ฐ•ํ–ˆ์Šต๋‹ˆ๋‹ค. artifact์™€ Markdown์—๋Š” INSUFFICIENT_BENCHMARK_DATA, empty_universe_reason, selection_error, skipped_due_to_data๊ฐ€ ๋‚จ์•„ ๋ฐ์ดํ„ฐ ๋ฌธ์ œ๋ฅผ ์ „๋žต ์„ฑ๊ณผ๋กœ ์˜คํ•ดํ•˜์ง€ ์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ „๋žต ์ƒํƒœ Ret% PF WF P% WF Sh+% Paper Status
relative_strength_rotation provisional_paper_candidate +18.09 1.62 100 83.3 โ€”
target_weight_rotation_top5_60_120_floor0_exp75_rankrisk90_tol5_sectorcap2_posloss8_frac50_pdd10_floor40_cd1 provisional_paper_candidate (default capped pilot) +198.15 5.58 100 100 ์ „์šฉ paper/pilot adapter ๊ธฐ๋ณธ ํ›„๋ณด, 60์˜์—…์ผ verified pilot evidence ํ•„์š”
target_weight_rotation_top5_60_120_floor0_hold3_risk60_35 provisional_paper_candidate (previous default) +171.20 4.24 100 83.3 ์ด์ „ ๊ธฐ๋ณธ ํ›„๋ณด, ๊ด€์ฐฐ ์œ ์ง€
scoring paper_only +11.22 1.07 83.3 50.0 risk-adjusted alpha ๋ฏธ๋‹ฌ
breakout_volume disabled (research_only) -13.31 0.79 0 0 โ€”
mean_reversion disabled (research_only) -8.36 0.85 33.3 0 โ€”
trend_following disabled (research_only) -6.94 0.67 16.7 0 โ€”
ensemble disabled (research_only) โ€” โ€” 0 0 โ€”

์ฃผ์˜

์‹ค์ „ ํˆฌ์ž… ์ „์—๋Š” ๋ฐฑํ…Œ์ŠคํŠธ, ๊ฒ€์ฆ, ๋ชจ์˜ํˆฌ์ž๋ฅผ ์ถฉ๋ถ„ํžˆ ๊ฑฐ์นœ ๋’ค ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
ํ˜„์žฌ scoring์€ ๊ด€์ฐฐ์šฉ paper_only๋กœ ๊ฐ•๋“ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‹ ๊ทœ ์šฐ์„  ์‹คํ—˜์€ risk-adjusted ๊ธฐ์ค€์„ ํ†ต๊ณผํ•œ ํ›„๋ณด๋งŒ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋ฉฐ, Paper Evidence ์ฒด๊ณ„๋กœ ์Šน๊ฒฉ/๊ฐ•๋“ฑ ๊ทผ๊ฑฐ๋ฅผ ์ž๋™ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. Paper ์šด์˜ ๋„๊ตฌ: tools/run_paper_evidence_pipeline.py (backfill/finalize/package), tools/paper_preflight.py, tools/paper_launch_readiness.py, tools/paper_pilot_control.py, tools/paper_runtime_status.py, tools/research_candidate_sweep.py, tools/target_weight_rotation_pilot.py. tools/paper_pilot_control.py์™€ tools/paper_runtime_status.py์˜ ์ƒํƒœ ๋ณ€๊ฒฝ/์กฐํšŒ ์•ก์…˜ ์˜ต์…˜์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜๋งŒ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ™œ์„ฑํ™”์™€ ๋น„ํ™œ์„ฑํ™”์ฒ˜๋Ÿผ ์„œ๋กœ ๋‹ค๋ฅธ ์•ก์…˜์„ ๊ฐ™์€ ๋ช…๋ น์— ์„ž์œผ๋ฉด ํŒŒ์ผ ๊ธฐ๋ก์ด๋‚˜ ๋Ÿฐํƒ€์ž„ ์ƒํƒœ ์กฐํšŒ๋ฅผ ์ง„ํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. tools/paper_preflight.py์™€ tools/paper_launch_readiness.py๋„ ์ ๊ฒ€ ๋Œ€์ƒ์€ --strategy ๋˜๋Š” --all ์ค‘ ํ•˜๋‚˜๋งŒ ํ—ˆ์šฉํ•˜๋ฉฐ, ๋‘ ์˜ต์…˜์„ ํ•จ๊ป˜ ๋„˜๊ธฐ๋ฉด DB ์ดˆ๊ธฐํ™”๋‚˜ ์šด์˜ artifact ์ƒ์„ฑ ์ „์— ์ฆ‰์‹œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. preflight CLI๋Š” overall fail ๋˜๋Š” entry ์ฐจ๋‹จ ๊ฒฐ๊ณผ๋ฅผ non-zero๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ , launch readiness CLI๋Š” READY๊ฐ€ ์•„๋‹ˆ๋ฉด non-zero๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. readiness ๋ฆฌํฌํŠธ๋งŒ ๋งŒ๋“ค๊ณ  ์‹ถ์„ ๋•Œ๋งŒ --report-only๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. tools/paper_bootstrap.py๋Š” ๋นˆ watchlist, ๋นˆ/์—ญ์ „ ๋‚ ์งœ ๋ฒ”์œ„, ์š”์ฒญ์ผ canonical evidence ๋ฏธ์ƒ์„ฑ ์ƒํƒœ๋ฅผ incomplete๋กœ ๋ณด๊ณ  non-zero ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. target-weight ํ›„๋ณด๋Š” capped pilot ์Šน์ธ ์ „ tools/target_weight_rotation_pilot.py --record-shadow-evidence, --shadow-days 3, ๋˜๋Š” --shadow-start-date YYYY-MM-DD --shadow-end-date YYYY-MM-DD๋กœ dry-run plan artifact, shadow readiness evidence, launch readiness artifact, plan ๊ธฐ๋ฐ˜ cap ์ถ”์ฒœ๊ณผ enable ๋ช…๋ น์ด ํฌํ•จ๋œ pilot runbook์„ ๋จผ์ € ๋ˆ„์ ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ --readiness-audit๋กœ ์ฃผ๋ฌธ ์ œ์ถœ์ด๋‚˜ shadow/pilot evidence ๊ธฐ๋ก ์—†์ด clean shadow, launch readiness, active pilot caps, ์ค‘๋ณต ์„ธ์…˜, ์‹คํ–‰์ผ/์žฅ ์‹œ๊ฐ„, ์‹คํ–‰ ์ „ ํฌ์ง€์…˜ ๋“œ๋ฆฌํ”„ํŠธ, ์ข…๋ชฉ/๋ฒค์น˜๋งˆํฌ ๊ฐ€๊ฒฉ ์ตœ์‹ ์„ฑ, ์ถ”์ฒœ cap ์ถฉ์กฑ ์—ฌ๋ถ€, ์ตœ๊ทผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Œ€๊ธˆ ๋Œ€๋น„ ์ฃผ๋ฌธ ๋น„์œจ, ๋น„์šฉ ๋ฐ˜์˜ ํ›„ ํ˜„๊ธˆ/ํˆฌ์ž๋น„์ค‘ ํ•œ๋„๋ฅผ JSON artifact์™€ Markdown ์šด์˜ ๋ฆฌํฌํŠธ๋กœ ์ ๊ฒ€ํ•ฉ๋‹ˆ๋‹ค. ์œ ๋™์„ฑ preflight๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฃผ๋ฌธ๋ณ„ 20์ผ ํ‰๊ท  ๊ฑฐ๋ž˜๋Œ€๊ธˆ์˜ 5% ์ดˆ๊ณผ๋ฅผ ์ฐจ๋‹จํ•˜๋ฉฐ --max-order-adv-pct๋กœ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. pre-trade risk ๊ฒ€์ฆ์€ ์ฃผ๋ฌธ๋ณ„ ์ˆ˜์ˆ˜๋ฃŒ/์„ธ๊ธˆ/๋™์  ์Šฌ๋ฆฌํ”ผ์ง€๋ฅผ ๋ฐ˜์˜ํ•œ ์˜ˆ์ƒ ์ฒด๊ฒฐ๊ฐ€๋กœ ํ˜„๊ธˆ ๋ถ€์กฑ, ์ตœ์†Œ ํ˜„๊ธˆ๋น„์ค‘, ์ดํˆฌ์ž๋น„์ค‘, ์ข…๋ชฉ๋ณ„ ๋น„์ค‘, ์ตœ๋Œ€ ๋ณด์œ  ์ข…๋ชฉ ์ˆ˜ ์œ„๋ฐ˜์„ ์‹คํ–‰ ์ „์— ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. Markdown ๋ฆฌํฌํŠธ์—๋Š” shadow ์ˆ˜์ง‘, audit ์žฌ์‹คํ–‰, ์ถ”์ฒœ cap ์Šน์ธ, capped paper ์‹คํ–‰ ๋ช…๋ น์ด ํ•จ๊ป˜ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. --shadow-days N์€ ํœด์žฅ/๋ฐ์ดํ„ฐ ๊ณต๋ฐฑ์œผ๋กœ ๊ฐ™์€ ๊ฑฐ๋ž˜์ผ์— ๋งคํ•‘๋˜๋Š” ๊ฒฝ์šฐ ๊ณผ๊ฑฐ ํ‰์ผ์„ ์ถ”๊ฐ€ ์Šค์บ”ํ•ด N๊ฐœ ๊ณ ์œ  resolved trade_day ์ถฉ์กฑ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋ฉฐ, ๋ชฉํ‘œ ๋ฏธ๋‹ฌ์ด๋‚˜ ๋‚ ์งœ๋ณ„ ์‹คํŒจ๊ฐ€ ์žˆ์œผ๋ฉด CLI๊ฐ€ non-zero๋กœ ์ข…๋ฃŒํ•ด ์ž๋™ํ™”๊ฐ€ ๋ถˆ์™„์ „ํ•œ ์ฆ๊ฑฐ๋ฅผ ์„ฑ๊ณต์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ํ˜• pilot evidence๋Š” ๊ฐ™์€ candidate/trade_day์˜ ๊ธฐ์กด pilot session artifact๊ฐ€ ์—†๊ณ , run_pilot ์ ๊ฒ€๊ณผ execute_plan ์ฃผ๋ฌธ ์ œ์ถœ ์ง์ „ ์žฌํ™•์ธ์—์„œ ์‹ค์ œ paper position์ด ๊ณ„ํš ์ž…๋ ฅ ์žฅ๋ถ€ position_quantities_before์™€ ๋ชจ๋‘ ์ผ์น˜ํ•˜๋ฉฐ, plan.trade_day๊ฐ€ KST ์‹คํ–‰์ผ๊ณผ ์ผ์น˜ํ•˜๊ณ  KRX ์ •๊ทœ์žฅ ์ฃผ๋ฌธ ๊ฐ€๋Šฅ ์‹œ๊ฐ„์ธ ๊ฒฝ์šฐ์—๋งŒ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์œ ๋™์„ฑ preflight์™€ pre-trade risk ๊ฒ€์ฆ์„ ํ†ต๊ณผํ•˜๊ณ , ๋ชจ๋“  ๊ณ„ํš ์ฃผ๋ฌธ์ด ์„ฑ๊ณตํ•˜๋ฉฐ, ์„ฑ๊ณต ์ฃผ๋ฌธ ๊ฒฐ๊ณผ์™€ ๋‹น์ผ TradeHistory fill ์ง‘๊ณ„์˜ ์ข…๋ชฉ/๋ฐฉํ–ฅ/์ˆ˜๋Ÿ‰์ด ๊ณ„ํš๊ณผ ์ผ์น˜ํ•˜๊ณ , ์‹คํ–‰ ํ›„ ์‹ค์ œ paper position ์ „์ฒด๊ฐ€ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ ํ›„ target_quantities_after ์žฅ๋ถ€์™€ ์ผ์น˜ํ•˜๊ณ  ๊ณ„ํš ๋ฐ– ์–‘์ˆ˜ ํฌ์ง€์…˜์ด ์—†์„ ๋•Œ๋งŒ pilot_paper๋กœ ์ˆ˜์ง‘๋ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๋‚ ์งœ evidence๊ฐ€ ์ด๋ฏธ ์žˆ์œผ๋ฉด ์ตœ์‹  canonical record๋„ pilot_paper/authorized/target-weight complete/execution-market-session-allowed/liquidity-complete/pre-trade-risk-complete/fill-complete ์กฐ๊ฑด์„ ํ†ต๊ณผํ•ด์•ผ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ค‘๋ณต ์‹คํ–‰์€ ๊ธฐ๋ณธ ์ฐจ๋‹จํ•˜๋ฉฐ ์šด์˜์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์žฌ์‹œ๋„ํ•ด์•ผ ํ•  ๋•Œ๋งŒ --allow-rerun์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ถ€๋ถ„ ์‹คํ–‰/์ค‘๋‹จ/์ค‘๋ณต ์‹คํ–‰/์ฃผ๋ฌธ ๊ฒฐ๊ณผ ๋ถˆ์ผ์น˜/์ฒด๊ฒฐ ๊ธฐ๋ก ๋ถˆ์ผ์น˜/๊ธฐ์กด evidence ๊ฒ€์ฆ ์‹คํŒจ/์‹คํ–‰์ผ ๋ถˆ์ผ์น˜/์žฅ ์‹œ๊ฐ„ ์™ธ ์‹คํ–‰/์‹คํ–‰ ์ „ ํฌ์ง€์…˜ ๋“œ๋ฆฌํ”„ํŠธ/์œ ๋™์„ฑ preflight ์‹คํŒจ/pre-trade risk ์‹คํŒจ/์‹คํ–‰ ํ›„ ํฌ์ง€์…˜ ๋ถˆ์ผ์น˜๋Š” execution-backed ์Šน๊ฒฉ ์ฆ๊ฑฐ์—์„œ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค.

Target-weight 60์˜์—…์ผ pilot manifest: --readiness-audit๋Š” ์šด์˜ ๋ฆฌํฌํŠธ์™€ ํ•จ๊ป˜ target_weight_paper_experiment_manifest_*.json์„ ์ƒ์„ฑํ•ด ํ›„๋ณด snapshot, ์ถ”์ฒœ cap, ์ฐจ๋‹จ ์‚ฌ์œ , ์‹คํ–‰ ๋ช…๋ น, ๋ฐ์ดํ„ฐ ํ’ˆ์งˆ ์ง„๋‹จ, ์Šน๊ฒฉ ์ฆ๊ฑฐ ์กฐ๊ฑด์„ ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค. --daily-ops-summary๋Š” readiness, risk check, ๋ฐ์ดํ„ฐ ํ’ˆ์งˆ, ์‹คํ–‰์ผ ์ผ์น˜ ์—ฌ๋ถ€, ์žฅ ์‹œ๊ฐ„ ์ฃผ๋ฌธ ๊ฐ€๋Šฅ ์—ฌ๋ถ€, verified pilot day ์ง„ํ–‰๋ฅ , ๋‹ค์Œ ์‹คํ–‰ ๋ช…๋ น์„ target_weight_daily_ops_summary_*.json/.md๋กœ ๋ฌถ์–ด ๋งค์ผ ์šด์˜ ํŒ๋‹จ์„ ํ•œ ๋ฒˆ์— ํ™•์ธํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์ผ pilot_paper ์ฆ๊ฑฐ๊ฐ€ ์ด๋ฏธ ๊ธฐ๋ก๋๊ฑฐ๋‚˜ ๋ณต๊ตฌ ๋ณด์กด๋œ ๊ฒฝ์šฐ์—๋Š” summary ์ž์ฒด์—๋„ not_before_date์™€ premature_run_guard=target_weight_future_as_of_date_blocked๋ฅผ ๋‚จ๊ฒจ current_blockers.json์ด ๋Šฆ๊ฒŒ ๊ฐฑ์‹ ๋ผ๋„ ๋‹ค์Œ KRX ์˜์—…์ผ ์ „ ์žฌ์‹คํ–‰์„ ๋ง‰์Šต๋‹ˆ๋‹ค. ๋‘ no-order ๋ช…๋ น์€ sector map, stale benchmark, ๊ฐ€๊ฒฉ ๋ฐ์ดํ„ฐ, FDR/yfinance/KIS fallback ๋น„ํ™œ์„ฑํ™” ๊ฐ™์€ plan ์ƒ์„ฑ blocker๋กœ ๋ง‰ํ˜€๋„ traceback ๋Œ€์‹  target_weight_daily_ops_summary_failure_*.json/.md ๋˜๋Š” target_weight_readiness_audit_failure_*.json/.md๋ฅผ ๋‚จ๊ธฐ๋ฉฐ, ํ•ด๋‹น failure artifact์—๋Š” status=BLOCKED, ์›์ธ, ์žฌ์‹คํ–‰ ๋ช…๋ น, orders_submitted=false๊ฐ€ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. READY_TO_EXECUTE์™€ WAITING_FOR_MARKET_SESSION์€ ์‹คํ–‰์ผ/์žฅ ์‹œ๊ฐ„ ์ ๊ฒ€๊ณผ pilot authorization snapshot์ด ์‹ค์ œ checked=True๋กœ ํ†ต๊ณผํ•œ ๊ฒฝ์šฐ์—๋งŒ ํ‘œ์‹œํ•˜๋ฉฐ, ๋ฏธ์ ๊ฒ€ ํ•ญ๋ชฉ์€ NOT CHECKED๋กœ ๋‚จ๊ฒจ cap ์Šน์ธ ์ค€๋น„์™€ ์‹คํ–‰ ์ค€๋น„๋ฅผ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. daily ops/readiness/manifest์˜ ์‹คํ–‰ ๋ช…๋ น์€ READY_TO_EXECUTE๊ฐ€ ์•„๋‹ ๋•Œ # blocked: ์ฃผ์„ ๋ช…๋ น์œผ๋กœ ๊ณ ์ •ํ•ด cap ์Šน์ธ ์ „์ด๋‚˜ blocker ํ•ด์†Œ ์ „ paper ์‹คํ–‰์„ ์šด์˜ ๋ฆฌํฌํŠธ๊ฐ€ ์œ ๋„ํ•˜์ง€ ์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. reports/current_blockers.json๋„ schema v3๋ถ€ํ„ฐ operator_runbook๊ณผ next action๋ณ„ command/order_safety๋ฅผ ํฌํ•จํ•ด check-only โ†’ daily ops summary โ†’ readiness audit โ†’ READY_TO_EXECUTE ๋‹น์ผ capped paper evidence ์ˆ˜์ง‘ ์ˆœ์„œ๋ฅผ ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  daily ops summary๊ฐ€ ์—†์œผ๋ฉด current blockers์˜ 1์ˆœ์œ„๋Š” ๋จผ์ € daily ops summary ์ƒ์„ฑ์ด๊ณ , ์ตœ์‹  summary๊ฐ€ ์žˆ์œผ๋ฉด shadow 3์ผ ์ˆ˜์ง‘, Discord test preflight, ์ถ”์ฒœ cap ์Šน์ธ, READY_TO_EXECUTE ์‹คํ–‰ ์ค‘ ํ˜„์žฌ ์ƒํƒœ์— ๋งž๋Š” ๋ช…๋ น์œผ๋กœ ์ž๋™ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. Discord webhook ๋ฏธ์„ค์ • blocker๋Š” DISCORD_WEBHOOK_URL ์„ค์ •์ด ๋จผ์ € ํ•„์š”ํ•œ ์•ก์…˜์œผ๋กœ ํ‘œ์‹œํ•˜๊ณ , READY ์ƒํƒœ๊ฐ€ ์•„๋‹Œ ์ตœ์‹  summary์˜ ์‹คํ–‰ ๋ช…๋ น์€ current blockers์—์„œ๋„ # blocked:๋กœ๋งŒ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค. preflight์™€ pilot runbook๋„ target-weight ํ›„๋ณด์—์„œ๋Š” generic paper evidence pipeline ๋Œ€์‹  target_weight_rotation_pilot.py --shadow-days, --daily-ops-summary, --readiness-audit, Discord --send-test-notification ๊ฒฝ๋กœ๋ฅผ ์šฐ์„  ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค. ๊ณต์‹ reports/paper_experiment_manifest.json๋„ ๊ธฐ์กด scoring 60์˜์—…์ผ ์‹คํ—˜๊ณผ target-weight capped paper pilot์„ ๋ถ„๋ฆฌํ•ด ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

Target-weight cash override ์ •์ฑ…: --cash๋Š” dry-run ๊ณ„ํš ๊ฒ€ํ† ์™€ shadow bootstrap ๋ณด์กฐ ์ž…๋ ฅ์—๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. --readiness-audit, --daily-ops-summary, --execute, --collect-evidence์—์„œ๋Š” ์‹ค์ œ paper ๊ณ„์ขŒ ํ˜„๊ธˆ๊ณผ ์‹คํ–‰ ์ง์ „ ํฌ์ง€์…˜์„ ๊ธฐ์ค€์œผ๋กœ๋งŒ ํŒ๋‹จํ•˜๋ฉฐ, --cash๊ฐ€ ๊ฐ™์ด ๋“ค์–ด์˜ค๋ฉด CLI์™€ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ชจ๋‘ target_weight_cash_override_blocked๋กœ fail-closed ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. --collect-evidence๋Š” ๋ฐ˜๋“œ์‹œ --execute์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, ๋‹จ๋… ์ฆ๊ฑฐ ์ˆ˜์ง‘ ์š”์ฒญ์€ target_weight_collect_evidence_requires_execute๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

Generic paper entry๋„ ๋™์ผํ•œ ์‹คํ–‰ ๊ฒฝ๊ณ„ ์›์น™์„ ๋”ฐ๋ฅธ๋‹ค. main.py --mode paper, scheduler auto-entry, fixed-quantity paper BUY ๋ชจ๋‘ preflight status์™€ runtime state๋ฅผ ์ฃผ๋ฌธ ์ƒ์„ฑ ์ „์— ํ™•์ธํ•˜๊ณ , ํ™•์ธ ์‹คํŒจ๋Š” fail-closed๋กœ ์ฐจ๋‹จํ•œ๋‹ค. blocked runtime์—์„œ pilot authorization์ด ํ™œ์„ฑํ™”๋˜์–ด๋„ check_pilot_entry()๋ฅผ ๋‹ค์‹œ ํ†ต๊ณผํ•ด์•ผ ํ•˜๋ฉฐ, pilot ์ด๋…ธ์ถœ cap์€ ํ˜„์žฌ ๋…ธ์ถœ๋ฟ ์•„๋‹ˆ๋ผ ์ด๋ฒˆ ์ฃผ๋ฌธ ํ›„ ์˜ˆ์ƒ ๋…ธ์ถœ๊นŒ์ง€ ๊ธฐ์ค€์œผ๋กœ ๊ฒ€์‚ฌํ•œ๋‹ค. SELL/exit ๊ฒฝ๋กœ๋Š” ํฌ์ง€์…˜ ์ •๋ฆฌ๋ฅผ ์œ„ํ•ด ๊ณ„์† ํ—ˆ์šฉํ•œ๋‹ค. ์šด์˜ ์†์‹ค ํ•œ๋„๋„ ๊ฐ™์€ ์›์น™์„ ๋”ฐ๋ฅธ๋‹ค. risk_params.yaml:drawdown.max_portfolio_mdd ๋˜๋Š” max_daily_loss์— ๋‹ฟ์œผ๋ฉด ์‹ ๊ทœ BUY๋งŒ fail-closed๋กœ ์ฐจ๋‹จํ•˜๊ณ , ์†์ ˆยทํŠธ๋ ˆ์ผ๋งยท์ˆ˜๋™ ์ฒญ์‚ฐ SELL์€ ๊ณ„์† ์—ด์–ด ๋‘”๋‹ค. pilot evidence freshness๋Š” ๋‹ฌ๋ ฅ์ผ์ด ์•„๋‹ˆ๋ผ ์ฃผ๋ง๊ณผ ํ•œ๊ตญ์žฅ ํœด์žฅ์ผ์„ ์ œ์™ธํ•œ ์˜์—…์ผ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

Target-weight pilot ์Šน์ธ/์žฌ์‹œ๋„ ๋ณด๊ฐ•: tools/paper_pilot_control.py --enable์€ reports/promotion/run_metadata.json์˜ canonical strategy_specs[].base_strategy=target_weight_rotation์„ ์šฐ์„  ๊ธฐ์ค€์œผ๋กœ target-weight ํ›„๋ณด๋ฅผ ์‹๋ณ„ํ•˜๊ณ , ๊ธฐ์กด target_weight_* ์ ‘๋‘์–ด๋Š” ํ˜ธํ™˜ fallback์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. pilot auth๋ฅผ ์“ฐ๊ธฐ ์ „ target-weight readiness audit์„ ๋‹ค์‹œ ์‹คํ–‰ํ•ด ์šด์˜์ž๊ฐ€ ์š”์ฒญํ•œ cap์ด ํ˜„์žฌ plan, launch readiness, ์œ ๋™์„ฑ preflight, ๋น„์šฉ ๋ฐ˜์˜ pre-trade risk๋ฅผ ๋งŒ์กฑํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์š”์ฒญ cap์€ audit์˜ cap_recommendation.suggested_caps์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ํ†ต๊ณผ ๊ฐ€๋Šฅํ•œ ๋” ํฐ cap์œผ๋กœ pilot์„ ์—ฌ๋Š” ๊ฒฝ๋กœ๋„ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. ์Šน์ธ auth์—๋Š” ๋‹น์‹œ plan์˜ trade_day, as_of_date, params_hash, targets, ์‹œ์ž‘/๋ชฉํ‘œ ์ˆ˜๋Ÿ‰ snapshot์„ ํ•จ๊ป˜ ์ €์žฅํ•ด cap ์Šน์ธ๊ณผ ์‹คํ–‰ ๊ณ„ํš์„ ๋ฌถ์Šต๋‹ˆ๋‹ค. ์œ ๋™์„ฑ diagnostics๊ฐ€ ์—†์œผ๋ฉด fail-closed๋กœ ์ฐจ๋‹จํ•˜๊ณ , ์ด๋ฏธ ์ฃผ๋ฌธ์ด ์™„๋ฃŒ๋œ same-candidate/trade-day ์„ธ์…˜์€ --allow-rerun์„ ์ค˜๋„ ์žฌ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. --execute๋Š” ์ฃผ๋ฌธ ์ œ์ถœ ์ „ ๊ฐ™์€ candidate/trade_day์˜ atomic .lock์„ ์„ ์ ํ•˜๋ฉฐ, ์ด๋ฏธ in-progress lock์ด ์žˆ์œผ๋ฉด ์ฃผ๋ฌธยทํฌ์ง€์…˜ ์กฐํšŒยท์ฆ๊ฑฐ ์ˆ˜์ง‘ ์ „์— ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. --allow-rerun๋„ ์ด์ „ ์„ธ์…˜์ด ์ฃผ๋ฌธ ์ œ์ถœ์— ๋„๋‹ฌํ–ˆ๊ฑฐ๋‚˜ ์‹คํŒจ/์ค‘๋‹จ ํ”์ ์ด ์žˆ์œผ๋ฉด ์žฌ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ , ์ฃผ๋ฌธ ์ œ์ถœ ์ „ ๋‹จ๊ณ„์—์„œ ๋ง‰ํžŒ ๋ถˆ์™„์ „ ์„ธ์…˜ ๋ณต๊ตฌ์—๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Target-weight ์‹คํ–‰ ์ฐจ๋‹จ ๊ธฐ๋ก: --execute๊ฐ€ pilot cap validation์—์„œ ๋ง‰ํžˆ๋ฉด ์ฃผ๋ฌธยท์ฒด๊ฒฐยท์ฆ๊ฑฐ ์ˆ˜์ง‘ ์—†์ด session JSON artifact์— ์ฐจ๋‹จ ์‚ฌ์œ ๋ฅผ ๋‚จ๊น๋‹ˆ๋‹ค. runtime pilot session์€ ์“ฐ์ง€ ์•Š์•„ cap์„ ๊ณ ์นœ ๋’ค ๊ฐ™์€ ๊ฑฐ๋ž˜์ผ ๊ณ„ํš์„ ๋‹ค์‹œ ์ ๊ฒ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ plan.trade_day์™€ KST ๊ธฐ์ค€ ์‹ค์ œ ์‹คํ–‰์ผ์ด ๋‹ค๋ฅด๊ฑฐ๋‚˜, ํ˜„์žฌ ์‹œ๊ฐ„์ด KRX ์ •๊ทœ์žฅ ์ฃผ๋ฌธ ๊ฐ€๋Šฅ ์‹œ๊ฐ„์ด ์•„๋‹ˆ๊ฑฐ๋‚˜, ํ™œ์„ฑ pilot auth์˜ ์Šน์ธ snapshot์ด ํ˜„์žฌ plan์˜ params_hash/trade day/targets/์ˆ˜๋Ÿ‰ ์žฅ๋ถ€์™€ ๋‹ค๋ฅด๋ฉด ์ฃผ๋ฌธ, idempotency, ํฌ์ง€์…˜ ์กฐํšŒ, ์ฒด๊ฒฐ ๋Œ€์กฐ, session ์ €์žฅ, ์Šน๊ฒฉ ์ฆ๊ฑฐ ์ˆ˜์ง‘ ์ „์— fail-closed๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. target-weight ์ „์šฉ ์‹คํ–‰ ์–ด๋Œ‘ํ„ฐ๋Š” ํ›„๋ณด๋ช… ์ ‘๋‘์–ด์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์Šน์ธ snapshot์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. no-order --readiness-audit์™€ --daily-ops-summary๋„ ์‹คํ–‰์ผ check, ์žฅ ์‹œ๊ฐ„ check, ์Šน์ธ snapshot check๋ฅผ blocker๋กœ ํ‘œ์‹œํ•ด ์˜ค๋ž˜๋˜์—ˆ๊ฑฐ๋‚˜ ์žฅ ์™ธ ์‹คํ–‰ ๋ช…๋ น์„ READY ์ƒํƒœ๋กœ ๋…ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. pilot entry๊ฐ€ ๋ง‰ํ˜€ ์•„์ง ์Šน์ธ snapshot์ด๋‚˜ ์žฅ ์‹œ๊ฐ„ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ Markdown๊ณผ JSON risk snapshot์€ NOT CHECKED๋กœ ํ‘œ์‹œํ•ด ๋ฏธ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผ๋กœ ์˜คํ•ดํ•˜์ง€ ์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Target-weight ๊ฐ€๊ฒฉ ์ตœ์‹ ์„ฑ guard: ๋ชฉํ‘œ๋น„์ค‘ plan ์ƒ์„ฑ ์‹œ ์ข…๋ชฉ๋ณ„ ๋งˆ์ง€๋ง‰ ์‹ค์ œ ์ข…๊ฐ€ ๋‚ ์งœ(price_last_dates)์™€ ๋ฒค์น˜๋งˆํฌ ์ตœ์‹  ๋‚ ์งœ(benchmark_last_date)๋ฅผ diagnostics์— ๋‚จ๊น๋‹ˆ๋‹ค. ์šด์˜ ์ฃผ๋ฌธ ๊ณ„ํš์—์„œ๋Š” ffill๋กœ ๋ณด์ •๋œ ๋‚ก์€ ์ข…๋ชฉ ๊ฐ€๊ฒฉ์ด trade_day ์ตœ์‹  ๊ฐ€๊ฒฉ์ฒ˜๋Ÿผ ์“ฐ์ด๋ฉด target_weight_stale_price_data๋กœ ์ฐจ๋‹จํ•˜๊ณ , benchmark_excess ์ ์ˆ˜๋‚˜ benchmark risk overlay์— ํ•„์š”ํ•œ ๋ฒค์น˜๋งˆํฌ ๊ฐ€๊ฒฉ์ด score day๋ณด๋‹ค ์˜ค๋ž˜๋˜๋ฉด target_weight_benchmark_price_stale๋กœ plan ์ƒ์„ฑ ์ž์ฒด๋ฅผ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. --readiness-audit์™€ --daily-ops-summary๋Š” ๊ฐ™์€ diagnostics๋ฅผ data_quality_check/Data Quality ์„น์…˜์œผ๋กœ ๋‹ค์‹œ ๋…ธ์ถœํ•ด ๊ฐ€๊ฒฉ ์ตœ์‹ ์„ฑ ์ง„๋‹จ ๋ˆ„๋ฝ, stale ์ข…๋ชฉ, ๋ฒค์น˜๋งˆํฌ ์ง€์—ฐ์„ READY ์ƒํƒœ๋กœ ์ˆจ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. research target-weight backtest๋Š” ์›๋ณธ close/open panel์„ ๋ณด์กดํ•˜๋˜, score day ์‹ค์ œ ์ข…๊ฐ€๊ฐ€ ์—†๋Š” ์ข…๋ชฉ์€ ํ›„๋ณด์—์„œ ์ œ์™ธํ•˜๊ณ  stale_score_symbols_*๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋ณด์œ  ์ข…๋ชฉ์˜ ์ผ๋ณ„ stale ํ‰๊ฐ€๋Š” held_stale_valuation_*๋กœ ๋‚จ๊ธฐ๋ฉฐ, ๋ณด์œ  ์ข…๋ชฉ์˜ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์ผ ์‹œ๊ฐ€๊ฐ€ ์—†์œผ๋ฉด ๊ฑฐ๋ž˜ ์—†์ด missing_held_open_*/skipped_rebalance_missing_held_open_count๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋ฒค์น˜๋งˆํฌ stale๊ณผ ์‹ ๊ทœ top-N ๋งค์ˆ˜ ํ›„๋ณด์˜ ์‹œ๊ฐ€ ๋ˆ„๋ฝ์€ ๊ณ„์† fail-closed๋กœ ์ค‘๋‹จํ•ด stale ๊ฐ€๊ฒฉ์ด๋‚˜ ๋‹น์ผ ์ข…๊ฐ€ ์ฒด๊ฒฐ ์ฐฉ์‹œ๊ฐ€ pilot ํ๋ฆ„์— ์„ž์ด์ง€ ์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Target-weight daily ops ์‹คํ–‰ ์ตœ์‹ ์„ฑ guard: READY_TO_EXECUTE, READY_TO_ENABLE_CAPS, WAITING_FOR_MARKET_SESSION summary๋Š” trade_day๊ฐ€ ํ˜„์žฌ KST ๋‚ ์งœ์™€ ๋งž์•„์•ผ ํ•  ๋ฟ ์•„๋‹ˆ๋ผ generated_at๋„ ํ˜„์žฌ์ผ 30๋ถ„ ์ด๋‚ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„๋ฝ, ํ˜•์‹ ์˜ค๋ฅ˜, ๋ฏธ๋ž˜ ์‹œ๊ฐ, 30๋ถ„ ์ดˆ๊ณผ ์š”์•ฝ์€ paper_pilot_control.py --status์™€ current blockers runbook์—์„œ ์‹คํ–‰/์Šน์ธ ๋ช…๋ น์„ # blocked:๋กœ ๋ฐ”๊พธ๊ณ  daily ops summary ์žฌ์ƒ์„ฑ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

Earnings filter fail-closed: trading.skip_earnings_days๊ฐ€ 0๋ณด๋‹ค ํฌ๋ฉด ์‹ ๊ทœ BUY ์ „์— yfinance์™€ DART ์ˆœ์„œ๋กœ ์‹ค์ ์ผ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‘ ์†Œ์Šค ๋ชจ๋‘ ์‹ค์ ์ผ์„ ํ™•์ธํ•˜์ง€ ๋ชปํ•˜๋ฉด ๊ธฐ๋ณธ trading.earnings_filter_unknown_policy=block ์ •์ฑ…์œผ๋กœ ๋งค์ˆ˜๋ฅผ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. ์กฐํšŒ ๋ถˆ๊ฐ€ ์ƒํƒœ๋ฅผ ๊ฐ์ˆ˜ํ•˜๊ณ  ์šด์šฉํ•˜๋ ค๋ฉด earnings_filter_unknown_policy: "allow"๋ฅผ ๋ช…์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Paper trade quality gate: tools/paper_trade_quality_report.py๋Š” ์ฒด๊ฒฐ ํ’ˆ์งˆ์ด review์ด๊ฑฐ๋‚˜ ์„ ํƒ ๊ธฐ๊ฐ„์˜ TradeHistory๊ฐ€ 0๊ฑด์ด๋ฉด ๊ธฐ๋ณธ non-zero๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์ฒด๊ฒฐ 0๊ฑด ๋ฆฌํฌํŠธ๋งŒ ์ƒ์„ฑํ•˜๋ ค๋ฉด --allow-no-trades๋ฅผ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. promotion package๋„ ๊ฐ™์€ ๊ธฐ๊ฐ„ trade_quality_status=no_trades๋ฅผ fill_quality_no_trades blocker๋กœ ๋ฐ˜์˜ํ•˜๊ณ , execution_session_id/order_id๊ฐ€ ๋น„์–ด ์žˆ๊ฑฐ๋‚˜ evidence์˜ total_trades ๋ฐ BUY/SELL ํ•ฉ๊ณ„๊ฐ€ TradeHistory์™€ ๋‹ค๋ฅด๋ฉด fill_quality_execution_link_missing/fill_quality_trade_count_mismatch/fill_quality_trade_action_mismatch๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. TradeHistory.action์ด BUY/SELL์ด ์•„๋‹Œ ๊ฒฝ์šฐ๋„ fill_quality_unknown_trade_action์œผ๋กœ fail-closed ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. promotion engine ์—ญ์‹œ live ํ›„๋ณด ํŒ์ •์—์„œ paper_trade_quality_status=ok๋ฅผ ์žฌํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

Target-weight ์Šน๊ฒฉ ์ฆ๊ฑฐ ๋ณด๊ฐ•: target-weight ๊ณ„์—ด ์ „๋žต์€ ์ผ๋ฐ˜ execution_backed=True paper record๋งŒ์œผ๋กœ promotion evidence day๋ฅผ ์ฑ„์šฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. pilot_paper/authorized record๊ฐ€ target-weight plan๊ณผ execution proof๋ฅผ ํฌํ•จํ•˜๊ณ , record date์™€ plan trade day๊ฐ€ ์ผ์น˜ํ•˜๋ฉฐ, execution_trade_day_allowed=True, execution_market_session_allowed=True, pilot_authorization_snapshot_allowed=True, liquidity/pre-trade risk/order result/fill/position reconciliation complete ๋ฐ plan/execution params hash ์ผ์น˜๋ฅผ ๋งŒ์กฑํ•œ ๋‚ ๋งŒ ์Šน๊ฒฉ ์นด์šดํŠธ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. 60์˜์—…์ผ ์ „์ฒด verified pilot evidence๋Š” ํ•˜๋‚˜์˜ params hash๋กœ ๊ณ ์ •๋˜์–ด์•ผ ํ•˜๋ฉฐ, promotion package ์ƒ์„ฑ๊ณผ promotion/live gate๋Š” canonical strategy_specs์˜ base_strategy=target_weight_rotation์„ ์šฐ์„  ๊ธฐ์ค€์œผ๋กœ target-weight ํ›„๋ณด๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. paper evidence package๋„ canonical params hash์™€ pilot proof๊ฐ€ ๋งž์ง€ ์•Š์œผ๋ฉด BLOCKED๋กœ ๋‚จ๊ธฐ๋ฉฐ, live gate๋„ canonical metadata์˜ params hash์™€ paper evidence params hash๊ฐ€ ๋‹ค๋ฅด๋ฉด target-weight live ์ „ํ™˜์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

Target-weight finalize ์„ฑ๊ณผ ์ง„๋‹จ: --finalize-pilot-evidence๊ฐ€ total_value/daily_return ๋ฏธํ™•์ •์œผ๋กœ ๋ง‰ํžˆ๋ฉด finalize report์— source record ๋ณด์œ  ์„ฑ๊ณผ ํ•„๋“œ, portfolio metrics probe ์ˆ˜ํ–‰ ์—ฌ๋ถ€, probe์—์„œ ํ™•์ธ๋œ ํ•„๋“œ, ์ตœ์ข… ๋ˆ„๋ฝ ํ•„๋“œ๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. current blockers์™€ paper_pilot_control.py --status๋„ ์ด ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•ด, ์„ฑ๊ณผ snapshot ๋Œ€๊ธฐ์ธ์ง€ benchmark ๋Œ€๊ธฐ์ธ์ง€ ์šด์˜์ž๊ฐ€ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. daily_return/portfolio_value/benchmark excess ๋ˆ„๋ฝ์ฒ˜๋Ÿผ finalize๋กœ promotable record๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์œ ๋Š” repair๋ณด๋‹ค finalize๋ฅผ ๋จผ์ € ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.

About

Risk-first Python quant trading lab for Korean stocks: backtesting, paper trading, KIS API, live gates, and portfolio rebalancing.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors