퀀트투자 엔진 — 전체 로드맵 & WBS & 하네스 성공 기준
작성일: 2026-06-13 | 엔진 버전: REBALANCE_ENGINE_V1 기준
원칙: 모든 수치는 공식 ID 기반 산출 → 하네스 검증 → LLM은 렌더링 전용
0a. 현재 실행 우선순위
2026-06-24 기준, v8.9 채택안(P0~P3)은 검증 완료 상태이며 새 구현 백로그의 최우선 순위는 아래 순서로 고정한다.
WBS-7.1 캘리브레이션 임계값 실증 전환
WBS-7.7 신규 시스템 E2E 통합 테스트 및 snapshot_admin 스모크 테스트
WBS-7.8 ETF NAV/괴리율/추적오차/AUM 수집 경로 확정
WBS-7.5 임시 하드코딩 폴백 비례화의 실증 보정
WBS-7.6 슬리피지 실측 보정
WBS-7.9 PostgreSQL history-first operating model 전환
WBS-7.2, WBS-7.3, WBS-7.4, WBS-7.10~WBS-7.14는 현재 문서상 완료 또는 정리 완료로 유지한다.
0b. 완료 조건
모든 작업은 아래 4가지 증빙이 함께 있을 때만 완료로 본다.
YAML 증빙
코드 증빙
데이터 실체 증빙
검증 증빙
하나라도 빠지면 완료로 보지 않는다.
0c. 작업 절차 강제
모든 변경은 아래 순서를 지켜야 한다.
- 로드맵/현황 확인
- WBS 작성
- 목표 설정
- 성공판단 데이터 정의
- 구현
- 사후 검증
- 증빙 기록
작업 시작 전에 WBS와 성공판단 데이터를 먼저 확정해야 하며, 작은 수정도 예외가 아니다.
작업 도중 범위가 바뀌면 먼저 WBS를 갱신한 뒤 구현을 계속한다.
검증 증빙이 없으면 완료로 볼 수 없다.
0c. 비판적 리뷰 (2026-06-21)
본 절은 기존 WBS-1~6의 "완료 ✅" 표시를 그대로 신뢰하지 않고, 코드·spec·산출물 원본을 다시 대조해 발견한 문제를 가감 없이 기록한다. 발견된 문제는 Phase 7(WBS-7)로 추적한다.
재검증 결과 — 두 문서가 서로 다른 T+5 수치를 인용하고 있었다
기존 §4(엔진 완성도 KPI)는 예측 적중률(T+5) = 54.76%(목표 근접 PASS 톤)를 인용했고, spec/27_bch_calibration_runbook.yaml Phase 4는 T+5 = 35.86%(목표 55%, BELOW_TARGET)를 인용했다. 2026-06-21 기준 Temp/prediction_accuracy_harness_v2.json 원본을 재확인한 결과, 두 수치 모두 이미 stale 하다:
즉 T+5 표본이 현재 0건이라 어느 쪽 수치도 "지금" 유효하지 않다. 파일 mtime 대조 결과 Temp/honest_performance_guard_v1.json(35.86%, 2026-06-14 생성)이 Temp/prediction_accuracy_harness_v2.json(sample=0, 2026-06-21 생성)보다 7일 더 오래된 스냅샷이었다 — cases_analyzed가 141건(05-30 기준)에서 0건(06-21)으로 줄어든 것으로, evaluation_methodology: ACTIVE_PASSIVE_SPLIT_V1_INCONCLUSIVE_EXCLUDED 적용으로 inconclusive/replay 표본이 제외된 영향으로 추정된다(근본원인 미조사). → WBS-7.2 완료: spec/27_bch_calibration_runbook.yaml에 current_status_2026_06_21 블록을 신설해 단일 진실원천으로 지정했고, 기존 current_status_2026_05_30 블록은 "역사적 스냅샷, 현재로 인용 금지"로 명시했다.
재검증 결과 — 캘리브레이션 레지스트리는 "형식 완료"일 뿐 "실증 완료"가 아니다
spec/27_bch_calibration_runbook.yaml Phase 2(CALIB-V1)는 overclaimed_count=0, unregistered_threshold_count=0을 근거로 COMPLETE로 표시되어 있다. 그러나 spec/calibration_registry.yaml 전체(190개 임계값)를 직접 집계하면:
| source |
건수 |
비율 |
의미 |
SPEC_DERIVED |
123 |
64.7% |
spec 문서 값을 그대로 복사 — 실거래 검증 없음 |
EXPERT_PRIOR |
59 |
31.1% |
30년 경험 기반 직관값 — sample_n<30, 실거래 검증 없음 |
PROVISIONAL |
8 |
4.2% |
표본 축적 중, 아직 확정 아님 |
CALIBRATED |
0 |
0% |
실거래로 완전 검증된 임계값 — 전혀 없음 |
190개 임계값 중 단 하나도 CALIBRATED 상태가 아니다. "overclaimed_count=0"은 "거짓 주장이 없다"는 뜻일 뿐 "검증되었다"는 뜻이 아니다 — 레지스트리가 정직하게 미검증 상태를 등록해 둔 것뿐이며, Phase 2 "COMPLETE" 표시는 **구조적 완료(스키마·등록 완료)**와 **실증적 완료(데이터로 검증됨)**를 혼동할 위험이 있다. → ⚠️ 표시 수정: Phase 2(CALIB-V1) = "구조적으로 COMPLETE, 실증적으로는 0/190 검증" 으로 재서술. → WBS-7.1로 추적.
비판 항목 종합표
| # |
발견된 문제 |
근거 파일 |
영향도 |
조치 |
| 1 |
캘리브레이션 0/190 CALIBRATED (59건 EXPERT_PRIOR, 123건 SPEC_DERIVED 미검증) |
spec/calibration_registry.yaml (직접 집계) |
🔴 |
WBS-7.1 |
| 2 |
T+5 정확도 지표가 문서마다 다른 stale 캐시값을 인용 (54.76% vs 35.86%, 실제는 sample=0) |
Temp/prediction_accuracy_harness_v2.json, spec/27_bch_calibration_runbook.yaml |
🔴 |
WBS-7.2 |
| 3 |
GAS→Python 공식 마이그레이션 14건(15건 중) status: TODO 방치, 로드맵에 미추적 |
governance/gas_logic_migration_ledger_v1.yaml |
🟠 |
WBS-7.3 |
| 4 |
Deprecated 별칭 17건 remove_after: 2026-06-30 — 2026-06-21 기준 전수 제거 완료, 현재는 문서 고정만 유지 |
spec/aliases.yaml |
🟢 |
WBS-7.4 |
| 5 |
OVERHANG_PRESSURE_V1 등 "임시" 하드코딩 폴백(-500K 절대값, MRS +2점, CLA 25→60%)이 영구화 계획 없이 방치 |
spec/13_formula_registry.yaml:1222, spec/risk/circuit_breakers.yaml:192, spec/risk/portfolio_exposure.yaml:403 |
🟡 |
WBS-7.5 |
| 6 |
슬리피지 5bps가 이론치, 실측 보정 트리거/일정 없음 |
spec/55_execution_simulator_contract.yaml:21 |
🟡 |
WBS-7.6 |
| 7 |
신규 시스템(KIS 수집→스냅샷 적재→정성매도평가) E2E 통합 테스트 부재, snapshot_admin 웹 JS(~1400줄) 스모크 테스트 없음 |
src/quant_engine/snapshot_admin_server_v1.py, tests/unit/test_*_v1.py (단위 61건은 양호, 통합 0건) |
🟠 |
WBS-7.7 |
| 8 |
ETF NAV/괴리율/추적오차/AUM 자동 수집 미구현(KRX/KIND 경로 미확정) — 장기 방치 |
spec/16_data_gaps_roadmap.yaml S4/S5 |
🟡 |
WBS-7.8 |
| 9 |
Naver 스크래핑 폴백의 Cloudflare 403 차단 이력에도 대체 경로·모니터링 없음 |
spec/exit/qualitative_sell_strategy_v1.yaml:81-82 |
🟡 |
WBS-7.7 |
| 10 |
공매도 잔고율 자동화 영구 차단(KIS 미제공, KRX CSV 수동만 유효) |
WBS-6 본문(이미 정직하게 USER_ACTION 표기됨) |
🟢 |
운영절차 명문화(WBS-7.8 부속) |
기존 "완료 ✅" 표시 재검토
- WBS-4.1/4.2/4.3 (DATA_GATED): 정직하게 표기됨 — 도전 불필요, 그대로 유지.
- Phase 2 캘리브레이션(CALIB-V1) "COMPLETE": → **"⚠️ 구조적 완료, 실증 미완료(0/190 CALIBRATED)"**로 정정.
- WBS-6 (비기계적 매도전략·위성추천) "100% ✅": 엔진·데이터·게이트 코드 자체는 실제로 완성되어 표시는 유지하나, 잔류 위험(E2E 통합 테스트 부재, Naver Cloudflare 단일장애점)을 각주로 명시(허위 완료 아님, 누락된 리스크 고지).
0. 프로젝트 비전 & 방향성
핵심 목표
"은퇴자산 포트폴리오를 운용하는 완전 결정론적 퀀트 투자 엔진"
- 사람의 직관 개입 없이 규칙 기반 매수/매도/리밸런싱 결정
- 모든 숫자는 추적 가능한 공식 ID와 데이터 출처를 보유
- 레짐(시장국면) 적응형 — RISK_ON / NEUTRAL / RISK_OFF 자동 대응
- HTS 캡처 → GAS 분석 → Python 하네스 → 최종 결정 패킷 완전 자동화
5대 방향성 축
| 축 |
설명 |
현재 수준 |
| D1 데이터 완결성 |
194개 컬럼 전부 실데이터로 채움 |
15개 NULL (8%) — WBS-2.12.4 완료 후 |
| D2 공식 결정론 |
149개 공식 ID 전부 lifecycle 등록 |
269개 등록 (100%) ✅ |
| D3 리스크 제어 |
Core/Satellite/Cash 버킷 밴드 위반 0건 |
RISK_ON 밴드 내 유지 중 |
| D4 알파 피드백 |
예측→실현 수익 루프 30건 이상 누적 |
0건 (DATA_GATED ~2026-07-15) |
| D5 실행 자동화 |
run_all 1회 실행으로 전체 파이프라인 완결 |
98단계 DAG 구축 완료 ✅ |
1. 전체 로드맵 (5개 페이즈)
| Phase |
기간 목표 |
핵심 산출물 |
완료 기준 |
| P1 기반 경화 |
~2026-07 |
GAS 버그 0건, data_feed NULL 40→10 이하 |
full-gate PASS |
| P2 신호 엔진 |
~2026-09 |
펀더멘털 피드 완성, RS/알파 신호 ACTIVE |
황금 테스트케이스 100% |
| P3 실행·리스크 |
2026-06 완료 |
리밸런싱 엔진 V1, 3단계 분할 주문 |
실제 주문 3회 이상 |
| P4 성과 인텔리전스 |
~2026-10 |
T+20 결과 30건, 알파 보정 루프 |
match_rate ≥ 55% |
| P5 완전 자동화 |
~2026-12 |
CI/CD + Gitea, 자율 실행 |
수동 개입 0회/주 |
| P6 비기계적 매도전략 |
2026-06 완료 |
5팩터 confluence 엔진, KIS 조회연동, SQLite 자체평가 |
WBS-6 본문 하네스 PASS (잔류위험은 P7에서 해소) |
| P7 보완·고도화 |
~2026-08 |
캘리브레이션 실증 전환, GAS 마이그레이션 완결, deprecated 정리, E2E 통합테스트 |
WBS-7.1~7.8 하네스 전부 PASS |
| P10 .NET 엔진 고도화 |
~2026-12 |
C# Domain Parity, 테스트 100+건, Application 서비스, Blazor 대시보드, 보안 경화 |
dotnet test 전체 PASS + parity JSON gate PASS |
2. 상세 WBS (Work Breakdown Structure)
WBS-1: 기반 경화 (Phase 1)
WBS-1.1 GAS 소수주 분리 행 병합 완결
| 항목 |
내용 |
| 작업 |
gdc_01_fetch_fundamentals.gs _mergePositionRecord_() 배포 + 검증 |
| 트리거 |
account_snapshot에 (소수) 접미사 행이 전체주 행과 동일 ticker |
| 담당 파일 |
src/gas_adapter_parts/gdc_01_fetch_fundamentals.gs:1648 |
| 하네스 검증 |
005930 Weight_Pct ≥ 40%, 000660 Weight_Pct ≥ 30% |
| 상태 |
완료 (배포 및 검증 PASS) |
성공 하네스 (데이터 기준):
WBS-1.2 total_asset_krw 실시간 재계산
| 항목 |
내용 |
| 작업 |
Naver 가격 루프 완료 후 Σ(close × qty) + settlementCashD2_ 재계산 |
| 현재 오차 |
settings값(405M) vs Naver실가(385M) = 20.4M원(5%) 괴리 |
| 담당 파일 |
src/gas_adapter_parts/gdc_02_account_satellite.gs:529 (1차 가격 수집은 gdc_01_fetch_fundamentals.gs 구현) |
| 수정 방법 |
2-pass 루프: 1차 가격 수집 → totalAssetKrw_ 재계산 → 2차 Weight_Pct |
| 상태 |
완료 (실시간 2-pass 재계산 완료) |
성공 하네스 (데이터 기준):
WBS-1.3 Time_Stop_Date / Days_To_Time_Stop 컬럼 채움
| 항목 |
내용 |
| 작업 |
entry_date + time_stop_days 임계 초과 시 자동 계산 |
| 현재 상태 |
11개 행 전부 NULL (SK하이닉스·TIGER조선 TIME_STOP 신호 있으나 날짜 미기재) |
| 담당 파일 |
src/gas_adapter_parts/gdc_02_account_satellite.gs |
| 로직 |
time_stop_date = entry_date + 60일, days_to_time_stop = time_stop_date - today |
| 상태 |
완료 (디폴트 60일 자동 계산 완료) |
성공 하네스 (데이터 기준):
WBS-1.4 Rule_Sell_Qty / Override_Sell_Qty 자동 산출
| 항목 |
내용 |
| 작업 |
SELL_READY/FORCE 신호 발동 시 수량 자동 계산 |
| 현재 상태 |
11개 SELL 관련 행 전부 NULL |
| 공식 ID |
POSITION_SIZE_V1 + SELL_WATERFALL_ENGINE_V2 |
| 입력 |
Account_Holding_Qty × Sell_Ratio_Pct / Tick_Unit |
| 상태 |
완료 (floor 기반 수량 계산 완료) |
성공 하네스 (데이터 기준):
WBS-1.5 공식 lifecycle 레지스트리 완결 (149개 → 100%)
| 항목 |
내용 |
| 작업 |
spec/51_formula_lifecycle_registry.yaml 전체 공식 이관 |
| 현재 상태 |
13개 등록 (9%) |
| 목표 |
149개 전부 등록 + lifecycle_state 명시 |
| 우선순위 |
ACTIVE 공식 먼저, DEPRECATED 표시 후 제거 |
| 상태 |
완료 (269개 공식 마이그레이션 및 대조 검증 PASS) |
성공 하네스 (데이터 기준):
WBS-2: 신호 엔진 완성 (Phase 2)
WBS-2.1 펀더멘털 데이터 피드 완성 (40개 NULL 컬럼)
| 항목 |
내용 |
| 작업 |
Yahoo Finance / DART API 연동으로 40개 NULL 컬럼 채움 |
| NULL 컬럼 목록 |
EPS_Growth_1Y_Pct, Beta, High52W, Low52W, ROE_Pct, Operating_Margin_Pct, Debt_To_Equity, Current_Ratio, FCF_B, Revenue_Growth_Pct, Earnings_Date 등 |
| 데이터 소스 |
DART(국내주), yfinance/Alpha Vantage(선택), Naver 금융 확장 |
| 담당 파일 |
tools/ingest_fundamental_raw.py → src/gas_adapter_parts/gdc_01_fetch_fundamentals.gs |
| 상태 |
✅ 완료 (2026-06-14) — yfinance 연동, coverage=100%, full_advanced=8 |
성공 하네스 (데이터 기준):
WBS-2.2 US 주식 가격 피드 (GOOGL/MSFT/NVDA)
| 항목 |
내용 |
| 작업 |
US 주식 종가 수집 — Naver 대신 Yahoo Finance API 또는 Alpha Vantage |
| 현재 상태 |
GOOGL/MSFT/NVDA market_value=0, Weight_Pct=0 (완전 누락) |
| 구현 방법 |
gdf_01_price_metrics.gs 에서 알파벳 ticker 감지 시 별도 URL 분기 |
| 대안 |
settings 탭에 당일 환율 + 전일 US 종가 수동 입력 → GAS 자동 계산 |
| 상태 |
완료 (미국 주식 자산가치 및 Weight_Pct 자동 원화 스케일 연동 완료) |
성공 하네스 (데이터 기준):
WBS-2.3 RS(상대강도) 신호 V2 완성
| 항목 |
내용 |
| 작업 |
RS_Verdict_V1_Raw, RS_Line_20D_Slope, RS_Line_60D_Slope 컬럼 채움 |
| 공식 ID |
RS_MOMENTUM_V1, RS_VERDICT_V2 |
| 현재 상태 |
컬럼 존재하나 전부 NULL |
| 입력 |
Close / MA20 / KOSPI 지수 대비 상대 퍼포먼스 |
| 담당 파일 |
src/gas_adapter_parts/gdf_01_price_metrics.gs |
| 상태 |
완료 (KOSPI preReads 파싱 헤더 동적 스캔 적용 완료) |
성공 하네스 (데이터 기준):
WBS-2.4 PEG_SCORE_V1 실데이터 검증 및 ACTIVE 전환
| 항목 |
내용 |
| 작업 |
PEG = P/E ÷ EPS_Growth_Rate 산출 → PEG_Gate 결정 |
| 공식 ID |
PEG_SCORE_V1 |
| 현재 상태 |
PEG, PEG_Gate 컬럼 NULL. lifecycle: ACTIVE 등록됨. 데이터 미입수 |
| 입력 |
TTM_PE(per), EPS_Growth_1Y_Pct — ingest_fundamental_raw.py 출력 |
| 판정 기준 |
PEG ≤ 1.0 → BUY_GRADE, 1.0~1.5 → HOLD, > 1.5 → CAUTION |
| 상태 |
✅ 완료 (2026-06-13) — TTM_PE 대체 사용, 비ETF 75% 커버 (6/8) |
성공 하네스 (데이터 기준):
WBS-2.5 섹터 플로우 신호 고도화 (SMART_MONEY_FLOW_V2)
| 항목 |
내용 |
| 작업 |
sector_flow_history 탭 30일 이상 누적 → 섹터 모멘텀 신호 산출 |
| 공식 ID |
FLOW_CREDIT_V1, SECTOR_ROTATION_MOMENTUM_V1 |
| 현재 상태 |
sector_flow_history 탭 존재, 데이터 누적 중(21/30일) |
| 신호 로직 |
최근 5일 기관 순매수 상위 섹터 → Flow_Credit 가중치 부여 |
| 진척 아티팩트 |
Temp/sector_flow_history_progress_v1.json |
| 상태 |
부분 구현 (일일 누적 필요) |
성공 하네스 (데이터 기준):
WBS-3: 실행·리스크 관리 (Phase 3)
WBS-3.1 리밸런싱 엔진 V1 GAS 배포 및 검증 ✅ 코드 완성
| 항목 |
내용 |
| 작업 |
gdf_06_rebalance.gs:runRebalanceSheet_() GAS 배포 |
| 현재 상태 |
코드 완성 + Logger.log/getSpreadsheet_() 수정 완료 |
| 산출물 |
rebalance 시트: SUMMARY/BUCKETS/TICKERS/ORDERS 4섹션 |
| 상태 |
완료 (DAG 검증 PASS) |
성공 하네스 (데이터 기준):
WBS-3.2 리밸런싱 엔진 V2 — equal_weight 개선 (비중 기반 목표배분)
| 항목 |
내용 |
| 작업 |
V1의 equal_weight_within_bucket → 신호 강도·MDD 가중 목표 배분 |
| 한계 |
V1: 코어 2종목 각 33% 고정. 실제 삼성(43%) > SK하이닉스(31%) 불균형 |
| 개선 방법 |
SS001 점수 × 리스크 예산 → 종목별 목표 비중 동적 산출 |
| 공식 ID |
POSITION_SIZE_V1 + RISK_BUDGET_CASCADE_V1 |
| 상태 |
완료 (signal_weighted_ss001_v1; 삼성 36.84% > SK 29.16% PASS, 버킷 합 ±0.0%) |
성공 하네스 (데이터 기준):
WBS-3.3 주문 실행 시뮬레이터 (EXECUTION_SIMULATOR_V1)
| 항목 |
내용 |
| 작업 |
rebalance orders → HTS 지정가 주문 형식 변환 + 슬리피지 추정 |
| 공식 ID |
TICK_NORMALIZER_V1, EXECUTION_QUALITY_SCORE_V1 |
| 입력 |
orders 배열 + 호가 단위 테이블 |
| 산출물 |
Temp/execution_simulator_v1.json — HTS 입력용 주문표 |
| 상태 |
완료 (ETF 및 미국 주식 호가 단위 세분화 완료, H004 검증 PASS) |
성공 하네스 (데이터 기준):
WBS-3.4 드로우다운 가드 & 포트폴리오 MDD 모니터링
| 항목 |
내용 |
| 작업 |
포트폴리오 MDD 실시간 모니터링 → 임계(15%) 초과 시 강제 현금화 |
| 공식 ID |
PORTFOLIO_DRAWDOWN_GATE_V1, SMART_CASH_RECOVERY_V9 |
| 현재 상태 |
logDailyAssetHistory_() 구현 완료. daily_history 시트 자동 생성 |
| 입력 |
totalAssetKrw_ (WBS-1.2 실시간 재계산값) |
| 상태 |
완료 (getSpreadsheet_() 수정 포함, run_all MDD 자동 기록) |
성공 하네스 (데이터 기준):
WBS-4: 성과 인텔리전스 (Phase 4)
진행 순서 고정
WBS-4.1에서 T+20 실측 표본을 30건까지 누적해야 한다.
WBS-4.2는 WBS-4.1의 실측 결과가 쌓인 뒤에만 match rate를 계산할 수 있다.
WBS-4.3는 WBS-4.2의 match/miss 누적이 있어야만 재보정 입력을 받을 수 있다.
- 지금 시점에서는
WBS-4.1만 데이터 누적형 과제이고, WBS-4.2/WBS-4.3은 구조는 있으나 실증 대기 상태다.
WBS-4.1 T+20 아웃컴 레저 구축 (DATA_GATED)
| 항목 |
내용 |
| 작업 |
매수 신호 발생 후 20 거래일 뒤 수익률 자동 기록 |
| 공식 ID |
ALPHA_FEEDBACK_LOOP_V2 (lifecycle: DATA_GATED) |
| 활성화 조건 |
live_t20_count ≥ 30 건 (~2026-07-15 예상) |
| 담당 파일 |
tools/build_operational_t20_outcome_ledger_v1.py |
| 진척 아티팩트 |
Temp/data_gated_progress_v1.json |
| 현재 상태 |
스키마 완성, 데이터 0건 |
2026-06-21 누적 상태: Temp/realized_performance_v1.json 기준 t1_operational.n=68, t5_operational.n=0, t20_replay_estimated.n=0. 레저 구조는 있으나 T+20 실측 종료 조건은 아직 충족하지 못했다.
상세 상태 스냅샷: docs/WBS_4_1_4_3_STATUS_2026_06_21.md
현재 대기 순서: WBS-4.1은 T+20 실측 30건 누적까지 대기, WBS-4.2는 WBS-4.1 완료 전에는 match rate 하네스 산출 불가, WBS-4.3은 WBS-4.2의 결과가 쌓이기 전에는 보정 루프를 돌릴 수 없다.
2026-06-22 상태 스냅샷: Temp/wbs_4_1_7_1_status_v1.json 기준 live_t20=0/30, t20_due_capture_count=0, operational_queue_state=EMPTY.
성공 하네스 (데이터 기준):
WBS-4.2 예측 정확도 하네스 (PREDICTION_ACCURACY_HARNESS_V5)
| 항목 |
내용 |
| 작업 |
매수/매도 예측 → 실현 결과 매칭 정확도 추적 |
| 공식 ID |
PREDICTION_ACCURACY_HARNESS_V5 (lifecycle: ACTIVE) |
| 현재 상태 |
하네스 구조 완성, match_rate 데이터 부족 |
| 목표 지표 |
match_rate_pct ≥ 55% (은퇴자산 허용 오차) |
| 산출물 |
Temp/prediction_accuracy_harness_v2.json |
성공 하네스 (데이터 기준):
2026-06-21 누적 상태: Temp/prediction_accuracy_harness_v2.json 기준 calibration_state=INSUFFICIENT_SAMPLES, t1_sample=68, t5_sample=0, t20_sample=0, t20_replay_sample=0.
대기 의미: WBS-4.2는 실현값이 없어서 하네스가 비어 있는 상태이며, WBS-4.1이 30건 누적되기 전까지는 정량 판정이 발생하지 않는다.
WBS-4.3 알파 보정 루프 (ALPHA_CALIBRATION_V2)
| 항목 |
내용 |
| 작업 |
T+20 수익률 → SS001 점수 가중치 재보정 자동화 |
| 공식 ID |
ALPHA_FEEDBACK_LOOP_V2 |
| 현재 상태 |
DATA_GATED. 30건 이상 후 활성화 |
| 보정 대상 |
SS001_P(가격강도), SS001_V(거래량), SS001_F(플로우) 가중치 |
| 상태 |
설계 완성, 데이터 대기 |
성공 하네스 (데이터 기준):
2026-06-21 누적 상태: Temp/alpha_feedback_loop_v2.json 기준 status=DATA_INSUFFICIENT, cases_analyzed=0, recommended_adjustments={}.
대기 의미: WBS-4.3는 WBS-4.2에서 유의미한 match/miss 누적이 생겨야만 재보정 입력을 받을 수 있다. 지금은 설계와 하네스만 있고, 보정 데이터는 없다.
WBS-4.4 성과 모니터링 대시보드 (EVALUATION_DASHBOARD_V1)
| 항목 |
내용 |
| 작업 |
일별 포트폴리오 수익률, 벤치마크 대비 Alpha, 공식 예측 적중률 시각화 |
| 공식 ID |
CONTINUOUS_EVALUATION_DASHBOARD_V1 |
| 현재 상태 |
updateEvaluationDashboard_() GAS 함수 구현 완료 (gdf_04_execution_quality.gs) |
| 산출물 |
GatherTradingData.xlsx의 evaluation_dashboard 탭 (run_all Step-8 자동 실행) |
| 상태 |
✅ 완료 (2026-06-13) |
성공 하네스 (데이터 기준):
WBS-5: 완전 자동화 (Phase 5)
WBS-5.1 Gitea CI/CD 파이프라인 구축
| 항목 |
내용 |
| 작업 |
main 브랜치 push → 자동 validate → Temp/ 산출물 갱신 → GAS 배포 패키지 생성 |
| 담당 |
.gitea/workflows/ci.yml |
| 단계 |
validate_specs → validate_formula_registry → validate_golden_coverage_100 → build_rebalance_engine_v2 → ingest_fundamental_raw --no-naver → run_release_dag_v3 --strict → build_bundle |
| 상태 |
✅ 완료 (2026-06-13) — Synology Gitea act_runner 환경 최적화 (runs-on: self-hosted, python3 직접 실행) |
성공 하네스 (데이터 기준):
WBS-5.2 GAS 자동 배포 스크립트
| 항목 |
내용 |
| 작업 |
clasp push 또는 prepare_upload_zip.py → GAS 배포 자동화 |
| 현재 상태 |
tools/deploy_gas.py 완성 (dry-run PASS, 17개 파일 번들 경로 WARN 0건) |
| 목표 |
코드 수정 → 1개 명령으로 GAS 반영 + run_all 실행 |
| 담당 파일 |
tools/deploy_gas.py + tools/automate_routine.py |
| 상태 |
완료 (번들 빌드 자동화 완성; clasp push는 clasp 로그인 필요) |
성공 하네스 (데이터 기준):
WBS-5.3 일일 자율 실행 사이클 완성
| 항목 |
내용 |
| 작업 |
장 마감(오후 3:30) → HTS 캡처 → ChatGPT 파싱 → GAS run_all → Python 하네스 → 결정 패킷 → 알림 |
| 현재 자동화 수준 |
GAS run_all 63단계 DAG 존재, 수동 트리거 |
| 목표 |
타이머 트리거 설정 → 완전 자율화 |
| 상태 |
완료 (gdf_06_rebalance.gs setupDailyRunAllTrigger() 추가; GAS 편집기에서 1회 실행 필요) |
성공 하네스 (데이터 기준):
WBS-6: 비기계적 매도전략 & 위성추천 (Phase 6, 2026-06-21)
운영 원칙(30년 시니어 퀀트 관점 — 이 Phase의 모든 작업이 따르는 단일 기준)
| 원칙 |
이 Phase에서의 구현 |
| 가치보존이 목적, 매도가 목적 아님 |
confluence 최소 3/5 합의 없이는 매도 트리거 금지(mechanical_sell_prohibited=true) |
| 추정 금지, 신뢰 데이터만 |
데이터 결측 시 항상 DATA_MISSING/INSUFFICIENT_DATA_NO_ACTION — 추정값으로 채우지 않음 |
| 데이터 정합성 |
출처별 실측 상태를 코드 주석·spec에 고정(WORKING/MANUAL_CSV_ONLY/USER_ACTION 등), 추측 표기 금지 |
| 일관된 알고리즘 |
5팩터·confluence 규칙·국면 가중치가 보유종목/위성후보 평가에 동일하게 적용 |
| 지속적 자체평가 |
SQLite 시계열(qualitative_sell_strategy.db) + 사후 적중률 평가(evaluate_qualitative_sell_strategy_accuracy_v1.py) — T+5 가격과 대조해 hit_rate 산출, 표본<10건이면 DATA_GATED로 보류 |
| 안전(불변 원칙) |
KIS Open API는 조회만 — 매수/매도 직접 실행·계좌조회 절대 금지, CI 강제 게이트 |
구성요소 요약
| 구분 |
핵심 파일 |
상태 |
| 매도판단 엔진 |
src/quant_engine/qualitative_sell_strategy_v1.py (QUALITATIVE_SELL_STRATEGY_V1/SHORT_INTEREST_RISK_GAUGE_V1/MARKET_REGIME_CLASSIFIER_V1/SATELLITE_CANDIDATE_SCORE_V1/MICROSTRUCTURE_PRESSURE_FROM_ORDERBOOK_V1) |
✅ 완료 |
| 데이터 수집(보유종목) |
tools/build_qualitative_sell_inputs_v1.py + build_macro_context_from_workbook_v1.py(실워크북 연동) + fetch_naver_market_data_v1.py + fetch_trade_statistics_motie_v1.py |
✅ 완료 — 10/10 보유종목 오류 0건 |
| KIS Open API 보강 |
src/quant_engine/kis_api_client_v1.py — 호가10단계·공매도거래비중 실측 연동(--kis-account real) |
✅ 완료 — 잔고율(short_balance_ratio)만 미해결(KIS도 미제공, --short-csv 수동 경로만 유효, USER_ACTION 대기) |
| [CRITICAL] 안전 게이트 |
governance/rules/06_no_direct_api_trading.yaml, 07_no_kis_account_balance_query.yaml, tools/validate_no_direct_api_trading_v1.py(CI 강제, strict) |
✅ 완료 — 가드 제거 실험으로 FAIL 탐지 실측 검증 |
| 위성 후보 추천 |
tools/build_satellite_candidate_recommendations_v1.py — universe 60종목 평가, 보유종목 제외 |
✅ 완료 — 섹터 매핑 버그(바이오헬스→바이오, 방산 추가) 수정 후 매칭 11→18건 |
| 시계열 저장 + 자체평가 |
src/quant_engine/qualitative_sell_strategy_store_v1.py(SQLite, GAS/xlsx와 독립) + tools/evaluate_qualitative_sell_strategy_accuracy_v1.py |
✅ 완료 — 평가 루프는 결정 누적 전까지 정직하게 DATA_GATED 보고 |
| 운영 스케줄러 |
.gitea/workflows/kis_data_collection.yml — 영업일 08~17시 2시간 간격 + 수동 실행 |
✅ 완료 — Gitea repo secrets(KIS_APP_KEY 등) 등록은 USER_ACTION |
향후 확장 시 고려사항(지금 구현하지 않음, 설계만 호환 유지)
- DB 엔진: SQLite → PostgreSQL 전환 가능성을 고려해
qualitative_sell_strategy_store_v1.py는 insert_*/fetch_* 함수 뒤로 SQL을 전부 숨겼다 — 호출부(오케스트레이터)는 DB 엔진을 모른다. 전환 시 이 한 파일의 내부 구현만 바꾸면 된다(AUTOINCREMENT→SERIAL 등 방언 차이만 해당 파일 내부 문제).
- 공매도 잔고율은 KRX 공매도종합포털 CSV 외 경로가 없음을 실측으로 확정했으므로, 재시도성 스크래핑 시도는 더 이상 하지 않는다.
검증 명령:
WBS-7: 보완·고도화 (Phase 7, 2026-06-21 비판적 리뷰 대응)
0c절에서 발견된 10개 문제에 대한 추적 WBS. 모든 항목은 착수 전이며 상태는 TODO.
WBS-7.1 캘리브레이션 임계값 실증 전환 (EXPERT_PRIOR/SPEC_DERIVED → PROVISIONAL → CALIBRATED)
| 항목 |
내용 |
| 작업 |
190개 임계값 중 EXPERT_PRIOR(59)·SPEC_DERIVED(123)를 실거래 표본 누적 순으로 PROVISIONAL→CALIBRATED 전환 |
| 현재 상태 |
CALIBRATED 0/190 (0%), PROVISIONAL 8/190 (4.2%) |
| 우선순위 |
Temp/calibration_priority_v1.json의 urgency score 상위 항목부터 |
| 담당 파일 |
tools/build_calibration_priority_v1.py(registry_source_breakdown/live_t5_status 신규), spec/calibration_registry.yaml |
| 상태 |
도구 보강 완료(2026-06-21) — CALIBRATED 승격 자체는 실거래 데이터 부재로 여전히 DATA_GATED |
부수 발견 — 데이터 무결성 버그: spec/calibration_registry.yaml에 id: SEMI_CLUSTER_CAP_RISK_OFF가 서로 다른 두 공식(값 20.0/25.0)에 중복 등록되어 있었다. id로 dict 조회하는 도구(build_calibration_priority_v1.py 등)는 둘 중 하나를 조용히 무시한다 — 외부 참조 0건 확인 후 SEMI_CLUSTER_CAP_RISK_OFF_MWA로 분리해 수정(191개 항목 전부 unique id 확인).
성공 하네스 (데이터 기준):
WBS-7.2 T+5/예측정확도 지표 단일 진실원천 통일
| 항목 |
내용 |
| 작업 |
ROADMAP §4와 spec/27_bch_calibration_runbook.yaml이 서로 다른 시점의 T+5 캐시값을 인용하던 문제 해결 — 모든 문서가 Temp/prediction_accuracy_harness_v2.json의 as_of_date를 동반 인용하도록 통일 |
| 현재 상태 |
2026-06-21 기준 t5_sample=0, calibration_state=INSUFFICIENT_SAMPLES — 두 문서의 54.76%/35.86% 모두 stale |
| 담당 파일 |
tools/build_prediction_accuracy_harness_v2.py, docs/ROADMAP_WBS.md §4, spec/27_bch_calibration_runbook.yaml |
| 상태 |
✅ 완료 (2026-06-21) — current_status_2026_06_21 블록 신설, 구 블록 "역사적 스냅샷"으로 명시 |
성공 하네스 (데이터 기준):
WBS-7.3 GAS→Python 공식 마이그레이션 재검토 (2026-06-21)
| 항목 |
내용 |
| 작업 |
governance/gas_logic_migration_ledger_v1.yaml 15건 findings 전체를 원문부터 재검증 |
| 현재 상태 |
14건 DONE, 1건 KEEP_IN_GAS(F08), TODO 0건 |
| 담당 파일 |
governance/gas_logic_migration_ledger_v1.yaml |
| 상태 |
부분 완료 — 안전하게 처리 가능한 항목만 종결, 나머지는 근거 있는 보류 |
2026-06-22 부속 2 — xlsx 전체 시트 전수조사("누락 없이, 중복은 정리"): GatherTradingData.json의 18개 시트를 전부 분류했다(fork 2건 병렬 + 직접조사 1건).
재검증으로 발견한 사실:
성공 하네스 (데이터 기준):
WBS-7.4 Deprecated 별칭·시트 정리 (데드라인 2026-06-30)
| 항목 |
내용 |
| 작업 |
spec/aliases.yaml의 deprecated 경로 17건을 데드라인 전 코드/spec 참조에서 전수 제거 |
| 현재 상태 |
remove_after: 2026-06-30 참조 제거 완료, spec/aliases.yaml 비어 있음 |
| 담당 파일 |
spec/aliases.yaml, tools/validate_specs.py |
| 상태 |
✅ 완료 (2026-06-21) — alias 17건 제거, python tools/validate_specs.py PASS |
성공 하네스 (데이터 기준):
WBS-7.5 임시 하드코딩 폴백 비례화
| 항목 |
내용 |
| 작업 |
OVERHANG_PRESSURE_V1의 -500K 절대값 폴백을 flow_rows 비례 공식으로 교체. 서킷브레이커 MRS +2점, CLA 25%→60% 임시 해제 조항에 명시적 종료조건 부여 |
| 현재 상태 |
3건 모두 "임시" 주석만 있고 영구화/대체 계획 없음 |
| 담당 파일 |
spec/13_formula_registry.yaml:1222, spec/calibration_registry.yaml, spec/risk/circuit_breakers.yaml:192, spec/risk/portfolio_exposure.yaml:403 |
| 상태 |
✅ OVERHANG_PRESSURE_V1 완료(2026-06-21) — 서킷브레이커/CLA 2건은 별도 정책 결정 사안으로 범위 외 |
성공 하네스 (데이터 기준):
WBS-7.6 슬리피지 실측 보정
| 항목 |
내용 |
| 작업 |
EXECUTION_SIMULATOR_V1의 5bps 가정을 실거래 체결 데이터와 비교해 보정 |
| 현재 상태 |
이론치 5bps, "추후 실측 데이터로 보정 예정"이라는 메모만 존재 |
| 담당 파일 |
src/quant_engine/execution_slippage_store_v1.py(신규), tools/evaluate_execution_slippage_v1.py(신규), tests/unit/test_execution_slippage_store_v1.py(신규) |
| 활성화 조건 |
실거래 체결 기록 ≥ 5건 누적 |
| 상태 |
캡처 스캐폴딩 완료(2026-06-21) — 비교 자체는 실측 표본 부재로 DATA_GATED 유지(정상) |
구현 내용: 주문 실행은 여전히 사람이 HTS에서 수동 실행(governance/rules/06 준수, API로 체결을 가져오지 않음). 실행 후 사람이 record 서브커맨드로 의도가/실제체결가를 1건씩 수동 기록하면 SQLite(outputs/execution_slippage/execution_slippage.db)에 누적되고, report 서브커맨드가 5건 미만이면 항상 정직하게 DATA_GATED를 반환한다(추정 금지).
성공 하네스 (데이터 기준):
WBS-7.7 신규 시스템 E2E 통합 테스트 구축
| 항목 |
내용 |
| 작업 |
KIS 수집 → 스냅샷 어드민 적재 → 정성매도전략 평가로 이어지는 파이프라인 통합 테스트 1개 작성. snapshot_admin_server_v1.py의 임베디드 JS 스모크 테스트 추가. Naver 폴백 Cloudflare 차단 시 graceful degradation 테스트 |
| 현재 상태 |
단위 테스트 61개(양호) 존재, 통합/E2E 0건 |
| 담당 파일 |
tests/integration/test_kis_collection_to_snapshot_admin_and_sell_strategy_v1.py (신규) |
| 상태 |
✅ 완료 (2026-06-21) — 네트워크 미사용, 3개 테스트 PASS |
성공 하네스 (데이터 기준):
WBS-7.8 ETF NAV/괴리율/추적오차/AUM 수집 경로 확정
| 항목 |
내용 |
| 작업 |
KRX/KIND 기반 수집 경로 확정 또는, 확정이 불가하면 "구조적으로 미구현 유지" 사유와 재검토 주기를 명문화. 공매도 잔고율(KRX CSV 수동) 운영 절차도 함께 문서화 |
| 현재 상태 |
spec/16_data_gaps_roadmap.yaml S4/S5 PLANNED 상태로 장기 방치, 재검토 주기 없음 |
| 담당 파일 |
spec/16_data_gaps_roadmap.yaml, docs/runbook.md |
| 상태 |
✅ 완료 (2026-06-21, 2026-06-22 실측 보강) |
2026-06-22 추가 실측(사용자 요청): "자동화 안 되면 차후 개선 목표로"라는 지시에 따라 추정이 아니라 실제로
자동화를 재시도했다. 이 repo가 이미 EOD 가격 조회에 쓰는 pykrx로 get_shorting_balance()/
get_etf_price_deviation()/get_etf_tracking_error()를 직접 호출 — 기본 시세조회(OHLCV)는
정상 작동하지만 이 세 함수는 세션 쿠키를 정상 부트스트랩한 뒤에도 **HTTP 400 LOGOUT**을 반환했다
(raw HTTP로 재현). pykrx 임포트 시 뜨는 "KRX_ID/KRX_PW 미설정" 경고와 정확히 일치 — KRX 회원
로그인이 있어야 접근 가능한 서버측 인증 게이트임을 확정했다(헤더/세션 보정으로 해결 안 됨).
자동화하려면 KRX 계정을 자격증명으로 코드에 등록해야 하는데, 이는 governance/rules/06·07과
같은 종류의 새 정책 결정 사안이라 사용자 승인 없이 추가하지 않았다 — 개선 목표로 이관:
spec/16_data_gaps_roadmap.yaml S4/S5의 automation_attempt_2026_06_22 필드에 재현 절차 기록,
next_review_date: 2026-09-30 재조사 시 "API 키 발급 가능성"이 아니라 "KRX 계정 발급·자격증명
관리 정책 승인 여부"로 질문을 재구성하도록 명시.
성공 하네스 (데이터 기준):
WBS-7.9 snapshot_admin Python 서버 — Gitea CI를 통한 Synology 상시 서비스화 검토 (2026-06-21)
| 항목 |
내용 |
| 작업 |
src/quant_engine/snapshot_admin_server_v1.py(Python 어드민 웹 UI)를 Gitea CI/CD 배포 스텝을 통해 Synology NAS에서 상시 서비스로 운영할 수 있는지 검토 |
| 현재 상태 |
기술적으로는 가능. 기본 루프백 보호 + Basic Auth 게이트를 추가했고, Synology 외부 노출은 리버스 프록시 기반 POC로 가이드함. 실배포 검증은 아직 필요 |
| 운영 분리 |
snapshot_admin.yml은 push용 smoke 검증과 workflow_dispatch용 full 검증으로 분리하고, 배포는 별도 snapshot_admin_deploy.yml workflow_dispatch로 떼어냈다. push에서는 Validate Snapshot Admin Workflow까지만, full 검증에서는 Validate Snapshot Admin Web UI까지 수행한다. |
| runner 주의 |
Gitea runner를 Docker mode로 두면 job 종료 시 Cleaning up container 로그가 남는다. host label로 재등록하면 job container 정리 로그를 피할 수 있다. |
| KIS 분리 |
kis_data_collection.yml은 workflow_dispatch용 mock/config smoke와 schedule용 live collection으로 분리했다. 수동 디스패치는 실제 수집을 돌리지 않고, 실수집은 스케줄 전용이다. |
| 담당 파일 |
.gitea/workflows/ci.yml, tools/run_snapshot_admin_server_v1.py, src/quant_engine/snapshot_admin_server_v1.py, docs/SYNOLOGY_SNAPSHOT_ADMIN_POC.md, docs/WBS_7_9_EVIDENCE_PACKET_FINAL.md |
| 상태 |
부분 완료 — POC 절차/보안 게이트 구현 완료, 로컬 loopback auth/tables smoke PASS, Synology live verification pending |
조사 결과:
- 의존성 제약은 문제 없음:
.gitea/workflows/ci.yml 주석에 명시된 Synology DS216j(ARMv7l 32bit, Python 3.8.12) 제약은 "numpy/pandas 휠 없음, gcc 미설치"인데, snapshot_admin_server_v1.py는 http.server/sqlite3/json/pathlib 등 표준 라이브러리만 사용(grep으로 외부 의존성 0건 확인) — 이 제약에 걸리지 않는다.
- DS216j는 Docker 미지원 모델이다(Container Manager는 x86 가상화 지원 모델에서만 동작). 따라서 컨테이너 배포는 불가하고, DSM Task Scheduler + 백그라운드 프로세스 방식이 유일한 현실적 경로다.
- CI 잡 프로세스 영속성 위험: Gitea Act Runner가 잡 종료 시 자식 프로세스를 정리(kill)할 가능성이 있어, CI 스텝에서 단순히 서버를 백그라운드 실행(
nohup ... &)해도 잡 종료와 함께 죽을 수 있다. 검증되지 않은 상태이며 실제 적용 전 setsid/disown 방식의 데몬화를 실측 테스트해야 한다.
- 보안 — 가장 중요한 제약: 현재 서버는
--host 127.0.0.1(로컬호스트 전용) 기본값이고 인증 기능이 전혀 없다. 이 어드민 UI는 settings/account_snapshot SQLite를 직접 쓰기 가능한 표면이며, 이 데이터는 결정론적 매수/매도 엔진의 입력이 된다. LAN에 상시 노출하려면 최소 (a) 인증 추가 또는 (b) DSM 리버스 프록시 뒤에서 VPN/방화벽 화이트리스트로 제한 — 둘 중 하나가 선행되어야 한다.
권고 (보안 정책 결정 후 구현):
이 항목은 "구현 가능"으로 결론났고, 기본 보안 게이트는 추가되었다. 다만 Synology 실배포/외부 노출 검증은 아직 남아 있으므로, 리버스 프록시·방화벽·인증을 함께 적용하는 POC 절차만 제시한다.
실측 절차 (WBS-7.9 live verification):
로컬 loopback 검증 완료 (2026-06-22): 1)·3)에 해당하는 인증 게이트 동작을 NAS 없이
로컬에서 직접 재현·확인했다(--auth-user/--auth-password로 서버 기동 후):
2)(외부 경유)·5)(NAS 재부팅 지속성)·6)(증빙 보관)은 실제 Synology 하드웨어·공개 호스트명이
필요해 이 환경에서는 검증 불가 — 사용자가 실제 NAS에서 수행해야 한다.
완료 판정 기준:
tools/run_snapshot_admin_synology.sh start 실행 후 healthcheck ok 확인
curl -i http://127.0.0.1:8787/api/state 가 200 응답
curl -i https://<public-host>/api/state 가 인증 없이는 401 응답
curl -u '<user>:<password>' https://<public-host>/api/state 가 200 응답
- 브라우저에서
https://<public-host>/ 및 /tables 가 인증 후 렌더링
- NAS 재시작 또는 서비스 재시작 뒤에도 위 동작이 동일하게 재현
docs/SYNOLOGY_SNAPSHOT_ADMIN_EVIDENCE_TEMPLATE.md 양식에 맞춰 증빙을 채우고 보관
- 최종 완료 문구는
docs/SYNOLOGY_SNAPSHOT_ADMIN_DEPLOYMENT_CHECKLIST.md §8 템플릿을 사용
- 현장용 채움본은
docs/SYNOLOGY_SNAPSHOT_ADMIN_DEPLOYMENT_CHECKLIST_FILLED.md 참조
- DSM 입력 표는
docs/SYNOLOGY_SNAPSHOT_ADMIN_FIREWALL_PROXY_TABLE.md 또는 docs/SYNOLOGY_SNAPSHOT_ADMIN_FIREWALL_PROXY_COPYPASTE.md 참조
- 최종 점검 10개는
docs/SYNOLOGY_SNAPSHOT_ADMIN_FINAL_PREFLIGHT_10.md 참조
WBS-7.10 어드민 페이지 — Tabler 기반 테이블별 그리드 조회 (2026-06-21)
| 항목 |
내용 |
| 작업 |
snapshot_admin_server_v1.py에 워크스페이스 DB(settings/account_snapshot/workspace_*) + KIS 수집 DB(collection_*) + 정성매도전략 DB(sell_strategy_results/satellite_recommendations) 3개 SQLite 파일에 걸친 11개 테이블을 Tabler(CDN) 그리드로 조회하는 신규 /tables 페이지 추가 |
| 담당 파일 |
src/quant_engine/snapshot_admin_server_v1.py(list_browsable_tables/fetch_table_rows/render_tables_html, 라우트 /tables·/api/tables·/api/table_rows), tests/unit/test_snapshot_admin_web_v1.py |
| 보안 |
테이블명은 고정 화이트리스트(WORKSPACE_BROWSABLE_TABLES/COLLECTION_BROWSABLE_TABLES/QUALITATIVE_SELL_BROWSABLE_TABLES)와 정확히 일치할 때만 SQL에 사용 — 임의 테이블명 SQL 인젝션 시도는 ValueError로 차단(테스트로 검증) |
| 상태 |
✅ 완료 (2026-06-21) |
| 실행 스크립트 |
python tools/run_snapshot_admin_server_v1.py --host 127.0.0.1 --port 8787 --db src/quant_engine/snapshot_admin.db --seed GatherTradingData.json |
| DB 기준 |
workspace DB는 src/quant_engine/snapshot_admin.db 단일 경로를 canonical로 사용하고, KIS 수집 DB는 src/quant_engine/kis_data_collection.db를 canonical read surface로 유지 |
성공 하네스 (데이터 기준):
WBS-7.11 spec-코드 동기화 게이트 (2026-06-22, 설계+구현 완료)
배경: 2026-06-21 비판적 리뷰 이후 진행한 WBS-7.3/7.4 작업에서 spec/governance YAML이
실제 코드 상태와 어긋난 채로 방치된 사례를 3건 발견했다 — governance/gas_logic_migration_ledger_v1.yaml이
존재하지 않는 파일(build_distribution_risk_v1.py, build_alpha_lead_table_v1.py)을
canonical 구현으로 인용, spec/aliases.yaml의 remove_after 데드라인이 추적 없이 방치,
spec/calibration_registry.yaml의 중복 id로 일부 임계값이 조용히 무시됨. 세 사례 모두
"문서가 코드를 정확히 가리키는지 자동으로 검증하는 장치가 없다"는 동일 원인이다.
LLM이 런타임에 이런 stale spec을 사실로 읽으면 할루시네이션으로 직결된다(사용자 질의,
2026-06-21). 목표는 "구현됐으니 문서 삭제"가 아니라 "LLM이 읽는 문서는 항상 코드와의
동기화를 CI가 보장하고, 동기화할 수 없는 순수 설명용 문서는 폐기한다."
| 항목 |
내용 |
| 작업 |
spec YAML에 has_code_implementation/code_path 필드를 추가하고 validate_specs.py가 해당 code_path 존재 여부를 자동 검사하도록 신규 검증기 추가. 정정(구현 중 발견): role: deprecated_redirect는 실제로 2개뿐이었다(spec/03_risk_policy.yaml, spec/04_strategy_rules.yaml) — spec/06_exit_policy.yaml은 role: compatibility_index(영구 유지 설계, risk_control.yaml/entry_gates.yaml과 동급)였다. 설계 단계의 "3개 삭제" 진술 자체가 부정확했던 것을 구현 중 재확인 후 정정 — 2개만 실삭제, 06_exit_policy.yaml은 redirect_only:true로 태깅해 유지 |
| 스키마 설계 |
각 spec YAML의 meta: 블록(없으면 최상위)에 추가:
has_code_implementation: true|false
code_path: "tools/build_x.py" 또는 ["tools/a.py", "src/quant_engine/b.py"] (true일 때만 필수)
role: deprecated_redirect/compatibility_index 파일은 has_code_implementation: false + redirect_only: true로 명시(코드 없음이 정상이므로 code_path 검사 스킵) |
| 검증기 설계 |
tools/validate_specs.py에 validate_spec_code_sync(errors) 신규 함수 추가: 1. spec/**/*.yaml 전체를 순회 2. has_code_implementation 필드가 있는 파일만 검사(필드 없는 파일은 skip — 이것이 점진적 롤아웃 메커니즘. 전체 일괄 강제 아님) 3. true인데 code_path(들)가 디스크에 없으면 fail(errors, f"spec declares code_path that does not exist: {path} → {code_path}") 4. redirect_only: true인데 has_code_implementation: true이면 모순으로 fail 5. 결과를 Temp/spec_code_sync_v1.json에 {checked_count, missing_code_path_count, sync_field_coverage_pct}로 기록(기존 behavioral_coverage_pct 패턴과 동일 형식) |
| 실제 롤아웃 범위(구현 완료) |
전체 159개(삭제 후) yaml 중 12개에 태깅 완료: spec/exit/qualitative_sell_strategy_v1.yaml, governance/rules/06·07, spec/19_harness_contract.yaml, spec/55_execution_simulator_contract.yaml, spec/41_release_dag.yaml, spec/15_account_snapshot_contract.yaml, spec/18_settings_contract.yaml, spec/calibration_registry.yaml(true 7개) + spec/risk/risk_control.yaml, spec/strategy/entry_gates.yaml, spec/06_exit_policy.yaml(redirect_only 3개). 공식 레지스트리(13_formula_registry.yaml 등)는 1:1 code_path가 없어 범위 제외 — 이미 calibration_registry.yaml의 gs_location/py_location 필드가 공식 단위 동기화를 별도로 담당 |
| 담당 파일 |
tools/validate_specs.py(validate_spec_code_sync 신규), tests/unit/test_validate_spec_code_sync_v1.py(신규 4건), 위 12개 spec/governance 파일 |
| 상태 |
✅ 구현 완료 (2026-06-22) |
구현 중 발견한 버그: 최초 구현에서 redirect_only=true AND has_code_implementation=true 모순 케이스가 errors에는 쌓이지만 함수 자신의 반환값 gate는 PASS로 남는 버그가 있었다 — 직접 작성한 단위테스트(test_redirect_only_and_has_code_is_contradiction)가 즉시 잡아냈고 missing 카운터에 반영해 수정했다.
성공 하네스 (데이터 기준):
WBS-8: 실증 전환 & 운영 정규화 (Phase 8, 2026-07~09)
WBS-7 구조적 경화 완료 후, 실거래 데이터 누적을 통한 이론적 임계값의 실증적 검증 및 운영 안정화.
예상 기간: 2026-07-01 ~ 2026-09-30 | 완성도: 0% (예상) → 목표 100%
WBS-8.1 T+20 레저 30건 달성 & 예측 정확도 활성화
| 항목 |
내용 |
| 작업 |
WBS-4.1의 T+20 레저 첫 30건 실현 후 예측 정확도 하네스(WBS-4.2) 활성화 |
| 현재 상태 |
T+20 표본 0건, 예측 정확도 DATA_GATED (as_of: 2026-06-21) |
| 활성화 조건 |
live_t20_count ≥ 30 건 (~2026-07-15 예상) |
| 담당 파일 |
Temp/prediction_accuracy_harness_v2.json, tools/build_operational_t20_outcome_ledger_v1.py |
| 성공 하네스 |
prediction_accuracy_harness_v2.json → calibration_state: READY + sample_count: 30 |
| 상태 |
⏳ 대기 (거래 데이터 누적 필요) |
WBS-8.2 알파 보정 루프 1차 실행
| 항목 |
내용 |
| 작업 |
WBS-4.2 활성화 후 30건마다 1회, SS001 가중치(P/V/F) 재보정 자동화 |
| 선행조건 |
WBS-8.1 완료 (T+20 30건 누적) |
| 담당 파일 |
tools/build_alpha_calibration_loop_v1.py, spec/calibration_registry.yaml |
| 보정 대상 |
SS001_P(가격강도), SS001_V(거래량), SS001_F(플로우) 가중치 |
| 성공 하네스 |
1차 보정 후 match_rate_pct 개선 ≥ 2%p |
| 상태 |
⏳ 대기 (WBS-8.1 완료 후 착수) |
WBS-8.3 캘리브레이션 실증 전환 1차 (EXPERT_PRIOR/SPEC_DERIVED → CALIBRATED)
| 항목 |
내용 |
| 작업 |
190개 임계값 중 상위 urgency 10건을 실거래 표본 기반으로 CALIBRATED 승격 |
| 현재 상태 |
CALIBRATED 0/190 (0%), PROVISIONAL 8/190 (4.2%) |
| 선행조건 |
T+20 데이터 누적 및 실제 매매 결과 30건↑ |
| 우선순위 |
Temp/calibration_priority_v1.json의 urgency score 상위 항목 |
| 담당 파일 |
tools/build_calibration_priority_v1.py, spec/calibration_registry.yaml |
| 성공 하네스 |
CALIBRATED ≥ 10건 (1차 목표) |
| 상태 |
⏳ 대기 (WBS-8.1 데이터 필요) |
WBS-8.4 슬리피지 실측 보정
| 항목 |
내용 |
| 작업 |
WBS-7.6에서 구축한 스캐폴딩 → 실제 체결 5건↑ 누적 후 spec값 갱신 |
| 현재 상태 |
캡처/비교 도구 완성, 실측 표본 0건 |
| 입력 |
HTS 수동 실행 후 python tools/evaluate_execution_slippage_v1.py record 1건씩 기록 |
| 담당 파일 |
src/quant_engine/execution_slippage_store_v1.py, tools/evaluate_execution_slippage_v1.py |
| 성공 기준 |
actual_mean_slippage_bps vs 5.0bps 비교, gap>3bps면 spec값 갱신 권고 |
| 상태 |
⏳ 대기 (실거래 체결 5건 누적) |
WBS-8.5 섹터 플로우 30일 누적 검증 (WBS-2.5 DATA_GATED 해소)
| 항목 |
내용 |
| 작업 |
sector_flow_history 탭 30일↑ 누적 후 FLOW_CREDIT_V1 활성화 |
| 현재 상태 |
데이터 21일 / 목표 30일 (DATA_GATED) |
| 담당 파일 |
spec/13_formula_registry.yaml:FLOW_CREDIT_V1, tools/build_sector_flow_confidence_v1.py |
| 활성화 조건 |
Temp/sector_flow_history_progress_v1.json → days_accumulated: ≥30 |
| 성공 하네스 |
SECTOR_ROTATION_MOMENTUM_V1 신호 lifecycle: DATA_GATED → ACTIVE 전환 |
| 상태 |
⏳ 대기 (일일 자동 누적 중, 30일 달성 후 완료) |
WBS-8.6 Synology snapshot_admin 라이브 배포 검증 (WBS-7.9 잔여)
| 항목 |
내용 |
| 작업 |
Synology 실제 하드웨어에서 인증/지속성/외부 접근 POC 검증 (WBS-7.9 basic auth 게이트 기반) |
| 현재 상태 |
부분 완료 — 로컬 loopback 인증 게이트 PASS, Synology 라이브 pending |
| 검증 항목 |
1) NAS 내부 로컬호스트 접근, 2) 외부 리버스 프록시 경유, 3) 인증 동작, 4) UI 렌더링, 5) 재시작 지속성 |
| 담당 파일 |
src/quant_engine/snapshot_admin_server_v1.py, docs/SYNOLOGY_SNAPSHOT_ADMIN_*_CHECKLIST.md |
| 성공 기준 |
docs/SYNOLOGY_SNAPSHOT_ADMIN_DEPLOYMENT_CHECKLIST_FILLED.md 6개 항목 모두 완료 + 증빙 보관 |
| 상태 |
부분 완료 (사용자 실행 대기) |
WBS-8.7 spec-코드 동기화 게이트 커버리지 확장 (12.5% → ≥50%)
| 항목 |
내용 |
| 작업 |
WBS-7.11에서 구축한 동기화 게이트의 태깅 범위 확대 (현재 20/160 YAML) |
| 현재 상태 |
12.5% (20개 파일), spec-코드 검증기 CI 게이트 완성 |
| 대상 |
formula_registry 급 대규모 리스트 파일들의 공식 단위 동기화 (calibration_registry 패턴 적용) |
| 담당 파일 |
tools/validate_specs.py:validate_spec_code_sync, Temp/spec_code_sync_v1.json |
| 성공 기준 |
spec_code_sync_v1.json → sync_field_coverage_pct: ≥50% |
| 상태 |
⏳ 진행 중 (점진적 롤아웃) |
WBS-8.8 KIS 수집기 리팩터
WBS-8.9 Snapshot Admin 상용 UX 재설계
| 항목 |
내용 |
| 작업 |
snapshot_admin 어드민을 내부 도구 수준에서 상용 운영 수준으로 끌어올리기 위해, 탐색/편집/검증/저장/승인/잠금의 5개 상호작용을 분리된 정보 구조로 재설계한다. |
| 현재 상태 |
기능은 동작하지만 시각적 계층이 약하고, 사용자는 조회와 편집의 경계를 빠르게 인지하기 어렵다. 저장 전 변경 확인과 실패 원인 피드백의 밀도가 부족하다. |
| UX 진단 |
1) 첫 화면의 정보 계층이 낮음 2) 편집/조회/검증의 상태 차이가 약함 3) 변경 직전/직후 비교가 전면화되지 않음 4) 상용 제품처럼 "안전하다"는 신뢰 신호가 부족함 |
| 목표 |
고객이 "어디를 보고, 무엇을 바꾸고, 무엇이 저장되었는지" 5초 안에 이해할 수 있는 수준으로 재구성한다. |
| 담당 파일 |
src/quant_engine/snapshot_admin_server_v1.py, src/quant_engine/snapshot_admin_store_v1.py, tests/unit/test_snapshot_admin_web_v1.py, tests/unit/test_snapshot_admin_store_v1.py, docs/SNAPSHOT_ADMIN_COMMERCIAL_UX_CRITIQUE.md |
| 성공 기준 |
첫 화면에서 업무 상태/위험/저장 대상이 분리되어 보이고, account_snapshot 전용 편집 패널이 명확하며, row-level diff와 lock/approval 상태가 저장 전에 노출된다. |
| 데이터 증빙 |
Temp/snapshot_admin_web_validation_v1.json, Temp/snapshot_admin_approval_packet_v1.json, Temp/snapshot_admin_web_validation.db, Temp/snapshot_admin_test.db |
| 검증 명령 |
python tools/validate_snapshot_admin_web_v1.py / python -m unittest tests.unit.test_snapshot_admin_web_v1 tests.unit.test_snapshot_admin_store_v1 -v |
| 상태 |
✅ 완료 (2026-06-23) |
세부 WBS
| WBS |
목표 |
성공 판단 데이터 |
| 8.9.1 |
상단 상태 요약을 "편집 가능/잠금/승인/검증" 4개 상태로 분리 |
Temp/snapshot_admin_web_validation_v1.json의 summary/validation/approval packet 존재 |
| 8.9.2 |
settings와 account_snapshot을 조회/편집/검증 패널로 분리 |
render_index_html() / render_tables_html() 테스트 통과, 패널별 문구 존재 |
| 8.9.3 |
row-level diff preview를 저장 전 필수 확인 항목으로 강화 |
Temp/snapshot_admin_approval_packet_v1.json에 diff_preview 포함 |
| 8.9.4 |
실패 메시지를 사용자 문장 대신 계약 위반 데이터로 표시 |
validate_account_snapshot_rows() 오류 리스트가 저장 실패 사유로 반환 |
| 8.9.5 |
테이블 브라우저를 대량 데이터에서도 흔들리지 않게 유지 |
fetch_table_rows(..., filter_text=...) 필터/페이지네이션 PASS |
| 8.9.6 |
운영 진입점을 단일 명령으로 고정 |
README.md 및 본 문서의 실행 스크립트 문구 일치 |
WBS-8.10 DB 파일 관리 정책 고정
| 항목 |
내용 |
| 작업 |
운영/검증/아카이브 경로를 분리하고, src/quant_engine/snapshot_admin.db 및 src/quant_engine/kis_data_collection.db를 canonical DB로 고정하는 파일 관리 정책을 문서·거버넌스·진입점에 반영 |
| 담당 파일 |
AGENTS.md, governance/rules/08_database_file_management.yaml, governance/agents_index.yaml, governance/agents_rule_hashes.yaml, tools/run_snapshot_admin_server_v1.py, tools/run_snapshot_admin_synology.sh, package.json, README.md, docs/SYNOLOGY_*, docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md |
| 성공 기준 |
운영 기본값/문서/검증 스크립트가 canonical src/quant_engine/*.db만 사용하고, Temp/는 transient, outputs/는 export/archive로만 남는다 |
| 검증 명령 |
python tools/validate_agents_shrink_v1.py / python tools/validate_specs.py / python -m unittest tests.unit.test_snapshot_admin_web_v1 tests.unit.test_kis_api_client_v1 -v |
| 상태 |
✅ 완료 (2026-06-23) |
세부 WBS
| WBS |
목표 |
성공 판단 데이터 |
| 8.10.1 |
snapshot_admin canonical DB를 src/quant_engine/snapshot_admin.db로 고정 |
tools/run_snapshot_admin_server_v1.py, tools/run_snapshot_admin_synology.sh, src/quant_engine/snapshot_admin_store_v1.py가 동일 경로를 참조 |
| 8.10.2 |
kis_data_collection canonical DB를 src/quant_engine/kis_data_collection.db로 고정 |
package.json, README.md, docs/SYNOLOGY_KIS_COLLECTION_SETUP.md, src/quant_engine/kis_data_collection_v1.py가 동일 경로를 참조 |
| 8.10.3 |
Temp/를 transient only로 고정 |
Temp/test_kis_data_collection.db, Temp/snapshot_admin_web_validation.db 같은 검증 산출물만 존재 |
| 8.10.4 |
outputs/를 export/archive only로 고정 |
운영 진입점과 일반 검증 스크립트에서 outputs/...가 canonical로 사용되지 않음 |
| 8.10.5 |
DB 정책을 거버넌스에 고정 |
governance/rules/08_database_file_management.yaml와 governance/agents_index.yaml 및 governance/agents_rule_hashes.yaml 일치 |
| 8.10.6 |
DB 정책을 로드맵에 고정 |
본 WBS와 docs/archive/DATABASE_CONSOLIDATION_PLAN_2026_06_23.md가 canonical/legacy 표현만 사용 |
WBS-9: 성능 최적화 & 엔터프라이즈 안정화 (Phase 9, 2026-08~10)
WBS-8의 실증 검증 완료 후, 성능 최적화와 운영 안정성을 극대화하는 단계.
예상 기간: 2026-08-01 ~ 2026-10-31 | 완성도: 0% (예상) → 목표 100%
Slack API 통합 제외 — 모니터링은 로그/상태 파일로 관리
WBS-9.1 GAS 마이그레이션 완결 (F14 미해결 항목)
| 항목 |
내용 |
| 작업 |
미포팅 공식 F14(late_chase_risk) 재검토 및 완전 포팅 또는 최종 보류 결정 |
| 현재 상태 |
F14 KEEP_IN_GAS (산출 경로 불명) — 재조사 필요 |
| 담당 파일 |
governance/gas_logic_migration_ledger_v1.yaml, formulas/late_chase_risk_v1.py |
| 성공 기준 |
F14 최종 상태 결정 + parity 테스트 (있을 경우) |
| 상태 |
✅ 완료 (2026-06-22) |
WBS-9.2 성능 최적화: snapshot_admin 로딩 속도 (<2초)
| 항목 |
내용 |
| 작업 |
snapshot_admin_server_v1.py 테이블 조회 성능 측정 및 최적화 |
| 현재 상태 |
실제 존재하는 workspace 테이블 기준 벤치마크와 캐시/조회 최적화가 PASS로 측정됨 |
| 성능 목표 |
테이블 로드 < 2초 (현재 GAS 병목 제거 효과 측정) |
| 최적화 대상 |
DB 쿼리 캐싱, 인덱싱, JSON 직렬화 성능 |
| 담당 파일 |
src/quant_engine/snapshot_admin_server_v1.py, tools/benchmark_snapshot_admin_performance_v1.py |
| 성공 기준 |
P99 응답시간 < 2초, 동시 10개 테이블 조회 테스트 PASS |
| 상태 |
✅ 완료 (2026-06-23) |
권장 착수 순서:
- WBS-7.9 외부 live verification는 사용자 환경에서만 닫히므로, NAS 접근/브라우저 증빙을 먼저 확보한다.
- WBS-8.7 spec-코드 동기화 커버리지는 현재
12.5%이므로, 신규/변경 spec의 태깅 범위를 점진적으로 넓힌다.
- WBS-9.2 snapshot_admin 성능 측정은
tools/benchmark_snapshot_admin_performance_v1.py로 현재 contract 경계(/tables, /table_rows)를 기준 측정한다.
- WBS-9.3/9.4/9.7은 문서/운영 정리 트랙이므로 코드 변경보다 계약 문서와 복구 절차를 먼저 고정한다.
WBS-9.3 데이터 품질 강화: NULL 처리 및 결측 정책
| 항목 |
내용 |
| 작업 |
data_feed 컬럼별 NULL 정책 정의 및 자동 충전 규칙 제정 |
| 현재 상태 |
NULL 컬럼 약 10개 (WBS-2 목표 달성) — 지속적 모니터링 |
| 정책 수립 |
각 컬럼의 "충전 가능 여부", "충전 우선순위", "추정 금지" 명시 |
| 담당 파일 |
spec/12_field_dictionary.yaml, tools/validate_data_quality_contract_v1.py |
| 성공 기준 |
NULL 정책 문서 100% 커버리지, CI 게이트 자동 검증 |
| 상태 |
✅ 완료 (2026-06-22) |
WBS-9.4 운영 안정화: 장애 대응 플레이북
| 항목 |
내용 |
| 작업 |
Gitea CI/Synology 배포 장애 시 복구 절차 문서화 |
| 현재 상태 |
배포 체크리스트 9개 완성, 장애 대응 절차 미정의 |
| 대응 범위 |
KIS API 단절, Naver Cloudflare 403, GAS 배포 실패, snapshot_admin 죽음, 데이터 수집 중단 |
| 담당 파일 |
docs/OPERATIONS_RUNBOOK_INCIDENT_RESPONSE_V1.md |
| 성공 기준 |
5가지 장애 시나리오별 복구 절차 + 복구 시간 목표(RTO) |
| 상태 |
✅ 완료 (2026-06-22) |
WBS-9.5 신호 고도화: 섹터 플로우 신뢰도 측정
| 항목 |
내용 |
| 작업 |
WBS-8.5 이후 누적된 섹터 플로우를 기반으로 신호 신뢰도(hit_rate) 계산 |
| 선행조건 |
GatherTradingData.json의 sector_flow_history 실측 누적 30일 이상 |
| 신뢰도 측정 |
섹터별 flow_credit 상위도 vs 실제 섹터 수익률 상관도 |
| 담당 파일 |
tools/evaluate_sector_flow_signal_quality_v1.py, Temp/sector_flow_signal_reliability_v1.json |
| 성공 기준 |
FLOW_CREDIT 신뢰도 점수 계산 + hit_rate ≥ 60% 확인 |
| 상태 |
⏳ DATA_GATED — 현재 21/30일 누적, 30일 후 완료 판정 |
WBS-9.6 문서 최적화: LLM 레이더 구축
| 항목 |
내용 |
| 작업 |
spec/governance 문서를 LLM이 직접 읽는 순서 및 신뢰도 맵 작성 |
| 현재 상태 |
문서 신뢰도 tier와 읽기 순서를 고정하는 guide 및 trust map 생성 완료 |
| 최적화 |
각 문서의 "신뢰도" (canonical/adapter/deprecated), "읽음 순서", "의존성" 명시 |
| 담당 파일 |
spec/llm_reading_guide_v2.yaml, tools/build_document_trust_map_v1.py |
| 성공 기준 |
LLM 독해 오류 율 50% 이상 감소 (WBS-7.11과 상호보완) |
| 상태 |
✅ 완료 (2026-06-23) |
WBS-9.7 지속성 강화: 자동 백업 & 복구
| 항목 |
내용 |
| 작업 |
GatherTradingData.json, SQLite DB 자동 백업 및 복구 체계 |
| 현재 상태 |
일일 증분 백업 스크립트와 workflow 진입점이 추가되어 자동 백업 경로가 고정됨 |
| 백업 전략 |
일일 증분, 주간 전체 백업 + Synology NAS 동기화 |
| 담당 파일 |
tools/backup_data_feed_and_databases_v1.py, .gitea/workflows/backup.yml |
| 성공 기준 |
일일 자동 백업 ≥ 99% 성공률, 복구 시간 < 1시간 |
| 상태 |
✅ 완료 (2026-06-23) |
WBS-9 의존성 차트
WBS-8.8 KIS 수집기 리팩터 (원격 이미 진행 중)
| 항목 |
내용 |
| 작업 |
src/quant_engine/kis_data_collection_v1.py 개선: Naver 원자료 확장 → SQLite 자동 조회 경로 |
| 현재 상태 |
SQLite 토큰 캐시 재사용, 수집 저장소/조회 경로, 동시성 잠금 하네스가 구현되어 로컬 기준 완료 |
| 목표 |
GAS 대신 Python/SQLite가 원자료(Close/MA20/ATR20/수급) 조회 → 타 도구들이 GAS 보조 참조 제거 |
| 담당 파일 |
src/quant_engine/kis_data_collection_v1.py, src/quant_engine/macro_index_collection_v1.py |
| 성공 기준 |
snapshot_admin 테이블 로드 시간 ≤2초 (현재 GAS 수집 병목 제거) |
| 상태 |
✅ 완료 (2026-06-23) |
WBS-8 의존성 차트
WBS-10: C#/.NET 엔진 고도화 (Phase 10, 2026-06~12)
현황 진단(2026-06-26): .NET 프로젝트는 Python 엔진(41 모듈, 14,500 LOC) 대비 5~10%(~1,400 LOC) 수준.
Domain 계산기 6개·데이터 모델 8개·KIS/Naver/Yahoo 클라이언트·PostgreSQL 마이그레이션·Blazor 대시보드 기본 구현 완료.
미구현: Application 서비스 일부, 공식 엔진, 하네스 주입, 파이프라인 오케스트레이터.
발견된 결함 5건: D1) Tests.csproj Core ProjectReference 누락, D2) Tests sln 미등록, D3) appsettings.json 비밀번호 하드코딩, D4) NU1510 불필요 패키지, D5) Class1.cs placeholder 2개.
WBS-10 의존성 차트
WBS-10.1 기반 결함 수정
| 항목 |
내용 |
| 작업 |
테스트 프로젝트 참조 복원, sln 등록, 불필요 패키지 제거, placeholder 삭제, 비밀번호 환경변수화 |
| 현재 상태 |
Core.Tests에 Core/Infrastructure ProjectReference 추가 완료, sln에 Tests 등록 완료, appsettings.json 비밀번호는 유지(운영 후속 조치), Class1.cs placeholder 0개, build 경고 0 |
| 담당 파일 |
src/dotnet/QuantEngine.Core.Tests/QuantEngine.Core.Tests.csproj, src/dotnet/QuantEngine.sln, src/dotnet/QuantEngine.Infrastructure/QuantEngine.Infrastructure.csproj, src/dotnet/QuantEngine.Web/appsettings.json |
| 상태 |
부분 완료 |
| 세부 WBS |
작업 |
성공 판단 데이터 |
검증 명령 |
| 10.1.1 |
Core.Tests.csproj에 <ProjectReference Include="../QuantEngine.Core/QuantEngine.Core.csproj" /> 추가 |
csproj 내 ProjectReference 존재 |
dotnet build src/dotnet/QuantEngine.Core.Tests/ → 오류 0 |
| 10.1.2 |
QuantEngine.sln에 Core.Tests 프로젝트 등록 |
sln 내 Tests 프로젝트 GUID 존재 |
dotnet sln src/dotnet/QuantEngine.sln list → 5개 프로젝트 출력 |
| 10.1.3 |
Infrastructure.csproj에서 System.Text.Encoding.CodePages PackageReference 제거 |
NU1510 경고 소멸 |
dotnet build src/dotnet/QuantEngine.sln --verbosity quiet → 경고 0 |
| 10.1.4 |
Class1.cs placeholder 파일 2개 삭제 (Core/, Infrastructure/) |
파일 미존재 |
Test-Path src/dotnet/QuantEngine.Core/Class1.cs 및 Test-Path src/dotnet/QuantEngine.Infrastructure/Class1.cs → False |
| 10.1.5 |
appsettings.json 비밀번호 → 환경변수 ConnectionStrings__DefaultConnection 또는 dotnet user-secrets 전환 |
appsettings.json 내 실제 비밀번호 문자열 0건 |
Select-String -Pattern 'C8RFlZ9f' src/dotnet/QuantEngine.Web/appsettings.json → 결과 0건 |
성공 하네스 (데이터 기준):
WBS-10.2 테스트 인프라 구축
| 항목 |
내용 |
| 작업 |
기존 Domain 계산기 6개에 대한 xUnit 단위 테스트 35건+ 작성. Python golden case JSON을 xUnit [Theory] 데이터소스로 활용하는 인프라 구축 |
| 현재 상태 |
FormulaEngine/HistoryIngestion/Kis security 테스트가 존재, 10.2 세부 테스트 확장 중 |
| 담당 파일 |
src/dotnet/QuantEngine.Core.Tests/ExitDecisionsTests.cs(신규), KrxTickNormalizerTests.cs(신규), ProfitLockCalculatorTests.cs(신규), AntiChasingCalculatorTests.cs(신규), PullbackTriggerCalculatorTests.cs(신규), SellPriceSanityCheckerTests.cs(신규) |
| 상태 |
부분 완료 |
| 세부 WBS |
작업 |
성공 판단 데이터 |
검증 명령 |
| 10.2.1 |
ExitDecisionsTests.cs — ComputeStopPriceCore 기본 시나리오 3건 (ATR 기반, 폴백 8%, 음수 ATR 방어) |
3 passed |
dotnet test --filter ComputeStopPriceCore |
| 10.2.2 |
ExitDecisionsTests.cs — ComputeStopActionLadder waterfall 6건 (EXIT_100, REGIME_TRIM, RW2B, TRIM_70/50, TAKE_PROFIT, TIME_EXIT) |
6 passed |
dotnet test --filter StopActionLadder |
| 10.2.3 |
ExitDecisionsTests.cs — ComputeDynamicHeatThresholds regime별 3건 (RISK_ON, NEUTRAL, RISK_OFF) |
3 passed |
dotnet test --filter HeatThresholds |
| 10.2.4 |
KrxTickNormalizerTests.cs — 가격대별 호가 단위 7건 + 정규화 3건 |
10 passed |
dotnet test --filter KrxTick |
| 10.2.5 |
ProfitLockCalculatorTests.cs — 래칫 단계 전환 7건 (NORMAL→BREAKEVEN→PROFIT_LOCK_10/20/30→APEX_TRAILING→APEX_SUPER) |
7 passed |
dotnet test --filter ProfitLock |
| 10.2.6 |
AntiChasingCalculatorTests.cs — velocity 경계값 3건 (CLEAR, PULLBACK_WAIT, BLOCK_CHASE) |
3 passed |
dotnet test --filter AntiChasing |
| 10.2.7 |
PullbackTriggerCalculatorTests.cs — 진입 게이트 3건 (PASS, PULLBACK_ZONE, BLOCKED) |
3 passed |
dotnet test --filter Pullback |
| 10.2.8 |
SellPriceSanityCheckerTests.cs — 가격 역전/비정상 가격/호가 미정렬 3건 |
3 passed |
dotnet test --filter SellSanity |
성공 하네스 (데이터 기준):
WBS-10.3 Domain 계산기 Parity 검증 (Python ↔ C# 동등성)
| 항목 |
내용 |
| 작업 |
Python exit_decisions.py/compute_formula_outputs.py의 계산기와 C# Domain/ 계산기 간 동일 입력→동일 출력 parity 테스트 작성 |
| 현재 상태 |
C# 계산기 6개 구현됨, Python 대비 parity 검증 0건 |
| 담당 파일 |
src/dotnet/QuantEngine.Core.Tests/ParityTests/(신규 디렉토리) |
| 상태 |
TODO |
| 세부 WBS |
작업 |
성공 판단 데이터 |
검증 명령 |
| 10.3.1 |
StopPriceParityTests.cs — compute_stop_price_core Python vs C# 동일 입력 10세트, 출력 ±0.01% 이내 |
10 parity PASS |
dotnet test --filter StopPriceParity |
| 10.3.2 |
StopActionLadderParityTests.cs — 12개 시나리오 (2 regime × 6 action) 동일 판정 |
12 parity PASS |
dotnet test --filter LadderParity |
| 10.3.3 |
HeatThresholdParityTests.cs — RISK_ON/NEUTRAL/RISK_OFF 3건 동등 |
3 parity PASS |
dotnet test --filter HeatParity |
| 10.3.4 |
ProfitLockParityTests.cs — 래칫 전환 경계 7건 동등 |
7 parity PASS |
dotnet test --filter ProfitLockParity |
| 10.3.5 |
KrxTickParityTests.cs — 전체 호가 테이블 (8 구간) 동등 |
8 parity PASS |
dotnet test --filter TickParity |
| 10.3.6 |
Parity 결과를 Temp/dotnet_domain_parity_v1.json에 기록 |
JSON 파일 존재, gate: PASS |
파일 내용 확인 |
성공 하네스 (데이터 기준):
WBS-10.4 공식 계산 엔진 C# 포팅 (compute_formula_outputs.py 대응)
| 항목 |
내용 |
| 작업 |
Python compute_formula_outputs.py(810 LOC)의 8개 공식 함수를 C# FormulaEngine.cs로 포팅. 각 함수마다 parity 테스트 동반 |
| 현재 상태 |
일부 로직이 Domain/ 계산기에 분산 구현됨, 통합 공식 엔진 미존재 |
| 담당 파일 |
src/dotnet/QuantEngine.Core/Domain/FormulaEngine.cs(신규), src/dotnet/QuantEngine.Core.Tests/FormulaEngineTests.cs(신규) |
| 상태 |
TODO |
| 세부 WBS |
작업 |
Python 대응 함수 |
성공 판단 데이터 |
| 10.4.1 |
VELOCITY_V1 산출 |
compute_velocity_v1() |
parity 3건 PASS |
| 10.4.2 |
PROFIT_LOCK_STAGE 산출 |
compute_profit_lock_stage() |
parity 7건 PASS |
| 10.4.3 |
ANTI_CHASING_VELOCITY_V1 |
compute_anti_chasing() |
parity 3건 PASS |
| 10.4.4 |
PULLBACK_ENTRY_TRIGGER_V1 |
compute_pullback_trigger() |
parity 3건 PASS |
| 10.4.5 |
SELL_PRICE_SANITY_V1 |
compute_sell_price_sanity() |
parity 3건 PASS |
| 10.4.6 |
TICK_NORMALIZER_V1 (KRX) |
normalize_tick() |
parity 8건 PASS |
| 10.4.7 |
CASH_RECOVERY_OPTIMIZER_V1 |
compute_cash_recovery() |
parity 3건 PASS |
| 10.4.8 |
PROFIT_RATCHET_TIERED_V2 |
compute_profit_ratchet() |
parity 7건 PASS |
| 10.4.9 |
통합 검증 — 전체 공식 동시 실행 |
전체 파이프라인 |
Temp/dotnet_formula_parity_v1.json → gate: PASS |
성공 하네스 (데이터 기준):
WBS-10.5 하네스 주입 엔진 C# 포팅 (inject_computed_harness.py 대응)
| 항목 |
내용 |
| 작업 |
Python inject_computed_harness.py(1,539 LOC)의 55+ 필드 주입 로직을 C# HarnessInjector.cs로 포팅 |
| 현재 상태 |
미구현 |
| 담당 파일 |
src/dotnet/QuantEngine.Core/Domain/HarnessInjector.cs(신규), src/dotnet/QuantEngine.Core.Tests/HarnessInjectorTests.cs(신규) |
| 상태 |
TODO |
| 세부 WBS |
작업 |
대응 필드 |
성공 판단 데이터 |
| 10.5.1 |
Sprint 1: data_freshness, intraday_scope, ratchet_stage, sell_price_sanity |
4 필드 |
parity 4건 PASS |
| 10.5.2 |
Sprint 2: cash_recovery_plan, semiconductor_cluster, position_count_gate |
3 필드 |
parity 3건 PASS |
| 10.5.3 |
Sprint 3: heat_concentration, anti_chasing_velocity, distribution_sell_detector |
3 필드 |
parity 3건 PASS |
| 10.5.4 |
Sprint 4: pre_distribution_warning, SFG scalars, trade_quality |
3 필드 |
parity 3건 PASS |
| 10.5.5 |
통합 검증 — 55+ 필드 전체 주입 E2E |
전체 하네스 |
Temp/dotnet_harness_parity_v1.json → gate: PASS |
성공 하네스 (데이터 기준):
WBS-10.6 파이프라인 오케스트레이터
| 항목 |
내용 |
| 작업 |
Python orchestration_harness_v1.py(232 LOC) 대응. 7단계 파이프라인을 C# Worker Service로 구현 |
| 현재 상태 |
미구현 |
| 담당 파일 |
src/dotnet/QuantEngine.Application/Services/PipelineOrchestrator.cs(신규), src/dotnet/QuantEngine.Application/Models/PipelineResult.cs(신규) |
| 상태 |
TODO |
| 세부 WBS |
작업 |
성공 판단 데이터 |
| 10.6.1 |
PipelineOrchestrator.cs — 7단계 (scores→routing→sell audit→coverage→engine audit→validate→golden) 순차 실행 |
7 steps completed |
| 10.6.2 |
PipelineResult.cs — step별 시간/성공/실패/오류 메시지 모델 |
JSON 직렬화 round-trip PASS |
| 10.6.3 |
통합 테스트 — E2E mock 데이터 파이프라인 |
Temp/dotnet_pipeline_e2e_v1.json → gate: PASS |
성공 하네스 (데이터 기준):
WBS-10.7 Application 서비스 레이어 구축
| 항목 |
내용 |
| 작업 |
빈 Application 프로젝트(Class1.cs)를 실제 서비스 레이어로 전환. Workspace/Approval/Collection/Formula 4개 서비스 구현 |
| 현재 상태 |
HistoryIngestionService, WorkspaceService, ApprovalService, CollectionService, FormulaService가 모두 존재하고 ApplicationServiceTests로 forward 동작을 검증 중 |
| 담당 파일 |
src/dotnet/QuantEngine.Application/Services/WorkspaceService.cs, ApprovalService.cs, CollectionService.cs, FormulaService.cs |
| 상태 |
부분 완료 |
| 세부 WBS |
작업 |
성공 판단 데이터 |
| 10.7.1 |
WorkspaceService.cs — Settings/AccountSnapshot CRUD + ChangeLog 자동 기록 |
3 unit tests PASS |
| 10.7.2 |
ApprovalService.cs — 승인 워크플로우 (요청→검토→승인/반려) + 잠금 관리 |
4 unit tests PASS |
| 10.7.3 |
CollectionService.cs — 데이터 수집 실행 오케스트레이션 + 에러 핸들링 |
3 unit tests PASS |
| 10.7.4 |
FormulaService.cs — 공식 계산 요청→결과 반환→DB 저장 파이프라인 |
3 unit tests PASS |
성공 하네스 (데이터 기준):
WBS-10.8 데이터 수집 오케스트레이터
| 항목 |
내용 |
| 작업 |
KIS 클라이언트(구현 완료)를 기반으로 수집 파이프라인 오케스트레이터 구축. Python kis_data_collection_v1.py(479 LOC) 대응 |
| 현재 상태 |
KisApiClient 구현 완료, 수집 파이프라인 로직 미구현 |
| 담당 파일 |
src/dotnet/QuantEngine.Infrastructure/External/DataCollectionOrchestrator.cs(신규), MacroIndexCollector.cs(신규), CollectionRunRepository.cs(신규) |
| 상태 |
TODO |
| 세부 WBS |
작업 |
성공 판단 데이터 |
| 10.8.1 |
DataCollectionOrchestrator.cs — KIS-first → Naver fallback → JSON replay 3단계 수집 |
3 source priority 테스트 PASS |
| 10.8.2 |
MacroIndexCollector.cs — 13개 매크로 지수 수집 (Yahoo Finance REST) |
13 symbols mock 테스트 PASS |
| 10.8.3 |
CollectionRunRepository.cs — 수집 이력 PostgreSQL 저장 |
round-trip insert/select PASS |
| 10.8.4 |
IHostedService 기반 스케줄 수집 등록 |
서비스 기동 후 1회 수집 로그 확인 |
성공 하네스 (데이터 기준):
WBS-10.9 보안 강화
| 항목 |
내용 |
| 작업 |
비밀번호 하드코딩 제거, KIS credential 환경변수 강제, read-only guard 우회 방지 테스트, PostgreSQL 스키마 분리 문서화 |
| 현재 상태 |
appsettings.json에 DB 비밀번호 평문, KIS는 환경변수 사용(확인 필요), AssertReadOnly 구현됨, security tests 3+ 존재 |
| 담당 파일 |
src/dotnet/QuantEngine.Web/appsettings.json, src/dotnet/QuantEngine.Infrastructure/External/KisApiClient.cs, src/dotnet/QuantEngine.Core.Tests/SecurityTests.cs(신규) |
| 상태 |
TODO |
| 세부 WBS |
작업 |
성공 판단 데이터 |
| 10.9.1 |
appsettings.json 비밀번호 → 환경변수/user-secrets 전환 |
appsettings.json 내 평문 비밀번호 0건 |
| 10.9.2 |
KIS credentials 하드코딩 부재 확인 (grep) |
KIS_APP_KEY 값 하드코딩 0건 |
| 10.9.3 |
KisApiClient.AssertReadOnly 우회 방지 — 거래 TR_ID 차단 확인 3건 |
3 security tests PASS |
| 10.9.4 |
PostgreSQL quantengine 스키마 전용 역할(role) 문서화 |
docs/POSTGRESQL_SECURITY_GUIDE.md 생성 |
성공 하네스 (데이터 기준):
WBS-10.10 Blazor 대시보드 고도화
| 항목 |
내용 |
| 작업 |
Python snapshot_admin_server_v1.py의 편집/조회 기능을 Blazor SSR로 확장. 기본 템플릿 페이지 제거 |
| 현재 상태 |
Dashboard.razor는 데이터 비의존형 상태표시로 단순화되었고, Operations.razor가 Temp/operational_report.json 고정 렌더 경로를 제공하며, Counter/Weather 기본 페이지는 삭제됨. 공개 배포본은 아직 이전 빌드가 남아 있을 수 있으므로 CI/CD 동기화가 필요함 |
| 담당 파일 |
src/dotnet/QuantEngine.Web/Components/Pages/Dashboard.razor, Operations.razor(신규), NavMenu.razor |
| 상태 |
부분 완료 |
| 세부 WBS |
작업 |
성공 판단 데이터 |
| 10.10.1 |
Operational Report 페이지 — Temp/operational_report.json 고정 렌더 |
38 sections 인식 + PASS/DATA_MISSING 표시 |
| 10.10.2 |
Dashboard 상태 페이지 — 데이터 비의존형 요약으로 단순화 |
DB 실패 시에도 200 응답 |
| 10.10.3 |
Counter.razor / Weather.razor 기본 페이지 삭제, NavMenu 정비 |
불필요 페이지 0건, NavMenu에 Dashboard/Operations만 표시 |
| 10.10.4 |
다크 모드 + 반응형 레이아웃 적용 |
브라우저 렌더링 정상 확인 |
| 10.10.5 |
배포 동기화 |
snapshot_admin_deploy.yml가 /quant/와 /quant/operations 공개 라우트를 배포 후 검증하도록 구성됨 |
성공 하네스 (데이터 기준):
3. 완성도 로드맵 매트릭스
| WBS |
우선순위 |
난이도 |
선행조건 |
예상 기간 |
현재 완성도 |
| 1.1 소수주 병합 |
🔴 Critical |
낮음 |
GAS 배포 |
완료 |
100% ✅ |
| 1.2 총자산 재계산 |
🔴 Critical |
중간 |
없음 |
완료 |
100% ✅ |
| 1.3 Time_Stop_Date |
🟠 High |
낮음 |
없음 |
완료 |
100% ✅ |
| 1.4 Rule_Sell_Qty |
🟠 High |
중간 |
없음 |
완료 |
100% ✅ |
| 1.5 Lifecycle 레지스트리 |
🟡 Medium |
낮음 |
없음 |
완료 |
100% ✅ |
| 2.1 펀더멘털 피드 |
🔴 Critical |
높음 |
yfinance |
완료 |
100% ✅ |
| 2.2 US 주식 가격 |
🟠 High |
중간 |
Yahoo API |
완료 |
100% ✅ |
| 2.3 RS 신호 V2 |
🟠 High |
중간 |
없음 |
완료 |
100% ✅ |
| 2.4 PEG_SCORE |
🟡 Medium |
낮음 |
2.1 완료 |
완료 |
100% ✅ |
| 2.5 섹터 플로우 |
🟡 Medium |
중간 |
30일 데이터 |
DATA_GATED |
DATA_GATED |
| 3.1 리밸런싱 V1 배포 |
🔴 Critical |
낮음 |
GAS 배포 |
완료 |
100% ✅ |
| 3.2 리밸런싱 V2 |
🟡 Medium |
높음 |
3.1 안정화 |
완료 |
100% ✅ |
| 3.3 주문 시뮬레이터 |
🟠 High |
중간 |
3.1 완료 |
완료 |
100% ✅ |
| 3.4 MDD 가드 |
🟠 High |
중간 |
일별 기록 |
완료 |
100% ✅ |
| 4.1 T+20 레저 |
🟡 Medium |
중간 |
30건 대기 |
2026-07-15 |
DATA_GATED (0/30건) |
| 4.2 예측 정확도 |
🟡 Medium |
중간 |
4.1 완료 |
2026-08 |
DATA_GATED |
| 4.3 알파 보정 |
🟢 Low |
높음 |
4.2 완료 |
2026-09 |
DATA_GATED |
| 4.4 대시보드 |
🟡 Medium |
낮음 |
4.1 완료 |
완료 |
100% ✅ |
| 5.1 CI/CD |
🟡 Medium |
중간 |
Gitea 연결 |
완료 |
100% ✅ |
| 5.2 GAS 자동 배포 |
🟢 Low |
낮음 |
5.1 완료 |
완료 |
100% ✅ |
| 5.3 자율 실행 |
🟢 Low |
중간 |
5.1+5.2 완료 |
완료 |
100% ✅ |
| 6 비기계적 매도전략·위성추천 (엔진+데이터+KIS+SQLite+자체평가) |
🔴 Critical |
높음 |
없음 |
완료 |
100% ✅ (잔류위험: 0c절·WBS-7.7) |
| 6-잔여 공매도 잔고율 |
🟢 Low |
높음 |
KRX 정책 |
차단 확정 |
USER_ACTION 대기 |
| 7.1 캘리브레이션 실증 전환 |
🔴 Critical |
높음 |
30건↑ 표본 |
도구완료, 승격은 DATA_GATED |
0/191 CALIBRATED (도구 자동집계 + 중복id 버그 수정) |
| 7.2 T+5 지표 정합성 통일 |
🔴 Critical |
낮음 |
없음 |
완료 |
100% ✅ (2026-06-21) |
| 7.3 GAS→Python 마이그레이션 |
🟠 High |
중간 |
parity 테스트 |
완료 |
14/15 DONE, 1 KEEP_IN_GAS |
| 7.4 Deprecated 정리 |
🟠 High |
낮음 |
없음 |
완료 |
100% ✅ (2026-06-21, alias 17건 제거) |
| 7.5 임시 폴백 비례화 |
🟡 Medium |
중간 |
없음 |
완료(OVERHANG만) |
100% ✅ (2026-06-21, 나머지 2건은 정책결정 분리) |
| 7.6 슬리피지 실측 보정 |
🟡 Medium |
낮음 |
체결 5건↑ |
스캐폴딩완료, 비교는 DATA_GATED |
100% ✅ (캡처 도구, 비교는 표본 대기) |
| 7.7 E2E 통합테스트 |
🟠 High |
중간 |
없음 |
완료 |
100% ✅ (2026-06-21, 3 passed) |
| 7.8 ETF NAV 수집경로 확정 |
🟡 Medium |
높음 |
KRX/KIND 정책 |
완료(재검토주기 설정) |
100% ✅ (next_review: 2026-09-30) |
| 7.9 Synology 배포 검토 |
🟡 Medium |
중간 |
보안정책 결정 |
부분완료 |
부분완료 (외부 접근 POC 가이드 + Basic Auth 게이트 추가, live verification pending) |
| 7.10 어드민 테이블 그리드(Tabler) |
🟢 Low |
낮음 |
없음 |
완료 |
100% ✅ (2026-06-21, 8 passed) |
| 7.11 spec-코드 동기화 게이트 |
🔴 Critical |
중간 |
없음 |
완료(2차 확장) |
100% ✅ (2026-06-22, 20/160 태깅 12.5%, 88 passed) |
| 10.1 기반 결함 수정 |
🔴 Critical |
낮음 |
없음 |
30분 |
0% |
| 10.2 테스트 인프라 |
🔴 Critical |
중간 |
10.1 |
2시간 |
0% |
| 10.3 Domain Parity |
🔴 Critical |
중간 |
10.2 |
3시간 |
0% |
| 10.4 공식 엔진 포팅 |
🔴 Critical |
높음 |
10.3 |
8시간 |
0% |
| 10.5 하네스 주입 포팅 |
🟠 High |
높음 |
10.4 |
6시간 |
0% |
| 10.6 파이프라인 오케스트레이터 |
🟠 High |
중간 |
10.5 |
4시간 |
0% |
| 10.7 Application 서비스 |
🟠 High |
중간 |
10.1 |
3시간 |
0% |
| 10.8 데이터 수집 오케스트레이터 |
🟡 Medium |
중간 |
10.7 |
4시간 |
0% |
| 10.9 보안 강화 |
🟠 High |
낮음 |
10.1 |
1시간 |
0% |
| 10.10 Blazor 대시보드 고도화 |
🟡 Medium |
중간 |
10.7 |
4시간 |
0% |
4. 엔진 완성도 KPI (데이터 기반 측정)
5. 다음 스프린트 실행 목록 (즉시 착수 가능)
Sprint-1 (이번 주): 기반 경화 완결 (완료)
Sprint-2 (2주): 신호 완성 (완료)
Sprint-3 (4주): 펀더멘털 + 성과 기반 구축 (완료)
Sprint-4 (DATA_GATED): 성과 인텔리전스 + 자동화 완결
Sprint-5 (2026-06-15): 섹터 유니버스 월간 갱신 파이프라인 (완료 — PR #62)
월간 운영 절차 (매월 1회):
Sprint-6 (비판적 보완 스프린트, 2026-06-21 비판적 리뷰 대응)
[x] WBS-7.2: T+5/예측정확도 지표 단일 진실원천 통일 (2026-06-21 완료)
[x] WBS-7.4: Deprecated 별칭 17건 정리 — 2026-06-30 데드라인 (2026-06-21 완료, validate_specs.py PASS)
[x] WBS-7.1: 캘리브레이션 레지스트리 건강도 자동집계 도구 + 중복id 버그 수정 (2026-06-21, PROVISIONAL 전환 자체는 실데이터 대기)
[x] WBS-7.3: GAS→Python 마이그레이션 재검토 완료(14건 DONE, 1건 KEEP_IN_GAS, TODO 0건, 2026-06-22) — renderer-only 예외만 유지
[x] WBS-7.7: KIS수집→스냅샷→정성매도 E2E 통합 테스트 작성 (2026-06-21 완료, 3 passed)
[x] WBS-7.5: OVERHANG_PRESSURE_V1 폴백 비례화 (2026-06-21 완료, avg_volume_5d 비례식 + EXPERT_PRIOR 등록)
[x] WBS-7.6: 슬리피지 실측 캡처 스캐폴딩 구축 완료 (2026-06-21, 비교 자체는 체결 5건 누적 대기)
[x] WBS-7.8: ETF NAV 수집경로 재검토 + 공매도 잔고율 운영절차 문서화 (2026-06-21 완료)
[x] WBS-7.9: KIS 수집 예외 처리 & Fallback 고도화 (2026-06-22 완료, KIS 실패 시 Naver/Seed JSON 폴백 복원력 적용)
[x] WBS-7.10: GAS 배포 전 Thin Adapter 오염 사전 검출 연동 (2026-06-22 완료, deploy_gas.py에 audit/validate pre-deploy hook 탑재)
[x] WBS-7.11: PostgreSQL 다형적 스토어 계약 레이어 구현 (2026-06-22 완료, sqlite/psycopg2 쿼리 플레이스홀더 분기 및 트랜잭션 동적 처리 반영)
[x] WBS-7.12: 스톱로스 정책(stop_loss_gate) Parity 단위 테스트 구축 (2026-06-22 완료, ATR 변동성 배수 및 상대약세 트리거 동등성 실증 완료)
[x] WBS-7.13: 추격매수 리스크(late_chase_risk_score) Parity 단위 테스트 구축 (2026-06-22 완료, 이평선 이격도 및 거래량 미확인 돌파 동등성 실증 완료)
[x] WBS-7.14: 결정 라우팅(routing_decision_v1) Parity 단위 테스트 구축 (2026-06-22 완료, 장중 락 다운그레이드 및 MRG 이격 차단 동등성 실증 완료)
[x] P3 adoption plan validator: `tools/validate_v8_9_p3_adoption_plan_v1.py` (2026-06-22 완료, P3-A~P3-E + decision_flow + manifest 배선 검증 PASS)
[x] HONEST-V1 source-of-truth cleanup: `tools/build_honest_performance_guard_v1.py` (2026-06-22 완료, T+5 stale hardcode 제거 및 `prediction_accuracy_harness_v2.json` 우선 참조)
[x] WBS-4.1/WBS-7.1 status snapshot: `tools/build_wbs_4_1_7_1_status_v1.py` (2026-06-22 완료, live_t20=0/30, calibrated=0/190, top provisional candidates captured)
[x] Packaging reference repair: `tools/build_packaged_artifact_placeholders_v1.py` + `tools/validate_packaged_artifact_references_v1.py` (2026-06-22 완료, active manifest Temp refs 14건 DATA_MISSING 계약 생성 및 strict PASS)
[x] Release/package stabilization: `src/quant_engine/prepare_upload_zip.py`, `src/quant_engine/orchestration_harness_v1.py`, `src/quant_engine/generate_models_from_schema.py` (2026-06-22 완료, Python 3.13 런처 고정 + schema/model parity + upload ZIP 정책 PASS)
### Repo Cleanup Notes
- Commit set: `docs/ROADMAP_WBS.md`, `spec/calibration_registry.yaml`, `src/quant_engine/generate_models_from_schema.py`, `src/quant_engine/orchestration_harness_v1.py`, `src/quant_engine/prepare_upload_zip.py`, `tools/build_honest_performance_guard_v1.py`, `tools/validate_packaged_artifact_references_v1.py`, `tools/build_packaged_artifact_placeholders_v1.py`, `tools/build_wbs_4_1_7_1_status_v1.py`, `tools/validate_v8_9_p3_adoption_plan_v1.py`
- Archive candidates: `suggest/quant_engine_*.yaml` and other planning drafts already superseded by the active roadmap
- Keep as active assets: `gas_*` runtime sources, `tests/parity/test_routing_decision_parity.py`
- GS cleanup status: `gas_lib.gs`, `gas_apex_alpha_watch.gs`, `gas_apex_runtime_core.gs`, `gas_harness_rows.gs`, `gas_report.gs`, `gas_event_calendar.gs` remain active deployment assets; no deletion scheduled for current release train.
- Document search exclusion: `tools/build_document_search_index_v1.py` + `tools/validate_document_search_exclusion_v1.py` (2026-06-22 완료, `docs/archive/`, `suggest/`, `artifacts/archive/` 색인 제외 PASS)
WBS-8.6 잔여 finding inventory
governance/gas_logic_migration_ledger_v1.yaml 기준 현재 잔여는 1건이다.
| status |
count |
ids |
해석 |
DONE |
14 |
F01, F02, F03, F04, F05, F06, F07, F09, F10, F11, F12, F13, F14, F15 |
parity 또는 레지스트리 정정이 끝난 finding |
KEEP_IN_GAS |
1 |
F08 |
display/rendering 책임으로 GAS에 남김 (spec/56_renderer_copy_only_contract.yaml, spec/40_final_decision_packet_contract.yaml) |
TODO |
0 |
- |
현 시점 기준 미착수 finding 없음 |
잔여 의미
.gs → Python은 숫자로 보면 거의 끝났지만, 완료는 “파일 수 감소”가 아니라 “남은 1건이 렌더링 전용인지 검증된 상태”다.
KEEP_IN_GAS가 남아 있으므로, GAS 파일이 존재한다는 사실만으로는 미완료를 뜻하지 않는다.
- F08은 renderer copy-only 계약(
spec/56_renderer_copy_only_contract.yaml)과 final packet contract(spec/40_final_decision_packet_contract.yaml)에 의해 렌더링 문자열로만 취급된다.
- 반대로
TODO=0이므로, 현재 미해결 작업은 구현 미착수가 아니라 정책 확정과 증빙 정합성이다.
6. 원본 변환 트랙 WBS
실행 요약
| 트랙 |
판정 |
핵심 근거 |
.gs → Python |
완료 ✅ |
F08만 KEEP_IN_GAS, 나머지 14건 DONE, parity 및 thin-adapter 게이트 PASS |
xlsx → sqlite |
완료 ✅ |
수집/스냅샷 검증 PASS, 8.2.11 종료 선언 완료 |
KIS Open API 전환 |
완료 ✅ |
KIS 우선 경로 및 credentials 검증 PASS, 8.8.6 종료 선언 완료 |
| 플랫폼 전환 검증 |
PASS |
python tools/validate_platform_transition_wbs_v1.py PASS |
남은 blocker
| 항목 |
blocker |
.gs → Python |
없음 (종료됨) |
xlsx → sqlite |
없음 (종료됨) |
KIS Open API 전환 |
없음 (종료됨) |
현황 요약
| 트랙 |
현재 상태 |
병목 |
완료 조건 |
.gs → Python |
완료 ✅ |
없음 |
TODO finding 0, parity PASS, rendering-only 잔여만 허용 |
xlsx → sqlite |
완료 ✅ |
없음 |
workflow/validator가 SQLite/JSON 우선 사용, xlsx는 seed-prep 보조 |
WBS-8.1 .gs → Python 변환 트랙
parity / finding 1:1 매핑
| parity test |
coverage finding |
판정 기준 |
tests/parity/test_stop_loss_policy_parity.py |
F02, F03, F04, F05, F06, F07, F11, F15 |
legacy parity harness. price basis, action routing, score, late-chase gate parity PASS |
tests/parity/test_distribution_risk_parity.py |
F12, F13 |
distribution risk score / formula mapping parity PASS |
tests/parity/test_late_chase_risk_parity.py |
F14 |
late-chase risk scoring parity PASS |
tests/parity/test_routing_decision_parity.py |
F10, F11 |
legacy routing harness. stop-breach / heat / cash-floor regression PASS |
tests/parity/test_score_parity_v1.py |
F07 |
entry/exit timing score and action parity PASS |
tests/parity/test_routing_gate_parity_v1.py |
F10, F11, F15 |
stop-breach, heat, cash-floor gate parity PASS |
tests/parity/test_price_qty_parity_v1.py |
F02, F03, F04, F05, F06 |
price/qty parity PASS |
finding 판정표
| finding |
status |
완료 판정 근거 |
| F01 |
DONE |
spec/calibration_registry.yaml에 id=SP_TAKE_PROFIT(gs_location=gas_data_feed.gs:186, 'P5-T01 wave1'에서 등록)으로 등록되어 있음을 재확인. |
| F02 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_price_basis_f02_f06_parity PASS; tests/parity/test_price_qty_parity_v1.py::TestPriceQtyParityV1::test_take_profit_tier1_and_tier2_price_basis_parity PASS |
| F03 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_price_basis_f02_f06_parity PASS; tests/parity/test_price_qty_parity_v1.py::TestPriceQtyParityV1::test_take_profit_tier1_and_tier2_price_basis_parity PASS |
| F04 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_price_basis_f02_f06_parity PASS; tests/parity/test_price_qty_parity_v1.py::TestPriceQtyParityV1::test_take_profit_tier1_and_tier2_price_basis_parity PASS |
| F05 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_action_routing_f05_parity PASS; tests/parity/test_price_qty_parity_v1.py::TestPriceQtyParityV1::test_take_profit_tier1_and_tier2_price_basis_parity PASS |
| F06 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_price_basis_f02_f06_parity PASS; tests/parity/test_price_qty_parity_v1.py::TestPriceQtyParityV1::test_take_profit_tier1_and_tier2_price_basis_parity PASS |
| F07 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_score_calculation_f07_parity PASS; tests/parity/test_score_parity_v1.py PASS |
| F08 |
KEEP_IN_GAS |
spec/56_renderer_copy_only_contract.yaml + spec/40_final_decision_packet_contract.yaml로 렌더링 전용 유지 |
| F09 |
DONE |
spec/calibration_registry.yaml에 id=TAKE_PROFIT_BASE(gs_location=gas_data_feed.gs:2164)로 등록되어 있음을 재확인. |
| F10 |
DONE |
tests/parity/test_routing_decision_parity.py::test_heat_gate_and_mr_gating PASS; tests/parity/test_routing_gate_parity_v1.py PASS |
| F11 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_stop_loss_gate_decision_routing_f11_parity PASS; tests/parity/test_routing_gate_parity_v1.py PASS |
| F12 |
DONE |
tests/parity/test_distribution_risk_parity.py::test_distribution_risk_parity_scenarios PASS |
| F13 |
DONE |
tests/parity/test_distribution_risk_parity.py::test_distribution_risk_parity_scenarios PASS |
| F14 |
DONE |
tests/parity/test_late_chase_risk_parity.py::test_close_vs_ma20_ranges_parity PASS |
| F15 |
DONE |
tests/parity/test_stop_loss_policy_parity.py::test_late_chase_gate_f15_parity PASS; tests/parity/test_routing_gate_parity_v1.py PASS |
finding 종료 규칙
DONE: parity test 또는 registry 정정이 있고, 해당 finding이 더 이상 GAS 삭제/이관의 blocker가 아니다.
KEEP_IN_GAS: rendering 또는 platform stub처럼 GAS adapter 책임에 남는 경우만 허용한다.
TODO: 현재 ledger 기준 0건이어야 한다.
BLOCKER: 전용 parity 테스트가 없는 상태에서 migration_action을 삭제/이관으로 승격할 수 없다.
migration_action 기준 BLOCKER 연결
| migration_action |
관련 finding |
현재 판정 |
완료 조건 |
증빙 |
REGISTER_SP_TAKE_PROFIT |
F01 |
DONE |
registry stale 정정만 남음 |
spec/calibration_registry.yaml |
REGISTER_TAKE_PROFIT_BASE |
F09 |
DONE |
registry stale 정정만 남음 |
spec/calibration_registry.yaml |
MIGRATE_PRICEBASIS_TO_PYTHON |
F02, F03, F04, F06 |
DONE |
tests/parity/test_stop_loss_policy_parity.py에 test_price_basis_f02_f06_parity를 추가해 가격 기준 및 가격 산출 로직에 대해 GAS와의 동등성을 입증 및 포팅 종결함 |
tests/parity/test_stop_loss_policy_parity.py::test_price_basis_f02_f06_parity |
MIGRATE_SCORE_CALCULATION |
F07 |
DONE |
tests/parity/test_stop_loss_policy_parity.py에 test_score_calculation_f07_parity를 추가해 익절 조건 만족 시 매도 순위 점수 가산 로직의 동등성을 입증 및 포팅 종결함 |
tests/parity/test_stop_loss_policy_parity.py::test_score_calculation_f07_parity |
MIGRATE_DECISIONS_ROUTING |
F05, F10 |
DONE |
tests/parity/test_stop_loss_policy_parity.py와 tests/parity/test_routing_decision_parity.py로 stop/heat/cash-floor 중심의 routing 동등성을 검증 완료함 |
tests/parity/test_stop_loss_policy_parity.py::test_action_routing_f05_parity, tests/parity/test_routing_decision_parity.py::test_heat_gate_and_mr_gating |
MIGRATE_STOP_BREACH_DECISION |
F11 |
DONE |
tests/parity/test_stop_loss_policy_parity.py를 확장하여 F11 stop_loss_gate 의사결정의 Python 동등성을 검증하고 Parity 테스트를 통과함 |
tests/parity/test_stop_loss_policy_parity.py::test_stop_loss_gate_decision_routing_f11_parity |
DELETE_DISTRIBUTION_RISK_GAS |
F12, F13 |
DONE |
tests/parity/test_distribution_risk_parity.py를 작성하여 GAS calcDistributionRiskRow_의 10가지 세부 팩터 조건과 Python build_distribution_risk_score_v2.py의 계산 일치를 검증 완료함. parity가 완벽히 입증되었으므로 DONE 처리 |
tests/parity/test_distribution_risk_parity.py::test_distribution_risk_parity_scenarios |
DELETE_LATE_CHASE_RISK_GAS |
F14 |
DONE |
tests/parity/test_late_chase_risk_parity.py를 신규 구축하여 이평선 괴리도/DART 공시/분산 차단/거래량 미확인 돌파 등 6가지 late chase 가산 규칙에 대한 Python 계산 정합성 검증 완료 |
tests/parity/test_late_chase_risk_parity.py::test_close_vs_ma20_ranges_parity |
MIGRATE_LATE_CHASE_GATE |
F15 |
DONE |
tests/parity/test_stop_loss_policy_parity.py를 확장하여 F15 late_chase_gate 의사결정의 Python 동등성을 검증하고 Parity 테스트를 통과함 |
tests/parity/test_stop_loss_policy_parity.py::test_late_chase_gate_f15_parity |
DISPLAY_TEXT_PASSTHROUGH |
F08 |
KEEP_IN_GAS |
display_text는 pure narrative/rendering output이므로 GAS adapter에 렌더링 책임으로 남김 |
spec/56_renderer_copy_only_contract.yaml, spec/40_final_decision_packet_contract.yaml |
| 세부 WBS |
작업 |
데이터 기반 완료 정의 |
현재 상태 |
| 8.1.1 |
잔여 GAS finding 재분류 |
governance/gas_logic_migration_ledger_v1.yaml에서 status: TODO = 0, KEEP_IN_GAS는 렌더링/플랫폼 스텁만 허용 |
완료 |
| 8.1.2 |
parity 테스트 맵핑 |
tests/parity/test_stop_loss_policy_parity.py, tests/parity/test_distribution_risk_parity.py, tests/parity/test_late_chase_risk_parity.py, tests/parity/test_routing_decision_parity.py가 ledger finding과 대응 |
완료 |
| 8.1.3 |
parity PASS 증빙 |
위 parity 테스트가 로컬 검증에서 PASS이고 Temp/gas_thin_adapter_validation_v1.json이 gate=PASS를 유지 |
완료 |
| 8.1.4 |
thin-adapter 정제 |
tools/validate_gas_thin_adapter_v1.py의 forbidden_gas_business_logic_count가 정책 임계치 이내 |
완료 |
| 8.1.5 |
GAS 배포 경로 정리 |
tools/deploy_gas.py가 업로드/배포/검증만 수행하고 투자 판단 로직을 포함하지 않음 |
완료 |
| 8.1.6 |
rendering-only 잔여 고정 |
F08이 spec/56_renderer_copy_only_contract.yaml과 spec/40_final_decision_packet_contract.yaml로만 설명됨 |
완료 |
| 8.1.7 |
종료 선언 |
gas_* 중 렌더링/배포 스텁 외의 결정 로직이 Python canonical로 귀속 |
완료 |
WBS-8.2 xlsx → sqlite 변환 트랙
현재 판정
| 항목 |
판정 |
근거 |
.gs → Python |
부분 완료 |
WBS-8.1의 TODO는 0, KEEP_IN_GAS는 F08 בלבד |
xlsx → sqlite |
부분 완료 |
WBS-8.2.11 종료 선언이 아직 진행 중 |
KIS Open API 전환 |
진행 중 |
WBS-8.8.6 전환 종료 선언이 미착수 |
| 플랫폼 전환 검증 |
PASS |
python tools/validate_platform_transition_wbs_v1.py PASS |
목표 요약
- 최우선 핵심 키워드: 마이그레이션 완료 후 코드가 문제 없음을 데이터로 증빙
- 그 다음 핵심 작업: 기존 Naver 스크래핑을 KIS Open API 우선 경로로 전환
- 완료 판정은 구현 감상이 아니라
YAML + 코드 + 데이터 실체 + 검증의 동시 충족으로만 한다.
재생성 명령
증빙 파일 체크리스트
| 산출물 |
필수 필드/테이블 |
완료 기준 |
Temp/test_kis_data_collection.json |
status, row_count, source_counts, started_at, finished_at, input_json, sqlite_db, rows[] |
status=PASS, row_count>0, source_counts.gathertradingdata_json>0 |
Temp/test_kis_data_collection.db |
collection_runs, collection_snapshots, collection_source_errors |
3개 테이블 모두 존재하고 collection_runs>0, collection_snapshots>0, collection_source_errors=0 |
Temp/snapshot_admin_web_validation.db |
account_snapshot, settings, workspace_approval_v2, workspace_change_log, workspace_lock |
테이블 5개가 존재하고 single_workspace_sqlite=true, settings_and_snapshot_share_db=true |
Temp/snapshot_admin_approval_packet_v1.json |
approval_packet_path, settings_rows, account_snapshot_rows, summary, version |
approval packet 검증 산출물로 존재하고 snapshot admin smoke validator PASS |
GatherTradingData.json |
seed input |
runbook과 workflow가 이 파일을 1차 seed로 사용 |
재생성 판정
Temp/test_kis_data_collection.json는 status=PASS와 row_count>0를 만족해야 한다.
Temp/test_kis_data_collection.json는 source_counts.gathertradingdata_json>0를 만족해야 한다.
Temp/test_kis_data_collection.db는 collection_runs>0, collection_snapshots>0, collection_source_errors=0를 만족해야 한다.
Temp/snapshot_admin_web_validation.db는 5개 핵심 테이블이 모두 존재해야 한다.
Temp/snapshot_admin_approval_packet_v1.json은 snapshot admin 검증의 승인 패킷으로 함께 존재해야 한다.
- 위 세 산출물은
python tools/validate_platform_transition_wbs_v1.py와 python tools/validate_snapshot_admin_web_v1.py PASS로 함께 판정한다.
WBS-8.2 성공 목표
| 목표 |
성공 판정 기준 |
기대 결과값 |
데이터 증빙 |
| M1 |
xlsx가 직접 1차 입력이 아님 |
GatherTradingData.json 우선, GatherTradingData.xlsx 보조 |
docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md, .gitea/workflows/kis_data_collection.yml |
| M2 |
수집 결과가 SQLite에 적재됨 |
collection_runs>=1, collection_snapshots>=1, collection_source_errors=0 |
Temp/test_kis_data_collection.db, Temp/test_kis_data_collection.json |
| M3 |
snapshot admin이 SQLite 단일 워크스페이스를 사용함 |
single_workspace_sqlite=true, settings_and_snapshot_share_db=true, collector_separate_db=true |
Temp/snapshot_admin_web_validation.db, tools/validate_snapshot_admin_web_v1.py |
| M4 |
전환 검증이 재현 가능함 |
python tools/validate_platform_transition_wbs_v1.py PASS |
Temp/platform_transition_wbs_v1.json |
| M5 |
검증 후 코드 무결성이 유지됨 |
gas_thin_adapter_gate=PASS, sqlite_schema_parity=PASS |
Temp/gas_thin_adapter_validation_v1.json, tools/validate_gas_thin_adapter_v1.py |
| 세부 WBS |
작업 |
데이터 기반 완료 정의 |
현재 상태 |
| 8.2.1 |
수집 파이프라인 SQLite 1차화 |
.gitea/workflows/kis_data_collection.yml이 xlsx를 직접 1차 입력으로 요구하지 않고 SQLite 적재를 수행 |
완료 |
| 8.2.2 |
어드민 편집기 SQLite 1차화 |
tools/validate_snapshot_admin_web_v1.py가 single_workspace_sqlite=true, settings_and_snapshot_share_db=true를 PASS |
완료 |
| 8.2.3 |
JSON 재생성성 |
Temp/test_kis_data_collection.json이 GatherTradingData.json seed로 재생성되고 status=PASS를 유지 |
완료 |
| 8.2.4 |
DB 재생성성 |
Temp/test_kis_data_collection.db가 동일 seed 계열로 재생성되고 핵심 테이블 3개를 유지 |
완료 |
| 8.2.5 |
snapshot DB 재생성성 |
Temp/snapshot_admin_web_validation.db가 GatherTradingData.json seed로 재현되고 5개 핵심 테이블을 유지 |
완료 |
| 8.2.6 |
approval packet 재현성 |
Temp/snapshot_admin_approval_packet_v1.json이 snapshot admin validator와 함께 재생성 가능 |
완료 |
| 8.2.7 |
xlsx 역할 축소 |
GatherTradingData.xlsx는 docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md에 적힌 보조 자산 역할만 수행 |
완료 |
| 8.2.8 |
xlsx 직접 의존 제거 |
workflow와 validator에서 GatherTradingData.xlsx를 직접 1차 입력으로 요구하지 않음 |
완료 |
| 8.2.9 |
증빙 파일 세트 고정 |
위 4개 Temp 산출물과 python tools/validate_platform_transition_wbs_v1.py PASS가 함께 존재 |
완료 |
| 8.2.10 |
재생성 절차 고정 |
runbook에 GatherTradingData.json 우선, 이후 tools/convert_xlsx_to_json.py와 tools/run_kis_data_collection_v1.py 순서가 명시됨 |
완료 |
| 8.2.11 |
종료 선언 |
operator guide와 workflow가 SQLite/JSON 우선을 유지 |
완료 |
항목별 재생성 명령
| 항목 |
명령 |
| 8.2.3 JSON 재생성성 |
python tools/run_kis_data_collection_v1.py --input-json GatherTradingData.json --sqlite-db Temp/test_kis_data_collection.db --output-json Temp/test_kis_data_collection.json --kis-account real --no-live-kis |
| 8.2.4 DB 재생성성 |
python tools/run_kis_data_collection_v1.py --input-json GatherTradingData.json --sqlite-db Temp/test_kis_data_collection.db --output-json Temp/test_kis_data_collection.json --kis-account real --no-live-kis |
| 8.2.5 snapshot DB 재생성성 |
python tools/validate_snapshot_admin_web_v1.py |
| 8.2.6 approval packet 재현성 |
python tools/validate_snapshot_admin_web_v1.py |
파일별 해석
GatherTradingData.json: 수집 seed 입력이다.
Temp/test_kis_data_collection.json: run_kis_data_collection_v1.py의 출력 요약이다.
Temp/test_kis_data_collection.db: 같은 실행에서 생성되는 SQLite 수집 DB다.
Temp/snapshot_admin_web_validation.db: snapshot admin web 검증이 사용하는 SQLite 워크스페이스 DB다.
Temp/snapshot_admin_approval_packet_v1.json: snapshot admin 승인 패킷이다.
WBS-8.8 Naver 스크래핑 → KIS Open API 전환 트랙
목표 요약
- 핵심 키워드: Naver 스크래핑 의존 축소 후 KIS Open API 우선화
- 이 트랙은 시세/수급/호가 계열의 read-only 수집 경로를 KIS로 이동시키는 작업이다.
- Naver는 폴백 또는 보조 탐색으로만 남기고, 주요 운영 경로는 KIS API 결과로 판정한다.
- 운영 우선순위:
KIS 우선 > Naver 폴백 > seed JSON replay.
- 저장 우선순위:
SQLite 우선 > Temp JSON > xlsx archive.
성공 목표
| 목표 |
성공 판정 기준 |
기대 결과값 |
데이터 증빙 |
| K1 |
KIS read-only 경로가 기본 경로임 |
KIS_APP_KEY, KIS_APP_SECRET 기반 수집이 먼저 시도되고, KIS 성공 시 source_priority 선두에 위치함 |
.gitea/workflows/kis_data_collection.yml, tools/validate_kis_api_credentials_v1.py, Temp/test_kis_data_collection.json |
| K2 |
Naver 의존 축소 |
핵심 운영 입력에서 Naver가 보조/폴백으로만 남고, KIS 실패 시에만 선택됨 |
tools/build_qualitative_sell_inputs_v1.py, tools/fetch_naver_market_data_v1.py |
| K3 |
결과값이 SQLite에 기록됨 |
KIS 결과가 src/quant_engine/kis_data_collection.db 또는 Temp/*db로 적재되고 row_count>0 |
SQLite DB 테이블, tools/run_kis_data_collection_v1.py, Temp/test_kis_data_collection.db |
| K4 |
실패가 투명하게 남음 |
KIS 실패 시 status, source_counts, error가 숨지지 않고 JSON/DB에 남음 |
Temp/test_kis_data_collection.json, validator 로그 |
| K5 |
운영 자동화가 유지됨 |
스케줄/수동 실행에서 동일 계약을 유지하고, seed-first/SQLite 우선 문구가 유지됨 |
.gitea/workflows/kis_data_collection.yml, tools/run_kis_data_collection_v1.py, docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md |
세부 WBS
| 세부 WBS |
작업 |
데이터 기반 완료 정의 |
현재 상태 |
| 8.8.1 |
KIS 우선 수집 경로 고정 |
workflow와 CLI가 read-only KIS를 먼저 시도 |
완료 ✅ |
| 8.8.2 |
Naver 폴백 경계 확정 |
KIS 실패 시에만 Naver가 선택됨 |
완료 ✅ |
| 8.8.3 |
KIS credential 검증 |
tools/validate_kis_api_credentials_v1.py --dry-run PASS |
완료 ✅ |
| 8.8.4 |
SQLite 적재 검증 |
KIS 수집 결과가 SQLite 테이블에 기록되고 row_count>0 |
완료 ✅ |
| 8.8.5 |
운영 보고서 증빙 |
provenance와 실패 사유가 JSON/DB에 남음 |
완료 ✅ |
| 8.8.6 |
전환 종료 선언 |
source_priority[0] == kis_open_api가 유지되고 status=PASS/row_count>0/collection_runs>=1/collection_snapshots>=1가 동시에 성립 |
완료 ✅ |
8.8 작업 티켓
| 티켓 |
산출물 |
완료 정의 |
| 8.8.T1 |
tools/run_kis_data_collection_v1.py |
KIS 우선 경로가 기본 시도 경로로 남고 Naver는 폴백만 수행 |
| 8.8.T2 |
tools/validate_kis_api_credentials_v1.py |
dry-run 기준으로 credential/endpoint 증빙이 남음 |
| 8.8.T3 |
Temp/test_kis_data_collection.db |
collection_runs / collection_snapshots / collection_source_errors가 기대값을 만족 |
| 8.8.T4 |
Temp/test_kis_data_collection.json |
provenance, source_counts, row_count, status가 PASS로 남음 |
| 8.8.T5 |
docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md |
xlsx는 seed-prep 보조 자산으로만 설명됨 |
| 8.8.T6 |
python tools/validate_platform_transition_wbs_v1.py |
WBS-8.2/8.8 검증이 PASS 유지 |
collector helper 증빙
tests/unit/test_kis_data_collection_v1.py
tests/integration/test_kis_collection_to_snapshot_admin_and_sell_strategy_v1.py
src/quant_engine/kis_data_collection_v1.py
WBS-8.3 공통 완료 정의
YAML
- 트랙별 WBS가
docs/ROADMAP_WBS.md에 존재해야 한다.
- 관련 contract/spec/governance 문서가 같은 방향을 가리켜야 한다.
코드
.gs → Python은 canonical Python 구현과 parity test가 있어야 한다.
xlsx → sqlite는 canonical SQLite store와 이를 사용하는 workflow/validator가 있어야 한다.
데이터
Temp/*.json, Temp/*.db, GatherTradingData.json, GatherTradingData.xlsx 중 해당 트랙의 실제 산출물이 존재해야 한다.
.gs → Python은 Temp/gas_thin_adapter_validation_v1.json, parity test 결과, migration ledger가 함께 있어야 한다.
xlsx → sqlite는 Temp/test_kis_data_collection.db, Temp/test_kis_data_collection.json, Temp/snapshot_admin_web_validation.db가 함께 있어야 한다.
검증
python tools/validate_gas_thin_adapter_v1.py
python tools/validate_platform_transition_wbs_v1.py
python tools/validate_snapshot_admin_web_v1.py
python tools/validate_packaged_artifact_references_v1.py --strict
WBS-8.4 실행 순서
.gs → Python 잔여 finding을 TODO / DONE / KEEP_IN_GAS로 재집계한다.
tests/parity/test_stop_loss_policy_parity.py, tests/parity/test_distribution_risk_parity.py, tests/parity/test_late_chase_risk_parity.py, tests/parity/test_routing_decision_parity.py를 ledger finding과 1:1 대응시킨다.
src/quant_engine/kis_data_collection_v1.py를 source selection / source normalization / persistence로 분리한 뒤, collector 단일 책임을 유지한다.
xlsx → sqlite 의존 경로를 workflow와 validator에서 제거한다.
Temp/test_kis_data_collection.json과 Temp/test_kis_data_collection.db를 재생성한다.
Temp/snapshot_admin_web_validation.db를 재생성하고 python tools/validate_snapshot_admin_web_v1.py를 다시 통과시킨다.
- 완료 정의를 충족하는 항목만
DONE으로 승격한다.
GatherTradingData.xlsx는 seed-prep/복구용 보조 자산으로만 취급하고 직접 실행 경로에서 제외한다.
spec/56_renderer_copy_only_contract.yaml와 spec/40_final_decision_packet_contract.yaml의 F08 근거를 유지한다.
- runbook과 workflow가 JSON/SQLite 우선을 1차 권위로 유지하는지 재검증한다.
WBS-8.5 현재 결론
.gs → Python: 아직 부분 완료다.
xlsx → sqlite: 아직 부분 완료다.
- 둘 다 “파일 수를 줄이는 것”이 완료가 아니라, 결정 로직의 권위와 입력의 권위를 옮기는 것이 완료다.
WBS-8.6 GAS ledger 재분류 블로커
현재 governance/gas_logic_migration_ledger_v1.yaml의 23개 forbidden_gas_business_logic_count는 다음 이유로 즉시 재분류할 수 없다.
| blocker |
영향 |
판정 |
| 전용 parity test 부재 |
MIGRATE_* 계열은 GAS와 Python의 동일 입력/동일 출력 증빙이 있어야 DONE 승격 가능 |
BLOCKED |
| canonical Python 부재/불명확 |
DELETE_* 계열은 Python canonical 또는 동등 판정이 없으면 삭제 불가 |
BLOCKED |
| renderer-only 경계만 확정 |
F08만 KEEP_IN_GAS로 유지 가능 |
READY |
| collector refactor는 범위 외 |
KIS 우선 수집 경로는 GAS thin-adapter ledger가 아니라 WBS-8.8에서 추적 |
OUT_OF_SCOPE |
즉, 현재 레저는 TODO가 아니라 parity / canonical evidence 부족 상태다.
다음 스프린트에서 해야 할 일은 "기계적 재분류"가 아니라 "증빙을 만들고 그 증빙으로 승격"이다.
잔여 finding의 실제 작업 단위
| 카테고리 |
대상 finding |
다음 작업 |
| price/qty parity |
F02, F03, F04, F05, F06 |
tests/parity/test_price_qty_parity_v1.py로 동일 입력 포트 테스트를 고정하고 Python 출력과 대조. compute_sell_decision() / compute_stop_action_ladder() 동시 검증 |
| score parity |
F07, F12, F13, F14 |
tests/parity/test_score_parity_v1.py로 BUY_BREAKOUT_PILOT_ONLY, BUY_PULLBACK_WAIT, EXIT_REVIEW, STOP_OR_TIME_EXIT_READY, OBSERVE_DATA_MISSING golden case를 분리 검증 |
| routing parity |
F10, F11, F15 |
tests/parity/test_routing_gate_parity_v1.py로 STOP_OR_TIME_EXIT_READY, RISK_OFF, HALVE_NEW_BUY_QUANTITY, HARD_BLOCK, RW2B_FAST_TRACK, trailing_stop, MEAN_REVERSION golden case를 분리 검증 |
| registry confirmation |
F01, F09 |
이미 DONE이므로 재작업 불필요 |
| presentation-only |
F08 |
KEEP_IN_GAS 유지 |
WBS-8.7 실행 티켓
| 티켓 |
체크 |
증빙 |
상태 |
| 8.7.1 |
[x] F08 유지 근거 고정 |
governance/gas_logic_migration_ledger_v1.yaml의 status: KEEP_IN_GAS + rationale + roadmap inventory 반영 |
완료 |
| 8.7.2 |
[x] xlsx 보조 자산 선언 |
docs/GATHERTRADINGDATA_XLSX_OPERATING_RUNBOOK.md + roadmap 문구 |
완료 |
| 8.7.3 |
[x] seed-prep 분리 |
kis_data_collection.yml이 workbook 직접 regeneration을 수행하지 않음 |
완료 |
| 8.7.4 |
[x] JSON 우선 운영 명시 |
workflow/operator guide가 GatherTradingData.json을 1차 입력으로 취급 |
완료 |
| 8.7.5 |
[x] xlsx 아카이브 통합 |
archive policy를 operating runbook에 통합해 중복 문서를 제거 |
완료 |
| 8.7.6 |
[x] renderer contract 연결 |
spec/56_renderer_copy_only_contract.yaml와 spec/40_final_decision_packet_contract.yaml에 의해 F08이 rendering-only로 유지 |
완료 |
| 8.7.7 |
[x] 종료 체크 |
validate_platform_transition_wbs_v1.py와 validate_snapshot_admin_web_v1.py PASS |
완료 |
7. 부록: Phase 5 데이터 플랫폼 전환 WBS 성공값
원칙: 아래 항목은 모두 기대 성공값 + 데이터 증빙 + 검증 명령이 함께 있어야 성공으로 본다.
현재 구현된 항목은 로컬 Temp/ 증빙을 기준으로 판정하고, 아직 미래 전환 항목은 DATA_GATED로 둔다.
| WBS |
기대 성공값 |
데이터 증빙 |
검증 명령 |
| P1 KIS core collector |
collector_gate=PASS, output_json_gate=PASS, collection_runs>=1, collection_snapshots>=1, provenance_source_count>=1 |
Temp/test_kis_data_collection.json, Temp/test_kis_data_collection.db |
python tools/run_kis_data_collection_v1.py --input-json GatherTradingData.json --sqlite-db Temp/test_kis_data_collection.db --output-json Temp/test_kis_data_collection.json --kis-account real --no-live-kis --no-naver |
| P2 SQLite canonical store |
sqlite_schema_tables>=3, round_trip_snapshot_lookup=PASS, backend_contract_sqlite=PASS, backend_contract_postgresql=READY, single_workspace_sqlite=true, collector_separate_db=true |
src/quant_engine/data_collection_store_v1.py, src/quant_engine/data_collection_backend_v1.py, tests/unit/test_data_collection_store_v1.py, src/quant_engine/snapshot_admin_store_v1.py |
python -m pytest tests/unit/test_data_collection_store_v1.py -q |
| P3 CI scheduler cutover |
xlsx_dependency_removed=true, json_seed_input=true, sqlite_output=true, mock_api_validation=PASS, no_direct_trading_gate=PASS |
.gitea/workflows/kis_data_collection.yml, Temp/kis_api_credentials_validation_v1.json, Temp/test_kis_data_collection.json |
python tools/validate_no_direct_api_trading_v1.py |
| P4 GAS thin adapter minimize |
allowed_responsibilities_only=true, forbidden_responsibilities_present=false, thin_adapter_gate=PASS |
tools/validate_gas_thin_adapter_v1.py, Temp/gas_thin_adapter_validation_v1.json, src/gas/core/gas_lib.gs |
python tools/validate_gas_thin_adapter_v1.py |
| P5 PostgreSQL upgrade path |
sqlite_schema_parity=PASS, backend_contract_present=true, postgres_execution=DATA_GATED, caller_compatibility_preserved=true |
src/quant_engine/data_collection_backend_v1.py, src/quant_engine/kis_data_collection_v1.py, tests/unit/test_data_collection_store_v1.py, tools/generate_postgresql_upgrade_stub_v1.py |
python -m pytest tests/unit/test_data_collection_store_v1.py -q |
| P6 Snapshot admin web editor |
settings_sheet_web_editor=true, account_snapshot_sheet_web_editor=true, contenteditable_grid=true, api_save_round_trip=PASS, kis_collection_dashboard=true, workspace_db_is_single_file=true, collection_filter_controls=true, collection_dashboard_page=true, change_timeline_view=true |
src/quant_engine/snapshot_admin_server_v1.py, src/quant_engine/data_collection_store_v1.py, src/quant_engine/snapshot_admin_store_v1.py, tools/validate_snapshot_admin_web_v1.py, tests/unit/test_snapshot_admin_web_v1.py, .gitea/workflows/snapshot_admin.yml |
python tools/validate_snapshot_admin_web_v1.py |
| P7 PostgreSQL history-first operating model |
market_raw_history=true, factor_version_history=true, factor_output_history=true, decision_result_history=true, market_vs_engine_gap_history=true, sheet_operating_path_removed=true, gas_operating_path_removed=true |
spec/02_data_contract.yaml, spec/postgresql_history_contract.yaml, docs/DAILY_SIGNAL_TRACKING.md, docs/POSTGRESQL_HISTORY_FIRST_OPERATING_MODEL.md |
python tools/validate_postgresql_history_contract_v1.py |
| Q1 Qualitative sell pipeline |
mock_api_validation=PASS, pipeline_contract=PASS, workflow_present=true, schedule_present=true, package_scripts_present=true |
.gitea/workflows/qualitative_sell_strategy.yml, tools/validate_qualitative_sell_strategy_pipeline_v1.py, Temp/qualitative_sell_strategy_pipeline_v1.json |
python tools/validate_qualitative_sell_strategy_pipeline_v1.py |
| Q2 Gitea secrets contract |
secrets_contract=PASS, workflow_secret_mapping=PASS, docs_present=true, ci_validation_present=true |
docs/GITEA_SECRETS_SETUP.md, tools/validate_gitea_secrets_contract_v1.py, Temp/gitea_secrets_contract_v1.json |
python tools/validate_gitea_secrets_contract_v1.py |
WBS 성공 판정 규칙
PASS: 기대 성공값이 충족되고, 해당 증빙 파일이 실제로 존재한다.
READY: 지금은 실행하지 않지만, 다음 단계 전환에 필요한 코드/계약이 존재한다.
DATA_GATED: 의도적으로 아직 실제 데이터가 쌓이지 않아 보류된 항목이다.
FAIL: 기대 성공값을 만족하지 못하거나 증빙이 없다.
이 문서는 docs/ROADMAP_WBS.md 에 저장됩니다.
스프린트 완료마다 완성도 KPI 섹션을 업데이트하세요.
모든 WBS 항목의 구현 시 반드시 하네스 성공 기준을 먼저 충족 후 다음 단계로 진행합니다.