Files
QuantEngineByItz/spec/20_harness_output_schema.yaml
kjh2064 ee3e799de1 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>
2026-06-13 13:20:14 +09:00

315 lines
15 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
meta:
title: "은퇴자산포트폴리오 — GAS 수치 출력 의무 스키마"
version: "2026-05-22-V1.0-NUMERIC"
purpose: >
YAML 스펙은 의도 문서이고, LLM 텍스트 판단은 매번 다른 결과를 낸다.
이 파일은 GAS가 반드시 숫자로 채워야 할 harness_context 필드를 정의한다.
measure_harness_coverage.py 가 이 스키마를 기준으로 커버리지를 측정한다.
필드가 공백이면 LLM이 추정 = 랜덤성 원천 = 정보 가치 없음.
principle:
- "하네스가 계산하지 않은 숫자는 정보가 아니다. 텍스트 추정은 매번 다르다."
- "GAS가 산출한 숫자만 ground_truth. LLM 출력과 불일치 시 CRITICAL_EXECUTION_FAILURE."
- "커버리지 목표: 100%. 공백 필드 수 = LLM 자유도 = 재현성 위험."
# ──────────────────────────────────────────────────────────────────────────────
# 필드 정의 형식:
# required: true → GAS 반드시 산출 (공백이면 COVERAGE FAIL)
# type: numeric | enum | bool | json
# formula: 산출 공식 ID
# gas_field: harness_context 내 필드명
# range: [min, max] (numeric 전용)
# allowed: [값1, 값2, ...] (enum 전용)
# llm_action: 공백 시 LLM이 취할 수 있는 유일한 행동
# ──────────────────────────────────────────────────────────────────────────────
mandatory_numeric_outputs:
# ── STAGE 0: 데이터 & 라우팅 ──────────────────────────────────────────────
- gas_field: "intraday_lock"
type: bool
formula: "INTRADAY_ACTION_MATRIX_V1"
required: true
description: "장중 잠금 여부 — false이면 전략 전체 허용"
llm_action: "DATA_MISSING — 장중/장후 판단 중단"
- gas_field: "intraday_scope"
type: enum
formula: "INTRADAY_ACTION_MATRIX_V1"
required: true
allowed: ["FULL_STRATEGY", "TRIM_ONLY", "WATCH_ONLY"]
description: "허용 전략 범위 — TRIM_ONLY 시 신규매수·전량매도 금지"
llm_action: "DATA_MISSING — 기본 TRIM_ONLY로 처리"
# ── STAGE 1: 포트폴리오 현금 & 열 ──────────────────────────────────────────
- gas_field: "settlement_cash_d2_krw"
type: numeric
formula: "CASH_RATIOS_V1"
required: true
range: [0, 10_000_000_000]
description: "D+2 정산현금(원) — 매수 가용 현금 기준"
llm_action: "DATA_MISSING — 매수 금지"
- gas_field: "cash_shortfall_min_krw"
type: numeric
formula: "CASH_RATIOS_V1"
required: true
range: [0, 10_000_000_000]
description: "현금 부족분(원) — 현금확보 매도 발동 기준"
llm_action: "DATA_MISSING — 현금확보 매도 중단"
- gas_field: "total_heat_pct"
type: numeric
formula: "TOTAL_HEAT_V1"
required: true
range: [0, 100]
description: "포트폴리오 총 Heat(%) — 10% 초과 시 신규매수 전면 차단"
llm_action: "DATA_MISSING — 신규매수 차단"
- gas_field: "heat_gate_status"
type: enum
formula: "TOTAL_HEAT_V1"
required: true
allowed: ["PASS", "BLOCK_NEW_BUY", "HALVE_NEW_BUY_QUANTITY"]
description: "Heat 게이트 상태"
llm_action: "DATA_MISSING — BLOCK_NEW_BUY 처리"
# ── STAGE 2: 손절·래칫 ────────────────────────────────────────────────────
- gas_field: "profit_lock_stage"
type: enum
formula: "PROFIT_LOCK_RATCHET_V1"
required: true
per_ticker: true
allowed:
- "NORMAL"
- "BREAKEVEN_RATCHET"
- "PROFIT_LOCK_10"
- "PROFIT_LOCK_20"
- "PROFIT_LOCK_30"
- "APEX_TRAILING"
- "APEX_SUPER"
- "SECULAR_LEADER_DEFERRED"
description: "수익 구간 단계 — APEX_SUPER(+60%)이면 trailing_stop 병기 필수"
llm_action: "DATA_MISSING — trailing_stop 병기 불가"
criticality: "HIGH — APEX_SUPER 미판정 시 +60% 수익 종목에 보유유지만 서술하게 됨"
- gas_field: "auto_trailing_stop_v2"
type: numeric
formula: "PROFIT_RATCHET_TIERED_V2"
required: false
per_ticker: true
description: "ATR×1.2 기반 APEX_SUPER 자동 trailing stop(원)"
note: "profit_lock_stage >= PROFIT_LOCK_20 일 때만 산출 (null이면 적용 안함)"
llm_action: "DATA_MISSING — trailing_stop 병기 불가. 보유유지 단독 서술 허용되어 수익 보호 실패"
criticality: "CRITICAL — 삼성전자 +61.5% 사례(E3)에서 미산출로 수익 보호 실패"
# ── STAGE 3: 설거지 감지 ──────────────────────────────────────────────────
- gas_field: "distribution_sell_detector_status"
type: enum
formula: "DISTRIBUTION_SELL_DETECTOR_V1"
required: true
per_ticker: true
allowed: ["DISTRIBUTION_CONFIRMED", "DISTRIBUTION_WARNING", "DISTRIBUTION_CLEAR"]
description: "설거지 6신호 합산 감지 상태 — CONFIRMED 시 BUY 완전 차단"
llm_action: "DATA_MISSING — '오를 것 같다' 주관 판단으로 매수 → 설거지 진입 위험"
criticality: "HIGH"
# ── STAGE 4: 매수 게이트 ──────────────────────────────────────────────────
- gas_field: "anti_chasing_verdict"
type: enum
formula: "ANTI_CHASING_VELOCITY_V1"
required: true
per_ticker: true
allowed: ["BLOCK_CHASE", "PULLBACK_WAIT", "CLEAR"]
description: "당일 속도 기반 뒷박 추격 차단 — BLOCK_CHASE 시 당일 BUY 금지"
llm_action: "DATA_MISSING — velocity_1d 미계산으로 뒷박 추격 매수 허용"
criticality: "CRITICAL — 뒷박 매수는 진입 당일 고점. 실패의 주원인."
- gas_field: "pullback_entry_trigger_price"
type: numeric
formula: "PULLBACK_ENTRY_TRIGGER_V1"
required: false
per_ticker: true
description: "눌림목 허용 기준가(원) = MA20 - 0.5×ATR20, tick 정규화"
note: "PULLBACK_WAIT 상태일 때만 유효"
llm_action: "DATA_MISSING — '가격이 괜찮아 보이면' 즉시 매수 → 눌림목 미확인 진입"
criticality: "HIGH"
# ── STAGE 5: 현금확보 매도 ────────────────────────────────────────────────
- gas_field: "cash_recovery_plan_json"
type: json
formula: "CASH_RECOVERY_OPTIMIZER_V1"
required: true
condition: "cash_shortfall_min_krw > 0"
description: "현금부족 최적 매도조합 JSON — H2 우선순위 기반 결정론적 산출"
schema:
sell_sequence: "array of {ticker, qty, limit_price, expected_krw}"
expected_total_krw: "numeric"
shortfall_met: "boolean"
llm_action: "DATA_MISSING — LLM이 '삼성E&A 100주+한화에어로 50주' 즉석 계산 → HS011 위반"
criticality: "CRITICAL — 현금확보 매도 조합이 LLM마다 달라짐"
- gas_field: "waterfall_plan_json"
type: json
formula: "SELL_WATERFALL_ENGINE_V1"
required: true
condition: "cash_shortfall_min_krw > 0"
description: "4단계 폭포수 매도 계획 JSON"
schema:
current_stage: "int 1~4"
stage_label: "enum [IMMEDIATE_TRIM,REBOUND_WAIT,CASCADING_TRIM,EMERGENCY_EXIT]"
sell_sequence: "array of {ticker, stage, qty, limit_price, rebound_trigger_price}"
llm_action: "DATA_MISSING — stage 순서 없이 즉흥 매도 → 주식가치 훼손"
criticality: "HIGH"
- gas_field: "preservation_verdict"
type: enum
formula: "SELL_VALUE_PRESERVATION_TIERED_V2"
required: true
per_ticker: true
condition: "Final_Action in [SELL_READY, TRIM]"
allowed:
- "EMERGENCY_EXIT"
- "OVERSOLD_REBOUND_SELL"
- "APEX_TRIM"
- "STAGED_EXIT"
- "PRESERVE_TIERED"
- "HOLD"
description: "주식가치 보호 매도 결정 — HOLD 외에는 구체 계획 필수"
llm_action: "DATA_MISSING — 무작위 매도 스타일 서술"
criticality: "MEDIUM"
# ── STAGE 6: 가격 검증 ────────────────────────────────────────────────────
- gas_field: "sell_price_sanity_status"
type: enum
formula: "SELL_PRICE_SANITY_V1"
required: true
per_ticker: true
condition: "Final_Action in [SELL_READY, TRIM, EXIT_100]"
allowed: ["PASS", "INVALID_PRICE_INVERSION", "INVALID_UNREALISTIC_PRICE", "INVALID_TICK"]
description: "매도가 역전·비현실가 검증 — INVALID 시 HTS 주문표 제거"
llm_action: "DATA_MISSING — LS Electric 사례처럼 역전 가격이 HTS 주문표에 그대로 들어감"
criticality: "CRITICAL — 실제 손실 오류 E1의 직접 원인"
# ── STAGE 6: HTS 주문 잠금 ────────────────────────────────────────────────
- gas_field: "prices_json"
type: json
formula: "PRICES_LOCK"
required: true
description: "종목별 stop_price, tp1_price, tp2_price JSON — LLM 재계산 금지"
schema:
stop_price: "numeric KRW"
tp1_price: "numeric KRW or null"
tp2_price: "numeric KRW or null"
profit_lock_stage: "enum"
llm_action: "DATA_MISSING — LLM이 차트 지지선으로 손절가 임의 추정 → 매번 다른 값"
criticality: "CRITICAL — 수량·가격 기반 모든 주문이 불확실해짐"
- gas_field: "sell_quantities_json"
type: json
formula: "QUANTITIES_LOCK"
required: true
description: "종목별 매도 수량 잠금 JSON"
llm_action: "DATA_MISSING — LLM이 '적절한 수량으로' 즉흥 계산"
criticality: "CRITICAL"
- gas_field: "order_blueprint_json"
type: json
formula: "ORDER_BLUEPRINT"
required: true
description: "HTS 주문 청사진 JSON — validation_status=PASS만 HTS 입력 허용"
llm_action: "DATA_MISSING — Shadow Ledger / HTS 주문표 분리 불가"
criticality: "CRITICAL"
# ── STAGE 7: RS 판정 ──────────────────────────────────────────────────────
- gas_field: "rs_verdict"
type: enum
formula: "RS_VERDICT_V2"
required: true
per_ticker: true
allowed: ["LEADER", "NEUTRAL", "LAGGARD", "BROKEN"]
description: "최종 상대강도 판정 — BROKEN 시 매도 우선순위 최상위"
llm_action: "DATA_MISSING — '차트가 좋아 보이면 LEADER' 주관 판단"
criticality: "HIGH"
# ── MONTHLY BATCH ──────────────────────────────────────────────────────────
- gas_field: "trade_quality_json"
type: json
formula: "TRADE_QUALITY_SCORER_V1"
required: false
batch_only: true
description: "T+5/T+20 거래 품질 채점 결과 — POOR/CRITICAL 누적 블랙리스트 발동"
schema:
ticker: "string"
score: "int 0~100"
grade: "enum [EXCELLENT,GOOD,ACCEPTABLE,POOR,CRITICAL]"
feedback_tag: "enum"
llm_action: "DATA_MISSING — 'POOR 매매였지만 이번엔 다르다' 무근거 판단"
criticality: "MEDIUM — 반복 실수 패턴 차단 불가"
# ──────────────────────────────────────────────────────────────────────────────
# 커버리지 임계값
# ──────────────────────────────────────────────────────────────────────────────
coverage_thresholds:
critical_fields_target_pct: 100 # CRITICAL 필드는 100% 필수
overall_target_pct: 85 # 전체 목표 커버리지
llm_freedom_score_max: 15 # LLM 자유도 15% 이하 목표
grade_table:
100: {grade: "DETERMINISTIC", label: "완전 결정론적 — 이상적 상태"}
85_99: {grade: "NEAR_FULL", label: "거의 결정론적 — 배치 필드만 미계산"}
60_84: {grade: "PARTIAL", label: "부분 결정론적 — GAS 구현 필요"}
0_59: {grade: "LLM_DEPENDENT", label: "LLM 의존 — 결과 재현 불가"}
# ──────────────────────────────────────────────────────────────────────────────
# 현재 GAS 구현 상태 (2026-05-22 기준)
# ──────────────────────────────────────────────────────────────────────────────
current_state:
gas_version: "2026-05-19-X4R1"
overall_coverage_pct: 30 # 실측값 — measure_harness_coverage.py 참조
llm_freedom_score: 70 # 100 - 30 = 70% → LLM 의존도 매우 높음
grade: "LLM_DEPENDENT"
critical_gaps:
- field: "prices_json"
status: "EMPTY"
impact: "stop_price/tp_price 전부 LLM 추정 → 매 호출마다 다른 손절가"
- field: "sell_quantities_json"
status: "EMPTY"
impact: "매도 수량 LLM 추정 → 매 호출마다 다른 수량"
- field: "order_blueprint_json"
status: "EMPTY"
impact: "HTS 주문 청사진 없음 → Shadow Ledger 분리 불가"
- field: "anti_chasing_verdict"
status: "MISSING"
impact: "뒷박 추격 매수 차단 미작동 → 진입 당일 고점 손실 반복"
- field: "sell_price_sanity_status"
status: "MISSING"
impact: "LS Electric 사례(E1) 재발 — 역전 매도가 HTS 입력 허용"
- field: "auto_trailing_stop_v2"
status: "MISSING"
impact: "삼성전자 +61.5% 사례(E3) 재발 — APEX_SUPER trailing_stop 미병기"
- field: "rs_verdict"
status: "MISSING"
impact: "RS_VERDICT_V2 미산출 → H2 매도 우선순위 BROKEN 판정 불가"
- field: "cash_recovery_plan_json"
status: "MISSING"
impact: "현금확보 매도조합 LLM 즉석 계산 → HS011 위반 반복 (E2)"
next_gas_implementation_priority:
1: "prices_json — stop_price, tp_price 실제 계산 및 채우기"
2: "sell_quantities_json — Sell_Qty 실제 수량 채우기"
3: "order_blueprint_json — HTS 주문 청사진 생성"
4: "anti_chasing_verdict — velocity_1d 계산 + 차단 판정"
5: "sell_price_sanity_status — 역전/비현실가 검증"
6: "auto_trailing_stop_v2 — ATR×1.2 APEX_SUPER trailing"
7: "rs_verdict — RS_VERDICT_V2 실제 산출"
8: "cash_recovery_plan_json — H2 순서 누적 매도조합"