콘텐츠로 이동

S326 — /discover 원자화 설계서 (v6 6도구 → atomic agent 분해)

작성: 2026-05-26 (Tue) 23:35 KST 선행: topic_discovery_walkforward.md Phase E v6 채택 목표: v6 6도구 결합 모델을 production-grade /discover ad-hoc 커맨드로 운영화. 에이전트 원자화 + 데이터 도구 연결 + 하네스 엔지니어링. 이후 기존 /rs_* 커맨드에서 테마/종목 발굴 부분 제거.


0. 원칙 (v2 갱신 — 2026-05-26 23:43)

PM 교정: - 입력 데이터 고정 ❌ → 도구 카탈로그 제공 ✅ (에이전트가 도구 선택) - 산식 박제 ❌ → 단일 질문 + 가이드 + 해석 위임 ✅ - 도구 제약 거의 없음 (단, 표준 도구·표준 데이터는 정형화하여 권장)

하이브리드 분담:

영역 담당 이유
수치 산출 (RS, cvd_z, accel_ratio, EA_z, theme_rank...) 코드 (deterministic) 백테스트 재현성 + 결정론
데이터 적재 에이전트가 직접 (Read/Bash/MCP) 유연성
임계 판정 / 신호 해석 / 결손 대응 에이전트 (interpretive) LLM 강점 활용
최종 단일 답변 에이전트 (verdict + evidence + confidence) 근거 인용 의무

v2 원칙: 1. 1 atomic agent = 1 단일 질문. 합성 판단 금지. 2. 질문은 의미 단위. "L1_gate_ON 컬럼이 True인가?"가 아니라 "오늘 매크로 환경이 매수 진입에 우호적인가?" 3. 도구 제약 거의 없음 — Read, Bash(run_py.ps1), 서브에이전트 호출, WebSearch, MCP 자유 사용. 4. 표준 도구·표준 데이터·판단 가이드 = 정형 제공. 에이전트 정의서가 이걸 명시. 5. 수치 산출 = 코드 위임 의무. 에이전트가 RS를 직접 계산하지 않음. 코드 실행 후 결과를 인용. 6. 출력 = 표준 JSON 스키마 (verdict + evidence + 수치 인용). 다음 agent 입력으로 직결. 7. 각 atomic은 단독 실행 가능 (idempotent). T0 인자만 받음. 8. 하네스 = 게이팅 체인. 앞 게이트가 PASS면 뒷 게이트 skip → 비용 절감.


1. v6 운영 룰 (인용 — sim_v6_6tools.py:8-12)

L1 ON + L2 confirmed + stock_RS>0 + theme_RS>0 + leader + rs_vs_theme>=0 + (v6: OF 매수 강세)
score = z(rs_vs_theme) + z(stock_rs) + z(accel) + z(ofm_cvd_z)   ← v6
final select: 일별 final_score rank 1
D+20 hold (EXIT 룰 없음)

L2 = transition_to_imb_up_confirmed OR imb_up_acceleration_confirmed (sim_v6:154-157) Leader = rs_rank ≤ max(3, n//3) (sim_v6:178) OF 매수 강세 = ofm_cvd_z > 0 AND ofm_bvc_5bar >= 0.55 (sim_v6:193-195)


2. Atomic 분해 (8개) — 의미 질문 중심

각 에이전트는 단일 의미 질문에만 답한다. 산식·임계는 가이드일 뿐 박제하지 않는다. 수치는 코드로 산출 후 인용한다.

ID Agent 의미 질문 (해석 위임)
D1 discover/macro-judge "오늘 매크로 환경이 매수 진입에 우호적인가? 유동성·심리·금리·파생 신호 종합."
D2 discover/chart-judge "이 종목 차트가 매수 진입 가치 있는가? 불균형 구조·가속·국면 종합."
D3 discover/relative-strength-judge "이 종목이 시장(KOSPI)보다 강한가? 60일 RS + 추세 일관성."
D4 discover/theme-leadership-judge "이 종목이 속한 테마가 강한가 + 그 안에서 leader인가?"
D5 discover/orderflow-judge "최근 30분봉에서 매수 흐름이 우세한가? CVD/BVC/흡수 종합."
D6 discover/earnings-quality-judge "이 종목의 실적 가속(EA)이 점수 가중을 얼마로 받을 가치 있는가?"
D7 discover/portfolio-selector "T0 통과 후보들 중 오늘 진입할 1종은 무엇인가? + 사유."
D8 discover/position-monitor "보유 종목들의 D+20 hold 동안 상태는 정상인가? HOLD/EXIT/WARN."

2.1 에이전트 vs 코드 분담 (각 atomic 내부)

atomic 코드 (deterministic) 에이전트 (interpretive)
D1 scripts/discover/macro_indicators.py → 39열 panel + S317 ★ 신호 발화 표 + S308 regime cell 위 3 자료 읽고 "우호 Y/N + 근거 + confidence"
D2 scripts/discover/chart_indicators.py → L2 시나리오 enum + accel_ratio + S317 60 룰 발화표 "매수 가치 Y/N + 어느 신호 우세인지"
D3 scripts/discover/stock_rs.py → stock_rs, stk_ret60, MA 기울기 "RS > 0 충족인가 + 추세 일관성 해석"
D4 scripts/discover/theme_rs.py → primary_theme, theme_rs, theme_rank, rs_vs_theme "leader 자격 + 테마 강도 해석"
D5 scripts/discover/of_indicators.py → ofm_cvd_z, ofm_bvc_5bar, lower_wick 비율 "매수 흐름 우세 Y/N + 신호 견고성"
D6 scripts/discover/ea_indicators.py → ea_z, ea_yoy, sue "weight 0.5/0.8/1.0 결정 + 실적 추세 코멘트"
D7 scripts/discover/score_compose.py → final_score, rank 후보표 "rank1 채택 OR 차상위 추천 OR PASS"
D8 scripts/discover/position_status.py → days_held, current_alpha, drawdown "HOLD/EXIT/WARN + 사유"

Claude main session 역할: 하네스. D1 verdict=NEGATIVE면 PASS 종료. POSITIVE면 universe 루프 시작.


3. 각 Atomic — Input Package + 도구 카탈로그 + 판단 가이드 + 출력 스키마

핵심 원칙 (v3 보강 — 2026-05-27 00:04): 에이전트가 데이터를 사냥하지 않는다. 하네스(main session)가 호출 전에 Input Package를 사전 조립해 에이전트에 전달한다. 에이전트는 패키지를 받은 상태에서 종합 판정만.

  • Input Package = 블록 단위 (의미 단위) 구조화 JSON/YAML
  • 모든 패키지는 Pydantic 모델로 검증 (scripts/discover/schemas.py)
  • 검증 실패 시 즉시 stop (s236 gatekeeper 계보 계승)
  • 에이전트는 추가 도구 사용권 유지 — 패키지가 부족하면 도구로 보강 가능, 단 결정론적 판정은 패키지 인용만으로 가능해야 함

각 절은 에이전트 정의서(.claude/agents/discover/*.md)에 그대로 들어간다.


3.1 D1 — macro-judge

의미 질문: "오늘 매크로 환경이 매수 진입에 우호적인가?"

Input Package 빌더: scripts/discover/build_d1_input.py --date T0 → Pydantic D1Input 검증 후 JSON 반환

Input Package 구조 (D1Input):

package_id: D1_input_{date}
date: 2026-05-27
blocks:
  liquidity:                          # 유동성 (Druckenmiller 본질)
    fed_net_liquidity_usd_b: 5931.2
    delta_20d_b: +230
    z_60d: +1.35
    walcl_lev: HIGH                   # enum: LOW/MID/HIGH
    walcl_chg_z: +0.82
    rrp_chg_z: -1.10
    deposit_lev: HIGH                 # 한국 고객예탁금 (Phase A7)
    deposit_chg_z: +0.45
    spy_lev / gspc_lev / sox_lev: HIGH/HIGH/MID
    evidence_grade: "★★"
  sentiment:                          # 심리 (Howard Marks pendulum)
    vix: 14.2
    vix_chg_z: -0.32
    vix_term_regime: STRONG_CONTANGO
    vkospi_fut_oi_chg_z: +1.42        # S317 ★★ bull D+20 1.000
    pcr_vol_z: +0.91                  # S317 ★★ bull 0.893
    cnn_fng: {value: 58.6, label: GREED, delta_1w: -4.6}
    aaii / naaim: {available: false}  # paywall
    evidence_grade: "★★"
  rates:                              # 금리
    kr_10y_chg_z: -0.18
    us_2y: 4.32 / us_10y: 4.18
    curve_2_10: -0.14
    real_yield_10y: 1.45
    hy_oas: 312                       # FRED BAMLH0A0HYM2
    hy_regime: EUPHORIA
    evidence_grade: "★"
  derivatives:                        # 파생 (KRX 4년 백필, Phase A2)
    basis_z: +0.85                    # S317 ★★ bull 0.842
    fut_oi_chg_z: +1.21               # S317 ★★ bull 0.909
    kr_10y_fut_chg_z / kr_10y_fut_volume_chg_z: +0.45 / +0.62
    usd_fut_oi_chg_z: -0.42           # 약한 회피
    kospi200_fut_chg_z: +0.78
    max_pain_dist_z: +0.32
    evidence_grade: "★★"
  context:                            # 메타
    s308_regime_cell: L_UP_S_UP_BULL
    s317_active_signals:
      bull: [_NEW_vkospi_fut_oi_chg_z_HIGH, fut_oi_chg_z_HIGH, basis_z_HIGH]
      bear: []
    today_events:                     # WebSearch 또는 EVENT_CALENDAR 인용
      - {time: "2026-05-27 03:00 KST", event: "FOMC minutes"}
    is_option_expiry: false
    yesterday_d1_verdict: POSITIVE
data_quality:
  missing_columns: []
  stale_data: []                      # 24h 이상 미갱신 컬럼
schema_version: 1

도구 카탈로그 (선택, 패키지 보강 시): 1. (1차) Input Package — 이미 전달됨, 재호출 없음 2. Read data/macro/panel_4y_daily.parquet — 패키지 외 컬럼 필요 시 3. Read docs/research/2026-05-26_S317_module_audit_v2.md — 검증표 원본 인용 필요 시 4. Agent macro-economist — 모순 신호 발화 시 도메인 의견 5. WebSearch — 패키지 today_events에 없는 긴급 이벤트 의심 시 6. (자유) DART/KRX MCP, fetch_* 스크립트 등 제약 없음

판단 가이드:

  • 4 블록 evidence_grade 종합:
  • ★★ 다수(3+) + bear 신호 0 → POSITIVE HIGH
  • ★★ 2 + bear 신호 1 → POSITIVE MED
  • ★ 위주 + bear 1+ → NEUTRAL/NEGATIVE
  • bear 신호 ★★ 1+ → NEGATIVE HIGH (회피)
  • ★★ bear 신호 목록 (S317 v2 검증): _NEW_vkospi_fut_oi_chg_z LOW (D+20 0.067), fut_oi_chg_z LOW (0.120), kr_10y_chg_z LOW (0.174), _NEW_kospi200_fut_chg_z LOW (0.158)
  • S308 regime cell 우선: L_UP_S_UP_BULL / L_UP_S_DOWN_Contrarian 진입 우호 / L_DOWN_S_UP_TopWarning 회피
  • data_quality.missing_columns가 3개 이상이면 자동 confidence LOW

출력 스키마 (D1Output Pydantic):

{
  "atomic": "D1_macro_judge",
  "package_id_in": "D1_input_2026-05-27",
  "date": "2026-05-27",
  "verdict": "POSITIVE",
  "confidence": "HIGH",
  "regime": "L_UP_S_UP_BULL",
  "block_grades": {"liquidity": "★★", "sentiment": "★★", "rates": "★", "derivatives": "★★"},
  "signals_supporting": [
    {"name": "_NEW_vkospi_fut_oi_chg_z", "direction": "HIGH", "value": 1.42, "rule_d20": 1.000, "grade": "★★"}
  ],
  "signals_opposing": [],
  "reasoning": "유동성 ★★(WALCL/SPY/SOX lev_HIGH 3/3), 심리 ★★(vkospi_fut_oi_z 1.42 bull D+20 1.000 검증), 파생 ★★(basis_z+fut_oi_z 동반 bull)...",
  "tools_used": ["D1Input package", "macro-economist (consulted on rates ambiguity)"]
}

3.2 D2 — chart-judge

의미 질문: "이 종목 차트가 매수 진입 가치 있는가?"

Input Package 빌더: scripts/discover/build_d2_input.py --date T0 --code CD2Input

Input Package 블록 구조 (D2Input):

blocks:
  trend:                              # C1 가격 궤적
    ma_20/60/120_slope_z: [...]
    drawdown_60d: -0.08
    high_proximity_52w: 0.92
    range_pos_52w: 0.87
  structure:                          # C3/C4 스윙 + 구조 전환
    swing_pattern: HH_HL              # enum
    l2_scenario: transition_to_imb_up_confirmed
    accel_ratio: 1.34
    structure_break_stage: NONE
  volume_profile:                     # 1-4 VP
    poc_dist_atr: +0.42
    va_position: above_vah
    up_down_amount_ratio_log: +0.45   # ★★ S317 bull 우호
    volume_asymmetry_20d: +0.18
    overhang_below_pct: 0.62
  vsa:                                # 1-2 VSA
    last_signal: {id: SOS, strength: 2, age: 3}
    spring_count_20d: 1               # ★★ bull D+20 0.707
    bullish_strength_sum: 4
    bearish_strength_sum: 1
  orderflow_daily:                    # 1-5 OF daily
    cvd_z: +1.2
    bvc_5bar: 0.62
    absorption_score_last: +1.8       # ★★ bull D+20 0.846
  candles:                            # 1-7
    last_10: [{type: hammer, body_ratio: 0.3, ...}]
    lower_upper_wick_ratio: 0.65
  s317_signals_active:                # 발화 룰 자동 집계
    bull: [absorption_score_last_high, spring_count_pos, in_lvn]
    bear: []
data_quality: {...}
schema_version: 1

도구 카탈로그 (선택): 위 블록 외에 Agent chartist (C10 종합) / Agent trader/imbalance-map,structure,origin,dynamics (불균형 4 Layer) 자유 호출.

판단 가이드: - ★★ 진입 시나리오 (v6 검증): transition_to_imb_up_confirmed OR imb_up_acceleration_confirmed - ★★ 강 bull 신호: absorption_score_last >+1.5 (D+20 0.846), in_lvn (0.818), spring_count_20d>0 (0.707), retracement RESOLVING_EARLY (0.665) - ★★ 회피 신호: vp_up_down_amount_ratio_log <-0.3 (D+20 0.062 = 94% 하락), vp_volume_asymmetry_20d <-0.3 (0.160), ofm_bvc_5bar <0.45 (0.152), close_pos <0.3 (0.247) - 역방향 주의 (운영 가치 낮음): err_zscore >+1 (Effort no Result), AMT strong bull - 신호 1개 강하지만 나머지 모호 → confidence LOW

출력 스키마:

{
  "atomic": "D2_chart_judge",
  "date": "...", "code": "069540",
  "verdict": "POSITIVE | NEGATIVE | NEUTRAL",
  "confidence": "HIGH | MED | LOW",
  "l2_scenario": "transition_to_imb_up_confirmed",
  "accel_ratio": 1.34,
  "bull_signals": [{"name": "absorption_score_last", "value": 1.8, "rule_d20": 0.846}],
  "bear_signals": [],
  "reasoning": "...",
  "tools_used": [...]
}


3.3 D3 — relative-strength-judge

의미 질문: "이 종목이 시장(KOSPI)보다 강한가?"

Input Package 빌더: scripts/discover/build_d3_input.py --date T0 --code CD3Input

Input Package 블록 구조:

blocks:
  rs_metrics: {stock_rs_60d, stk_ret_60d, kospi_ret_60d, rs_z_cs}  # cross-sectional z
  rs_trend: {rs_5d, rs_20d, rs_60d, monotonic_up_pct, recent_20d_drawdown}
  consistency: {days_above_kospi_60d, max_consec_below, ma200_above}
data_quality: {...}

도구 카탈로그 (선택): raw OHLCV 직접 read 자유.

판단 가이드: - ★ 베이스라인: stock_rs > 0 (sim_v6 룰 3) - 추가 점검: 60일 단조 상승 vs 변동 큰 RS / 최근 20일 RS 가속 / MA 200 위 - RS>0이지만 직전 20일 급락이면 confidence LOW - 데이터 부족 (60일 미만) → UNKNOWN

출력 스키마:

{
  "atomic": "D3_rs_judge",
  "code": "069540",
  "verdict": "POSITIVE | NEGATIVE",
  "confidence": "HIGH | MED | LOW",
  "stock_rs": 0.082,
  "stk_ret60": 0.171,
  "rs_trend": "consistent | volatile | recent_weak",
  "reasoning": "..."
}


3.4 D4 — theme-leadership-judge

의미 질문: "이 종목이 속한 테마가 강한가 + 그 안에서 leader인가?"

Input Package 빌더: scripts/discover/build_d4_input.py --date T0 --code CD4Input

Input Package 블록 구조:

blocks:
  theme_mapping:                      # ats_main_v2.json 인용
    primary_theme: "광통신"
    all_themes: ["광통신", "5G"]
  theme_rs:                           # 멤버 상위 30 평균
    theme_rs_60d: +0.054
    theme_n: 18
    theme_rank_in_market: 7           # 전체 테마 중 순위
  leadership:                         # 테마 내 leader 판정
    theme_rank: 2                     # 종목의 테마 내 RS rank
    rs_vs_theme: +0.028
    is_leader: true                   # rank ≤ max(3, n//3)
    top3_members: [...]
  lifecycle:                          # sector/lifecycle-tagger 산출
    stage: expansion                  # 5단계 enum
    days_in_stage: 12
    freshness: 0.7
data_quality: {...}

도구 카탈로그 (선택): Agent sector/leader-judge (5대 기준 교차) / Agent sector/lifecycle-tagger (생명주기 보강) / Agent sector/overheat-detector (과열 점검).

판단 가이드: - ★★ 베이스라인 (v6 검증): theme_rs > 0 AND rank ≤ max(3, n//3) AND rs_vs_theme ≥ 0 - 테마 멤버 < 3 → 통계 불충분, UNKNOWN - 종목이 여러 테마 소속 시 primary는 매핑상 첫 번째 — 단, 더 강한 테마가 있다면 명시 - 생명주기 = 소멸 단계면 confidence LOW (테마 RS 양수여도)

출력 스키마:

{
  "atomic": "D4_theme_leader_judge",
  "code": "069540",
  "verdict": "POSITIVE | NEGATIVE | UNKNOWN",
  "confidence": "HIGH | MED | LOW",
  "primary_theme": "광통신",
  "theme_rs": 0.054,
  "theme_n": 18,
  "theme_rank": 2,
  "rs_vs_theme": 0.028,
  "is_leader": true,
  "lifecycle_stage": "expansion",
  "reasoning": "..."
}


3.5 D5 — orderflow-judge

의미 질문: "최근 30분봉에서 매수 흐름이 우세한가?"

Input Package 빌더: scripts/discover/build_d5_input.py --date T0 --code CD5Input

Input Package 블록 구조:

blocks:
  availability:
    has_30min: true
    bars_count: 240
    last_bar: "2026-05-26 15:30"
  cvd:                                # 누적 매수강도
    cvd_last: 1.42M
    cvd_z_40bar: +1.45                # S317 ★★ bull 우호 임계
    cvd_slope_z: +0.85
    cvd_price_divergence: null        # -1/0/+1
  bvc:                                # Buy Volume Concentration
    bvc_5bar: 0.60                    # S317 ★★ baseline 0.55
    bvc_20bar: 0.58
  pressure:
    buy_pres_sell_pres_diff: +0.35    # S317 ★★ bull > 0.3
    lower_upper_wick_ratio: 0.65      # S317 ★★ bull > 1
  absorption:
    absorption_score_last: 0          # 30분봉은 결손 빈도 높음
    absorption_count_20bar: 0
    exhaustion_flag: null
  s317_signals_active:
    bull: [bvc_5bar_high, buy_pres_diff_high]
    bear: []
data_quality:
  missing_bars_pct: 0.02

가용X 시: blocks.availability.has_30min = false. Pydantic 검증 통과. D5 verdict=UNAVAILABLE 반환.

도구 카탈로그 (선택): raw 30분봉 read / Agent trader/imbalance-dynamics (VSA evr_residual + delta 시계열).

판단 가이드: - ★★ 베이스라인 (v6 검증): ofm_cvd_z > 0 AND ofm_bvc_5bar ≥ 0.55 - ★★ S317 v2 강신호: OF 30분 lower_wick > upper_wick (D+20 0.644), OF 30분 buy_pres - sell_pres > 0.3 (0.615) - ★★ 강 회피: ofm_bvc_5bar <0.45 (D+20 0.152), ofm_cvd_z <-1 (0.250) - 30분봉 미가용 → verdict UNAVAILABLE (skip 아님 — score_compose에서 weight 처리) - bvc_5만 통과 / cvd_z만 통과 → MED confidence

출력 스키마:

{
  "atomic": "D5_of_judge",
  "code": "069540",
  "verdict": "POSITIVE | NEGATIVE | UNAVAILABLE",
  "confidence": "HIGH | MED | LOW",
  "ofm_cvd_z": 1.45,
  "ofm_bvc_5bar": 0.60,
  "ofm_bvc_20bar": 0.58,
  "lower_wick_ratio": 0.62,
  "reasoning": "..."
}


3.6 D6 — earnings-quality-judge

의미 질문: "이 종목의 실적 가속이 점수 가중을 얼마로 받을 가치 있는가?"

Input Package 빌더: scripts/discover/build_d6_input.py --date T0 --code CD6Input

Input Package 블록 구조:

blocks:
  ea_metrics:
    ea_yoy_latest: +0.42
    ea_z_cs: +0.95                    # T0 cross-section z
    sue: +1.4                         # Foster-Olsen 한국변형
    ea_qoq: +0.18                     # FA-M4
  vintage:
    latest_quarter: "2026Q1"
    report_date: "2026-04-15"
    days_since_report: 42             # PEAD 60거래일 추적 범위 내
    is_in_pead_window: true
  history:
    ea_yoy_5q: [+0.10, +0.15, +0.22, +0.31, +0.42]   # 가속 추세
    monotonic_up: true
  guidance:                           # FA-M5 (있으면)
    last_guidance_signal: BEAT_RAISED
  quality:                            # FA-M1 quality grade
    quality_grade: B
data_quality:
  missing_data: false
  is_fallback_dart: false             # FnGuide 5Q 한계 시 true

도구 카탈로그 (선택): mcp__korea-stock-mcp__get_financial_statement (최신 분기 보강) / Agent fundamentals/pead-tracker / Agent fundamentals/guidance-priority.

판단 가이드: - 베이스라인 (sim_v6): ea_z > 0 → weight 1.0, ea_z < -0.5 → 0.5, 결손 → 0.8 - ea_z 결정 시 cross-sectional 분포 확인 (T0 전체 종목 대비). 단일 z는 시점 의존 - 최근 분기 실적 발표 안 됨 (lag 50d 미만) → weight 0.8 (보수) - PEAD 추적 중이면 weight 상향 검토

출력 스키마:

{
  "atomic": "D6_ea_judge",
  "code": "069540",
  "verdict": "POSITIVE | NEGATIVE | NEUTRAL",
  "ea_z": 0.95,
  "ea_yoy": 0.42,
  "weight": 1.0,
  "rationale": "ea_z > 0, PEAD active",
  "missing_data": false
}


3.7 D7 — portfolio-selector

의미 질문: "T0 통과 후보들 중 오늘 진입할 1종은 무엇인가?"

Input Package 빌더: scripts/discover/build_d7_input.py --date T0D7Input (D1~D6 verdict 통합 + score_compose 결과)

Input Package 블록 구조:

blocks:
  d1_macro: {verdict: POSITIVE, confidence: HIGH, regime: L_UP_S_UP_BULL}
  candidates:                         # D2~D6 모두 POS 통과 종목들
    - code: "069540"
      verdict_chain: {D2: POS, D3: POS, D4: POS, D5: POS, D6: POS}
      confidence_chain: {D2: HIGH, D3: HIGH, D4: HIGH, D5: HIGH, D6: HIGH}
      raw_metrics:                    # 코드 산출 인용
        stock_rs: 0.082
        theme_rs: 0.054
        rs_vs_theme: 0.028
        accel_ratio: 1.34
        ofm_cvd_z: 1.45
        ea_z: 0.95
        ea_weight: 1.0
      score_components_z:             # score_compose.py 산출
        rs_vs_theme_z: 1.20
        stock_rs_z: 1.00
        accel_z: 0.90
        ofm_cvd_z_z: 1.70
      final_score: 4.82
      rank: 1
    - code: "..." (rank 2~)
  gate_funnel:
    universe_size: 200
    after_D1: 200                     # D1=POS 통과
    after_D2: 23
    after_D3: 14
    after_D4: 9
    after_D5: 7
    after_D6: 7
  exposure_context:                   # exposure-coach 스킬 산출
    suggested_exposure: 0.6
    market_extreme_regime: normal
data_quality: {...}

도구 카탈로그 (선택): Agent day-trader (GO/WAIT/PASS 종합) / Agent decision/final-picks (단일 박스 응축) / Skill exposure-coach (비중).

판단 가이드: - 산식 (sim_v6): final_score = z(rs_vs_theme) + z(stock_rs) + z(accel) + z(ofm_cvd_z) * ea_weight - 일별 rank 1 채택이 기본. 단, rank 1과 rank 2 score 차 < 0.3 → 차상위도 후보 보고 - 통과 0건 → "NO_CANDIDATE" + 어느 게이트에서 막혔는지 stat - D1 verdict=NEGATIVE면 D7 호출 자체 skip

출력 스키마:

{
  "atomic": "D7_portfolio_selector",
  "date": "2026-05-26",
  "selected": {
    "code": "069540", "final_score": 4.82, "rank": 1,
    "components": {"rs_vs_theme_z": 1.2, "stock_rs_z": 1.0, "accel_z": 0.9, "ofm_cvd_z_z": 1.7},
    "ea_weight": 1.0,
    "verdict_chain": {"D1": "POS", "D2": "POS", "D3": "POS", "D4": "POS", "D5": "POS", "D6": "POS"}
  },
  "runners_up": [...],
  "n_passed": 7,
  "gate_funnel": {"D1_pass": true, "after_D2": 23, "after_D3": 14, "after_D4": 9, "after_D5": 7}
}


3.8 D8 — position-monitor

의미 질문: "보유 종목들의 D+20 hold 동안 상태는 정상인가?"

Input Package 빌더: scripts/discover/build_d8_input.py --as-of T0D8Input

Input Package 블록 구조 (보유 종목 list):

blocks:
  positions:
    - code: "069540"
      entry_date: "2026-05-26"
      entry_price: 18500
      days_held: 10
      days_remaining: 10
      pnl:
        current_ret: 0.041
        kospi_ret: 0.012
        alpha: 0.029
        drawdown_from_entry: -0.018
        max_drawdown: -0.035
      regime_snapshot:                # 진입일 D1 vs 오늘 D1
        entry_d1_verdict: POSITIVE_HIGH
        today_d1_verdict: POSITIVE_MED
        regime_shift: minor_degradation
      chart_warning_signals:          # S317 bear 신호 발화 여부
        ofm_bvc_5bar_low: false
        vp_up_down_ratio_log_low: false
        cvd_z_low: false
      events_since_entry: []          # 공시/뉴스
data_quality: {...}

도구 카탈로그 (선택): Agent postmarket/position-evaluator (HOLD/EXIT/UPGRADE) / Agent trader/exit (9 트리거 참고).

판단 가이드: - v6 베이스라인: D+20 무조건 hold. EXIT 룰 없음 (백테스트 검증 결과) - 실거래 안전 장치 (PM 결정 사항 §10-3): drawdown < -25% 시 WARN, 매크로 regime 급전환(D1 NEGATIVE→D1 매우 강한 NEGATIVE) 시 EXIT 추천 - 일별 PnL 추적 + alpha vs KOSPI 기록

출력 스키마:

{
  "atomic": "D8_position_monitor",
  "as_of": "2026-06-05",
  "positions": [
    {"code": "069540", "entry_date": "2026-05-26", "days_held": 10, "days_remaining": 10,
     "current_ret": 0.041, "kospi_ret": 0.012, "alpha": 0.029, "drawdown_from_entry": -0.018,
     "status": "HOLD", "warnings": []}
  ]
}


4. 하네스 (실행 흐름) — Input Package 사전 조립 + verdict 기반 게이팅

핵심 추가 (v3): 각 atomic 호출 직전 main session이 build_d{n}_input.py를 실행해 Pydantic 검증된 Input Package를 생성. 검증 실패 시 즉시 stop (gatekeeper 계승). 검증 통과한 패키지만 에이전트에 전달.

각 atomic이 verdict: POSITIVE | NEGATIVE | NEUTRAL | UNKNOWN | UNAVAILABLE을 반환. 하네스는 verdict 체인으로 분기.

4.0 호출 단위 패턴 (모든 atomic 공통)

1. main: Bash run_py.ps1 scripts/discover/builders/build_d{n}_input.py --date T0 [--code C]
   → Pydantic 검증 통과 시 JSON 출력 / 실패 시 exit 1 + 에러
2. main: Agent discover/{atomic-name} 호출 시 package JSON을 prompt에 임베드
3. agent: 패키지 받음 → 가이드 따라 종합 판정 → Output JSON 반환 (Pydantic 검증)
4. main: Output을 data/discover/verdicts/{T0}/{atomic}.json에 기록
5. main: verdict 분기 결정
[Claude main] /discover T0=2026-05-26
        │
        ▼
   D1 macro-judge(T0)
        │ verdict?
   ┌────┼─────┬─────────┐
 NEG  UNK   POS                       (NEUTRAL은 POS 처리, confidence LOW)
   │   │    │
  PASS  PM   universe 후보 추출
  종료  확인  (거래대금 20d 상위 200종)
              │
              ▼
   [per code] D2 chart-judge
              │ NEG → skip / POS → 통과
              ▼
              D3 rs-judge
              │ NEG → skip / POS → 통과
              ▼
              D4 theme-leader-judge
              │ NEG → skip / UNK → skip / POS → 통과
              ▼
              D5 of-judge
              │ NEG → skip / UNAVAIL → 통과(weight↓) / POS → 통과
              ▼
              D6 ea-judge (정보 부착, skip 안 함)
              │
              ▼
[Claude main] candidate panel + verdict_chain 누적
        │
        ▼
   D7 portfolio-selector → 일별 rank 1 + runners_up
        │
        ▼
   [Claude main] entries.parquet append
        │
        ▼
   D8 position-monitor (보유 종목 전체)
        │
        ▼
   리포트: data/discover/reports/{T0}.md
   (선정 1종 + verdict_chain 인용 + RR + D+20 exit 예정일 + gate_funnel)

4.1 verdict 처리 규칙

atomic NEGATIVE NEUTRAL UNKNOWN UNAVAILABLE
D1 PASS 종료 universe 진입 (confidence 표시) PM 수동 확인 요청 (해당없음)
D2 skip code skip code skip code skip code
D3 skip code skip code skip code (해당없음)
D4 skip code skip code skip code (해당없음)
D5 skip code 통과 (HIGH conf 필요) skip code 통과 (weight 0.8)
D6 weight 0.5 weight 0.8 weight 0.8 weight 0.8
D7 n_passed=0 시 NO_CANDIDATE 리포트 rank1과 rank2 차 작으면 runners_up 보고
D8 EXIT 추천 HOLD 계속 WARN

4.2 비용/순서 최적화

  • D1 (1회) → NEGATIVE면 종목 루프 자체 skip
  • 종목 루프 내부: D2 → D3 → D4 → D5 순 (cheap → expensive)
  • D2/D3/D4 = parquet read + 산술 (싸다). D5만 30분봉 read (조금 비쌈)
  • 일별 호출 시간 추정: 200종 × 150ms ≈ 30초. main session 1턴 안에 처리 가능
  • D2~D5는 종목별 sub-agent 호출이 아니라 에이전트 1회 호출 + 종목별 코드 반복으로 비용 절감 가능. 단, 의문 종목은 sub-agent 호출 권장

5. Atomic 에이전트 명세서 위치 (v2 갱신)

.claude/agents/discover/
  ├── macro-judge.md                 (D1) — 의미 질문 + 도구 카탈로그 + 가이드
  ├── chart-judge.md                 (D2)
  ├── relative-strength-judge.md     (D3)
  ├── theme-leadership-judge.md      (D4)
  ├── orderflow-judge.md             (D5)
  ├── earnings-quality-judge.md      (D6)
  ├── portfolio-selector.md          (D7)
  └── position-monitor.md            (D8)

.claude/commands/
  └── discover.md                    (하네스 + §4 흐름)

scripts/discover/                    (deterministic 수치 산출 전용. 판정 X)
  ├── __init__.py
  ├── schemas.py                     (Pydantic D1Input/D1Output ~ D8Input/D8Output 16개 + 공통 enum)
  ├── macro_indicators.py            (D1 산출: 39열 panel + S317 발화표)
  ├── chart_indicators.py            (D2 산출: L2 enum + S317 60 룰)
  ├── stock_rs.py                    (D3 산출)
  ├── theme_rs.py                    (D4 산출: primary_theme/rank)
  ├── of_indicators.py               (D5 산출: cvd_z/bvc/wick)
  ├── ea_indicators.py               (D6 산출: ea_z 등)
  ├── score_compose.py               (D7 산출: final_score+rank)
  ├── position_status.py             (D8 산출: alpha/drawdown)
  ├── builders/                      (Input Package 사전 조립기)
  │   ├── build_d1_input.py
  │   ├── build_d2_input.py
  │   ├── build_d3_input.py
  │   ├── build_d4_input.py
  │   ├── build_d5_input.py
  │   ├── build_d6_input.py
  │   ├── build_d7_input.py
  │   └── build_d8_input.py
  ├── validate.py                    (Pydantic 검증 + 실패 시 stop)
  └── pipeline.py                    (entry point — main session에서 호출)

data/discover/
  ├── entries.parquet                (진입 기록, append-only)
  ├── verdicts/{T0}/{atomic}.json    (atomic verdict 로그)
  ├── daily_panel/{T0}.parquet       (일별 통과 후보 panel)
  └── reports/{T0}.md                (최종 리포트)

6. 기존 자산 이관표 (제거 대상 + 이관 위치)

6.1 /rs_* 커맨드에서 제거할 발굴 블록

파일 제거 대상 블록 이관 위치
.claude/commands/rs_morning_open.md 신규 후보 발굴 / theme 매핑 /discover 호출로 대체 (참조만 유지)
.claude/commands/rs_mid_morning.md candidate-pipeline 호출 제거 (모니터링만 남김)
.claude/commands/rs_afternoon.md candidate-pipeline Phase 시작 제거
.claude/commands/rs_post_market.md candidate-pipeline + leader-opportunity D8 postentry-monitor + /discover 분리
.claude/commands/rs_evening.md theme mapping (NC-6 일부) 유지 (뉴스→테마 매핑은 evening 본업)

6.2 스킬/에이전트 이관

기존 자산 처리 사유
.claude/skills/candidate-pipeline/SKILL.md deprecated → _archive/skills/ /discover로 대체
.claude/agents/postmarket/leader-opportunity.md 이관 → discover/score-rank.md 보조 입력 leader 선정 = D4 책임
.claude/agents/sector/leader-judge.md 유지하되 D4와 역할 분리 sector/leader-judge = 테마 차원 5대기준 (다른 use case) / D4 = v6 RS leader
.claude/agents/postmarket/discovery-detector.md 유지 이상움직임 탐지 ≠ v6 발굴, 별개
.claude/agents/postmarket/position-evaluator.md D8와 통합 HOLD/EXIT 판정 로직 흡수
scripts/quant/themes/{theme_rs, theme_state_classifier, theme_selection, theme_leader_select, chart_state_score}.py 이관 → scripts/discover/ 5개 스크립트가 v6의 D2/D3/D4 산출 책임

6.3 데이터 이관

기존 위치 신규 위치 사유
data/backtest/sim_v6/{entries_v6, strategy_v6}.parquet data/discover/_history/sim_v6/ 백테스트 기록 보존 (production 분리)
data/backtest/discovery_walkforward/ data/discover/_history/walkforward/ 동일
data/ats_main_v2.json 유지 (공용 자산) D4가 의존
data/backtest/e1/ea_panel_dart.parquet 유지 (공용) D6 의존

7. 출력 스키마

§3 각 atomic 절에 통합 — 별도 섹션 없음. 모든 출력은 공통 필수 키:

  • atomic (식별자)
  • verdict (POSITIVE/NEGATIVE/NEUTRAL/UNKNOWN/UNAVAILABLE)
  • confidence (HIGH/MED/LOW)
  • reasoning (자연어 근거)
  • tools_used (호출한 도구 목록 — Evidence Required 의무)
  • 도메인 수치 (코드 산출값을 그대로 인용)

8. 마이그레이션 단계 (실행 순서)

순서 작업 산출
M1a scripts/discover/schemas.py Pydantic 16 클래스 (D1~D8 In/Out) + 공통 enum 정의 schemas.py
M1b scripts/discover/builders/build_d{1..8}_input.py 8개 — 코드 산출 결과 + raw 데이터 → Input Package 조립 + Pydantic 검증 builders/*.py
M1c scripts/discover/ 8개 indicator 모듈 신규 (sim_v6 + quant/themes 이관) — pure 수치 산출 scripts/discover/*.py 8종 + pipeline.py + validate.py
M2 .claude/agents/discover/ 8개 atomic 명세서 — 질문/도구 카탈로그/가이드/스키마 *-judge.md, *-selector.md, *-monitor.md 8종
M3 .claude/commands/discover.md 하네스 + verdict 분기 흐름 /discover 호출 가능
M4 단독 실행 검증 — T0=2026-05-26 1시점 sim_v6 결과 대조 동일 종목 OR 일치 사유
M5 /rs_morning_open, _mid_morning, _afternoon, _post_market에서 발굴 블록 제거 diff
M6 candidate-pipeline SKILL → _archive/skills/ 이동 + deprecation 마크 mv
M7 data/backtest/sim_v6/data/discover/_history/sim_v6/ 이전 mv
M8 topic_discovery_walkforward.md WBS Phase E3 완료 + _index.md 진입점 갱신 doc update

9. 검증 성공 기준

  • M4: T0=2026-05-26 단독 실행 결과 = data/backtest/sim_v6/entries_v6.parquet의 2026-05-26 1행과 동일 종목 선정 OR 일치하지 않을 경우 verdict_chain에서 어느 단계가 달랐는지 명시
  • M5: /rs_morning_open 호출 후 어느 시점에도 candidate-pipeline / theme-leader / stock pool 발굴 블록이 실행되지 않음
  • M6: candidate-pipeline 스킬 호출 시도 시 deprecation 메시지
  • M8: _index.md "Today's Next Step" 갱신 — S326 완료, S327 명시

10. 미해결 결정 (PM 필요)

PM의 v2 방향(에이전트 자율 + 도구 무제약) 반영 — 일부 결정은 에이전트 가이드에 임계 룰 명시만 하고 최종 판단은 에이전트가.

  1. D1 매크로 임계: v6 베이스라인 룰(WALCL/SPY/GSPC/SOX/DEPOSIT) + S317 v2 강신호표를 둘 다 D1 가이드에 두고, D1 에이전트가 종합 verdict 결정. PM이 결정할 사항 — 모순 신호 발화 시 우선 순위? (★★ vs ★)
  2. OF 결손 시 처리: sim_v6 = skip / 본 설계 = weight 0.8. PM 결정 필요 (백테스트 재현성을 위해 skip 권장 vs production 운영 유연성을 위해 weight 0.8)
  3. D8 D+20 강제 hold 유지: 실거래에서도 백테스트와 동일하게 EXIT 룰 없음? OR drawdown < -25% / D1 NEGATIVE 급전환 시 EXIT 안전장치? (Risk: 급락 시 -30% 실현 vs 안전장치가 alpha 깎을 가능성)
  4. /discover 호출 빈도: 확정 = ad-hoc (/discover 수동 호출). 추가로 morning_open에서 자동 호출 trigger도 둘지?
  5. 에이전트 호출 정책: D2~D5는 종목당 sub-agent 호출 (느림, 종목별 깊은 해석) vs main session 1회 호출 + 종목별 코드 반복 (빠름, 일괄 해석). 일별 200종 처리 시 후자 권장. PM 결정 필요

11. 참조

  • v6 채택 근거: data/backtest/sim_v6/v5_vs_v6.json
  • v6 코드: scripts/backtest/sim_v6_6tools.py
  • 모듈 인벤토리: docs/research/2026-05-26_S317_module_audit_v2.md
  • Phase A~E 결과: topic_discovery_walkforward.md
  • 운영 룰 8가지: _index.md "v6 채택 운영 룰" 섹션