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:
+115
-5
@@ -9,7 +9,7 @@ meta:
|
||||
각 상태는 통과 조건, 실패 시 행동, 참조 파일을 가진다.
|
||||
|
||||
decision_flow:
|
||||
initial_state: "INPUT_VALIDATION"
|
||||
initial_state: "MODEL_GOVERNANCE_GATE"
|
||||
terminal_states: ["FINAL_DECISION", "INSUFFICIENT_DATA", "BLOCKED"]
|
||||
deterministic_execution_control:
|
||||
purpose: "텍스트 해석 차이로 매번 다른 결론이 나오는 것을 줄이기 위한 결정 추적·동률 처리·first-match 규칙."
|
||||
@@ -37,6 +37,18 @@ decision_flow:
|
||||
null_propagation_rule: "필수 입력이 null이면 해당 계산은 null로 유지하고 prohibited_calculations에 사유를 남긴다. null을 0으로 대체 금지."
|
||||
output_requirement: "OUTPUT_VALIDATION에서 decision_trace 누락 시 schema_validation_status=FAIL."
|
||||
states:
|
||||
MODEL_GOVERNANCE_GATE: # [governance/todo/v8_9_p1_adoption_plan.yaml P1-5]
|
||||
purpose: >
|
||||
매 의사결정 사이클 시작 전 kill switch(data_quarantine_rate, implementation_shortfall,
|
||||
T5_hit_rate, calibration_error, drawdown)를 평가해 execution_mode를 확정한다.
|
||||
이후 모든 단계는 이 execution_mode를 기준으로 동작한다.
|
||||
required_refs:
|
||||
- "spec/formulas/domains/governance.yaml:MODEL_GOVERNANCE_KILL_SWITCH_V1"
|
||||
- "tools/build_model_governance_kill_switch_v1.py"
|
||||
required_inputs: ["data_quarantine_rate_pct", "implementation_shortfall_ratio", "t5_hit_rate_pct", "t5_sample_count", "calibration_error", "account_mdd_pct"]
|
||||
computed_outputs: ["execution_mode", "kill_switch_triggered", "kill_switch_reason_codes"]
|
||||
pass_condition: "execution_mode 확정(kill switch 평가 완료 또는 DATA_MISSING)"
|
||||
fail_state: "INSUFFICIENT_DATA"
|
||||
INPUT_VALIDATION:
|
||||
purpose: "요청, 기준일, 계좌, 보유수량, 가격/수급/ATR 입력 존재 여부 확인"
|
||||
required_refs:
|
||||
@@ -57,6 +69,20 @@ decision_flow:
|
||||
computed_outputs: ["data_completeness_matrix", "missing_fields", "field_unit_conflicts"]
|
||||
pass_condition: "data_completeness_matrix produced"
|
||||
fail_state: "INSUFFICIENT_DATA"
|
||||
STATE_VECTOR_CONSTRUCTION: # [governance/todo/v8_9_p3_adoption_plan.yaml P3-F]
|
||||
purpose: >
|
||||
holdings, cash, tax_lots, sector_graph, factor_exposures, macro_regime_probabilities를
|
||||
단일 state_vector로 통합한다. cash_ladder 구성 시 WEEKLY_LEGACY_TRANSFER_PLAN_V1을
|
||||
통해 미확정 레거시 이전계획을 deployable_cash에서 제외한다.
|
||||
required_refs:
|
||||
- "spec/formulas/domains/portfolio.yaml:STATE_VECTOR_CONSTRUCTOR_V1"
|
||||
- "spec/formulas/domains/cash.yaml:WEEKLY_LEGACY_TRANSFER_PLAN_V1"
|
||||
- "tools/build_state_vector_constructor_v1.py"
|
||||
- "tools/build_weekly_legacy_transfer_plan_v1.py"
|
||||
required_inputs: ["data_completeness_matrix", "account_snapshot"]
|
||||
computed_outputs: ["state_vector", "state_vector_completeness_pct", "missing_components", "deployable_cash_contribution_krw"]
|
||||
pass_condition: "state_vector 산출(결측 component 포함 가능)"
|
||||
fail_state: "INSUFFICIENT_DATA"
|
||||
HARD_FILTER_CHECK:
|
||||
purpose: "하드 필터를 점수보다 먼저 적용"
|
||||
required_refs:
|
||||
@@ -130,6 +156,18 @@ decision_flow:
|
||||
- "trim_assignments 없이 현금 부족 해소 주장 금지"
|
||||
- "QEH_AUDIT_BLOCK.SELL_PRIORITY_V1 행에 배정 결과 요약 필수"
|
||||
- "1순위 소진 전 2순위 배정 금지 (sell_priority_engine 순서 준수)"
|
||||
SECTOR_EXPOSURE_REVIEW: # [governance/todo/v8_9_p1_adoption_plan.yaml P1-5]
|
||||
purpose: >
|
||||
섹터를 canonical ID로 분류하고 ETF lookthrough·factor beta residualization을 적용해
|
||||
실질노출을 산출하며, 리더 생명주기(CAPTAIN~DISTRIBUTION_RISK)를 평가한다.
|
||||
required_refs:
|
||||
- "spec/formulas/domains/sector.yaml:SECTOR_EXPOSURE_GRAPH_V1"
|
||||
- "spec/formulas/domains/sector.yaml:LEADER_LIFECYCLE_GATE_V1"
|
||||
- "tools/build_sector_exposure_graph_v1.py"
|
||||
required_inputs: ["exposure_limit_amounts", "current_exposures", "etf_constituents_json"]
|
||||
computed_outputs: ["sector_family_total_pct", "lookthrough_etf_weight_pct", "leader_role"]
|
||||
pass_condition: "섹터 노출 산출 또는 ETF_BUY_BLOCKED/DATA_MISSING 명시"
|
||||
fail_state: "INSUFFICIENT_DATA"
|
||||
POSITION_SIZING:
|
||||
purpose: "ATR20·현금·목표비중·유동성으로 정수 수량 산출"
|
||||
required_refs:
|
||||
@@ -175,6 +213,44 @@ decision_flow:
|
||||
- "CRITICAL_ALERT 시 코어 포지션 포함 전면 재검토 강제"
|
||||
- "LLM이 레이더 결과를 완화하는 서사 출력 금지 (Section B 해설만 허용)"
|
||||
- "RADAR_MISSING(데이터 부족) 시 soft-block: 보유 포지션 수동 점검 권고 문구 출력"
|
||||
PORTFOLIO_TRANSITION_REVIEW: # [governance/todo/v8_9_p0_adoption_plan.yaml P0-1.6, v8_9_p2_adoption_plan.yaml P2-E]
|
||||
purpose: >
|
||||
개별 종목 단위 결정을 포트폴리오 전체 전환 효용으로 재평가한다.
|
||||
EXIT_POLICY_CHECK에서 나온 sell 후보들을 단일 전환 패킷으로 비교해
|
||||
selected_transition_set 또는 NO_TRADE를 결정론적으로 확정한다. CE70/CVaR95 분포는
|
||||
WALK_FORWARD_BOOTSTRAP_V1으로 생성하고 SCENARIO_SHOCK_MATRIX_V1의 5개 스트레스
|
||||
시나리오를 반영하며, candidate 1건이 아니라 TRANSITION_SET_ENUMERATOR_V1으로 조합 단위
|
||||
hard_constraint(MRC/CVaR95 포함)를 재검증한다. 실제 실행은 REBALANCE_CADENCE_GATE_V1의
|
||||
rebalance_execution_allowed=true일 때만 허용된다.
|
||||
required_refs:
|
||||
- "spec/formulas/domains/portfolio.yaml:PORTFOLIO_TRANSITION_UTILITY_V1"
|
||||
- "spec/formulas/domains/portfolio.yaml:TRANSITION_SET_ENUMERATOR_V1"
|
||||
- "spec/formulas/domains/portfolio.yaml:REBALANCE_CADENCE_GATE_V1"
|
||||
- "spec/formulas/domains/simulation.yaml:SCENARIO_SHOCK_MATRIX_V1"
|
||||
- "spec/formulas/domains/simulation.yaml:WALK_FORWARD_BOOTSTRAP_V1"
|
||||
- "tools/build_portfolio_transition_optimizer_v1.py"
|
||||
- "tools/build_transition_set_enumerator_v1.py"
|
||||
- "tools/build_scenario_shock_matrix_v1.py"
|
||||
- "tools/build_walk_forward_bootstrap_v1.py"
|
||||
- "tools/build_rebalance_cadence_gate_v1.py"
|
||||
required_inputs: ["stop_order", "take_profit_order", "sell_waterfall_rows", "cash_repair_benefit_krw", "rebalance_execution_allowed"]
|
||||
computed_outputs: ["transition_utility_krw", "acceptance_margin_krw", "selected_transition", "portfolio_transition_final_action", "selected_transition_set", "scenario_results", "post_trade_mrc", "post_trade_cvar95_krw"]
|
||||
pass_condition: "selected_transition_set 결정(rebalance_execution_allowed=true 필요) 또는 default_action=NO_TRADE 명시"
|
||||
fail_state: "INSUFFICIENT_DATA"
|
||||
EXECUTION_CAPACITY_CHECK: # [governance/todo/v8_9_p1_adoption_plan.yaml P1-5, v8_9_p2_adoption_plan.yaml P2-E]
|
||||
purpose: >
|
||||
selected_transition_set의 주문금액이 실제 체결 가능 용량(20일 평균거래대금, 당일 거래대금,
|
||||
호가창 깊이)을 초과하지 않는지 확인하고, broker_microstructure_packet 결측 시 차단한다.
|
||||
용량이 확인되면 EXECUTION_PLAN_COMPILER_V1으로 30/30/40 LIMIT_SPLIT 슬라이스를 컴파일한다.
|
||||
required_refs:
|
||||
- "spec/formulas/domains/execution.yaml:EXECUTION_CAPACITY_LADDER_V1"
|
||||
- "spec/formulas/domains/execution.yaml:EXECUTION_PLAN_COMPILER_V1"
|
||||
- "tools/build_execution_capacity_ladder_v1.py"
|
||||
- "tools/build_execution_plan_compiler_v1.py"
|
||||
required_inputs: ["selected_transition_set", "avg_trade_value_20d_krw", "intraday_trade_value_krw", "orderbook_top3_depth_krw", "spread_bps"]
|
||||
computed_outputs: ["order_capacity_krw", "execution_plan_status", "compiled_slices"]
|
||||
pass_condition: "order_capacity_krw 산출 또는 EXECUTION_PLAN_BLOCKED 명시"
|
||||
fail_state: "INSUFFICIENT_DATA"
|
||||
OUTPUT_VALIDATION:
|
||||
purpose: "JSON Schema와 HTS 표 필드 검증"
|
||||
required_refs:
|
||||
@@ -188,25 +264,38 @@ decision_flow:
|
||||
purpose: "BUY/HOLD/SELL/TRIM/ROTATE/AVOID/WATCH/INSUFFICIENT_DATA 중 하나로 결론"
|
||||
required_refs:
|
||||
- "spec/07_output_schema.yaml:recommendation_grade"
|
||||
- "spec/formulas/domains/governance.yaml:IMMUTABLE_DECISION_LEDGER_V1"
|
||||
output_required:
|
||||
- "final_action"
|
||||
- "grade"
|
||||
- "orders or prohibited_calculations"
|
||||
- "rules_used"
|
||||
- "ledger_append_status"
|
||||
post_state_action: "tools/build_immutable_decision_ledger_v1.py 호출 — decision_id 재기록 시도는 DUPLICATE_DECISION_ID로 거부."
|
||||
INSUFFICIENT_DATA:
|
||||
purpose: "데이터 부족으로 산출 불가. 다음 확인 출처를 제시."
|
||||
output_required:
|
||||
- "missing_fields"
|
||||
- "prohibited_calculations"
|
||||
- "next_source_to_check"
|
||||
- "ledger_append_status"
|
||||
post_state_action: "INSUFFICIENT_DATA로 종료해도 IMMUTABLE_DECISION_LEDGER_V1에 기록한다(결정 없음도 기록 대상)."
|
||||
BLOCKED:
|
||||
purpose: "하드 필터 또는 리스크 정책으로 행동 차단."
|
||||
output_required:
|
||||
- "triggered_rules"
|
||||
- "blocked_action"
|
||||
- "allowed_alternative"
|
||||
- "ledger_append_status"
|
||||
post_state_action: "BLOCKED로 종료해도 IMMUTABLE_DECISION_LEDGER_V1에 기록한다."
|
||||
|
||||
transitions:
|
||||
- from: "MODEL_GOVERNANCE_GATE"
|
||||
to: "INPUT_VALIDATION"
|
||||
condition: "execution_mode 확정(kill switch 평가 완료 또는 DATA_MISSING)"
|
||||
- from: "MODEL_GOVERNANCE_GATE"
|
||||
to: "INSUFFICIENT_DATA"
|
||||
condition: "kill switch 평가에 필요한 모든 지표가 결측"
|
||||
- from: "INPUT_VALIDATION"
|
||||
to: "DATA_COMPLETENESS_CHECK"
|
||||
condition: "minimum request context exists"
|
||||
@@ -214,11 +303,14 @@ transitions:
|
||||
to: "INSUFFICIENT_DATA"
|
||||
condition: "account/request context missing and cannot be inferred"
|
||||
- from: "DATA_COMPLETENESS_CHECK"
|
||||
to: "HARD_FILTER_CHECK"
|
||||
to: "STATE_VECTOR_CONSTRUCTION"
|
||||
condition: "data_completeness_matrix produced"
|
||||
- from: "DATA_COMPLETENESS_CHECK"
|
||||
to: "INSUFFICIENT_DATA"
|
||||
condition: "matrix cannot be produced"
|
||||
- from: "STATE_VECTOR_CONSTRUCTION"
|
||||
to: "HARD_FILTER_CHECK"
|
||||
condition: "state_vector 산출(결측 component 포함 가능)"
|
||||
- from: "HARD_FILTER_CHECK"
|
||||
to: "BLOCKED"
|
||||
condition: "blocking hard_filter failed"
|
||||
@@ -235,17 +327,35 @@ transitions:
|
||||
to: "BLOCKED"
|
||||
condition: "cash_floor, duplicate exposure, account limit, or Total_Heat blocks requested action"
|
||||
- from: "PORTFOLIO_CONSTRAINT_CHECK"
|
||||
to: "POSITION_SIZING"
|
||||
condition: "requested action requires quantity"
|
||||
to: "SECTOR_EXPOSURE_REVIEW"
|
||||
condition: "requested action requires quantity or affects sector exposure"
|
||||
- from: "PORTFOLIO_CONSTRAINT_CHECK"
|
||||
to: "EXIT_POLICY_CHECK"
|
||||
condition: "requested action is hold/trim/sell review"
|
||||
- from: "SECTOR_EXPOSURE_REVIEW"
|
||||
to: "POSITION_SIZING"
|
||||
condition: "섹터 노출 산출 또는 ETF_BUY_BLOCKED/DATA_MISSING 명시"
|
||||
- from: "SECTOR_EXPOSURE_REVIEW"
|
||||
to: "INSUFFICIENT_DATA"
|
||||
condition: "sector exposure 계산에 필요한 입력 누락"
|
||||
- from: "POSITION_SIZING"
|
||||
to: "EXIT_POLICY_CHECK"
|
||||
condition: "quantity calculated or NO_QUANTITY reason emitted"
|
||||
- from: "EXIT_POLICY_CHECK"
|
||||
to: "OUTPUT_VALIDATION"
|
||||
to: "PORTFOLIO_TRANSITION_REVIEW"
|
||||
condition: "order/hold/watch decision prepared"
|
||||
- from: "PORTFOLIO_TRANSITION_REVIEW"
|
||||
to: "EXECUTION_CAPACITY_CHECK"
|
||||
condition: "selected_transition 결정 또는 NO_TRADE 명시"
|
||||
- from: "PORTFOLIO_TRANSITION_REVIEW"
|
||||
to: "INSUFFICIENT_DATA"
|
||||
condition: "transition utility 계산에 필요한 입력 누락"
|
||||
- from: "EXECUTION_CAPACITY_CHECK"
|
||||
to: "OUTPUT_VALIDATION"
|
||||
condition: "order_capacity_krw 산출 또는 EXECUTION_PLAN_BLOCKED 명시 (NO_TRADE인 경우 즉시 통과)"
|
||||
- from: "EXECUTION_CAPACITY_CHECK"
|
||||
to: "INSUFFICIENT_DATA"
|
||||
condition: "broker_microstructure_packet 필드 누락"
|
||||
- from: "OUTPUT_VALIDATION"
|
||||
to: "FINAL_DECISION"
|
||||
condition: "schema and required output fields valid"
|
||||
|
||||
Reference in New Issue
Block a user