/discover 파이프라인 전체 명세서¶
작성일: 2026-05-31 (S333)
시스템 지향점: 차트 단독 분석 X → 시장환경(D1) + 차트(D2) + RS(D3) + 테마/섹터(D4) + 수급(D5) + 펀더멘탈(D6) + 재료(catalyst) 결합. 인간 트레이더의 종목·테마 발굴 워크플로를 시스템화.
정본 코드: scripts/discover/, scripts/run_discover.py
에이전트 명세: .claude/agents/discover/*.md
모든 산식·블록·필드는 정본
schemas.py+indicators/*.py에서 추출. 누락 없이 전 지표 망라.
0. 전체 흐름¶
T0 정리 (P0)
→ D9 어제 채점 (P1)
→ Phase 1.5: 매크로/섹터 데이터 갱신 (FRED, sector ETF)
→ D1 매크로 게이트 (P2)
├─ NEGATIVE → D8 보유추적만 → 종료
└─ POS/NEU
→ universe 80 (P3, 5 trigger union)
→ Phase 3.5: universe OHLCV/30분봉 자동 수집
→ pregate (P3.7, 옵션, 상위 N 컷)
→ D2~D6 × N종 input + agent verdict (P4)
→ D7 score_compose + selected/runners_up (P5)
→ D8 보유추적 (P6)
→ history dump (P7) → 리포트 조립 (P8)
| Phase | step 모듈 | LLM agent | 산출 |
|---|---|---|---|
| 0 | step_t0.py |
— | runs/{date}/ |
| 1 | step_d9_selfcheck.py |
system-self-check | D9_output.md |
| 1.5 | step_collect_macro.py |
— | macro panel + sector_flow 갱신 |
| 2 | step_d1_macro.py |
macro-judge | D1_input.json + output.md |
| 3 | step_universe.py |
— | universe.json (Top 80) |
| 3.5 | step_collect_ohlcv.py |
— | universe별 OHLCV/30분봉 |
| 3.7 | step_pregate.py (옵션) |
— | 차트 복합강도 상위 N |
| 4 | step_loop_d2to6.py |
chart/rs/theme/of/ea judge × N | D{2..6}{code}*.json/md |
| 5 | step_d7_select.py |
portfolio-selector | D7_input.json + output.md |
| 6 | step_d8_monitor.py |
position-monitor | D8_input.json + output.md |
| 7 | step_history_dump.py |
— | history/{date}_{D1,D7,D8}.json |
| 8 | step_report.py |
— | docs/discover/{date}.md |
오케스트레이터 scripts/run_discover.py가 phase 강제 순회 + 필수 산출(D9/D1/D7/D8 output.md) 검증.
1. Universe — 5 trigger union (Phase 3)¶
5개 후보 추출기 합집합 → Top 80. 목적: 유동성 + 시장 주목.
| Trigger | 정의 |
|---|---|
volume_top |
오늘 거래대금 Top N |
volume_spike |
오늘 Top 50 ∩ 전일 Top 100 밖 (신규 주목) |
theme_strong |
ACCELERATING/LEADING 테마 멤버 |
news_material |
상한가/+10% 급등 + 재료 보유 |
report_carryin |
어제 D7 runners_up + evening carry_forward |
산출: universe.json (80 codes + 트리거 기여 점수).
2. D1 — 매크로/시장환경 게이트 (Phase 2)¶
역할: 시장 환경이 매수에 우호적인가?
D1Input 블록 전체 (schemas.py 기준)¶
2.1 D1LiquidityBlock (유동성)¶
| 필드 | 의미 |
|---|---|
fed_net_liquidity_usd_b |
Fed 순유동성 (WALCL − TGA − RRP) |
delta_20d_b |
20일 변화 |
z_60d |
60일 z |
walcl_lev / walcl_chg_z |
Fed 자산총액 레벨/변화 |
rrp_chg_z |
RRP 잔액 변화 |
deposit_lev / deposit_chg_z |
미국 예금 |
spy_lev / gspc_lev / sox_lev |
S&P/SOX 위험자산 레벨 |
evidence_grade |
★★/★/? |
2.2 D1SentimentBlock (시장 심리)¶
| 필드 | 의미 |
|---|---|
vix / vix_chg_z / vix_term_regime |
VIX 레벨·변화·기간구조 |
vkospi_fut_oi_chg_z |
VKOSPI 선물 OI 변화 |
pcr_vol_z |
풋콜 비율(거래량) z |
cnn_fng_value / label / delta_1w |
CNN Fear&Greed |
vix_chg / sox_chg / kospi_chg |
ChangeSet(spot/d1/d5/d20) |
2.3 D1RatesBlock (금리)¶
kr_10y_chg_z, us_2y, us_10y, curve_2_10, real_yield_10y, hy_oas, hy_regime, us_10y_chg, us_2y_chg, curve_2_10_chg, t10yie_chg, hy_oas_chg (전부 ChangeSet)
2.4 D1DerivativesBlock (파생)¶
| 필드 | 의미 |
|---|---|
basis_z |
KOSPI 선물 베이시스 z |
fut_oi_chg_z |
선물 OI 변화 z |
kr_10y_fut_chg_z |
한국 10년 선물 |
kospi200_fut_chg_z, kospi200_fut_oi_chg |
KOSPI200 선물 |
vkospi_fut_oi_chg, usd_fut_oi_chg, kr_10y_fut_oi_chg, basis_chg |
ChangeSet |
pcr_oi, pcr_vol, call_oi_total, put_oi_total, put_call_oi_ratio |
옵션 포지셔닝 |
max_pain_dist_z |
옵션 max pain 거리 |
deriv_sent_z |
파생 심리 종합 z |
2.5 D1FxCommodityBlock (환율/상품) — 글로벌 자금흐름¶
| 필드 | 의미 |
|---|---|
dxy_chg |
달러지수 → 강세=EM유출 |
usd_krw_chg |
원달러 → 약세=외인 환손실 |
wti_chg, gold_chg, copper_chg |
유가/금/구리 |
2.6 D1CotFlowBlock (CFTC COT) — 글로벌 큰손 포지션¶
spx,ndx,jpy,eur각각 CotContract- CotContract:
am_net,lev_net,am_net_chg_1w,lev_net_chg_1w,lev_net_z_52w,open_interest
2.7 D1SectorFlowBlock (글로벌 섹터 자금흐름) ⭐¶
12 섹터 US ETF 자금흐름:
- sectors: dict[str, SectorEtfFlow]
- SectorEtfFlow: etf, d1, d5, d20, accel, status, last_date
- spy_options / qqq_options: 미국 지수 옵션
- vix, vix3m, vvix, vix_term_regime, vix_vix3m_spread
2.8 D1ContextBlock¶
s308_regime_cell— 전일 regime 셀s317_active_signals_bull/bear— S317 발화 신호today_events— 이벤트 캘린더 (FOMC 등)is_option_expiry— 옵션만기일yesterday_d1_verdict— 어제 D1 verdict (연속성)
2.9 D1Output → verdict¶
룰: 4축 중 3+ POS → POSITIVE / 2+ NEG 또는 극단 → NEGATIVE / 그 외 NEUTRAL 분기: NEGATIVE → universe·D2~D7 skip, D8만 후 종료
3. D2 — Chart Judge (차트 = 1차 진입점)¶
철학: 차트는 시장참여자 심리의 압축. 1차 셋업이 안 되면 다음 단계 안 감.
PM 결정 (2026-05-31): D2에서 일봉 OF (
compute_orderflow_daily) 완전 제거. 이유: OF의 본질 = 시장참여자가 동의한 가격대(POC) 식별 + 흡수/분배 시도 측정. 이건 장중 가격×거래량 분포가 있어야 가능. 일봉은 봉 시·고·저·종 + 총거래량만 있어 POC 프록시조차 의미가 약함. → OF는 D5(30분봉)에서만 산출.제거된 것:
D2OFDailyBlock(cvd_z/bvc_5bar/absorption_score_last),compute_orderflow_daily(), S317 신호cvd_z_high/cvd_z_low/absorption_high.
3.1 chart_indicators.py 6개 함수 (OF 제거 후)¶
compute_trend (이동평균·고점근접)¶
ma_20_slope_z = _slope_z(MA20, win=20) # 추세 가속도 z
ma_60_slope_z = _slope_z(MA60, win=60)
ma_120_slope_z = _slope_z(MA120, win=120)
drawdown_60d = (close - max(close.tail(60))) / max
high_proximity_52w = close / max(close.tail(252))
range_pos_52w = (close - 52w_low) / (52w_high - 52w_low)
# _slope_z 산식
slope = (S.last - S.first) / S.first
rolling = S.diff()
z = (slope - rolling.mean) / rolling.std
compute_structure (불균형 단계 — l2_scenario)¶
swings = _detect_swings(close.tail(60), threshold=0.03) # 3% 임계 swing
pattern = _swing_pattern(swings) # HH_HL / HH_LL / LH_HL / LH_LL
accel = mean(close.tail(10).pct_change) / mean(close.tail(40).head(30).pct_change)
break_stage = "EARLY" if recent_low < prev_low else "NONE"
if HH_HL + accel > 1.2: l2 = "imb_up_acceleration_confirmed"
elif HH_HL/LH_HL + break_stage==NONE: l2 = "transition_to_imb_up_confirmed"
else: l2 = "other"
당위성: HH_HL = Wyckoff 마크업. accel>1.2 = 10일이 30일보다 20% 빠름.
compute_volume_profile (POC/LVN/매물대)¶
last = ohlcv.tail(60)
typical = (high + low + close) / 3
bins = pd.cut(typical, 20)
vol_by_bin = volume.groupby(bins).sum()
poc_price = (poc_bin.left + poc_bin.right) / 2 # 최대 거래대금 bin
atr = (high - low).tail(14).mean()
poc_dist_atr | (close - poc) / atr |
| va_position | "above"/"below" POC |
| up_down_amount_ratio_log | log(상승봉_vol / 하락봉_vol) |
| volume_asymmetry_20d | (up_vol - down_vol) / (up_vol + down_vol) |
| overhang_below_pct | 현재가 이하 매물대 비율 |
| in_lvn | vol_by_bin[현재가] < median |
당위성: LVN 진입 = 매물 비어있어 빠른 이동 (S317 ★★ D+20 0.818).
compute_vsa (Volume Spread Analysis)¶
close_zone = (close - low) / (high - low) # 0=하단, 1=상단
bullish_strength_sum = sum((close_zone>0.7) * vol) / total_vol
bearish_strength_sum = sum((close_zone<0.3) * vol) / total_vol
spring_count = sum((low<low.shift(1)) & (close>open) & (close_zone>0.7))
last_signal_id | Spring / SOS / SOW / None |
| last_signal_strength, last_signal_age | 강도/경과봉 |
| spring_count_20d | Spring 횟수 (D+20 ★★ 0.707) |
| bullish/bearish_strength_sum | 강매수/강매도 비중 |
compute_candles (마지막 10봉)¶
last_10: list[{type, body, upper, lower}]lower_upper_wick_ratio = sum(lower_wick) / sum(upper_wick)— 아랫꼬리 우세 = 매수의지
compute_s317_signals (60룰 검증된 bull/bear, OF 제거 후)¶
| Bull (★★) | 조건 | D+20 hit |
|---|---|---|
| vp_in_lvn | LVN 진입 | 0.818 |
| vp_up_down_ratio_log_high | > 0.3 | (역수 0.062) |
| vsa_spring_count | > 0 | 0.707 |
| lower_wick_dominant | > 1.0 | — |
| accel_ratio_high | > 1.2 | — |
| Bear | 조건 |
|---|---|
| vp_up_down_ratio_log_low | < -0.3 |
| structure_break_confirmed | break_stage = CONFIRMED |
제거된 신호 (2026-05-31, D2 일봉 OF 폐기): cvd_z_high, cvd_z_low, absorption_high → D5(30분봉)에서 산출.
3.2 D2Output¶
verdict, confidence, reasoning, code, l2_scenario, accel_ratio, bull_signals, bear_signals
Verdict 룰 (chart-judge.md): - L2 진입 + bull★★ 2+ + bear 0 → POSITIVE HIGH - L2 진입 + bull 1 + bear 0 → POSITIVE MED - bear ★★ 1+ → NEGATIVE HIGH - L2 other + bull 0 → NEGATIVE HIGH
4. D3 — Relative Strength (stock_rs.py)¶
4.1 compute_rs_metrics¶
stk_ret_60d = stock.close.last / stock.close[-60] - 1
kospi_ret_60d = kospi.close.last / kospi.close[-60] - 1
stock_rs_60d = stk_ret_60d - kospi_ret_60d
rs_z_cs = (population 횡단면 z — score_compose에서 산출)
4.2 compute_rs_trend¶
| 필드 | 산식 |
|---|---|
rs_5d / rs_20d / rs_60d |
같은 산식의 다기간 |
monotonic_up_pct |
RS 시계열 일별 증가 비율 (지속성) |
recent_20d_drawdown |
최근 20일 고점 대비 낙폭 |
4.3 compute_consistency¶
days_above_kospi_60d/max_consec_below/ma200_above
4.4 D3Output¶
stock_rs, stk_ret60, rs_trend_label- Verdict: rs > 0.5 → POS HIGH / > 0 → POS MED / > -0.3 → NEU / 그 외 NEG MED
5. D4 — Theme Leadership (theme_rs.py + theme_concentration.py)¶
5.1 lookup_themes (ats_main_v2.json)¶
primary(themes[0]),all(전체),members(같은 테마 멤버)
5.2 compute_theme_rs_and_leader¶
for m in members: rets[m] = m.close.last / m.close[-60] - 1
theme_avg = mean(rets)
theme_rs_60d = theme_avg - kospi_ret_60d
rank = position of code in sorted(rets desc)
is_leader = rank <= max(3, n // 3) # 상위 3 또는 상위 1/3
rs_vs_theme = code.ret - theme_avg
top3_members = top 3 codes
5.3 compute_lifecycle (data/theme_tracker/dashboard.json)¶
| 입력 | 매핑 stage |
|---|---|
| emerging | incubation |
| accelerating | expansion |
| leading | peak |
| cooling | decay |
| re_accelerating | expansion |
- days_in_stage, freshness |
5.4 theme_concentration (강한 종목 집결도) ⭐¶
universe stock_rs를 테마별 그룹핑 → "강한 종목이 한 테마에 모여있나" 역산.
상수:
- STRONG_RS_Z = 1.0 / HIGH_CONC = 0.4 / MIN_MEMBERS_FOR_CONC = 2
- BONUS_LEADER_HIGH = 1.5 / BONUS_LEADER_LOW = 0.3 / BONUS_FOLLOWER_MAX = 0.5
for theme:
strong = [c for c,rs in members if z(rs) >= 1.0]
concentration = len(strong) / len(members)
leader_code = max by rs
for code:
if leader and conc >= 0.4 and members >= 2: bonus = 1.5
elif leader: bonus = 0.3
elif z(code.rs) >= 1.0 and not leader: bonus = 0.5 * conc
else: bonus = 0
5.5 D4Output¶
primary_theme, theme_rs, theme_rank, is_leader- Verdict: theme_rs > 0.3 AND leader → POS HIGH / > 0 → POS MED / 그 외 NEU/NEG
- theme_n < 3 → UNKNOWN
6. D5 — Orderflow (of_indicators.py)¶
중요 (2026-05-31 확정): 30분봉 전용. 일봉 근사 금지.
- 데이터: data/minute_charts/30min/{code}.parquet
- 30분봉 없으면 D5AvailabilityBlock.has_30min=False → verdict UNAVAILABLE → score_compose 0 기여
6.1 D5AvailabilityBlock¶
has_30min: bool,bars_count: int,last_bar: str
6.2 compute_cvd¶
sign = sign(close.diff())
cvd = (sign * volume).cumsum()
cvd_z_40bar = (cvd.last - cvd.tail(40).mean) / cvd.tail(40).std
cvd_slope_z = (slope.last - slope.tail(40).mean) / slope.tail(40).std
# divergence
if price 20d up & cvd 20d down → -1 # 가격 오르는데 매수 약화 (분배 의심)
if price 20d down & cvd 20d up → +1 # 가격 빠지는데 매수 누적 (매집 의심)
else → 0
cvd_last, cvd_z_40bar, cvd_slope_z, cvd_price_divergence
6.3 compute_bvc (Buy Volume Concentration)¶
bvc_5bar = (양봉 in last 5) / 5bvc_20bar동일
6.4 compute_pressure¶
close_zone = (close - low) / (high - low)
buy_pres = sum((close_zone>0.6) * vol)
sell_pres = sum((close_zone<0.4) * vol)
buy_pres_sell_pres_diff = (buy - sell) / (buy + sell)
lower_upper_wick_ratio = lower_wick_total / upper_wick_total
6.5 compute_absorption (매물 흡수)¶
big_vol = volume > MA20_vol * 1.5
absorption_mask = big_vol & (close_zone > 0.6)
absorption_score_last = mask.last * 2.0
absorption_count_20bar = sum(mask in last 20)
exhaustion_flag = (옵션)
6.6 compute_s317_of_signals (30분봉 bull/bear)¶
| Bull | 조건 |
|---|---|
| bvc_5bar_high | ≥ 0.55 |
| buy_pressure_dominant | diff > 0.3 |
| lower_wick_dominant | > 1.0 |
| cvd_z_high | > 1.0 |
| absorption_high | > 1.5 |
| Bear | 조건 |
|---|---|
| bvc_5bar_low | < 0.45 |
| cvd_z_low | < -1.0 |
6.7 D5Output¶
ofm_cvd_z, ofm_bvc_5bar- Verdict: bear≥2 NEG HIGH / bull≥2 POS HIGH / 30분봉 X → UNAVAILABLE
7. D6 — Earnings Quality (ea_indicators.py)¶
데이터: data/backtest/e1/ea_panel_dart.parquet (DART 분기 실적 패널)
7.1 D6 블록 전체¶
| 블록 | 필드 |
|---|---|
| D6EAMetricsBlock | ea_yoy_latest, ea_z_cs (모집단 z), sue (Standardized Unexpected Earnings), ea_qoq |
| D6VintageBlock | latest_quarter, report_date, days_since_report, is_in_pead_window (60일 이내) |
| D6HistoryBlock | ea_yoy_5q: list[float] (5분기 시계열), monotonic_up |
| D6GuidanceBlock | last_guidance_signal (raise/maintain/cut) |
| D6QualityBlock | quality_grade (A/B/C/D from triple-cross IS/CF/BS) |
7.2 D6Output¶
ea_z, weight, rationale- Verdict: ea_z > 1.5 POS HIGH / > 0.5 POS MED / > -0.5 NEU / 그 외 NEG
8. Catalyst (재료, catalyst_parser.py) — D6 보조 + D7 입력¶
전날 장마감 리포트(data/postmarket_phases/{date}_phase5.md) UNIT5/6 표 파싱.
8.1 추출 필드¶
strength: hard / soft / noneverdict: TRACK / WATCH / NOISEoverheat: boolraw_catalyst,source_unit
8.2 catalyst_raw_score 산식¶
CATALYST_SCORE = {
"strength": {"hard": +1.0, "soft": +0.3, "none": -0.5},
"verdict": {"TRACK": +0.5, "WATCH": 0.0, "NOISE": -1.0},
}
raw = strength_score + verdict_score
당위성: hard = 실적·계약·공시(실체) / soft = 루머·기대감 / overheat = 가속과열 (정보, 점수 미포함)
9. D7 Portfolio Selector (score_compose.py) — 핵심 통합¶
9.1 final_score 산식 (line 53~119) — 10 컴포넌트 합산¶
# 1단계: universe 모집단 분포 산출 (결손 제외)
stkrs_pop = [stock_rs_60d for code if not None]
accel_pop, ofm_pop, ea_pop, cat_pop 동일
(mean, std) = (population.mean, population.std or 1.0)
# 2단계: 종목별 모집단 z (결손=0)
_z_of(x, mean, std) = (x - mean) / std
components = {
# raw z축 (D3/D2/D5/D6/catalyst)
"stock_rs_z": _z_of(stock_rs_60d, *stkrs_ms),
"accel_z": _z_of(accel_ratio, *accel_ms),
"ofm_cvd_z_z": _z_of(ofm_cvd_z, *ofm_ms), # D5 cvd_z를 또 모집단 z (2단계)
"catalyst_z": _z_of(catalyst_raw, *cat_ms),
"ea_z": _z_of(ea_z, *ea_ms),
# 테마 집결도 (theme_concentration)
"theme_bonus": bonus_by_code[code], # 0~1.5
# verdict축 (LLM judge 종합 해석을 점수로)
"chart_verdict": 1.0 * sign(d2) * conf(d2),
"of_verdict": 1.0 * sign(d5) * conf(d5),
"theme_verdict": 0.6 * sign(d4) * conf(d4),
"ea_verdict": 0.6 * sign(d6) * conf(d6),
}
final_score = sum(components.values()) # 게이트 X
9.2 verdict_signal 변환¶
_VERDICT_SIGN = {"POSITIVE": +1, "NEGATIVE": -1, "NEUTRAL": 0}
_CONF_SCALE = {"HIGH": 1.0, "MED": 0.6, "LOW": 0.3, None: 0.3}
# UNAVAILABLE / UNKNOWN / None → 0 기여
9.3 D7CandidateRow 출력 필드¶
code, verdict_chain, confidence_chain, raw_metrics, score_components_zfinal_score, rank, overheat_flag, positive_axis_count, gate_warning
9.4 D7Input/Output¶
| 블록 | 필드 |
|---|---|
| D7Input.d1_macro | dict (D1 verdict) |
| D7Input.candidates | list[D7CandidateRow] |
| D7GateFunnelBlock | universe_size, after_D1~D6 (감소 추적) |
| D7ExposureBlock | suggested_exposure, market_extreme_regime |
| D7Output.selected | rank 1 D7CandidateRow |
| D7Output.runners_up | rank 2~ (score 차 < 0.3 시) |
| D7Output.n_passed | 통과 종목 수 |
9.5 PM 원칙 (S330)¶
- 게이트 폐기: POS 축 수로 자르지 않음. 순수 합산.
- 분배·과열·NEG는 verdict 음수로 점수 반영 → rank 밀림.
- 결손은 0 기여, 다른 축 합산은 정상.
- selected = rank 1 (final_score 음수면 NEUTRAL 보류)
10. D8 Position Monitor (position_status.py)¶
보유 종목 일별 추적. D+20 hold 기본. EXIT 트리거는 안전장치만.
10.1 D8Input¶
| 블록 | 필드 |
|---|---|
| D8Position | code, entry_date, entry_price, days_held, days_remaining, entry_context, today_snapshot, pnl, regime_snapshot, events_since_entry |
| D8EntryContextBlock | d7_final_score, d7_verdict_chain, d7_key_signals, entry_d1_verdict |
10.2 함수¶
| 함수 | 산출 |
|---|---|
compute_pnl |
D8PnLBlock — current_ret, kospi_ret, alpha, drawdown_from_entry, max_drawdown, d5/d10/d20 alpha |
compute_days |
(days_held, days_to_d20_exit) |
compute_today_snapshot |
D8TodaySnapshotBlock — chart_intact, chart_warning, material_alive, flow_pattern, flow_5d_direction, amount_trend |
compute_regime_snapshot |
entry vs today D1 verdict + regime_shift (NONE/MINOR/MAJOR/IMPROVEMENT) |
collect_events_since_entry |
뉴스/공시 이벤트 list |
10.3 D8ChartWarningBlock¶
ofm_bvc_5bar_low/vp_up_down_ratio_log_low/cvd_z_low
10.4 D8Conditions (4조건 + breaks)¶
c1_chart_intact/c2_material_alive/c3_flow_maintained/c4_amount_trend_okintact_breaks: int(위반 수)
10.5 D8PositionReport¶
status: HOLD / WARN / EXITchart_warnings_active: list[str]pnl_summary(D8PnLSummary + D8AlphaPath d5/d10/d20)regime_shift: strevents_summary: dict
10.6 D8DailyEnvReport¶
avg_alpha,regime_shift_distribution,new_chart_warnings_today,new_bear_events_today,n_hold/warn/exit
11. D9 System Self-Check (decision_scoring.py)¶
어제 D7/D1/D8 결정의 실제 결과 채점.
11.1 D9Input¶
decisions_to_score: list[D9DecisionRow]- D9DecisionRow: decision_id, decision_type (D7_SELECTED / D1_MACRO_VERDICT / D8_POSITION_VERDICT), decision_date, payload (D9DecisionPayload), outcome (D9Outcome)
- D9DecisionPayload: code, verdict, confidence, reasoning, key_signals
- D9Outcome: days_elapsed, price_path (D9PricePath), regime_path (D9RegimePath), events_observed
- D9PricePath: d_plus_1, d_plus_5, d_plus_10, current_ret, kospi_ret_same_window, alpha
- D9RegimePath: entry_d1, today_d1, regime_shift
- D9ScoringWindow: primary (D+5/D+10/D+20), interim
11.2 D9Output¶
decision_scorecards: list[D9DecisionScorecard]score_verdict: HIT / PARTIAL / MISS / REVERSE / PENDINGactual_alpha,actual_summary,root_cause,lesson,could_have_caught,target_componentaggregate: D9Aggregate— total_scored, n_hit/partial/miss/reverse, accuracy_pct, root_cause_distributionsystem_actions: list[D9SystemAction]— target_component, action, priority (HIGH/MED/LOW)
11.3 함수¶
build_outcome_for_code— code 결정의 후행 outcomebuild_market_outcome— selected=None 일의 시장 outcomeextract_key_signals(sel)— D7 selected에서 ★★ 신호 추출
12. 데이터 소스 전체¶
| 카테고리 | 경로 | 용도 |
|---|---|---|
| OHLCV 일봉 | data/backtest/s303/ohlcv/*.parquet |
270종 D2/D3/D4 |
| 30분봉 | data/minute_charts/30min/{code}.parquet |
272종 D5 전용 |
| KOSPI | data/dart_cache/kospi_daily.parquet |
D3 RS 기준 |
| 테마 매핑 | data/ats_main_v2.json |
S332 검증본 791종 themes[0] |
| 테마 보강 | knowledge_base/market/themes/_all_key_themes.json |
네이버 264 테마 |
| 테마 트래커 | data/theme_tracker/dashboard.json |
D4 lifecycle |
| EA panel | data/backtest/e1/ea_panel_dart.parquet |
DART 분기 실적 |
| 매크로 panel | data/macro/panel_4y_daily.parquet |
D1 4년 일별 panel |
| 섹터 ETF | data/sector_flow/{date}.json |
D1 12 섹터 자금흐름 |
| FRED | data/fred_cache/* |
D1 Fed liquidity |
| Catalyst | data/postmarket_phases/{date}_phase5.md |
UNIT5/6 표 |
| 수급 시계열 | data/flow_series/*.json |
종목 외인/기관 (미통합) |
| discover 산출 | data/discover/runs/{date}/ |
input/output |
| history | data/discover/history/{date}_{D1,D7,D8}.json |
D9 next-day 입력 |
| positions | data/discover/positions/positions.json |
보유 종목 |
13. 실행¶
powershell.exe -ExecutionPolicy Bypass -File scripts/run_py.ps1 scripts/run_discover.py --date YYYYMMDD
옵션: --start-phase 5 / --skip-loop
검증 게이트: D9/D1/D7/D8 output.md 누락 → sys.exit(1)
14. 시스템 정비 로드맵 (S334 — PM 확정)¶
더할 것¶
- 거래량 수축 / 박스 압축 —
chart_indicators.py신규 (출발 직전 셋업) - RS 풀백 다이버전스 (가격↓ RS↑) —
stock_rs.py신규 (대장주 소화 후 재출발) - 수급 주체별 분리 (외인/기관/개인 CVD) —
data/flow_series/→ D5 통합 - 위험 분모 (구조적 무효화 거리) + RR 분포 — score_compose에 risk_distance 컬럼 + 분포 분석
- 재료 시간축 추적 (D-N 발표 → 감쇠/재점화) — catalyst_parser 확장
덜어낼 것¶
- OF 일봉 근사 fallback (완료 — 30분봉 전용으로 정정)
- score_compose 단순 합산 (영역 간 상호작용 파괴) — 구조화 벡터로 전환
수정할 것¶
- score_compose: 합산 → 축별 점수 벡터 + leader/follower 관계 출력
- 차트 1차 게이트: 3 셋업(불균형 가속 / 대장주 소화 / 매집+트리거) 중 하나 만족 안 하면 컷
- D7 selector: 코드 rank1 → AI 에이전트가 BUY/인버스/헷지/키맞추기/PASS 결정
검증 (코드 추가 X)¶
- D1 sector_flow 12 섹터 + COT + FX commodity 실제 산출 검증
- catalyst_parser ↔ ISSUE_LOG/POLICY_TRACKER 연결 확인
보류¶
- 프로그램 매매 측정 (데이터 별도 수집)
- 장중 1분/5분 (30분봉으로 충분한지 추가 검증)
- 에이전트 결정 채점 체계 (D7 변경 시 동반)
15. 백테스트 (LLM 없이 코드만)¶
verdict 4축(chart/of/theme/ea_verdict) NULL → score_compose는 raw z 5축 + theme_bonus만 합산.
S333 v6 결과 (2026-03-01~04-30, 30분봉 정본): - NAV 2.146 (+114.6%, KOSPI +13.9%, 알파 +100.7pp) - 진입 8 / 청산 7 / 승률 86% - rank 1 T+20d 평균 +56.1%, rank 5 +3.2%, rank 10 +2.7% - top 1-5 vs 6-10: T+20d 차 +16.8pp → 점수 단조성 확인
16. 변경 이력¶
| 시점 | 변경 | 핵심 |
|---|---|---|
| S326 | Pydantic schemas | 검증 게이트 |
| S327 | 9 phase 원자화 | step_*.py 분리 |
| S329 | score_compose 재설계 | RS 1회 + theme_bonus |
| S330 | 게이트 폐기 | 순수 합산 |
| S332 | ats_main_v2 검증 | D4 lookup 정확도 |
| S333 | 백테스트 v1~v6 | rank 단조성 + 시스템 알파 입증 |
| 2026-05-31 | D5 30분봉 전용 확정 | 일봉 근사 금지 |
| 2026-05-31 | D2 일봉 OF 완전 제거 | D2OFDailyBlock/compute_orderflow_daily/S317 OF 신호 폐기. OF는 D5(30분봉)만. |
| S334 (계획) | 차트 게이트 + 위험 분모 + 에이전트 선택 | 인간 트레이더 워크플로 정합 |
17. 관련¶
- 에이전트:
.claude/agents/discover/*.md(9개) - 코드:
scripts/discover/{indicators,builders,steps,triggers}/*.py - 스키마:
scripts/discover/schemas.py - 백테스트:
scripts/backtest/s333_v6_code_only.py - 산출:
data/backtest/s333_v6/,docs/discover/{date}.md