discover 발굴 순서 전환 — "강한 종목 먼저 → 테마 집결도 역산"¶
작성: 2026-05-29 (S329)
배경: score_compose에서 rs_vs_theme_z + stock_rs_z = RS 이중계상. 010170 폭등주가 게이트로 막혀도 score 서열 상위 잔존.
PM 결정: 테마 RS 별도계산 폐기 → 강한 종목 집결도로 테마 강도 역산.
Status: 📋 설계 — 구현 전 PM 승인 대기
0. 현행 구조의 문제¶
universe 80 → 종목별 D4(테마매핑 + 테마RS 별도계산) → score: z(stock_rs) + z(rs_vs_theme) + ...
↑ OHLCV로 테마RS 재계산 ↑ RS가 두 축에 중복
문제 2가지:
1. RS 이중계상: stock_rs(시장 대비)와 rs_vs_theme(=stock_rs − theme_rs)가 둘 다 stock_rs를 품음 → 폭등주 score 2배 부풀림.
2. 테마 RS 중복계산: D4가 OHLCV로 테마 RS를 재계산. 그런데 data/theme_tracker/dashboard.json에 검증된 테마 RS(latest_rs/grade/leader)가 이미 존재.
1. PM 제안 구조 (역산)¶
1단계: universe 80종목 → 종목 RS(시장 대비 강도) 계산 → 강한 종목 식별
2단계: 강한 종목들을 테마별 그룹핑 (ats_main themes 매핑)
3단계: "테마 X에 강한 종목 N개 집결" = 테마 강도 (역산, 별도 RS계산 불필요)
4단계: 테마 내 순위 = 그 종목이 테마 leader인가
핵심 전환: 테마 강도 = "그 테마에 RS 강한 종목이 몇 개 모였나 + 평균 RS". 종목 RS를 한 번만 쓴다.
테마 집결도 정의 (theme_concentration)¶
각 테마별:
- member_count_in_universe: universe 80개 중 이 테마 소속 수
- strong_member_count: 그중 stock_rs > 임계(예: z>1.0) 수
- theme_avg_rs: 소속 종목 stock_rs 평균
- concentration = strong_member_count / member_count_in_universe (집결 비율)
- is_leader: 이 종목이 테마 내 stock_rs 최댓값인가
→ 테마 강도는 소속 종목들의 RS 집계로 역산. dashboard.json 별도 RS 불필요(단 교차검증용 참고 가능).
2. score 산식 변경 (RS 한 번)¶
현행 (6축, RS 중복)¶
final = z(rs_vs_theme) + z(stock_rs) + z(accel) + z(ofm_cvd) + z(catalyst) + z(ea)
└─ RS 중복 ──┘
신규 (RS 1회 + 테마 보너스)¶
final = z(stock_rs) # 시장 대비 강도 (1회만)
+ z(accel) # 차트 가속
+ z(ofm_cvd) # 수급
+ z(catalyst) # 재료
+ z(ea) # 펀더멘탈
+ theme_bonus # 테마 집결도 가산 (rs_vs_theme 대체)
theme_bonus = f(concentration, is_leader):
- is_leader AND concentration 높음 → +α (강한 테마의 대장)
- is_leader AND concentration 낮음 → 0 (외톨이 강세 = 테마 미형성)
- follower (테마 강한데 본인 약함) → 약한 +
- 무테마/약테마 → 0
→ rs_vs_theme_z(이중계상) 제거. 테마는 "score 축"이 아니라 "보너스/맥락"으로. 폭등주가 무테마면 theme_bonus=0 → RS 단독으로는 못 올라옴.
010170 역산 효과¶
- stock_rs_z 여전히 높음(+4.5) — 시장 대비 강한 건 사실
- 하지만 rs_vs_theme +4.83 제거 → score에서 한 축 통째로 빠짐
- 광통신 테마 집결도: universe에 광통신 종목 소수 → concentration 낮음 → theme_bonus 작음
- catalyst_z −2.0 + 과열 게이트 유지
- → score 서열에서도 하락 (게이트+점수 동시)
3. 구현 범위 (PM 승인 후)¶
| Step | 파일 | 변경 |
|---|---|---|
| 1 | scripts/discover/indicators/theme_concentration.py (신규) |
universe 종목들의 stock_rs → 테마별 그룹핑 → concentration/avg_rs/is_leader 산출 |
| 2 | score_compose.py |
rs_vs_theme_z 제거 + theme_bonus 추가. RS 1회. |
| 3 | build_d7_input.py |
전체 universe stock_rs를 모아 theme_concentration 1회 산출 → 각 후보에 theme_bonus 주입 |
| 4 | build_d4_input.py / theme_rs.py |
테마 RS 별도계산 축소 — dashboard.json 인용 또는 집결도로 대체 (D4 verdict는 leader 여부 위주로 유지) |
| 5 | .claude/agents/discover/theme-leadership-judge.md |
"테마 집결도 기반 leader 판정"으로 해석 규칙 갱신 |
| 6 | 검증 | 20260527 재점수 → 010170 rs_vs_theme 제거로 순위 추가 하락 + 반도체/MLCC(집결도 높은 테마) 상위 |
의존: 이번 score_compose(S329 1차)에서 만든 catalyst_z·게이트는 유지. rs_vs_theme_z만 theme_bonus로 교체.
4. 미해결/판단 필요¶
- theme_bonus 가중치 크기: α를 얼마로? (z축들과 균형 — 과하면 테마 쏠림, 작으면 무의미)
- concentration 임계: strong member를 stock_rs z>1.0으로 볼지, 절대 수익률로 볼지
- dashboard.json 교차: 집결도 역산값 vs dashboard latest_rs 불일치 시 어느 쪽? (역산 우선, dashboard는 참고)
- D4 verdict의 역할 재정의: 기존 "테마 강한가+leader인가" → "이 종목이 (집결도 높은)테마의 leader인가"로 축소