Topic: 시스템 재설계 - 시나리오 엔진 + 누적/변화 기반 분석¶
Status: ACTIVE¶
Priority: HIGH¶
Created: 2026-05-04¶
문제 진단 (PM 5/4 피드백)¶
1. 스팟 데이터로 해석하는 문제¶
- "오늘 전력설비 +26%" → 이건 결과일 뿐, 판단 근거가 아님
- "오늘 외인 매수" → 1일치로 판단 불가. 누적 + 가속/감속이 핵심
- 수급/가격/거래량 전부 시계열(5일/20일/60일)로 봐야 방향이 보임
2. "테마가 좋다"에서 멈추는 문제¶
- 현재: "전력설비 LEADING, composite 86.6" → 끝
- 필요: "전력설비가 좋다 → 그래서 어떤 종목이 수혜를 입을 수 있는가?"
- 이 질문을 분해하면 다양한 축이 나올 수 있다 (수급 누적, 실적 뒷받침, 상대강도, 정책 연결 등)
- 어떤 축으로 볼지, 어떻게 조합할지는 설계 단계에서 제대로 고민해야 함
- PM 예시: "5일 양매수 누적 종목, 프로그램 순매수 종목, 수주/실적 예상 좋은 종목, RS 강한 종목, 대장주 이력, 정책 뒷받침 종목 — 이런 것들을 판별할 수 있어야"
- 핵심: 6축이 정답이 아니라, "테마가 좋다"에서 "이 종목을 산다"까지의 경로가 있어야 한다는 것
3. 시나리오 부재¶
- 현재: 뉴스 감지 → 등급 → 기록
- 필요: 뉴스 감지 → 시나리오(Bull/Base/Bear) → 각 시나리오별 대응 → 트리거 조건 → 조건 충족 시 실행
- 예: 호르무즈 교전 → "확대/자제/보복" 3시나리오 → 각각에서 뭘 사고 뭘 피하나
4. GO 판정의 의미 부재¶
- 현재: WAIT 종목 중 SL 가능한 것 → GO
- 문제: "왜 이 종목인가"가 테마 분석과 단절. 그냥 기존 감시 목록에서 뽑는 것
- 필요: 테마가 강하다 → 그 테마에서 6축 교차로 최적 종목 도출 → GO
설계 계획¶
원칙¶
- 리포트를 만드는 시스템이 아니라 돈을 버는 시스템
- 모든 판단은 변화와 누적에서 나온다 (스팟 금지)
- "테마가 좋다"는 시작점이지 결론이 아니다
- 시스템은 매일 연속적이다 (어제 시나리오의 오늘 진행 상태)
Phase 1: 누적/변화 기반 데이터 구조 — S261 완료¶
- ~~종목별 일별 시계열 저장 (수급/RS/거래대금/프로그램)~~
- ~~5d/20d/60d 누적 + 가속도(변화의 변화) 자동 산출~~
- ~~기존 스팟 데이터(fetch_stock_investors 1일치)를 시계열로 전환~~
접근 변경: 시계열 DB 구축 대신, 에이전트 호출 전 코드로 데이터를 미리 수집하는 방식 채택. 이유: 추적 종목이 매일 바뀌므로 고정 DB보다 온디맨드 수집이 효율적.
산출물 (3개 스크립트):
| 스크립트 | 출력 | 소비 에이전트 |
|---------|------|-------------|
| scripts/collect_stock_flow_series.py | data/flow_series/{code}.json — 20일 일별 외인/기관/프로그램 + 누적 + 패턴 | sentiment, trader |
| scripts/collect_macro_series.py | data/macro_series/macro_series.json — 파생 시계열 + 글로벌 자산 + 누적/방향 | macro-economist |
| scripts/collect_sector_series.py | data/sector_series/sector_series.json — 테마별 RS/거래대금/가속도 + 순위 | sector-analyst |
에이전트 명세 수정: sentiment-analyst, sector-analyst, macro-economist에 "Step 0: 스크립트 먼저 실행" 추가. AGENT_TOOL_CATALOG §4.5 등록.
검증: 3개 스크립트 모두 테스트 통과. 키움 ka10045 + 네이버 폴백 정상.
Phase 2: 이슈→종목 연결 파이프라인 — S263 검증 완료, 구조 확정¶
S263 광통신 테마 실전 검증 (77종목, 2026-05-05)
확정된 구조¶
1. 촉매 식별 (법안/재료/뉴스/이벤트)
→ 법안 원문 분해 → 품목/제약 조건 추출
→ 제약의 실효성 검증 (공급 능력, 웨이버 여부, 한국 기업 진출)
2. 관련 테마 식별
→ 네이버 테마 크롤링 (테마 no → 종목 리스트)
→ 관련 테마 복수 합산 (광통신+통신장비+전선+5G = 77종목)
3. 종목 풀 전체에 대한 다차원 분석
→ 수급 이상치 (일별 총합 z-score 2σ+)
→ DART 실적 (매출 성장/영업이익)
→ 법안 연결성 (Top-down 품목→공급자 매핑)
→ 가격 강도 (52주 위치, 미확인)
→ 거래대금 변화 (미확인)
4. 교차 선정
S263 검증 결과 — 단일 축 한계¶
| 분석 축 | 대한광통신(+232%) | 우리로(+559%) | 가온전선(+154%) |
|---|---|---|---|
| DART 실적 | X (적자 -553억) | X (적자 -37억) | O (흑자 360억) |
| 수급 전환 | X (선반영→차익실현) | X (개인 주도) | O (외인 전환) |
| 수급 이상치 | O (3/10 +983만, z=3.6, 77종목 1위) | X | X |
| 법안 Top-down | O (INCAB→BABA) | X | △ |
핵심: 단일 축으로는 대장주를 잡을 수 없음. 수급 이상치가 가장 유효했지만 그것만으로도 불완전. 촉매 식별 → 테마 풀 확보 → 다차원 교차가 필수 구조.
미확인 축¶
- 52주 대비 가격 위치 (KRX API KEY 없음, 키움 일봉으로 대체 가능)
- DART 매출 세그먼트 (테마 매출 비중)
- 거래대금 폭증 시점
도구 확인 결과¶
- DART MCP: 정상 (OFS로 조회, CFS 없는 종목 있음)
- 키움 ka10045: 과거 수급 조회 가능 (start_date/end_date 지정)
- 네이버 테마 크롤링: 기존 코드 복원 완료
- KRX get_stock_trade_info: API KEY 없음 → 사용 불가
Phase 3: 시나리오 엔진¶
- S/A급 이슈가 복수 교차할 때 자동 시나리오 생성
- "법안+실적+수주 동시 = 폭발 가능"
- "유가급등+봉쇄격화 = 에너지 대안 가속"
- 각 시나리오에 Bull/Base/Bear + 트리거 조건
- 이전 시나리오의 오늘 진행 상태 추적 (연속성)
- 산출물: data/scenarios/active/{YYYYMMDD}_{theme}.json
Phase 4: POST_MARKET "테마→종목" 선별 개선¶
- 현재: WAIT 목록에서 SL 가능한 것 뽑기
- 개선: LEADING 테마 확정 → 테마 내 전 종목 스캔 → 조건 부합 종목 도출
- "어떤 축으로 볼지"는 PM과 함께 결정 (수급/실적/RS/정책 등)
- 산출물: 기존 GO/WAIT 판정이 테마 분석과 연결된 형태
실행 순서¶
| 순서 | 작업 | 의존성 | 상태 |
|---|---|---|---|
| 1 | Phase 1 시계열 데이터 수집 | 없음 | S261 완료 |
| 2 | Phase 2 법안→종목 연결 | Phase 1 | 다음 |
| 3 | Phase 3 시나리오 엔진 | Phase 2 | 대기 |
| 4 | Phase 4 POST_MARKET 개선 | Phase 1 + 3 | 대기 |
Phase 1 완료. Phase 2 코드화 완료 (S267). Phase 3~4는 Topic M(에이전트 실체화)으로 흡수.
Phase 2 코드화 완료 (S267, 2026-05-06)¶
산출물: scripts/candidate_from_theme.py
| 단계 | 구현 | 데이터 소스 |
|---|---|---|
| 1. 종목 풀 추출 | ats_main.json themes 키워드 매칭 | ats_main.json |
| 2. 주가 시계열 | 52주 위치/5d 수익률/거래대금 변화 | fdr (FinanceDataReader) |
| 3. DART 실적 | 매출/영업이익/YoY (CFS→OFS 폴백) | opendart REST API 직접 호출 |
| 4. 수급 시계열 | 외인/기관 5d/20d 누적 + z-score 이상치 | 키움 ka10045 → 네이버 폴백 |
| 5. 교차 스코어링 | 가격+실적+수급+거래량 4축 가중합산 | - |
검증: 광통신 테마 13종목 full 파이프라인 성공. - DART sj_div 이슈 수정 (IS→CIS 포괄손익계산서 대응) - corp_code 매핑 캐시 (3963건, 7일 TTL) - S263 검증 결과와 일치: 대한광통신(적자), 가온전선(흑자) 패턴 재현
등록: AGENT_TOOL_CATALOG §4.6 추가.
Phase 2 코드화 원칙 (S264, 2026-05-05 PM 확정)¶
종목 소스 원칙¶
- ats_main.json themes 매핑이 유일한 종목 소스
- WebSearch로 "XX 관련주"를 검색해서 종목을 가져오지 않음
- 테마에 종목이 부족하면 ats_main에 테마/종목을 먼저 등록한 후 사용
판단 근거 원칙¶
- Claude 학습 지식으로 "이 종목이 수혜다" 판단 금지
- 모든 판단은 코드로 수집한 데이터에서만:
- DART: 실적 (매출/영업이익/YoY)
- fdr/키움: 주가 시계열 (52주 위치/상승률/거래대금)
- flow_series: 수급 (외인/기관 누적, 이상치)
- 수주 공시: DART 공시 조회
- WebSearch는 수주 뉴스 보충에만 사용 (종목 선정이 아닌 검증용)
코드화 대상¶
1. ats_main에서 테마별 종목 풀 추출 (이미 _tmp_theme_optical.py로 수동 검증)
2. 종목 풀 전체에 fdr 주가 시계열 일괄 조회 (이미 _tmp_optical_all.py로 수동 검증)
3. 종목 풀 전체에 DART 실적 일괄 조회
4. 종목 풀 전체에 flow_series 수급 수집
5. 4개 축 교차 → 후보 선정
발굴 시스템 재설계 (S298, 2026-05-22 PM 논의)¶
진단¶
시스템 전체가 '시황 정리 리포트 생산'에 머묾. 아키텍처는 이미 공개 LLM 트레이딩 시스템 수준 이상이나(에이전트 수·연속성·검증 인프라), 그것이 edge를 만들지 못함. 원인: 시스템이 리포트 완결성(supervisor)에 책임지지 수익에 책임지지 않음.
확정 결정사항 (PM)¶
- 발굴 시스템 ⊥ 리포팅 시스템 — 발굴은 독립된 1급 시스템, 리포트는 입력 소스로 참조만.
- 구조 = 분석기법 레이어(raw→정규화·구조화·확률화 사실) → 제약된 LLM 에이전트 종합 → verdict(D+N 상승/조정).
- LLM 실시간·룰베이스 하이브리드 배제 — 속도 경쟁 안 함. 알파의 원천은 LLM 해석(뉴스·차트·심리), 룰베이스가 구조적으로 못 하는 것.
- 에이전트 게으름 차단 — "raw 데이터 + 열린 질문 = 관망" 헷지를 입력·출력 스키마 강제(harness 검증)로 차단. 관망 출력 옵션 제거, 확률 분포 강제, 사실 인용 강제.
- base rate는 한국 코퍼스 자체 측정 — 외부에 신뢰할 base rate 없음. look-ahead 차단(익명화·정규화·시간경계).
발굴 시스템 4층¶
①발굴 funnel(퀀트, 상대 랭킹) → ②분석기법 레이어(정규화·구조화·확률화, Layer A/B/C) → ③제약된 LLM 종합 → ④base-rate 엔진+검증(walk-forward·DSR). 입력 4영역: 가격(차트·수급) + 매출·전망 + 이벤트 + 대체데이터.
측정 1차 단위¶
재료(촉매) 존재 × 시장이 그 재료를 소화하는 방식. 소화의 측정자 = 매수·매도자의 공격성·시급성. 재료 = {종목재료 + 펀더(매출·전망) + 시장환경}. 시장환경은 재료이자 소화 게이트.
Output (외부 리서치 5라운드)¶
docs/research/20260522_llm_trading_discovery_research.md— LLM 트레이딩 전반docs/research/20260522_llm_interpretation_methods_research.md— LLM 해석 방법론docs/research/20260522_chart_flow_structuring_research.md— 차트·수급 구조화 (스키마 Layer A/B/C)docs/research/20260522_quant_discovery_funnel_research.md— 퀀트 발굴 funneldocs/research/20260522_fundamental_event_signal_research.md— 매출·전망·이벤트·대체데이터docs/work_logs/2026-05-22_S298_discovery_system_research.md
설계 산출물¶
docs/planning/discovery_feature_spec.md— 발굴 시스템 피처 명세(후보). 도구별(키움·DART·FRED·yfinance·파생·뉴스) 수치화 항목 + 산식 + 레퍼런스 + Status. 전 피처 ⬜후보, 백테스트 통과 시 ✅. 매크로 보강 리서치(순유동성·FCI·연결성지수·매크로 신호화) 결과 반영.docs/planning/chart_discovery_layer_mapping.md(S299, 2026-05-23) — R3 §2 Layer A/B/C 전 필드를 우리 데이터에 1:1 매핑. v0 채택 = 일봉 Layer A 12 + Layer B 2 = 14필드. 분봉 order_flow 5필드는 funnel Stage 2. 개발/연구 단계(전종목×N년)와 실전 운영(funnel 압축 후 N개) 구분.scripts/discovery/{layer_a.py, state_classifier.py, scan.py}(S299) — 차트 발굴기 v0. R3 CF3 단일 불균형 상태기 + 소화 측정. universe → classify_state → state별 그룹핑.scripts/lib/verified_price.py(S299) — EVENING 가격·날짜 오인용 차단 3층 (Layer 1 수집 / 2 격리 / 3 검증).
Decisions/Corrections¶
- PM 교정: 리포트 내에서 척추를 바꾸려던 접근(로스터를 리포트 척추로) 폐기 → 발굴을 별도 독립 시스템으로.
- PM 교정: LLM 실시간/2-tier 하이브리드는 승산 없음 → 스윙 호라이즌 + LLM 해석 우위로 한정.
- PM 교정: Round 4 퀀트 리서치가 가격 신호 편향(차트분석과 유사) → Round 5로 매출·전망·이벤트·대체데이터 보강.
- PM 교정: 펀더멘탈·시장환경은 별도 축이 아니라 '재료'의 일부 (관심·유동성을 끄는 것).
- PM 교정 (S299): "큰 상승 다음날"은 base-rate 테스트일 뿐, 발굴 시스템 자체 신설이 목표.
- PM 교정 (S299): 차트 발굴 = R3 CF3대로 4모듈 단일 불균형 상태기 + 소화 측정. VCP·SOS·LPS 같은 미국식 셋업 카탈로그 라벨이 아님. 측정 1차 단위 =
재료 × 소화(공격성·시급성). - PM 교정 (S299, 핵심): 발굴기는 "폭증 종목 찾기"가 아니다. 우리가 알고 싶은 것은 5질문 — ① 오늘 상승 종목 내일 지속? ② 지속 신호 차트 어디서? ③ 상승 후 하락이 조정인가 추세 종료인가? ④ 조정이면 완료/추가? ⑤ 시장참여자가 가격에 어떻게 반응했나? 각 종목 현 차트 상태의 의미를 해석하는 시스템이지 폭등 스크리너가 아님.
- 가격·날짜 검증 결함(EVENING 5/22 삼성전자 +8.51% 오인용, WTI $101과 동종 결함): morning 수정이 evening에 미적용 + 소스 date가 collect()에서 누락. 3층(가격 출처 고정 / 에이전트 격리 / harness 스캔) + 소스 date 보존으로 차단.
Status: 🔄 진행 중 — 차트 발굴 v0 구현·작동 확인, framing 재정렬 필요¶
차트 발굴 trigger 5방법론 재설계 (S300, 2026-05-23 PM 논의)¶
진단¶
S299 차트 발굴기 v0(state_classifier 회귀 기울기 라벨러)는 32개 측정자를 산출하나 verdict 결정에 영향 미치는 측정자는 1개(cycle_position via Upthrust age)뿐. 5/22 005930 차트 시점에 시스템 출력은 PM 질문 "BALANCE면 사라는 거야 말라는 거야?"에 답 불가.
확정 결정사항 (PM, S300)¶
- 임의 측정자 합산 금지 — 가중합/합산 점수가 아니라 각 방법론이 자기 본래 도구로 판정.
- 답 맞추기 금지 — D+N 결과 보고 trigger 튜닝하지 말 것.
- 일봉 모드에서 Order Flow 제외 — 분봉이 본래 그릇(R3 CF4·매핑 §1-D). 일봉은 VSA/Wyckoff/AMT/Bulkowski 4 trigger.
- 단순화 X — 5방법론 압축 합치기 X. 각 방법론 자기 언어로 유지.
- 4상태 매트릭스 — 매수/매도 결정 X. 다음 4상태 + 방향(UP/DOWN) 판정이 1차:
- 불균형 지속 (IMBALANCE_PERSIST)
- 불균형 해소 (IMBALANCE_RESOLVING)
- 균형 유지 (BALANCE_HOLDING)
- 균형 이탈 (BALANCE_BREAKING) 매수/매도는 (state × direction)에서 자동 도출.
Output (S300)¶
scripts/discovery/volume_profile.py— POC/VA/HVN/LVN/Rotation/Migration/거래대금 비대칭/overhang (정규화)scripts/discovery/vsa_signals.py— 8신호 + Spring/Upthrust 누적scripts/discovery/order_flow.py— BVC/CVD/Absorption/Exhaustion/Divergence (일봉 fallback)scripts/discovery/wyckoff.py— 4국면 + 11이벤트 + 3법칙scripts/discovery/triggers/_state4.py— 4상태 enum + decision 매핑scripts/discovery/triggers/vsa_trigger.py— VSA 본래 3축(spread·close·volume)만scripts/discovery/triggers/wyckoff_trigger.py— HH/HL 시퀀스 + S/R + 4국면 + 이벤트 + 3법칙scripts/discovery/triggers/amt_trigger.py— VA/POC/poc_migration/overhang만scripts/discovery/triggers/bulkowski_trigger.py— 명명된 패턴(rectangle/triangle/double bottom/top) + breakout + confirmationscripts/discovery/triggers/aggregator.py— 4 trigger vote 통합docs/work_logs/2026-05-23_S300_chart_discovery_trigger_redesign.md
Decisions/Corrections (S300)¶
- PM 교정 (S300, 핵심): 매수/매도 결정은 4상태 판정에서 자동 도출. trigger를 BUY/SELL 직접 출력으로 만들지 말고 (state, direction) 먼저 판정 → decision 자동.
- PM 교정 (S300, 윈도우): 각 trigger가 다른 시간 윈도우(VSA 40봉 / Wyckoff 60봉 / AMT 120봉 / Bulkowski 40봉) 사용. 같은 시점 다른 판정의 절반은 윈도우 불일치 탓. 통일 또는 명시 필요.
- PM 교정 (S300, 검증): 차트 우측 끝(현재 시점)에서 검증 의미 없음. 과거 시점에 돌려야 D+N 흐름과 대조 가능.
- PM 교정 (S300, 일봉 OF): R3 CF4 명시대로 일봉에서 OF 제외. 분봉 인프라 후 도입.
검증 — 3시점 4상태 판정 결과¶
| 시점 | VSA | Wyckoff | AMT | Bulkowski | verdict |
|---|---|---|---|---|---|
| 3/9 | BALANCE_HOLDING/NONE | IMBALANCE_PERSIST/UP | IMBALANCE_RESOLVING/UP | IMBALANCE_PERSIST/UP | MIXED_BUY_LEAN |
| 3/31 | IMBALANCE_PERSIST/DOWN | BALANCE_HOLDING/NONE | BALANCE_HOLDING/NONE | IMBALANCE_PERSIST/UP | MIXED |
| 4/15 | BALANCE_BREAKING/DOWN | BALANCE_HOLDING/NONE | IMBALANCE_RESOLVING/UP | IMBALANCE_PERSIST/UP | MIXED_SELL_LEAN |
4상태가 실제 출력에 나타남. 단 윈도우 불일치로 방법론 간 합의 부재.
다음 WBS (S300 → S301)¶
1순위 — 데이터 윈도우 통일 (PM 직접 지적): 각 trigger가 보는 시간 범위 정의 일관. 옵션: - A: 60일 통일 (Wyckoff 기준) - B: 방법론별 본래 윈도우 유지 + 출력에 윈도우 명시 - C: multi-window (short/mid/long 3회 호출)
2순위 — 한국 임계 재보정: Wyckoff climax vol 2.0/VSA 임계 → 한국 대형주 실측.
3순위 — Bulkowski 박스 윈도우 재조정: 40봉 박스가 60일 상단(223k)에 묶임. 20봉 단축 또는 동적 패턴 식별.
4순위 — 38일 walk 재실행: 윈도우 통일 + 임계 보정 후 verdict 분포 변화 측정.
S301 — 5방법론 윈도우 원전 재설계 (2026-05-23)¶
PM 지시¶
원전대로 시스템에 적용. 옵션 A/B/C 중 선택이 아니라 각 방법론이 본래 권하는 윈도우를 그대로 + 신호별 분리.
리서치 (출처)¶
| 방법론 | 본래 윈도우 | 출처 |
|---|---|---|
| VSA volume baseline | 30봉 SMA | Williams Master the Markets / Tradeguider PDF |
| VSA No Demand/Supply | 직전 2~3봉 | 원전 정의 |
| VSA Climactic | 20봉 V×Range max | Better Volume / ATAS |
| Wyckoff TR | 40~125 일봉 (Phase A+B+C+D 합산) | Pruden / StockCharts ChartSchool / Wyckoff Analytics |
| Wyckoff Spring/Test | 직전 TR 경계 ±3봉 | 현대 통용 |
| AMT short/mid/long | 20 / 60 / 120봉 동시 | Steidlmayer composite / Aspen / TradingView VPVR |
| Bulkowski Rectangle | median 65일 (3개월) | thepatternsite.com/rectbots.html |
| Bulkowski Flag | 며칠~3주 (3주 초과 시 Rectangle) | thepatternsite.com/flags.html |
| Bulkowski Pennant | 약 10일, 최대 20일 | thepatternsite.com/pennants.html |
| Order Flow BVC | 65분 bar 79.7% / 1초 64.3% | Easley/Lopez de Prado/O'Hara 2012 |
| CVD divergence 일봉 | long-term flow 신호로 유효 | Bookmap / LuxAlgo |
구현¶
- vsa_trigger.py:
VOL_BASELINE_N=30+CLIMAX_LOOKBACK=20+ND_NS_LOOKBACK=3+TREND_N=20. 신호별 윈도우 분리. 단일 40봉 폐기. - wyckoff_trigger.py:
TR_LOOKBACK=125(Pruden 표준) +EVENT_WINDOW=3(Spring/UT 단봉).TR_MIN_FALLBACK=60. TR 경계 ±3봉 침범 후 회귀 자동 검출 (Spring/UT 원전 정의). - amt_trigger.py:
WINDOW_SHORT=20 / MID=60 / LONG=120동시. 합의 규칙: 2+동조 ×1.0 / long단독 ×0.7 / 불일치 ×0.6. - bulkowski_trigger.py:
RECTANGLE_N=65 / FLAG_N=15 / PENNANT_N=20. 3 윈도우 동시 패턴 식별, Breakout+vol_confirm 우선. - of_trigger.py:
intraday_available=False(default) → CVD divergence만 사용(BVC 제외). 일봉 confidence 보수적. mode 라벨 신호에 명시. - aggregator.py:
window_summarydict로 각 trigger의window_meta자동 집계.intraday_available결과에 명시.
검증 (4시점 walk, 005930)¶
| 시점 | S300 | S301 | 변화 |
|---|---|---|---|
| 3/9 | MIXED_BUY_LEAN | MIXED_BUY_LEAN | 유지 |
| 3/31 | MIXED | MIXED_BUY_LEAN | 상향 |
| 4/15 | MIXED_SELL_LEAN | MIXED | 상향 |
| 5/22 | - | MIXED_BUY_LEAN | 신규 |
TR 125봉 확장으로 큰 추세 컨텍스트 반영, AMT multi-window 합의로 단기 노이즈 필터링.
Decisions/Corrections (S301)¶
- PM 교정: 단일 윈도우 단순화 폐기. 원전이 신호/패턴별 분리 권장.
- 옵션 A/B/C 채택 X. 원전 그대로가 답.
- BVC 일봉 제외 정당(통계 약함), CVD divergence는 일봉 fallback 허용(Bookmap 명시).
- 각 trigger 결과에
window_meta강제 → 어떤 윈도우에서 나온 신호인지 추적 가능.
Output (S301)¶
scripts/discovery/triggers/vsa_trigger.py— 신호별 윈도우 분리 (30/20/3)scripts/discovery/triggers/wyckoff_trigger.py— TR 125 + event 3scripts/discovery/triggers/amt_trigger.py— multi-window 합의 (20/60/120)scripts/discovery/triggers/bulkowski_trigger.py— 패턴별 윈도우 (65/15/20)scripts/discovery/triggers/of_trigger.py— 일봉 fallback mode 분기scripts/discovery/triggers/aggregator.py— window_summary 집계docs/work_logs/2026-05-23_S301_chart_discovery_window_unification.md
Status: 🔄 진행 중 — 윈도우 재설계 완료, 임계 재보정 + walk 안정성 측정 대기¶
다음 (S302)¶
- 한국 임계 재보정 — KOSPI200 50종목 60일 vol 분포 → 분위수 기반 임계
- TR 경계 단봉 이벤트 false positive 측정 (노이즈 종목 30개)
- 38일 walk 재실행 — 영업일별 verdict 안정성
- CVD divergence 일봉 통계 — 50종목 발생 빈도 + 후속 5/20일 수익 분포
S302 — 차트 발굴 trigger 임계 재보정 (2026-05-23)¶
PM 지시¶
임계 보정 시작 전 "왜 1.8?" 근거 부재 지적. 학습 데이터로 70%ile 임의 매핑 시도 차단. 원전 출처 확인 후 보정.
리서치 (출처 인용)¶
| 임계 | 우리 코드 | 원전 명시? | 출처 |
|---|---|---|---|
| VSA HIGH × 1.8 | 1.8 | ❌ | 후속 구현체 관행 |
| VSA ULTRA × 3.0 | 3.0 | ❌ (외부 ×2.0 언급) | tradefundrr |
| VSA WIDE × 1.2 | 1.2 | ❌ marketvolume은 ×1.8 (충돌) | 벤더 |
| VSA NARROW × 0.83 | 0.83 | ❌ marketvolume은 ×0.8 | 벤더 |
| Wyckoff Climax × 2.0 | 2.0 | ❌ Pruden 정성만 | 시각적 |
| Wyckoff Spring 침범 | 0.998 (0.2%) | ❌ 원전 1~3% | wyckoffsmi.com |
| AMT VA 0.70 | 0.70 | ✅ Steidlmayer 정규분포 1σ | 원전 |
| AMT POC stable 0.15 | 0.15 | ❌ | 벤더 |
| Bulkowski vol_confirm × 1.2 | 1.2 | ❌ 30일 평균 ratio 분석 | 경험적 |
PM 결정 사항 (S302)¶
- 임계 통계 모델: Percentile (75/90/97) — TradingView 표준
- 적용 단위: 종목별 60일 rolling — Coulling 권고
- Spring 침범: 1% — Robert Evans 원전 최소
- AMT VA 0.70: 유지 — Steidlmayer 원전
- AMT POC stable: ATR 25th percentile — 종목 변동성 동적
Output¶
scripts/discovery/triggers/_thresholds.py— 신규 compute_all_thresholds 유틸scripts/discovery/triggers/vsa_trigger.py— multiplier → percentilescripts/discovery/triggers/wyckoff_trigger.py— Spring 0.998 → 0.99scripts/discovery/triggers/amt_trigger.py— POC stable 동적scripts/discovery/triggers/bulkowski_trigger.py— vol_confirm 70thdocs/work_logs/2026-05-23_S302_threshold_recalibration.md
검증 (005930 5/22)¶
S301 multiplier 환산 vs S302 percentile 실측: - HIGH: ×1.8 = 52.8M vs 90%ile = 42.4M → S301이 47% 더 보수적 - ULTRA: ×3.0 = 88.0M vs 97%ile = 54.2M → S301이 62% 더 보수적 - spring_penetration: 0.2% → 1% (5배 완화)
→ S301 multiplier가 005930 실제 분포보다 너무 높아서 climax 봉 0건 발화하던 문제 해결.
3시점 walk 변화¶
| 시점 | S301 | S302 | 비고 |
|---|---|---|---|
| 3/9 | MIXED_BUY_LEAN | 동일 | 변화 없음 |
| 3/31 | MIXED_BUY_LEAN | 동일 | 변화 없음 |
| 4/15 | MIXED (S1.30) | MIXED (S1.20) | VSA BALANCE_BREAKING/DOWN → IMBALANCE_RESOLVING/UP (spread 종목 분포 정합) |
S302가 더 보수적. 실제 D+20 +28.2% BUY 정답과 부합 방향.
Decisions/Corrections (S302)¶
- PM 교정: 임계 보정 전 원전 근거 리서치 필수. 학습 데이터 매핑 금지.
- 벤더 multiplier 폐기: VSA/Bulkowski 모두 종목별 percentile.
- AMT VA 0.70 유지: 유일한 원전 통계 임계 (Steidlmayer 1σ).
- Spring 0.2% → 1%: 원전 최소값. 한국 일봉 노이즈 환경에서 발화 가능해짐.
- window_meta thresholds_source 강제: 어떤 임계에서 신호 나왔는지 추적 가능.
Status: 🔄 진행 중 — 임계 재보정 완료, false positive + walk 안정성 대기¶
다음 (S303)¶
- TR 경계 단봉 이벤트 false positive 측정 (Spring 1% 완화로 발생 빈도 증가)
- 38일 walk 재실행 — 영업일별 verdict 안정성 측정
- MIXED_LEAN 1.5배 임계 재검토 (4/15 사례)
- 종목군별 임계 캐싱 (compute_all_thresholds 매번 호출 비효율)
S303 — 4년 16,297 samples 백테스트 (2026-05-23)¶
설계¶
- KOSPI 50 + KOSDAQ 30 = 80종목 (2026-05 시총 상위 고정)
- 2022-01 ~ 2026-04-15, 매 5 영업일, look-ahead 차단
- D+5/10/20/60 + max-high + Time-to-X
- 다중 지표 (Hit/Mean/MDD/Sharpe/Calmar/PF)
결과¶
- BUY_STRONG만 명확한 alpha (D+60 +5.64pp vs baseline +12.75%)
- MIXED 73% 정보 없음 (baseline과 동일)
- BUY 단독은 baseline 미만 (-1.56pp, 추격 매수 위험)
- 2022 하락장에서 BUY 계열 음수 (체계적 회피 가치 확인)
Output (S303)¶
scripts/backtest/s303_{universe, fetch_ohlcv, run_backtest, analyze, baseline}.pydata/backtest/s303/{universe.json, samples.parquet, verdict_summary.json, regime_breakdown.json, speed_distribution.json, ohlcv/*.parquet}docs/research/2026-05-23_S303_chart_backtest.mddocs/work_logs/2026-05-23_S303_backtest.md
Status: 🔄 진행 중 — 백테스트 완료, 결함 분석 대기¶
S304 — Retracement 측정자 + Fibonacci 게이트 (2026-05-23)¶
PM 결함 지적 1¶
"20일 +300%, 5일 -30%가 균형 회귀인가?" → 시스템에 회수율 측정자 부재. pchg < -3 등 절대값만 사용.
리서치¶
5방법론 원전 모두 상대값(impulse 대비 retracement) 기준 (VSA bar-by-bar, Wyckoff TR 폭, AMT 분포 %, Bulkowski breakout 근접, Fibonacci/Elliott/Dow).
Output (S304)¶
scripts/discovery/triggers/_retracement.py신규- 4 trigger 게이트 통합 (vsa/wyckoff/bulkowski + amt skip)
docs/work_logs/2026-05-23_S304_retracement_gate.md
PM 결함 지적 2 (옵션 B 추가)¶
"4/15는 신고가 근접인데 retrace 43.9%로 SELL 강제?" → 모듈이 max-retrace-ever 측정. retrace_ratio_current + retrace_ratio_max 둘 다 산출, state는 current 기반으로 수정. 4/15 → MIXED_BUY_LEAN 복원.
Status: ✅ 완료 (검증 + 백테스트는 S305)¶
S305 — Retrace 게이트 효과 백테스트 + 다양한 케이스 검증 (2026-05-23)¶
백테스트 (16,172 samples, 21분)¶
- retrace_override 77.2% 발생
- BUY D+60 +11.19% → +15.25% (alpha +4.06pp), baseline 초과로 전환
- BUY_STRONG 91 → 241 (165% 증가), alpha 안정 (+18.39 → +18.57%)
- MIXED 60% 감소 (3,913 → 1,552)
- MIXED_BUY_LEAN 130% 증가 (2,712 → 6,233)
- override 발생 sample이 미발생 대비 D+60 +6.46pp 높음
다양한 케이스 검증 (13 cases, A~F 패턴)¶
- 명확한 정답: 3 (A2 기아 2024-07 / E2 LGES 2024-04 / F1 HLB 2024-06 +45%)
- 명백 오답 5건 식별 (저점 매도 4건 + 신고가 BUY 1건)
Status: ✅ 완료¶
S306 — 명백 오답 5건 원인 분석 (2026-05-23)¶
PM 종합 교정¶
"모든 경우 적중하는 시스템은 불가. 명백 결함의 원인만 파악."
결함 3종¶
- SC/BC
c.diff()부호 분류 — Wyckoff 원전과 불일치 - 모든 trigger
lookback=60하드코드 — 다중 윈도우 합의 부재 - retrace 게이트가 비율만 보고 위치(pos60) 무시 — 비대칭
Output¶
scripts/backtest/s306_diagnose.py+s306_climax_check.pydata/backtest/s306/diagnostics.jsondocs/research/2026-05-24_S306_misjudgment_root_cause.md
Status: ✅ 완료¶
S307 — OF 30분봉 정책 + cp 동적 + 원전 정합성 점검 + 백테스트 + 결함 수정 (2026-05-24)¶
PM 핵심 교정 6건¶
- OF는 30분봉/900봉 (일봉 fallback 폐기)
- 원전에 있는 내용만 제대로 구현 (임의 추가 X)
- 임계는 한국 시장 종목별 rolling으로 동적
- 관행적 임계는 그대로 OK (룰베이스 최적해 불가)
- 위치=감정 매핑 금지 (본질 매트릭스만)
- 만능 차트 분석기 X — 시장+재료 결합 필요
Phase 1: OF 30분봉 정책¶
- 키움 ka10080 fetcher:
scripts/discovery/fetch_minute_30.py aggregator.py:intraday_available→of_30m인자 교체of_trigger.py재작성 (일봉 fallback 폐기)
Phase 2: cp 동적 임계¶
_thresholds.compute_cp_climax_thresholds(252봉 rolling, Q90 vol 봉 cp 분포 Q70/Q30)vsa_trigger.pySC/BC mask 동적 cp + wide_mask 제거- 6건 sample_n=26 검증 (종목별 차이 확인)
Phase 3: AMT POC 정체 동적화¶
amt_trigger.pypoc_mig 0.15→poc_stable_band(S302 ATR Q25) 적용 확장
Phase 4: 원전 정합성 점검¶
- 정합 확인: VSA 8신호 / AMT POC/VA / OF BVC/CVD /
_thresholdspercentile - 관행 유지: Wyckoff vol_mult 1.2 / breakout_tol 1.5% / ma 20 / climax 2.0
- 임의 가드 12+건 유지 (PM "관행으로 충분, 룰베이스 최적해 불가")
Phase 5: 백테스트¶
- S307 (80종목): 16,172 samples / 21분. AVOID/AVOID_STRONG 재분포(OF 제외 부작용)
- S307big (250종목): 47,456 samples / 62분. baseline 약화(+4.14% → +3.41%, survivorship bias). BUY_STRONG alpha 일관 +4.62~5.05%
- S307big+OF (가용 1,682): OF active 73건. BUY n=65 D+20 +15.16% sortino 2.16 calmar 1.27. SELL n=8 모두 양수=단독 실패 (PM "차트+시장+재료 결합" 직접 검증)
Phase 6: Risk Metrics (MDD/Sortino/Calmar)¶
- BUY_STRONG calmar: S305 0.44 → S307 0.37 → S307big 0.39 → S307big+OF 1.74
- 전체 baseline calmar: S305 0.38 → S307big 0.31 → S307big+OF 0.85
- MDD worst -60% (시총 작은 종목 단일 큰 낙폭)
Phase 7: 차트 모듈 결함 수정 (3건 수정 / 1건 주석)¶
결정적 결함 2건 수정:
- #1+#2 _retracement.py: UP/DOWN impulse_pct + retrace_pct 분모 4가지 조합 불일치 (예: 100→200, 145 회복 시 표준 55% vs 코드 27.5%). distance 비율로 일관화
- #3 wyckoff_trigger.py: Spring/UT support_tr 자기참조 (마지막 봉 신저점 시 Spring 미발화). support_for_event 신규 산출 (last_segment 제외)
잠재 결함 1건 (주석만):
- #4 bulkowski_trigger.py: today_idx와 seg 사이 5봉 갭 원전 출처 불명. PM 결정 대기
정합 확인: vsa_signals 8신호 / volume_profile POC/VA / order_flow BVC/CVD / _thresholds percentile
Smoke test 5건: 4건 verdict 동일, E1 sell vote 2→3 (Bulkowski 추가). retrace_ratio 모두 값 변경 확인.
Output (S307)¶
scripts/discovery/fetch_minute_30.py+fetch_minute_30_universe.pyscripts/discovery/triggers/_retracement.py(수정),wyckoff_trigger.py(수정),bulkowski_trigger.py(주석)scripts/discovery/triggers/vsa_trigger.py+amt_trigger.py+of_trigger.py+aggregator.py+_thresholds.pyscripts/backtest/s307_*.py+s307of_*.py+s307big_*.py+s307bigof_*.pydata/backtest/s307/+s307of/+s307big/+s307bigof/(4 백테스트)data/minute_charts/30min/*.parquet(250종목)docs/research/2026-05-24_S307_originalsource_compliance.mddocs/research/2026-05-24_S307_backtest.mddocs/research/2026-05-24_S307of_backtest.mddocs/research/2026-05-24_S307big_backtest.mddocs/research/2026-05-24_S307_defects_fix.mddocs/work_logs/2026-05-24_S307_originalsource_check.mddocs/work_logs/2026-05-24_S307_defects_fix.md
Status: ✅ 완료 (S304 이후 백테스트는 수정 전 산출. 재실행은 다음 세션 결정)¶
다음 (PM 결정 대기)¶
- 결함 수정 후 백테스트 재실행 (S307big + S307big+OF, ~70분)
- Bulkowski #4 5봉 갭 처리
- 차트 + 시장 + 재료 결합 시스템 본격 설계 (PM 6번 교정 응답)
- 부분 정답: 5 (A1, B2, C1, C2, F2)
- 명확한 오답: 5 (A3 한화에어로 신고가 BUY → 하락 / B1 삼전 2022 / B3 LGES / D1 KT&G 저점 SELL / E1 카카오 저점 SELL)
발견된 추가 결함 (S306 후보)¶
- 저점 매도 (Selling Climax 미검출) — B1/B3/E1/D1 4건 동일 패턴
- 신고가 BC 미검출 — A3
- Impulse 60봉 갇힘 — D1 (60일 최저점인데 DOWN 추세 PERSIST)
- 경계선 라벨 불안정 — F2 (38.2% 경계)
Output (S305)¶
scripts/backtest/{s305_run_backtest, s305_compare}.pydata/backtest/s305/samples.parquet(16,172 samples)docs/research/2026-05-23_S305_retrace_gate_backtest.mddocs/work_logs/2026-05-23_S305_retrace_backtest.md
PM 종합 교정 (S305)¶
- "모든 경우에 다 맞추는 시스템은 만들 수 없다. 다만 명백히 잘못된 경우에 왜 그런지 살펴볼 수 있을 뿐."
- 즉 다음 세션 S306은 "모든 케이스 적중"이 아니라 "명백히 잘못된 5개 오답 케이스의 원인 분석" 으로 방향 잡기.
Status: 🔄 진행 중 — 통계적 alpha 확인, 케이스별 결함 진단 대기¶
다음 (S306)¶
- 명백 오답 5건 원인 분석 (PM 지시): A3/B1/B3/D1/E1. 패턴 묶음 = 저점 매도 4건 + 신고가 BUY 1건.
- 저점 매도 결함 → Selling Climax 검출 강화 (큰 vol + 저점 + close 회복)
- D1 KT&G 케이스 → 다중 윈도우 impulse (60/120/252) 검토
- 38.2% 경계 회색 영역 라벨링 (F2)
- 거래비용 시뮬레이션 (S303→S305 BUY 175% 증가의 sustainability)
S306 — 명백 오답 5건 원인 분석 (2026-05-23)¶
PM 종합 교정¶
모든 경우 적중하는 시스템은 불가. 명백 결함의 원인만 파악.
5건 raw 진단 결함 3종¶
- SC/BC 부호 분류 - Wyckoff 원전(연속 2봉 쌍) 불일치
- 모든 trigger 하드코드 - 다중 윈도우 합의 부재
- retrace 게이트가 비율만 보고 위치(pos60) 무시 - 비대칭
Output¶
- scripts/backtest/s306_diagnose.py + s306_climax_check.py
- data/backtest/s306/diagnostics.json
- docs/research/2026-05-24_S306_misjudgment_root_cause.md
Status: 완료¶
S307 — OF 30분봉 정책 + cp 동적 임계 + 원전 정합성 점검 + 백테스트 + 결함 수정 (2026-05-24)¶
PM 핵심 교정 6건¶
- OF는 30분봉/900봉 (일봉 fallback 폐기)
- 원전에 있는 내용만 제대로 구현 (임의 추가 X)
- 임계는 한국 시장 종목별 rolling으로 동적
- 관행적 임계는 그대로 OK (룰베이스 최적해 불가)
- 위치=감정 매핑 금지 (본질 매트릭스만)
- 만능 차트 분석기 X - 시장+재료 결합 필요
Phase 1: OF 30분봉 정책 적용¶
- 키움 ka10080 fetcher: scripts/discovery/fetch_minute_30.py
- aggregator.py: intraday_available -> of_30m 인자 교체
- of_trigger.py 재작성 (일봉 fallback 폐기)
- 005930 검증 캐시 완료
Phase 2: cp 동적 임계¶
- _thresholds.compute_cp_climax_thresholds (252봉 rolling, Q90 vol 봉 cp 분포 Q70/Q30)
- vsa_trigger.py SC/BC mask 동적 cp + wide_mask 제거
- 6건 sample_n=26 검증 (한화에어로 bottom 0.480, 카카오 0.142 등 종목별 차이 확인)
Phase 3: AMT POC 정체 동적화¶
- amt_trigger.py poc_mig 0.15 -> poc_stable_band (S302 ATR Q25) 적용 확장
Phase 4: 원전 정합성 점검 + 임의 가드 분류¶
- 정합 확인: VSA 8신호 / AMT POC/VA / OF BVC/CVD / _thresholds percentile
- 관행 유지: Wyckoff vol_mult 1.2 / breakout_tol 1.5% / ma 20 / climax 2.0
- 임의 가드 12+건 유지 (PM 관행으로 충분, 룰베이스 최적해 불가)
Phase 5: 백테스트¶
- S307 (80종목): 16,172 samples / 21분. S305 대비 90.9% 동일, AVOID/AVOID_STRONG 재분포(OF 제외 부작용)
- S307big (250종목): 47,456 samples / 62분. baseline 약화(+4.14% -> +3.41%, survivorship bias 확인). BUY_STRONG alpha 일관 +4.62~5.05%
- S307big+OF (가용 1,682): OF active 73건. BUY n=65 D+20 +15.16% sortino 2.16 calmar 1.27. SELL n=8 모두 양수=단독 실패 확정 (PM 차트+시장+재료 결합 직접 검증)
Phase 6: Risk Metrics¶
- BUY_STRONG calmar 추적: S305 0.44 -> S307 0.37 -> S307big 0.39 -> S307big+OF 1.74
- 전체 baseline calmar: S305 0.38 -> S307big 0.31 -> S307big+OF 0.85
- MDD worst -60% (시총 작은 종목 단일 큰 낙폭)
Phase 7: 차트 분석 모듈 결함 점검 + 수정¶
결정적 결함 2건 수정: - #1+#2 : UP/DOWN impulse_pct + retrace_pct 분모 4가지 조합 불일치 (예: 100->200, 145 회복 시 표준 55% vs 코드 27.5%). distance 비율로 일관화 - #3 : Spring/UT 자기참조 (마지막 봉 신저점 시 Spring 미발화). support_for_event 신규 산출 (last_segment 제외)
잠재 결함 1건 주석만: - #4 : today_idx와 seg 사이 5봉 갭 원전 출처 불명. PM 결정 대기
정합 확인 (변경 없음): - vsa_signals 8신호 (Williams) / volume_profile POC/VA (Steidlmayer) / order_flow BVC/CVD (Easley 2012) / _thresholds percentile
Smoke test 5건: 4건 verdict 동일, E1 sell vote 2->3 (Bulkowski 추가). retrace_ratio 모두 값 변경 확인.
Output (S307)¶
- scripts/discovery/fetch_minute_30.py + fetch_minute_30_universe.py
- scripts/discovery/triggers/_retracement.py (수정)
- scripts/discovery/triggers/wyckoff_trigger.py (수정)
- scripts/discovery/triggers/bulkowski_trigger.py (주석)
- scripts/discovery/triggers/vsa_trigger.py + amt_trigger.py + of_trigger.py + aggregator.py + _thresholds.py
- scripts/backtest/s307_.py + s307of_.py + s307big_.py + s307bigof_.py
- data/backtest/s307/ + s307of/ + s307big/ + s307bigof/ (4 백테스트)
- data/minute_charts/30min/*.parquet (250종목)
- docs/research/2026-05-24_S307_originalsource_compliance.md
- docs/research/2026-05-24_S307_backtest.md
- docs/research/2026-05-24_S307of_backtest.md
- docs/research/2026-05-24_S307big_backtest.md
- docs/research/2026-05-24_S307_defects_fix.md
- docs/work_logs/2026-05-24_S307_originalsource_check.md
- docs/work_logs/2026-05-24_S307_defects_fix.md
Status: 완료 (S304 이후 백테스트는 수정 전 산출. 재실행은 다음 세션 결정)¶
다음 (PM 결정 대기)¶
- 결함 수정 후 백테스트 재실행 (S307big + S307big+OF, ~70분)
- Bulkowski #4 5봉 갭 처리
- 차트 + 시장 + 재료 결합 시스템 본격 설계 (PM 6번 교정 응답)
S308 — L×S Macro Engine v1~v3 + KRX 파생 v4a/v4b (2026-05-24)¶
작업¶
- 5단계 검증 사이클 v1→v2a→v2b→v2c→v3
- L축(유동성)+S축(심리) composite z 4분면 regime
- KRX OpenAPI 파생 1년 백필 (729 raw JSON), v4a 243 days
- v4b 파생 단독 swing 알람 평가
결과¶
- L×S Regime: PBO 0.038 / OOS 80% sign match / VERY_HIGH/VERY_HIGH +12.25pp
- v3 turning point: KOSPI ±8% swing 9건 모두 ±12일 내 부호 100% 부합
- v4b basis_z 14d 선행 ★ (매크로 mean 0d 압도)
PM 통찰¶
"매크로 = environment/prior + swing 알람" (방향 단독 X)
Status: ✅ 완료¶
S309 — v4b swing ±5% + v4c Chart × L×S × Derivatives (2026-05-24)¶
옵션 2: v4b swing ±5%¶
- swing 7건, basis_z 7/7 lead -6.0d, kr_10y_chg_z 7/7 lead -3.9d
- composite 실패 → 단일 신호 권장
옵션 4: v4c 3-axis (38일 교집합)¶
- 30분봉 250종 EOD breadth + L×S cell + basis_z
- HIGH_LOW Contrarian × 파생 MID/HIGH D+20 α +14.04pp ★★
- basis_z VERY_HIGH D+20 α -6.97pp (회피 신호)
- 결함: chart rolling 30일로 38일 중 30일 UNKNOWN
Output¶
scripts/backtest/lxs_v4b_swing5_derivatives_standalone.pyscripts/backtest/lxs_v4c_chart_quant_deriv.pydocs/research/2026-05-24_S309_lxs_v4c_3axis.md
Status: ✅ 완료 (PM: 결함은 데이터 문제, 본질 아님)¶
S310 — 실적 가속 시그널 5 에이전트 리서치 (2026-05-24)¶
PM 4축 발굴 시스템 정의 확정¶
- 퀀트 = 실적 가속 (단순 스크리닝 아님)
- 테마 = RS (시장보다 잘 가는 테마)
- 시장환경 = L×S + 파생 (진입 가능 환경)
- 차트 = 진입 (매수 자리)
한국 적용 5+1 채택¶
- E1 Earnings Acceleration (He-Narayanamoorthy 연 14~23%)
- E2 Korea-SUE / E3 Consensus Revision (월 68bp) / E4 매출 가속 Δ2차 / E5 CFO/NI
- E6 자사주 취득 공시 (보조)
한국 함정 5건¶
- 45d lag + 마감일 집중 2. 정정공시 3. K-IFRS 정의 변동 4. 일회성 손익(한화솔루션 +494%) 5. 가이던스 의무 부재
Output¶
docs/research/2026-05-24_S310_earnings_signal_research.mddocs/planning/2026-05-24_S310_earnings_module_spec.md
Status: ✅ 완료¶
S311 — 실적 데이터 백필 (DART→FnGuide PIVOT, 2026-05-24~25)¶
S311a~c: 모듈 + DART MCP dry-run + corp_code 매핑¶
- 단위테스트 19/19, universe_top500 산출
- corp_code 95 호출, 93 성공, 우선주 2 제외 → 98종 eligible
- 발견: 회사별 IS/CIS 구조 차이 (005930 분리 / 000660 통합)
PIVOT 결정¶
- DART 단일 sj_nm으로 모든 회사 매출/영업이익 못 잡음
- 80KB×240 메인 세션 한계
- FnGuide SVD_Main이 종목당 1 호출로 분기 5년 + 컨센 추정 모두 제공
- DART corp_code는 이벤트 폴링용 보존
S311d: FnGuide 백필¶
fnguide_loader.pytable_kind 분리 (annual vs quarter 12월 충돌 해결)- 98종 × 평균 8.4 분기 = 7,420 rows, 97/97 성공 120초
Output¶
scripts/quant/earnings/fnguide_loader.pyscripts/backfill/{fnguide_backfill_top100, fetch_kospi_daily, commit_*, _probe_*}.pydata/dart_cache/{fnguide_fs, kospi_daily, universe_top100_eligible}.parquetdocs/work_logs/2026-05-24_S311_earnings_data_backfill.md
Status: ✅ 완료¶
S312 / S312v2 — E1 EA_QoQ v0 backtest (2026-05-25)¶
S312 face validity (1차 시도)¶
- EA(6분기 필요) 데이터 부족 → g_q(YoY) 단일 전환
- 2026Q1 cross-section 61종, M1 spread +13pp / YTD -30pp (outlier)
- forward horizon 부족으로 정식 backtest 불가
S312v2 PM 통찰¶
"8분기 다 안써도 되잖아?" → EA_QoQ (4분기) 산식 추가:
EA_QoQ = (x_q − x_q-1)/|x_q-1| − (x_q-2 − x_q-3)/|x_q-3|
S312v2 결과 (2025Q4 1시점, n=81)¶
| H | TOP α | BOTTOM α | Spread |
|---|---|---|---|
| D+5 | -1.55% | +0.68% | -2.23pp |
| D+10 | -5.74% | +4.33% | -10.07pp |
| D+20 | -13.58% | -8.80% | -4.77pp |
| D+30 | -17.24% | -26.34% | +9.11pp ✅ |
- 절대: TOP +15.1% vs BOTTOM +5.9% (KOSPI +32.3%)
- LG이노텍 +126% outlier 영향
- 1시점·n=8 → 통계 유의성 X
FDR/Naver/FnGuide 동일 origin 확인¶
fdr.naver.snap.finstate_summary(freq='Q')발견- 모두 WiseReport iframe → 분기 5 + 연간 5 한계 동일
PM 마지막 질문¶
"차트+퀀트 다 사용했을 때 알파 없는건가?" → 아직 측정 안 됨 (S313)
Output¶
scripts/quant/earnings/e1_acceleration.pyscripts/backtest/{e1_base_rate, e1_face_validity}.pydata/backtest/e1/{ea_panel, decile_stocks, base_rate_results, face_validity_2026Q1}.{parquet,json}docs/research/2026-05-25_S312_e1_face_validity.mddocs/research/2026-05-25_S312v2_e1_qoq_backtest.mddocs/work_logs/2026-05-24_S309_S312v2_session.md
Status: ✅ 완료 (v0)¶
다음 (S313) — 종목 단위 4축 결합 backtest¶
의제¶
PM 질문 "차트+퀀트 다 사용했을 때 알파 없는건가?" 답 산출. 현재까지 각 축 단독으로만 측정 — 결합 미실시.
실행 계획¶
scripts/quant/themes/theme_rs.py신규 — ats_main 176테마 60일 RSdiscovery/scan.py확장 — 81종 chart state 점수 (2026-04-06)scripts/backtest/e2_4axis_combined.py신규 — 4축 결합 8×8 decile D+5~30 alphadocs/research/2026-05-26_S313_4axis_combined.md
4축 결합 산식¶
SCORE = z(EA_QoQ) × z(chart_state) × z(theme_RS) × cell_multiplier
TOP/BOTTOM decile D+5/10/20/30 alpha → S312v2 단독 +9.11pp 기준선
Status: ⏳ 계획¶
S316 — 에이전트 walk-forward + 도구 점검 (2026-05-25~26)¶
진행 흐름¶
- v1 (강한 테마×leader 컷오프): -32.66pp
- v2 (OF 정정 21:13): +22.99pp
- v3 (매출/차트 추가): +12.29pp
- v4 (universe 거래대금 200): +12.29pp
- v5 (통합 점수 6축 percentile): -17.96pp ❌ (compute_score 불일치, 1종 몰빵)
- v6 (에이전트 walk-forward): +41.87% / α +6.77pp ✅
PM 정정 (이번 세션)¶
-
9: OF는 점수 아니라 종목 상황 판단 도구 → 상황 A/B 분기¶
-
10: 종목 풀 = 시총X → 거래대금 20d 상위 200종¶
-
11: 강한 테마는 분류한 적 없음, RS로 구분¶
-
12: 매출/차트 빠진 절름발이 시스템 지적 → 전체 도구 통합¶
-
13: 컷오프 X → 통합 점수 (가중 합)¶
-
14: 코드 X → 에이전트 글로벌 판단¶
-
15: 도구는 알파 측정용 아니라 목적 충족 여부 기준 (차트=불균형/에너지, 퀀트=실적, OF=주문흐름)¶
도구 단독 알파 측정 (참고용)¶
| 도구 | NAV | α vs KOSPI |
|---|---|---|
| 차트 top10 | +17.35% | -17.76pp |
| 퀀트 top10 | +25.03% | -10.08pp |
| OF 4축 AND | +19.10% | -16.01pp |
| OF 2축 | +13.16% | -21.95pp |
| buy_intent 단독 | +26.57% | -8.53pp |
| EQ50 buy-and-hold | +16.78% | -18.32pp |
해석 (PM #15): 도구가 각자 목적(차트=불균형/에너지, 퀀트=실적, OF=주문흐름)에 맞게 작동만 하면 OK. 알파는 도구 단독이 아니라 에이전트 통합 판단에서 생성됨. v6 +6.77pp는 도구가 제 역할을 했고 에이전트가 잘 합성했다는 증거.
산출¶
- scripts/backtest/e4_agent_pack_builder.py — 일별 200종 × 6축 패키지 빌더
- scripts/backtest/e4_agent_harness.py — 거래 실행 + NAV
- scripts/backtest/e4_state_context.py — 보유 상태 컨텍스트
- scripts/backtest/e4_tool_alpha.py — 도구 단독 알파 측정
- data/backtest/e4_portfolio/agent_packs/*.txt (63개)
- data/backtest/e4_portfolio/agent_picks/*.json (63개)
- data/backtest/e4_portfolio/portfolio_nav_agent.parquet
- data/backtest/e4_portfolio/trade_log_agent.json (424건)
- data/backtest/e4_portfolio/summary_agent.json
- data/backtest/e4_portfolio/tool_alpha_summary.json
- docs/research/2026-05-26_S316_agent_walkforward.md
- docs/research/2026-05-26_S316_modules_summary.md
- docs/research/2026-05-26_S316_portfolio_walk_dynamic_pool.md
Status: ✅ 완료 (v6 NAV +41.87% / α +6.77pp, 도구 점검 완료)¶
다음 세션 후보¶
- 거래 비용 적용 NAV 재계산 (현 알파 +6.77pp 실효성 검증)
- 다른 구간(약상승/하락장) walk-forward → robustness 측정
- trailing stop / MDD 제어 룰 (현 MDD -12%)
- 에이전트 응답 안정성 측정 (동일 일자 N회 재호출)
- 매출 데이터 102종 백필 (현 커버 83/200)