S336 — 차트 이벤트 맥락 데이터 설계 (PM 승인 대기)¶
작성: 2026-05-31 (S336) 상태: 📋 설계안 — 코드 전, PM 승인 후 구현 전제: S335에서 chart-judge에 4프레임 반영 완료. 이번엔 "데이터 가공 + 질문 원자화"가 본질.
1. 문제 재정의 (PM 지침)¶
S335까지: chart-judge가 trajectory/energy/exceptionality 3종 재료로 verdict를 냄. S336 PM 지적 2가지:
-
거래대금 게이트 = 절대 임계 아님. universe가 이미 거래대금 상위로 추출됨 → "사람들이 보나"는 거의 항상 yes. 진짜 신호는 "평소보다 시선이 갑자기 쏠린 구간에 진입했는가"(자기 대비 급증). 게이트와 이례성 트리거는 같은 축 → 통합.
-
본질은 "데이터 가공 + 질문 원자화". PM 인용:
"결국은 가격과 거래량 거래대금의 쌍의 흐름 + 사람들이 가격에 반응하는 OF + 이벤트라 할 큰 사건의 맥락을 어떻게 합쳐서 제공할지가 중요. 인간 트레이더는 차트를 보며 '이날 무슨 일 있었구나, 종가 지키며 올라갔구나, 거래량 줄며 눌림목이구나, 저 저항 뚫으면 더 가겠구나, 거래량 동반했으니 동의받은 가격이구나'를 스스로 판단하는데 — 에이전트에겐 이 질문들을 체계화·원자화해서 자동으로 하도록 해줘야지." "기준일로 하는 게 아니라 데이터를 보면서 판단해야지."
→ 코드는 이벤트를 구간화·라벨링·신선도판정 하지 않는다(그건 에이전트 몫). 코드는 인간이 차트에서 읽는 raw 패턴을 풍부하게 펼쳐주고, 에이전트가 원자화된 질문 체크리스트로 스스로 읽게 한다.
2. 데이터 제약 (확인됨)¶
| 데이터 | 범위 | 용도 |
|---|---|---|
| 일봉 OHLCV (O/H/L/C/V) | 5년+ | 쌍흐름·CLV·이례성 (전 기간) |
| 30분봉 OF | 2026-02-13 ~ 05-22 (65영업일만) | 사람들 반응(흡수/돌파) — 최근 사건만 |
→ 2단 구조: 최근 65일 내 사건 = 일봉+OF 풀컨텍스트 / 그 이전 = 일봉+CLV만. (PM 기존 원칙 "OF 활용 가능 기간으로 제한"과 일치)
3. 코드가 제공할 재료 (판단 X, raw 펼침)¶
3.1 이례적인 날 컨텍스트 (PM "이날 무슨 일 = 가격움직임+수급 종합으로 봐야지")¶
PM 교정: 이벤트일을 거래대금 단일 축으로 뽑지 말 것. "이례적인 날"은 거래대금 급증 + 가격 움직임(시고종저·상승률) + 수급(OF) 종합으로 봐야 "무슨 일이 있었는지" 읽힘. (재료·시장상황은 다른 에이전트가 처리)
amount_vs_self_60d ≥ 임계로 후보를 잡되, 각 날에 가격+수급 풀 컨텍스트 동봉:
exceptional_days: # 자기 대비 거래대금 급증일, 날짜별 (구간 묶기 X)
- date: 2026-03-31
amt_vs_self: 4.9
amt_pctile_252d: 0.996
ret_pct: -30.0
ohlc: {o:1138000, h:1141000, l:829000, c:829000} # 인간 "이날 무슨 일" 읽기
clv: -1.0 # 종가위치 +1=고가 -1=저가 (검증: 추출됨)
# --- 수급(30분봉 OF, 65일 내만) — "어떤 가격대에서 어떻게 움직였나" ---
close_vs_vwap_pct: -9.0 # 종가가 일중 거래가중평균 대비 (동의받은 가격? 검증됨)
intraday_cvd_pct: -19 # 일중 순매수 비율 (분배 vs 흡수)
late_session_pct: 0 # 후반부 매수/매도 우위 (마감 직전 분배 잡힘 — 4/17 케이스)
binvol_low_to_high: [47,27,0,26,0] # 그날 H~L 5구간 거래량% (어느 가격대 집중)
# --- 후속 반응 ---
next_3d: {low_held: bool, vol_shrink: bool}
검증(§탐색2): 30분봉으로 close_vs_vwap/cvd/late/가격대별거래%가 전부 추출됨. 일봉 종가로 못 보는 "장 후반 분배"(미래에셋 4/17 late=-78%)까지 드러남.
→ "그런 사건이 계속 발생하면?"(PM 고민) = 날짜별로 주되 거래대금만이 아니라 가격+수급 종합 점수 큰 순 top-K. 에이전트가 시퀀스로 연속 서사 구성.
3.2 쌍 흐름 (가격·거래량·거래대금) — 이미 일부 있음¶
기존 trajectory/energy 유지 + 보강: - 최근 N일 (close, ret_pct, volume, amount, clv) 5쌍 시계열 (분절 금지, 묶어서) - 핵심: clv 추가 (종가위치) — "종가 지키며 올라갔나" 판정용
3.3 핵심 가격대 + 반응 (PM "저항 뚫으면 더 간다 / 동의받은 가격")¶
- 직전 주요 고점/저점 (swing) + 현재가와의 거리
- 그 레벨에서 과거 거래량 (거래량 동반 = 동의받은 가격)
- 현재가가 그 레벨 돌파/근접/거부 중 무엇인지의 raw 수치 (라벨 X, 거리·거래량만)
4. 질문 원자화 (에이전트 자동 판단용 체크리스트)¶
PM이 나열한 인간 트레이더 판단 → 원자 질문. 에이전트가 각 질문에 raw 데이터로 답:
| # | 원자 질문 | 인간 표현 | 근거 데이터 |
|---|---|---|---|
| A1 | 이례적 거래대금일이 언제, 얼마나 컸나? | "이날 무슨 일 있었구나" | exceptional_days[] |
| A2 | 그날 종가가 고가 부근인가? | "종가 지키며 올라갔구나" | clv, body_pos |
| A3 | 그 가격이 후속일 지지됐나? | "이 가격 지키려는 모습" | next_3d.low_held |
| A4 | 급등 후 거래량 줄며 얕은 조정? | "거래량 줄며 눌림목" | next_3d.vol_shrink |
| A5 | 직전 고점 대비 어디? 돌파 시도? | "저항 뚫으면 더 간다" | 핵심 가격대 거리 |
| A6 | 큰 거래량에서 가격 수용됐나? | "거래량 동반=동의받은 가격" | amt + clv + of_reaction |
| A7 | 지금 살아있는 사건의 며칠째인가? | "지금 진입 자리인가" | exceptional_days 최신 + 경과 |
| A8 | 이전 사건 대비 강한가(재점화)? | "또 뚫네, 힘 더 있네" | 이벤트 시퀀스 비교 |
→ 연속성: A7/A8이 "이어지는 사건" 담당. 에이전트는 이벤트 시퀀스를 보며 "어제 거부였는데 오늘 자금 재유입"을 A8로 읽음. 코드가 신선도 라벨 안 붙임.
5. 거래대금 게이트 재정의 (PM 지적 1 반영)¶
S335의 liquidity_gate WEAK/NORMAL/STRONG(절대 분위 임계) → 폐기.
대신: "시선 급증 구간 진입 여부"를 exceptional_days로 판단.
- 게이트 = "오늘 또는 최근에 자기 대비 시선 급증이 있었나"
- 없으면(시선 식음) = 차트 자리 해석 무게↓ (사람들이 안 보는 가격대 = 합의 약함)
- 게이트와 이례성 트리거 통합 (같은 축).
6. 구현 범위 (PM 승인 후)¶
chart_indicators.py:compute_exceptional_days신규 (날짜별 컨텍스트, top-K), clv 추가, 핵심 가격대+거래량. 이벤트 구간화·라벨링 안 함.- 30분봉 OF 반응 결합 (65일 내만, close_vs_vwap/late_bias)
schemas.py: D2ExceptionalDaysBlock 추가, schema_version 3chart-judge.md: 게이트 재정의 + A1~A8 원자 질문 체크리스트- 검증: 삼천당/미래에셋 + 추가 케이스로 에이전트가 이벤트 시퀀스 읽는지
7. OF 세부 (PM "어떤 가격대에서 사람들이 어떻게 움직였나" — 진입 판단 도움)¶
PM 교정: OF는 지표 1~2개 택이 아니라 "가격대별 사람들 움직임"의 세부 정보. 30분봉으로 그날의 (a)가격대별 거래분포 (b)각 가격대 종가정착/수용 (c)분배vs흡수를 가격대 해상도로. 검증된 추출 가능 항목:
| 항목 | 의미 | PM 표현 |
|---|---|---|
| close_vs_vwap_pct | 종가가 일중 거래가중평균 대비 | "동의받은 가격인가" |
| binvol_low_to_high[5] | H~L 5구간 거래량% | "어떤 가격대에 몰렸나" |
| intraday_cvd_pct | 일중 순매수 비율 | "흡수 vs 분배" |
| late_session_pct | 후반부 매수/매도 우위 | "마감 직전 분배(4/17 -78%)" |
| clv | 종가위치 | "종가 지키며 끝났나" |
8. 확정 사항 (PM 승인 완료, 2026-05-31)¶
상위 맥락 환기 (PM): chart-judge에 오는 종목은 이미 거래대금↑·상승률↑·테마군 동조로 걸러진 후보(universe + D3 RS + D4 테마). → 종목 레벨 "볼 가치 있나" 게이트는 상위에서 이미 끝남. chart-judge는 그 종목 차트 안에서 "이례적인 날 전개 + 지금 국면"만 읽는다.
| 결정 | 내용 |
|---|---|
| exceptional_days 선정 | 후보는 amt_vs_self ≥ 3x로 단순 추출, 가격+수급 컨텍스트 동봉. 코드는 종합점수 서열 안 매김(PM #14). top-8, 최근 6개월 |
| 과거(65일 밖) 이벤트 | 일봉 clv+시고종저+상승률+후속반응만 (OF 없이), of_available: false 명시 |
| 거래대금 게이트 | chart-judge에서 제거 (상위 파이프라인이 이미 함). exceptional_days로 "시선 급증 구간 진입 여부" 해석만 |
| 후속 반응 창 | next_3d + next_10d (지지/이탈 추적) |
| OF 세부 | close_vs_vwap / binvol_low_to_high[5] / intraday_cvd / late_session / clv (§7) |
| 질문 | A1~A8 (§4) — 게이트 질문 제외, 나머지 유지 |
9. 구현 완료 + 실호출 검증 ✅ (2026-05-31)¶
구현:
- schemas.py: D2ExceptionalDay/D2ExceptionalDaysBlock 추가, schema_version 3. is_today 플래그(오늘 행 항상 포함).
- chart_indicators.py: compute_exceptional_days(후보 amt_vs_self≥3x, top-8, 6개월) + _intraday_micro(30분봉 수급). 종합점수 서열·구간화·신선도 판정 안 함.
- build_d2_input.py: _load_30min(asof 컷, look-ahead 차단) + compute_exceptional_days 결합.
- chart-judge.md: 거래대금 게이트 제거(상위 파이프라인이 함), exceptional_days 중심 + 원자질문 A1~A8 + late_session 분배 점검. 출력 today_phase/event_continuity 신규.
실호출 검증 (chart-judge 2종):
| 삼천당 000250(3/31) | 미래에셋 100790(4/14) | |
|---|---|---|
| verdict | NEGATIVE HIGH | POSITIVE MED |
| today_phase | distribution | re_ignition |
| event_continuity | resolving | continuing(3막) |
| 반응 | 거부 | 용인 |
성과: (1) "이어지는 사건" 진짜 작동 — 미래에셋을 "3막극(파라볼릭붕괴→막판분배실패→깨끗한재점화)"으로 서술. (2) late_session이 일봉 못 보는 걸 잡음 — 03-27 clv 0.82(고가마감)인데 late -87(막판투매)→실제 next10d -14.1% 인과 직접 연결. (3) "같은 clv 1.0 폭발양봉, 다른 결과"를 거래량 질(비climactic+late 0.0)로 구분 — 12-22 천장(-34.9%) vs 오늘 재점화. 단정 않고 "내일 late 음전 재출현 시 회피" 분기 제시. 산출: data/backtest/s335/d2_*_v3.json