feat(quant-engine): v8.9 제안서 P0-P3 로드맵 채택 — 15개 의사결정 엔진 신규 구현
suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml의
implementation_todo_v8_9(P0~P4) 전체를 spec/tool/golden case 레벨로 구현.
- P0: PORTFOLIO_TRANSITION_UTILITY_V1, SELL_LOT_PARETO_SELECTOR_V1, FORECAST_SIMULATION_ENGINE_V1
- P1: SECTOR_EXPOSURE_GRAPH_V1/LEADER_LIFECYCLE_GATE_V1, EXECUTION_CAPACITY_LADDER_V1, MODEL_GOVERNANCE_KILL_SWITCH_V1
- P2: SCENARIO_SHOCK_MATRIX_V1, TRANSITION_SET_ENUMERATOR_V1, IMMUTABLE_DECISION_LEDGER_V1, EXECUTION_PLAN_COMPILER_V1
- P3: STATE_VECTOR_CONSTRUCTOR_V1, WALK_FORWARD_BOOTSTRAP_V1, TRANSITION_SET_ENUMERATOR_V1(MRC/CVaR 확장),
REBALANCE_CADENCE_GATE_V1, WEEKLY_LEGACY_TRANSFER_PLAN_V1
기존 regime/cluster 연동 정책 수치(현금방어선, 반도체 cap)는 그대로 유지하고 신규 cap 필드만 추가.
spec/09_decision_flow.yaml과 runtime/active_artifact_manifest.yaml에 전 엔진 배선 완료.
governance/todo/v8_9_p{0,1,2,3}_adoption_plan.yaml에 각 단계 작업 추적 기록.
검증: validate_specs/validate_golden_coverage_100(100%)/validate_calibration_registry_v1/
validate_schema_model_generation_v1/validate_agents_shrink_v1 전부 PASS. golden test 53/53 PASS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,254 @@ note: >
|
||||
|
||||
golden_cases:
|
||||
|
||||
# ── PORTFOLIO_TRANSITION_UTILITY_V1: v8.9 P0 채택 (governance/todo/v8_9_p0_adoption_plan.yaml) ──
|
||||
- formula_id: PORTFOLIO_TRANSITION_UTILITY_V1
|
||||
id: GV4_PTU_001
|
||||
name: V89_002 — 전환 입력 없음 (decision_packet 없음) → NO_TRADE 기본값
|
||||
input: {decision_packet: null, sell_waterfall: null}
|
||||
expected: {final_action: NO_TRADE, gate: NO_TRADE_AND_QUARANTINE}
|
||||
|
||||
- formula_id: PORTFOLIO_TRANSITION_UTILITY_V1
|
||||
id: GV4_PTU_002
|
||||
name: V89_048 — candidate 전부 hard_constraint_pass=false (solver_failure 등가) → NO_TRADE
|
||||
input: {candidates: [{hard_constraint_pass: false}]}
|
||||
expected: {final_action: NO_TRADE, selected_transition: null}
|
||||
|
||||
- formula_id: PORTFOLIO_TRANSITION_UTILITY_V1
|
||||
id: GV4_PTU_003
|
||||
name: V89_049 — utility 동률 후보 → 낮은 turnover 후보 선택
|
||||
input: {candidates: [{transition_utility_krw: 100000, turnover_pct: 5}, {transition_utility_krw: 100000, turnover_pct: 2}]}
|
||||
expected: {tie_breaker: lower_turnover}
|
||||
|
||||
- formula_id: PORTFOLIO_TRANSITION_UTILITY_V1
|
||||
id: GV4_PTU_004
|
||||
name: V89_050 — 충돌하는 runtime packet → BLOCK_AND_REQUIRE_MANIFEST_REPAIR
|
||||
input: {conflicting_packets: true}
|
||||
expected: {final_action: NO_TRADE, reason_code: BLOCK_AND_REQUIRE_MANIFEST_REPAIR}
|
||||
|
||||
# ── SELL_LOT_PARETO_SELECTOR_V1: v8.9 P0 채택 (governance/todo/v8_9_p0_adoption_plan.yaml) ──
|
||||
- formula_id: SELL_LOT_PARETO_SELECTOR_V1
|
||||
id: GV4_SLP_001
|
||||
name: V89_029 — deconcentration_trim 후보가 cash_repair 후보를 dominate
|
||||
input: {candidate_a: {avoided_tail_loss_krw: 100000, tax_fee_slippage_krw: 10000}, candidate_b: {avoided_tail_loss_krw: 50000, tax_fee_slippage_krw: 20000}}
|
||||
expected: {dominates: true, pareto_rank_a: 1}
|
||||
|
||||
- formula_id: SELL_LOT_PARETO_SELECTOR_V1
|
||||
id: GV4_SLP_002
|
||||
name: V89_030 — profit_lock 후보, missed_upside_penalty 미확인 시 0 보수적 하한 적용
|
||||
input: {missed_upside_penalty_krw: null}
|
||||
expected: {missed_upside_penalty_krw_used: 0.0, missing_fields_includes: missed_upside_penalty_krw}
|
||||
|
||||
- formula_id: SELL_LOT_PARETO_SELECTOR_V1
|
||||
id: GV4_SLP_003
|
||||
name: V89_031 — tax_drag_too_high, tax_fee_slippage가 benefit을 초과하면 score 음수
|
||||
input: {avoided_tail_loss_krw: 10000, tax_fee_slippage_krw: 50000}
|
||||
expected: {lot_sell_score_krw: -40000.0}
|
||||
|
||||
# ── FORECAST_SIMULATION_ENGINE_V1: v8.9 P0 채택 (governance/todo/v8_9_p0_adoption_plan.yaml) ──
|
||||
- formula_id: FORECAST_SIMULATION_ENGINE_V1
|
||||
id: GV4_FSE_001
|
||||
name: V89_013 — 분포 없음(missing_CVaR) → QUARANTINE 등가 WATCH_ONLY, null 출력
|
||||
input: {distribution: null, execution_mode: SHADOW}
|
||||
expected: {gate: WATCH_ONLY, cvar95_loss_krw: null, ce70_net_profit_krw: null}
|
||||
|
||||
- formula_id: FORECAST_SIMULATION_ENGINE_V1
|
||||
id: GV4_FSE_002
|
||||
name: V89_014 — same_regime 표본 SHADOW 기준(10건) 미달 → WATCH_ONLY
|
||||
input: {sample_count_total: 30, sample_count_same_regime: 5, execution_mode: SHADOW}
|
||||
expected: {gate: WATCH_ONLY}
|
||||
|
||||
# ── SECTOR_EXPOSURE_GRAPH_V1 / LEADER_LIFECYCLE_GATE_V1: v8.9 P1 채택 (governance/todo/v8_9_p1_adoption_plan.yaml) ──
|
||||
- formula_id: SECTOR_EXPOSURE_GRAPH_V1
|
||||
id: GV4_SEG_001
|
||||
name: V89_044 — sector_overlap, ETF lookthrough가 direct weight와 합산되어 cap 초과 감지
|
||||
input: {direct_weight_pct: 20.0, etf_constituents_json: [{ticker: X, weight_pct: 50, sector_id: EQ:TECH:SEMIS:HBM}], etf_weight_pct: 10.0, sector_id: EQ:TECH:SEMIS:HBM}
|
||||
expected: {sector_family_total_pct: 25.0, gate: PASS}
|
||||
|
||||
- formula_id: SECTOR_EXPOSURE_GRAPH_V1
|
||||
id: GV4_SEG_002
|
||||
name: V89_045 — ETF_direct_overlap, constituents 미확인 시 ETF_BUY_BLOCKED (0 추정 금지)
|
||||
input: {etf_constituents_json: null, etf_weight_pct: null}
|
||||
expected: {gate: ETF_BUY_BLOCKED, sector_family_total_pct: null}
|
||||
|
||||
- formula_id: LEADER_LIFECYCLE_GATE_V1
|
||||
id: GV4_LLG_001
|
||||
name: V89_046 — leader_distribution, CAPTAIN이 MA60 이탈+distribution이면 즉시 DISTRIBUTION_RISK
|
||||
input: {current_role: CAPTAIN, above_ma60_or_reclaim_confirmed: false, institutional_flow_status: distribution}
|
||||
expected: {leader_role: DISTRIBUTION_RISK, role_changed: true}
|
||||
|
||||
# ── EXECUTION_CAPACITY_LADDER_V1: v8.9 P1 채택 (governance/todo/v8_9_p1_adoption_plan.yaml) ──
|
||||
- formula_id: EXECUTION_CAPACITY_LADDER_V1
|
||||
id: GV4_ECL_001
|
||||
name: V89_019 — broker_packet_missing, 필드 결측 시 EXECUTION_PLAN_BLOCKED (capacity 0 추정 금지)
|
||||
input: {avg_trade_value_20d_krw: null, intraday_trade_value_krw: 500000000, orderbook_top3_depth_krw: 100000000, spread_bps: 5}
|
||||
expected: {gate: EXECUTION_PLAN_BLOCKED, order_capacity_krw: null}
|
||||
|
||||
- formula_id: EXECUTION_CAPACITY_LADDER_V1
|
||||
id: GV4_ECL_002
|
||||
name: V89_020 — capacity_too_low, 계획 주문금액이 용량보다 크면 ORDER_SIZE_CAPPED
|
||||
input: {planned_order_amount_krw: 50000000, avg_trade_value_20d_krw: 1000000000, intraday_trade_value_krw: 500000000, orderbook_top3_depth_krw: 100000000, spread_bps: 5}
|
||||
expected: {gate: ORDER_SIZE_CAPPED, order_capacity_krw: 3000000.0}
|
||||
|
||||
- formula_id: EXECUTION_CAPACITY_LADDER_V1
|
||||
id: GV4_ECL_003
|
||||
name: V89_022 — spread_widens, 기준 spread의 1.5배 초과 시 잔여 slice 취소
|
||||
input: {current_spread_bps: 16, baseline_spread_bps: 10}
|
||||
expected: {cancel_remaining: true}
|
||||
|
||||
# ── MODEL_GOVERNANCE_KILL_SWITCH_V1: v8.9 P1 채택 (governance/todo/v8_9_p1_adoption_plan.yaml) ──
|
||||
- formula_id: MODEL_GOVERNANCE_KILL_SWITCH_V1
|
||||
id: GV4_MGK_001
|
||||
name: V89_035 — T5 hit rate 50% 미달(30건 이상) → kill switch 발동, 1단계 강등
|
||||
input: {t5_hit_rate_pct: 40.0, t5_sample_count: 30, current_mode: PILOT}
|
||||
expected: {kill_switch_triggered: true, execution_mode: SHADOW}
|
||||
|
||||
- formula_id: MODEL_GOVERNANCE_KILL_SWITCH_V1
|
||||
id: GV4_MGK_002
|
||||
name: V89_036 — implementation_shortfall 기대치 2배 초과 → kill switch 발동
|
||||
input: {implementation_shortfall_ratio: 2.5}
|
||||
expected: {kill_switch_triggered: true, reason_code: implementation_shortfall_above_2x_expected}
|
||||
|
||||
- formula_id: MODEL_GOVERNANCE_KILL_SWITCH_V1
|
||||
id: GV4_MGK_003
|
||||
name: V89_037 — data_quarantine_rate 5% 초과 → kill switch 발동
|
||||
input: {data_quarantine_rate_pct: 7.0}
|
||||
expected: {kill_switch_triggered: true, reason_code: data_quarantine_rate_above_5pct}
|
||||
|
||||
# ── SCENARIO_SHOCK_MATRIX_V1: v8.9 P2 채택 (governance/todo/v8_9_p2_adoption_plan.yaml) ──
|
||||
- formula_id: SCENARIO_SHOCK_MATRIX_V1
|
||||
id: GV4_SSM_001
|
||||
name: V89_010 — candidate_good_portfolio_bad, crisis_case가 base_case보다 손실 확대
|
||||
input: {scenario_id: crisis_case, base_distribution_present: true}
|
||||
expected: {gate: PASS, crisis_worse_than_base: true}
|
||||
|
||||
- formula_id: SCENARIO_SHOCK_MATRIX_V1
|
||||
id: GV4_SSM_002
|
||||
name: 분포 없음 → 전체 시나리오 DATA_MISSING (가짜 분포 생성 금지)
|
||||
input: {distribution: null}
|
||||
expected: {gate: DATA_MISSING, scenario_ce70_krw: null}
|
||||
|
||||
# ── TRANSITION_SET_ENUMERATOR_V1: v8.9 P2 채택 (governance/todo/v8_9_p2_adoption_plan.yaml) ──
|
||||
- formula_id: TRANSITION_SET_ENUMERATOR_V1
|
||||
id: GV4_TSE_001
|
||||
name: V89_010 — 개별 PASS 후보 2개의 조합이 cash_floor를 위반하면 조합 거부, 단일 후보만 선택
|
||||
input: {candidates: [{id: A, cash_floor_delta: 1.0}, {id: B, cash_floor_delta: -2.0}]}
|
||||
expected: {selected_transition_set: [A], rejected_sets_count_gte: 1}
|
||||
|
||||
- formula_id: TRANSITION_SET_ENUMERATOR_V1
|
||||
id: GV4_TSE_002
|
||||
name: V89_048 — candidate_actions 없음 → NO_TRADE, 빈 조합 임의 생성 금지
|
||||
input: {candidate_actions: []}
|
||||
expected: {gate: NO_TRADE, selected_transition_set: []}
|
||||
|
||||
- formula_id: TRANSITION_SET_ENUMERATOR_V1
|
||||
id: GV4_TSE_003
|
||||
name: V89_049 — utility 동률 시 더 작은 조합(낮은 복잡도) 선택
|
||||
input: {set_a_utility: 100000, set_a_size: 1, set_b_utility: 100000, set_b_size: 2}
|
||||
expected: {selected: set_a}
|
||||
|
||||
# ── IMMUTABLE_DECISION_LEDGER_V1: v8.9 P2 채택 (governance/todo/v8_9_p2_adoption_plan.yaml) ──
|
||||
- formula_id: IMMUTABLE_DECISION_LEDGER_V1
|
||||
id: GV4_IDL_001
|
||||
name: V89_039 — operator_override 기록 필수, 신규 decision_id append 성공
|
||||
input: {decision_id: D1, engine_version: PORTFOLIO_TRANSITION_UTILITY_V1, input_hash_bundle: abc123, execution_mode: NO_TRADE, candidate_ids: [A]}
|
||||
expected: {ledger_append_status: APPENDED}
|
||||
|
||||
- formula_id: IMMUTABLE_DECISION_LEDGER_V1
|
||||
id: GV4_IDL_002
|
||||
name: 동일 decision_id 재기록 시도 → DUPLICATE_DECISION_ID (불변성 보장)
|
||||
input: {decision_id: D1, repeat: true}
|
||||
expected: {ledger_append_status: DUPLICATE_DECISION_ID}
|
||||
|
||||
- formula_id: IMMUTABLE_DECISION_LEDGER_V1
|
||||
id: GV4_IDL_003
|
||||
name: required_fields 결측 시 REJECTED_MISSING_FIELDS (빈값 채움 금지)
|
||||
input: {decision_id: null}
|
||||
expected: {ledger_append_status: REJECTED_MISSING_FIELDS}
|
||||
|
||||
# ── EXECUTION_PLAN_COMPILER_V1: v8.9 P2 채택 (governance/todo/v8_9_p2_adoption_plan.yaml) ──
|
||||
- formula_id: EXECUTION_PLAN_COMPILER_V1
|
||||
id: GV4_EPC_001
|
||||
name: V89_021 — partial_fill, slice 1 체결 후 정상 조건이면 slice 2/3도 컴파일
|
||||
input: {baseline_spread_bps: 10, revalidation_spread_bps: 10}
|
||||
expected: {all_slices_compiled: true}
|
||||
|
||||
- formula_id: EXECUTION_PLAN_COMPILER_V1
|
||||
id: GV4_EPC_002
|
||||
name: V89_022 — spread_widens, slice 2 직전 spread 1.5배 초과 시 잔여 slice 취소
|
||||
input: {baseline_spread_bps: 10, slice2_revalidation_spread_bps: 20}
|
||||
expected: {slice_1_status: COMPILED, slice_2_status: CANCELLED, slice_3_status: CANCELLED}
|
||||
|
||||
- formula_id: EXECUTION_PLAN_COMPILER_V1
|
||||
id: GV4_EPC_003
|
||||
name: V89_023 — gap_up_chase 등가, order_capacity_krw 결측 시 전체 EXECUTION_PLAN_BLOCKED
|
||||
input: {order_capacity_krw: null}
|
||||
expected: {gate: EXECUTION_PLAN_BLOCKED, compiled_slices: []}
|
||||
|
||||
# ── STATE_VECTOR_CONSTRUCTOR_V1: v8.9 P3 채택 (governance/todo/v8_9_p3_adoption_plan.yaml) ──
|
||||
- formula_id: STATE_VECTOR_CONSTRUCTOR_V1
|
||||
id: GV4_SVC_001
|
||||
name: V89_052 — goal_far_from_target, 모든 component 결측 시 completeness 0%, 보완 금지
|
||||
input: {cash_ladder: null, positions: null}
|
||||
expected: {state_vector_completeness_pct: 0.0, missing_components_count: 8}
|
||||
|
||||
- formula_id: STATE_VECTOR_CONSTRUCTOR_V1
|
||||
id: GV4_SVC_002
|
||||
name: 일부 component만 존재해도 결측 항목만 null로 기록(다른 값으로 보완 금지)
|
||||
input: {cash_ladder: present, positions: present, factor_exposures: null}
|
||||
expected: {missing_components_includes: factor_exposures}
|
||||
|
||||
# ── WALK_FORWARD_BOOTSTRAP_V1: v8.9 P3 채택 (governance/todo/v8_9_p3_adoption_plan.yaml) ──
|
||||
- formula_id: WALK_FORWARD_BOOTSTRAP_V1
|
||||
id: GV4_WFB_001
|
||||
name: V89_014 — same_regime_sample_low, 필터 결과 1건 이하 → DATA_MISSING (다른 레짐 대체 금지)
|
||||
input: {current_regime_state: NEVER_SEEN_REGIME, historical_returns_count: 30}
|
||||
expected: {gate: DATA_MISSING, net_profit_distribution_after_tax_fee_slippage: null}
|
||||
|
||||
- formula_id: WALK_FORWARD_BOOTSTRAP_V1
|
||||
id: GV4_WFB_002
|
||||
name: V89_048 — historical_returns 없음 → solver_failure 등가 DATA_MISSING
|
||||
input: {historical_returns: null}
|
||||
expected: {gate: DATA_MISSING, sample_count_total: 0}
|
||||
|
||||
# ── REBALANCE_CADENCE_GATE_V1: v8.9 P3 채택 (governance/todo/v8_9_p3_adoption_plan.yaml) ──
|
||||
- formula_id: REBALANCE_CADENCE_GATE_V1
|
||||
id: GV4_RCG_001
|
||||
name: V89_032 — no_trade_band, 토요일 점검은 의무 emit되나 utility 음수+hard block 없음 → NO_TRADE
|
||||
input: {check_date: 2026-06-20, transition_utility_after_tax_cost_krw: -5000, hard_risk_block_active: false}
|
||||
expected: {review_emitted: true, rebalance_execution_allowed: false}
|
||||
|
||||
- formula_id: REBALANCE_CADENCE_GATE_V1
|
||||
id: GV4_RCG_002
|
||||
name: V89_033 — hard_block_overrides_band, utility 음수여도 hard_risk_block_active=true면 실행 허용
|
||||
input: {check_date: 2026-06-20, transition_utility_after_tax_cost_krw: -5000, hard_risk_block_active: true}
|
||||
expected: {rebalance_execution_allowed: true}
|
||||
|
||||
- formula_id: REBALANCE_CADENCE_GATE_V1
|
||||
id: GV4_RCG_003
|
||||
name: V89_053 — weekly_rebalance_required, 토/일은 항상 cadence_check_required=true
|
||||
input: {check_date: 2026-06-20}
|
||||
expected: {cadence_check_required: true, cadence_trigger_reason: weekly_rebalance_required}
|
||||
|
||||
- formula_id: REBALANCE_CADENCE_GATE_V1
|
||||
id: GV4_RCG_004
|
||||
name: V89_054 — mid_check_required, 매월 1/11/21일은 cadence_check_required=true
|
||||
input: {check_date: 2026-06-11}
|
||||
expected: {cadence_check_required: true, cadence_trigger_reason: mid_check_required}
|
||||
|
||||
# ── WEEKLY_LEGACY_TRANSFER_PLAN_V1: v8.9 P3 채택 (governance/todo/v8_9_p3_adoption_plan.yaml) ──
|
||||
- formula_id: WEEKLY_LEGACY_TRANSFER_PLAN_V1
|
||||
id: GV4_WLT_001
|
||||
name: V89_005 — deployable_cash_negative, 입금 미확인 계획액은 deployable_cash에 0으로 기여
|
||||
input: {weekly_legacy_to_cma_transfer_plan_krw: 4000000, transfer_confirmed: false}
|
||||
expected: {deployable_cash_contribution_krw: 0.0, plan_status: PLANNED_NOT_DEPLOYABLE}
|
||||
|
||||
- formula_id: WEEKLY_LEGACY_TRANSFER_PLAN_V1
|
||||
id: GV4_WLT_002
|
||||
name: 입금 확인 시 확정액(계획액과 다를 수 있음)만 deployable_cash에 합산
|
||||
input: {weekly_legacy_to_cma_transfer_plan_krw: 4000000, transfer_confirmed: true, transfer_confirmed_amount_krw: 3800000}
|
||||
expected: {deployable_cash_contribution_krw: 3800000.0, plan_status: CONFIRMED_DEPLOYABLE}
|
||||
|
||||
# ── STOP_BREACH_V1: profit_pct < -20% 경계값 3 케이스 ─────────────────────
|
||||
- formula_id: STOP_BREACH_V1
|
||||
id: GV4_STOP_001
|
||||
|
||||
Reference in New Issue
Block a user