352 lines
15 KiB
YAML
352 lines
15 KiB
YAML
# Canonical Metrics Registry V1
|
|
# 목적: 같은 논리 지표를 여러 JSON 객체/키에서 읽는 "단일 진실원천 부재" 버그를 방지.
|
|
# 각 metric_id는 canonical_source 하나에서만 읽어야 하며,
|
|
# 렌더러(render_operational_report.py)는 build_canonical_metrics_v1.py가 산출한
|
|
# Temp/canonical_metrics_v1.json을 통해서만 이 값을 조회한다.
|
|
#
|
|
# 변경 정책 (spec/06_exit_policy.yaml Surgical Update와 동일):
|
|
# - canonical_source 변경 시 consumers 전부 업데이트 확인 필수
|
|
# - tolerance_abs: 두 원천 값이 이 차이 이내면 일치로 간주 (교차섹션 정합성 검사용)
|
|
|
|
formula_id: CANONICAL_METRICS_REGISTRY_V1
|
|
has_code_implementation: true
|
|
code_path: "tools/build_canonical_metrics_v1.py"
|
|
version: "2026-05-29"
|
|
|
|
# ─────────────────────────────────────────────────────────
|
|
# 스칼라 지표 (per_ticker: false)
|
|
# ─────────────────────────────────────────────────────────
|
|
metrics:
|
|
|
|
cluster_pct:
|
|
description: 반도체 클러스터(삼성전자+SK하이닉스+KODEX반도체) 합산 비중(%)
|
|
canonical_source: semiconductor_cluster_json.combined_pct
|
|
fallback_sources:
|
|
- mandatory_reduction_json.cluster_pct
|
|
- cluster_sync_result_json.cluster_pct
|
|
consumers:
|
|
- cluster_sync_audit
|
|
- portfolio_structure_risks
|
|
- mandatory_reduction_plan
|
|
tolerance_abs: 0.05
|
|
unit: percent
|
|
notes: >
|
|
cluster_sync_result_json.cluster_pct=0 버그가 있음.
|
|
mandatory_reduction_json.cluster_pct=62.79는 소수점 반올림 차이이므로 tolerance 허용.
|
|
canonical = semiconductor_cluster_json.combined_pct(62.93).
|
|
|
|
cash_min_required_krw:
|
|
description: 현금 최소 필요액(원) — cash_floor 확보를 위한 최소 매도 필요 금액
|
|
canonical_source: cash_recovery_display_json.min_required_krw
|
|
fallback_sources:
|
|
- cash_shortfall_min_krw
|
|
- trim_plan_to_min_cash_json.cash_shortfall_min_krw
|
|
consumers:
|
|
- exec_safety_declaration
|
|
- cash_recovery_plan_crdl
|
|
- single_conclusion
|
|
- QEH_AUDIT_BLOCK
|
|
tolerance_abs: 0
|
|
unit: krw
|
|
notes: >
|
|
cash_shortfall_json 객체가 None이므로 cash_shortfall_json.cash_shortfall_min_krw 읽기 불가.
|
|
harness_context 최상위 cash_shortfall_min_krw=39797073이 대안이나,
|
|
canonical = cash_recovery_display_json.min_required_krw(39797073).
|
|
|
|
cash_reference_total_krw:
|
|
description: 현금확보 전체 후보 누적 금액(원) — 주문 아님, 참고용
|
|
canonical_source: trim_plan_to_min_cash_json.total_plan_krw
|
|
fallback_sources:
|
|
- cash_recovery_display_json.reference_total_krw
|
|
consumers:
|
|
- cash_recovery_plan_crdl
|
|
tolerance_abs: 0
|
|
unit: krw
|
|
notes: >
|
|
cash_recovery_display_json.reference_total_krw=0(미산출).
|
|
올바른 원천 = trim_plan_to_min_cash_json.total_plan_krw(227,868,540).
|
|
|
|
# ─────────────────────────────────────────────────────────
|
|
# 종목별 지표 (per_ticker: true)
|
|
# harness_context에서 list를 ticker 키로 인덱싱한 딕셔너리로 변환
|
|
# ─────────────────────────────────────────────────────────
|
|
per_ticker_metrics:
|
|
|
|
scrs_immediate_qty:
|
|
description: SCRS-V2 즉시 매도 수량(주)
|
|
canonical_source: scrs_v2_json.selected_combo[ticker].immediate_qty
|
|
alias_in_data: immediate_qty
|
|
wrong_alias_in_renderer: immediate_sell_qty
|
|
consumers:
|
|
- scrs_v2_sell_table
|
|
notes: >
|
|
렌더러가 immediate_sell_qty를 찾지만 데이터에는 immediate_qty가 있음.
|
|
AGENTS.md 5b: "immediate_sell_qty는 '-' 출력 금지 (키 불일치)" 명시 위반.
|
|
|
|
scrs_rebound_qty:
|
|
description: SCRS-V2 반등 대기 수량(주)
|
|
canonical_source: scrs_v2_json.selected_combo[ticker].rebound_wait_qty
|
|
alias_in_data: rebound_wait_qty
|
|
consumers:
|
|
- scrs_v2_sell_table
|
|
|
|
ticker_profit_pct:
|
|
description: 종목별 미실현 손익률(%)
|
|
canonical_source: prices_json[ticker].profit_pct
|
|
alias_in_renderer_wrong: unrealized_pnl_pct
|
|
alias_in_renderer_correct: profit_pct
|
|
consumers:
|
|
- profit_preservation_table
|
|
notes: >
|
|
profit_preservation_json[].unrealized_pnl_pct=None.
|
|
올바른 원천 = prices_json[].profit_pct.
|
|
|
|
ticker_stop_price:
|
|
description: 종목별 손절가(원)
|
|
canonical_source: prices_json[ticker].stop_price
|
|
consumers:
|
|
- shadow_ledger_table
|
|
- profit_preservation_table
|
|
notes: shadow_ledger_json의 stop_loss_calc=None이므로 prices_json 직접 사용.
|
|
|
|
ticker_limit_price:
|
|
description: 종목별 산출 지정가(원) — 차단 종목 포함 전체 표시(H10)
|
|
canonical_source: proposal_reference_json[ticker].proposed_limit_price_krw
|
|
fallback_sources:
|
|
- prices_json[ticker].stop_price
|
|
consumers:
|
|
- shadow_ledger_table
|
|
notes: >
|
|
AGENTS.md H10: 차단 종목도 산출 지표 은폐 금지.
|
|
proposal_reference_json에 proposed_limit_price_krw가 있으면 사용,
|
|
없으면 prices_json.stop_price를 참고방어가로 표시.
|
|
|
|
ticker_base_qty:
|
|
description: 종목별 기준 매도 수량(주)
|
|
canonical_source: sell_quantities_json[ticker].sell_qty
|
|
fallback_sources:
|
|
- comprehensive_proposal_json[ticker].quantity
|
|
consumers:
|
|
- shadow_ledger_table
|
|
notes: >
|
|
shadow_ledger_json의 base_qty_calc=None.
|
|
sell_quantities_json[].sell_qty 또는 comprehensive_proposal_json[].quantity 사용.
|
|
|
|
ticker_tp1_price:
|
|
description: 종목별 1차 익절가(원)
|
|
canonical_source: prices_json[ticker].tp1_price
|
|
consumers:
|
|
- shadow_ledger_table
|
|
|
|
# ─────────────────────────────────────────────────────────
|
|
# v11 추가 지표 — 12개 모순 해소 (SINGLE_TRUTH_LEDGER_V3)
|
|
# P0-1: 보고서 섹션별 재계산 금지 — ledger 조회만 허용
|
|
# ─────────────────────────────────────────────────────────
|
|
v11_contradiction_metrics:
|
|
|
|
value_damage_pct:
|
|
description: 현금확보 매도의 가치훼손율(%) — raw 기준
|
|
canonical_source: smart_cash_recovery_v8.json.raw_value_damage_pct_avg
|
|
fallback_sources:
|
|
- smart_cash_recovery_v7.json.raw_value_damage_pct_avg
|
|
- smart_cash_recovery_v9.json.raw_value_damage_pct_avg
|
|
tolerance_abs: 0.1
|
|
unit: percent
|
|
contradiction_sites:
|
|
- {section: final_execution_decision, wrong_value: 0.0, correct_value: 15.7}
|
|
- {section: cash_recovery_plan_crdl, wrong_value: 0.0, correct_value: 15.7}
|
|
notes: "raw=15.7%가 canonical. adjusted=0.0 단독 표기는 RAW_VS_ADJUSTED_DISCLOSURE_V1 위반."
|
|
|
|
performance_readiness_score:
|
|
description: 성과 준비도 점수(0~100)
|
|
canonical_source: operational_truth_score_v1.json.performance_readiness_score
|
|
tolerance_abs: 0.1
|
|
unit: score
|
|
contradiction_sites:
|
|
- {section: operational_truth_score_section, value: 37.2}
|
|
- {section: performance_monitoring_dashboard, value: 50.0, note: "50은 비활성 기본값 — canonical 37.2 사용"}
|
|
|
|
operational_truth_score:
|
|
description: 운영 진실 점수(0~100)
|
|
canonical_source: operational_truth_score_v1.json.score_0_100
|
|
tolerance_abs: 0.1
|
|
unit: score
|
|
contradiction_sites:
|
|
- {section: operational_truth_score_section, value: 80.86}
|
|
- {section: performance_monitoring_dashboard, value: 89.12, note: "재계산값 — canonical 80.86 사용"}
|
|
|
|
short_horizon_pct:
|
|
description: 단기 호라이즌 비중(%)
|
|
canonical_source: horizon_classification_v1.json.allocation_pct.SHORT
|
|
tolerance_abs: 0.1
|
|
unit: percent
|
|
contradiction_sites:
|
|
- {section: horizon_allocation_lock_v1, value: 14.3}
|
|
- {section: performance_monitoring_dashboard, value: 71.4, note: "보유종목 SHORT비중과 전략노출 혼동"}
|
|
|
|
mid_horizon_pct:
|
|
description: 중기 호라이즌 비중(%)
|
|
canonical_source: horizon_classification_v1.json.allocation_pct.MID
|
|
tolerance_abs: 0.1
|
|
unit: percent
|
|
|
|
horizon_cap_short_pct:
|
|
description: 단기 호라이즌 비중 상한(%)
|
|
canonical_source: horizon_allocation_guard_v2.json.short_cap
|
|
fallback_sources:
|
|
- spec/strategy/horizon_allocation_v1.yaml.rules.HA002.condition
|
|
tolerance_abs: 1.0
|
|
unit: percent
|
|
notes: "엔진 감사 short_cap=40%, horizon_routing_lock short_threshold=40%"
|
|
|
|
horizon_cap_mid_pct:
|
|
description: 중기 호라이즌 비중 상한(%)
|
|
canonical_source: horizon_allocation_guard_v2.json.mid_cap
|
|
tolerance_abs: 1.0
|
|
unit: percent
|
|
contradiction_sites:
|
|
- {section: horizon_allocation_lock_v1, value: 45}
|
|
- {section: engine_audit_routing, value: 50}
|
|
|
|
final_score:
|
|
description: 종합 전략 점수(0~100)
|
|
canonical_source: scores_harness_v1.json.final_score.value
|
|
tolerance_abs: 0.5
|
|
unit: score
|
|
contradiction_sites:
|
|
- {section: engine_audit_scores, value: 40.5}
|
|
- {section: performance_monitoring_dashboard, value: 45.3, note: "재계산값 — canonical 40.5 사용"}
|
|
|
|
t5_match_rate_pct:
|
|
description: T+5 예측 방향 일치율(%)
|
|
canonical_source: prediction_accuracy_harness_v5.json.prediction_match_rate_pct
|
|
fallback_sources:
|
|
- outcome_quality_score_v1.json.metrics.t5_operational_pass_rate
|
|
tolerance_abs: 0.5
|
|
unit: percent
|
|
contradiction_sites:
|
|
- {section: outcome_eval_window_monitor, value: 35.69, note: "전체 이력 기준"}
|
|
- {section: performance_monitoring_dashboard, value: 73.24, note: "decisive 케이스만 — 혼용 금지"}
|
|
notes: "canonical = prediction_accuracy_harness_v5.prediction_match_rate_pct(47.28). 표본 정의 혼용 금지."
|
|
|
|
cash_immediately_raisable_krw:
|
|
description: 즉시 조달 가능 현금(원)
|
|
canonical_source: cash_recovery_optimizer_v4.json.cash_shortfall_min_krw
|
|
fallback_sources:
|
|
- smart_cash_recovery_v8.json.cash_recovered_krw
|
|
tolerance_abs: 0
|
|
unit: krw
|
|
contradiction_sites:
|
|
- {section: cash_recovery_plan_crdl, value: 57841575}
|
|
- {section: engine_audit_sell_classification, value: 59399085}
|
|
|
|
cash_shortfall_target_krw:
|
|
description: 현금 목표 부족액(원)
|
|
canonical_source: cash_recovery_optimizer_v4.json.cash_shortfall_min_krw
|
|
fallback_sources:
|
|
- operational_truth_score_v1.json.cash_shortfall_min_krw
|
|
tolerance_abs: 0
|
|
unit: krw
|
|
contradiction_sites:
|
|
- {section: executive_brief, value: 38671178}
|
|
- {section: single_conclusion, value: 47769737}
|
|
|
|
confidence_cap:
|
|
description: 신뢰도 캡(0~100) — honest 기준
|
|
canonical_source: imputed_data_exposure_gate_v2.json.effective_confidence_honest
|
|
tolerance_abs: 0.1
|
|
unit: score
|
|
contradiction_sites:
|
|
- {section: investment_quality_headline, value: 93.0, note: "schema_presence 기반 — 거짓"}
|
|
- {section: engine_audit_imputed_exposure_honest, value: 88.4, note: "honest 기반 — canonical"}
|
|
notes: "88.4가 canonical. 93.0은 schema_presence 기반 거짓 캡이므로 폐기."
|
|
|
|
position_weight_pct:
|
|
description: 종목별 포트폴리오 비중(%)
|
|
canonical_source: portfolio_exposure_v1.json[ticker].weight_pct
|
|
fallback_sources:
|
|
- prices_json[ticker].position_weight_pct
|
|
per_ticker: true
|
|
tolerance_abs: 0.1
|
|
unit: percent
|
|
contradiction_sites:
|
|
- {section: portfolio_risk_panel, samsung: 44.5}
|
|
- {section: ejce, samsung: 44.35}
|
|
- {section: executive, samsung: 45.5}
|
|
|
|
unrealized_return_pct:
|
|
description: 종목별 미실현 수익률(%)
|
|
canonical_source: prices_json[ticker].profit_pct
|
|
per_ticker: true
|
|
tolerance_abs: 0.1
|
|
unit: percent
|
|
contradiction_sites:
|
|
- {section: position_dashboard, samsung: 98.0}
|
|
- {section: profit_preservation_table, samsung: 96.44}
|
|
- {section: decision_trace, samsung: 96.4}
|
|
|
|
# ─────────────────────────────────────────────────────────
|
|
# 예측 성과 지표 (평가창 정직성 — EVALUATION_WINDOW_HONESTY_V1)
|
|
# RC5 수정: proxy를 T+20으로 인용하는 평가창 위조 차단
|
|
# ─────────────────────────────────────────────────────────
|
|
evaluation_window_metrics:
|
|
|
|
t20_pass_rate:
|
|
description: T+20 벤치마크 초과수익률 달성 비율(%)
|
|
canonical_source: outcome_quality_score_v1.json.metrics.t20_effective_rate
|
|
formula_id: EVALUATION_WINDOW_HONESTY_V1
|
|
proxy_detection:
|
|
source_field: outcome_quality_score_v1.json.metrics.t20_source
|
|
proxy_value: t5_operational_proxy
|
|
proxy_flag_field: t20_is_proxy
|
|
enforcement:
|
|
- "t20_source != operational_t20 이면 지표명을 'T+20(추정,프록시)'로 강제 라벨링"
|
|
- "T20_PROXY=true 인 동안 t20_pass_rate를 release_gate t20_alpha 합격 근거로 사용 금지"
|
|
current_state:
|
|
t20_source: t5_operational_proxy
|
|
t20_is_proxy: true
|
|
t20_effective_rate: 40.92
|
|
label: "T+20(추정,프록시)"
|
|
proxy_note: "[T20_PROXY: 실측 T+20 표본 0건 — t5_operational_proxy 사용 중]"
|
|
consumers:
|
|
- release_gate_t20_alpha
|
|
- operational_report.summary.t20_is_proxy
|
|
tolerance_abs: 0.1
|
|
unit: percent
|
|
notes: >
|
|
t20_source=t5_operational_proxy이므로 보고서에서 T+20으로 인용 금지.
|
|
실측 T+20 표본 30건 누적 후 t20_source=operational_t20으로 전환.
|
|
전환 전까지 release_gate t20_alpha(55%) 판단에 이 값 사용 불가.
|
|
|
|
prediction_match_rate:
|
|
description: 예측 방향 일치율(%) — T+5 기준
|
|
canonical_source: prediction_accuracy_harness_v5.json.prediction_match_rate_pct
|
|
fallback_sources:
|
|
- algorithm_guidance_proof_v1.json.honest_components.prediction_match_rate
|
|
current_state:
|
|
value: 47.28
|
|
target: 58.0
|
|
gap: -10.72
|
|
label: "[UNVALIDATED_LIVE: n=0 live samples]"
|
|
consumers:
|
|
- release_gate_prediction_quality
|
|
unit: percent
|
|
|
|
# ─────────────────────────────────────────────────────────
|
|
# 교차섹션 정합성 검사 규칙
|
|
# ─────────────────────────────────────────────────────────
|
|
consistency_rules:
|
|
enforcement_mode_until: "2026-06-15"
|
|
warn_threshold_conflict_count: 1
|
|
fail_threshold_conflict_count: 1
|
|
forbidden_uniform_labels:
|
|
- "데이터 누락"
|
|
- "DATA_MISSING"
|
|
- "중립"
|
|
- "NEUTRAL"
|
|
- "LOSING"
|
|
- "정상"
|
|
forbidden_uniform_labels_whitelist_columns:
|
|
- "비고"
|
|
- "해제조건"
|