feat: 리밸런싱 엔진 V1 + GAS 버그 수정 (2026-06-13)

주요 변경:
- tools/build_rebalance_engine_v1.py: REBALANCE_ENGINE_V1 신규
  * account_snapshot 직접 합산(_build_snap_position_map) → 소수주 분리 행 병합
  * 레짐 소스 macro.REGIME_PRELIM 최우선 (GAS 와 동일)
- src/gas_adapter_parts/gdf_06_rebalance.gs: runRebalanceSheet_() 신규
  * Logger.log / getSpreadsheet_() 로 run_all 연동 수정
- src/gas_adapter_parts/gdc_01_fetch_fundamentals.gs
  * _mergePositionRecord_(): 소수주 중복 행 합산 신규
  * parseInt → parseFloat (qty, availQty)
- src/gas_adapter_parts/gdf_01_price_metrics.gs
  * 미보유 종목 SELL_READY → WATCH_EXIT_SIGNAL
- spec/41_release_dag.yaml: build_rebalance_sheet 노드 추가 (step_count 63)
- spec/51_formula_lifecycle_registry.yaml: REBALANCE_ENGINE_V1 등록

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 13:20:14 +09:00
commit ee3e799de1
1474 changed files with 176087 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
meta:
title: "은퇴자산포트폴리오 — 종목 모델 분할 후보"
parent_file: "spec/04_strategy_rules.yaml"
version: "2026-05-16-F10_peg_gate"
language: "ko-KR"
timezone: "Asia/Seoul"
role: "canonical"
migration_status: "canonical_split_active"
authority_rule: "이 split 파일이 해당 섹션의 canonical source다. parent_file은 legacy compatibility index다."
stock_model:
pass: ["시총·섹터 대표성", "충분한 거래대금", "실적 개선", "20D 수급 우위", "기대수익비 2:1 이상"]
reject: ["관리종목·거래정지·유동성 부족", "적자 지속+테마성 급등", "거래대금 폭증 후 장대음봉", "실적 컨센서스 하향", "단일 뉴스만 근거인 상승"]
# [proposal_91 / 2026-05-16] 코스닥 전용 추가 reject 조건 — 코스닥 구조적 위험 특성 반영
kosdaq_extra_reject:
applicable: "코스닥 상장 종목에만 추가 적용. 위 reject 조건과 AND(모두 확인)."
conditions:
- "코스닥 상장 후 6개월 미만 — 실적 트랙 레코드 부족, 상장 직후 공모주 매도 물량 리스크"
- "최근 1년 내 감사의견 비적정 또는 내부회계 관리제도 중요 취약점 보고"
- "대주주 지분 50% 미만 + 최근 3개월 대주주 2회 이상 연속 매도"
- "영업이익 흑자 전환 1분기에 불과한 테마 종목 — 2분기 연속 흑자 미확인 시 reject"
- "유상증자·CB(전환사채)·BW(신주인수권부사채) 발행 후 6개월 이내 — 희석 리스크"
prohibition:
- "코스닥 종목에 대해 이 조건 미확인 상태에서 A등급 부여 금지"
- "테마 뉴스를 근거로 kosdaq_extra_reject 조건 면제 금지"
# [proposal_96 / 2026-05-16] 코스닥 밸류에이션 게이트 — PEG 기반 고성장 정당화 여부 판단
kosdaq_valuation_gate:
applicable: "코스닥 상장 종목에만 적용. KOSPI 종목은 기존 SS001_VAL_VALUATION 사용."
purpose: >
유동성·수급만으로는 한미반도체처럼 PER 40~60배 구간 진입 리스크를 잡지 못한다.
EPS 성장률로 PER을 나눈 PEG로 '비싸지만 정당한가'를 판단한다.
primary_metric:
name: "PEG (Price/Earnings to Growth)"
formula_ref: "spec/13_formula_registry.yaml:formula_registry.formulas.PEG_SCORE_V1"
formula: "ForwardPER / EPS_Growth_3Y_CAGR_pct"
unit_note: "EPS_Growth_3Y_CAGR_pct는 % 단위 숫자 (30% 성장이면 30). 소수점 아님."
gate_rules:
pass: {condition: "PEG <= 1.5", action: "밸류에이션 OK. 진입 수량 정상 산출."}
caution: {condition: "1.5 < PEG <= 2.5", action: "진입 수량 70%로 자동 축소. 보고서에 [PEG_CAUTION] 표기 필수."}
reject: {condition: "PEG > 2.5", action: "코스닥 진입 금지. 수량 0주."}
fallback:
trigger: "EPS_Growth_3Y_CAGR_pct 미확인 또는 데이터 누락"
rules:
- {if: "ForwardPER <= 섹터중앙값 × 2.0", result: "PASS"}
- {if: "섹터중앙값 × 2.0 < ForwardPER <= 섹터중앙값 × 3.0", result: "CAUTION (70% 수량)"}
- {if: "ForwardPER > 섹터중앙값 × 3.0", result: "REJECT"}
prohibition: "EPS 성장률 추정·보간으로 PEG 계산 금지 — 확정 컨센서스 데이터 없으면 fallback만 허용"
examples:
hanmi_semiconductor:
scenario: "ForwardPER=45, EPS_Growth_3Y=25%"
peg: 1.8
result: "CAUTION → 진입 수량 70%. full 진입 금지."
high_peg_reject:
scenario: "ForwardPER=60, EPS_Growth_3Y=10%"
peg: 6.0
result: "REJECT → 진입 금지."
growth_justified:
scenario: "ForwardPER=30, EPS_Growth_3Y=40%"
peg: 0.75
result: "PASS → 정상 수량 산출."
interaction:
kosdaq_extra_reject: "kosdaq_extra_reject와 AND 적용. 어느 하나 reject이면 진입 금지."
anti_climax_buy_gate: "PEG CAUTION + anti_climax 신호 2개 → 수량 70%×50%=35%로 중첩 축소."
scoring: "SS001_VAL_KOSDAQ_PEG 점수(최대 12점)로 전환. spec/08_scoring_rules.yaml 참조."
prohibition:
- "코스닥 종목 PEG 미산출 상태에서 A등급 부여 금지"
- "PEG CAUTION 상태에서 수량 축소 없이 full 진입 금지"
- "단일 호재 뉴스로 EPS_Growth 상향 추정 후 PEG 개선 처리 금지"
- "KOSPI 종목에 이 게이트 적용 금지"
core_satellite_rule:
alias_of: "satellite_rule"
definition: "조건부·소액·관찰 후보. 즉시매수 아님"
max_count: 3
max_weight: "총자산 7% 이하"
required_conditions: # [P127] mandatory 3개 ALL 필수 / optional 4개 중 1개 이상 권장
mandatory_all_3:
- 거래대금 증가
- 외국인/기관 순매수 전환
- "기대수익비 2:1 이상"
optional_confirm_any:
- 섹터 상대강도 개선
- 실적 추정치 상향
- "20일선 회복 후 유지 또는 신고가 후 눌림 재지지"
entry_spike_restriction: "단기 급등(당일 +5% 이상) 직후는 본진입 제외. risk_on 국면도 시범진입만 허용 (tiered_ladder 순서 준수). optional_confirm_any가 아닌 진입 제한 규칙."
rule: "핵심 데이터 미확인 시 A등급 불가. 첫 돌파는 시범진입만, 확인 전 전량 진입 금지. 강한 장세에서는 시범진입 타이밍을 늦추지 말고 수량만 줄인다."