S346 작업 계획 — D7 선정 로직 재설계 (받침 축 완비 + rank aggregation)¶
작성: 2026-06-03 (Wed) — S345 말미 PM 지시로 다음 세션 인계 상태: 📋 설계 확정, 구현 대기 (S346 시작점)
0. 배경 — 왜 재설계하나 (PM 지적 누적)¶
S345에서 D7 score를 "차트게이트 + RS 가점 ×2.5"로 바꿨더니 RS 편중이 생김. 6/02 selected = SKAI(357880): RS 1등·RS과거 1등·수급OF 1등이지만 거래대금 12등·펀더 13등(꼴찌)·재료 11등 = 한쪽으로 극단 쏠린 종목인데 가중치 합산(RS×2.5)이 약점을 덮어 1등이 됨.
PM 선정 논리 (정본):
차트상 갈 만한 자리(전제)인가 → 그렇다면 그게 받쳐지는가: ① 시장상황 ② 재료 ③ 수급(실제 거래대금) ④ 펀더멘탈 ⑤ 섹터 자금유입
현재 시스템의 받침 반영도 (코드 확인, score_compose.py):
| 받침 | 현재 | 문제 |
|---|---|---|
| 차트 갈자리(전제) | chart_verdict + D2 게이트 | ✅ OK |
| 시장상황(D1) | d1_macro는 D7 input에 있으나 게이트로만(NEGATIVE면 전체 중단), 종목 score 미반영 | ⚠️ 종목 차별 안 함 |
| 수급(실제 거래대금) | ofm_cvd_z(30분봉 방향만) | ❌ 거래대금 절대량/증가 축 없음 |
| 펀더(ea) | ea_z ×0.5 | ⚠️ 눌림 |
| 재료(catalyst) | catalyst_z ×0.5 | ⚠️ 눌림 |
| 섹터 자금유입 | data/sector_flow/{date}.json 존재하나 D7 미사용 | ❌ 통째 누락 |
→ 받침 2개(섹터·실거래대금) 누락 + 1개(시장) 게이트로만 + 2개(펀더·재료) 눌림 → 결국 RS·차트만 남아 편중.
1. 설계 방향 (PM 승인)¶
(A) 누락 축 추가¶
- 실제 거래대금 축 — market_top
amount_억(절대량) + 5d/20d 증가율(유입 가속). 소스:data/market_top/{YYYYMMDD}.jsontop_amount (S345에서 200행으로 확장됨). ofm(방향)과 별개 축. "돈이 실제로 얼마나·더 들어오는가". - 섹터 자금유입 축 — 종목의 primary_theme/섹터가 sector_flow에서 LEADING/유입 중인가.
소스:
data/sector_flow/{YYYYMMDD}.json(S343 백필됨). D1 관찰5(섹터 도착)와 정합. - 시장상황을 종목 차별 축으로 — D1 LEADING 섹터 ∈ 종목 테마면 가점. 현재 d1_macro는 게이트로만 → 종목별 "시장 자금 방향과 일치하는가"로 활용.
(B) 가중치 합산 → rank aggregation (PM "가중치 임의성 제거")¶
- 각 축에서 종목 순위(rank) 매기고 순위 합으로 종합 (Borda count).
- 가중치(2.5/0.5) 불필요 → 가중치에 따라 순위 흔들리는 문제 제거.
- 한 축만 튀어도 못 이김(SKAI 6등 강등 확인) = 균형 우대.
(C) 차트 게이트 유지 (전제)¶
- D2 verdict POSITIVE만 rank aggregation 진입. "차트 갈자리"가 자격 조건.
2. rank aggregation 시산 결과 (6/02, 비용0 검증 완료)¶
게이트 통과 13종, 순위합 낮을수록 좋음:
| 종목 | 순위합 | RS | RS과거 | 거래대금 | 수급OF | 펀더 | 재료 |
|---|---|---|---|---|---|---|---|
| 삼성전자 | 25 | 5 | 6 | 1 | 7 | 2 | 4 |
| 두산로보틱스 | 27 | 6 | 7 | 2 | 6 | 3 | 3 |
| 삼성생명 | 35 | 4 | 8 | 5 | 8 | 8 | 2 |
| 제주반도체 | 35 | 3 | 3 | 9 | 4 | 9 | 7 |
| 엔씨소프트 | 36 | 9 | 11 | 6 | 3 | 1 | 6 |
| SKAI | 39(6등) | 1 | 1 | 12 | 1 | 13 | 11 |
- SKAI 1등→6등 (약점 3축 반영). 삼성전자·두산로보(전 축 고르게 상위) 1·2등.
- ※ 이 시산은 섹터·시장 축 미포함(아직 미구현). 추가 후 재산정 필요.
3. 구현 WBS (S346)¶
M1. 거래대금 축¶
- [ ]
build_d7_input또는 신규 indicator: market_top에서 amount_억 + amt5/amt20 증가율 산출. - [ ] D7CandidateRow raw_metrics에 amount/amount_accel 추가.
- [ ] 결손 처리: market_top 200위 밖 종목(SKAI 같은 중소형 일부) → 거래대금 작음으로 실측 또는 FDR Close×Volume 폴백(s303 OHLCV 98종 한계 → universe 전체 일봉 필요할 수 있음, 데이터 점검).
M2. 섹터 자금유입 축¶
- [ ] sector_flow JSON 로드 → 종목 primary_theme → 섹터 status(LEADING/STRONG/...) + 유입 강도 매핑.
- [ ] 테마명 ↔ sector_flow 섹터명 매핑 테이블 점검(ats_main theme vs sector_series theme 명칭 정합).
- [ ] raw_metrics에 sector_inflow 추가.
M3. 시장상황 종목 차별¶
- [ ] D1 envelope의 LEADING 섹터(자금 도착) 리스트 → 종목 테마가 거기 속하면 가점/순위 반영.
- [ ] (게이트 역할은 유지) + 종목 차별 축 신설.
M4. rank aggregation 엔진¶
- [ ] score_compose 재작성: 가중치 합산 → 축별 rank → 순위 합. 차트 게이트 전제 유지.
- [ ] 결손 축 처리 정책 결정 (★ PM 논의 필요):
- SKAI 펀더 UNKNOWN(EA panel 없음)을 최하위로? 중간으로? 제외(그 축 빼고 평균)?
- S345 원칙 "정보 부재 ≠ 나쁜 신호"와 충돌 → 최하위 페널티는 그 원칙 위반.
- 후보: (a) 결손축 제외하고 가용축만 순위평균 (b) 결손=중간순위 (c) 결손=최하위(현 시산).
- 시산: 방식별 top 비교 후 PM 결정.
- [ ] D7CandidateRow에 per-axis rank + 순위합 보존(리포트 인용).
M5. 리포트 반영¶
- [ ] 선정 결론·한줄요약을 rank 기반으로(각 축 몇 등인지 표시 = "왜 이 종목"이 투명).
- [ ] 6/02 재스코어로 selected 변화 검증(LLM 0, envelope 재사용).
M6. EA panel 확장 (갭1, 병행)¶
- [ ] selected가 중소형(EA panel 196종 밖)이면 펀더 결손 구조적 → discover universe(거래대금 200종)로 EA panel DART 재백필. MCP 비용. SKAI 펀더가 안 채워지는 근본 원인.
4. 미결 — PM 결정 대기 (S346 시작 시)¶
- 결손 축 처리 (M4) — 최하위/중간/제외 중. "정보 부재 ≠ 나쁜 신호"와의 정합.
- 거래대금 결손 폴백 (M1) — market_top 200위 밖 종목 거래대금 어떻게 구할지(FDR? universe 일봉 백필?).
- 축 개수/구성 확정 — RS·RS과거를 1축으로 합칠지(현재 2축이라 RS 비중 2배), 차트를 rank 축에 넣을지 (게이트만? 축도?).
- EA panel 확장 범위/비용 (M6).
5. S345 완료분 (이번 세션, 이어받기용)¶
- 갭 진단(커버리지/라이브fetch) / 30분봉 271종 6/02 갱신 / 거래대금 풀 100→200 / D7 차트게이트+주도주 가점+rs_high(★이번 재설계로 가중치 부분은 대체될 예정, 게이트·rs_high는 유지) / 병렬화(8.5h→~1.3h, --parallel) / 리포트 수정(truncate·옛문구·재료Dnews우선·종목명·한줄요약).
- 주의: S346 rank aggregation은 S345의 "RS×2.5 가중치 합산"을 대체함. 게이트·rs_high 지표·병렬· 리포트수정·풀200은 유지. score_compose의 가중치 합산부만 교체.
- work_log:
docs/work_logs/2026-06-03_S345_coverage_gap_diagnosis.md