Files
QuantEngineByItz/spec/formulas/domains/simulation.yaml
T
kjh2064 aedabdd37b 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>
2026-06-18 00:06:52 +09:00

206 lines
10 KiB
YAML

schema_version: formula_domain.v1
source: C:\Temp\data_feed\spec\13_formula_registry.yaml
domain: simulation
meta:
note: >
governance/todo/v8_9_p0_adoption_plan.yaml P0-3.1.
source: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:forecast_and_simulation_engine_v8_9
배경: spec/29_backtest_harness_contract.yaml가 이미 "T+20 실현 표본 0건, walk_forward=insufficient_data"를
명시한다(AGENTS.md §6b). 이 도메인 파일은 분포를 날조하지 않고, 표본이 minimum_sample_rules를 충족할 때만
실제 bootstrap 계산 경로를 열고 미달이면 DATA_MISSING/WATCH_ONLY를 결정론적으로 반환하는 계약이다.
formulas:
FORECAST_SIMULATION_ENGINE_V1:
purpose: >
개별 종목의 점 추정 기대수익률이 아니라 레짐별 손익분포에서 CE70(30%분위)·CE90(10%분위)·
CVaR95(95% 신뢰구간 꼬리손실 평균)를 산출한다. 표본 부족 시 가짜 분포를 만들지 않고
WATCH_ONLY 또는 DATA_MISSING으로 정직하게 반환한다.
applicable: PORTFOLIO_TRANSITION_UTILITY_V1의 ce70_net_profit_krw 입력 직전.
inputs:
- field: net_profit_distribution_after_tax_fee_slippage
source: spec/29_backtest_harness_contract.yaml:current_metrics
unit: list_of_KRW
note: 세후·비용 차감 손익 표본. 현재 t20_op_rate.n_sample=0 (insufficient_data).
- field: sample_count_total
unit: count
- field: sample_count_same_regime
unit: count
- field: execution_mode
unit: enum
note: AUDIT_ONLY | SHADOW | PILOT | LIVE_LIMITED | LIVE_FULL
minimum_sample_rules:
AUDIT_ONLY:
sample_count_total_min: 0
sample_count_same_regime_min: 0
note: no minimum; report missing samples only (documentation only, no live order)
SHADOW:
sample_count_total_min: 30
sample_count_same_regime_min: 10
PILOT:
sample_count_total_min: 80
sample_count_same_regime_min: 20
LIVE_LIMITED:
sample_count_total_min: 150
sample_count_same_regime_min: 30
LIVE_FULL:
sample_count_total_min: 300
sample_count_same_regime_min: 50
agents_md_cross_check: "AGENTS.md §6b: Live T+20 표본 30건 미만이면 active/PASS_100 승격 금지"
gate_logic:
- if: sample_count_total < minimum_sample_rules[execution_mode].sample_count_total_min
action: WATCH_ONLY
output: "ce70_net_profit_krw=null, ce90_net_profit_krw=null, cvar95_loss_krw=null"
- if: sample_count_same_regime < minimum_sample_rules[execution_mode].sample_count_same_regime_min
action: WATCH_ONLY
output: "ce70_net_profit_krw=null, ce90_net_profit_krw=null, cvar95_loss_krw=null"
- if: sample_count_total >= minimum AND sample_count_same_regime >= minimum
action: COMPUTE
expression:
ce70_net_profit_krw: quantile(net_profit_distribution_after_tax_fee_slippage, 0.30)
ce90_net_profit_krw: quantile(net_profit_distribution_after_tax_fee_slippage, 0.10)
cvar95_loss_krw: mean(losses beyond 95th percentile loss threshold in net_profit_distribution_after_tax_fee_slippage)
estimator_allowlist:
- walk_forward_bootstrap
- regime_matched_bootstrap
forbidden_estimators:
- LLM_guess_return
- single_point_target_price_without_distribution
- backtest_without_cost_or_leakage_test
output:
field: ce70_net_profit_krw
unit: KRW_or_null
additional_outputs:
- ce90_net_profit_krw
- cvar95_loss_krw
- sample_count_total
- sample_count_same_regime
- gate
missing_policy:
net_profit_distribution_after_tax_fee_slippage: 표본 없으면 모든 출력 null + gate=WATCH_ONLY. 0으로 대체 금지.
canonical_ref: spec/29_backtest_harness_contract.yaml:current_metrics.walk_forward
implementation: tools/build_forecast_simulation_engine_v1.py
owner: quant_team
lifecycle_state: shadow
input_fields:
- net_profit_distribution_after_tax_fee_slippage
- sample_count_total
- sample_count_same_regime
- execution_mode
output_fields:
- ce70_net_profit_krw
- ce90_net_profit_krw
- cvar95_loss_krw
- sample_count_total
- sample_count_same_regime
- gate
golden_cases:
- V89_013_missing_CVaR
- V89_014_same_regime_sample_low
activation_threshold:
min_t20_sample: 30
retirement_condition: performance_degradation
SCENARIO_SHOCK_MATRIX_V1:
purpose: >
base_case 분포 하나만으로 위기 취약성을 가리지 않도록, FORECAST_SIMULATION_ENGINE_V1의
net_profit_distribution_after_tax_fee_slippage에 5개 스트레스 시나리오를 결정론적으로
적용해 각 시나리오별 CE70/CVaR95를 산출한다. 거짓 분포 생성을 금지하며, base distribution이
없으면 모든 시나리오가 DATA_MISSING이다.
(governance/todo/v8_9_p2_adoption_plan.yaml P2-A,
source: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:forecast_and_simulation_engine_v8_9.simulation_grid)
applicable: FORECAST_SIMULATION_ENGINE_V1의 gate=PASS(분포 산출 성공) 직후.
scenario_definitions:
base_case: {shock_multiplier: 1.0, note: current_regime_probability_weighted, source_distribution: as-is}
adverse_case: {shock_multiplier: 1.5, note: volatility_up_and_breadth_down — 손실 구간 증폭}
liquidity_drought_case: {shock_multiplier: 1.3, capacity_derate_pct: 40, note: spread_widening_and_capacity_down}
crisis_case: {shock_multiplier: 2.0, correlation_to_one: true, note: correlation_to_one_and_gap_down}
fx_shock_case: {shock_multiplier: 1.2, applies_only_to: foreign_assets, note: USDKRW adverse movement}
tax_cost_case: {shock_multiplier: 1.0, additional_cost_pct: 5, note: realized_gain_tax_and_reentry_cost_stress}
inputs:
- field: net_profit_distribution_after_tax_fee_slippage
unit: list_of_KRW
- field: scenario_id
unit: 'enum: base_case | adverse_case | liquidity_drought_case | crisis_case | fx_shock_case | tax_cost_case'
expression: >
shocked_distribution = [v * scenario.shock_multiplier if v < 0 else v / scenario.shock_multiplier
for v in net_profit_distribution_after_tax_fee_slippage] (손실만 증폭, 이익은 보수적으로 축소)
scenario_ce70_krw = quantile(shocked_distribution, 0.30)
scenario_cvar95_krw = mean(losses beyond 95th percentile loss threshold in shocked_distribution)
output:
field: scenario_results
unit: 'list_of_{scenario_id, scenario_ce70_krw, scenario_cvar95_krw}'
missing_policy: net_profit_distribution_after_tax_fee_slippage가 없으면 전체 scenario_results가 DATA_MISSING. 시나리오별로 임의 분포 생성 금지.
canonical_ref: spec/formulas/domains/simulation.yaml:FORECAST_SIMULATION_ENGINE_V1
implementation: tools/build_scenario_shock_matrix_v1.py
owner: quant_team
lifecycle_state: shadow
input_fields:
- net_profit_distribution_after_tax_fee_slippage
- scenario_id
output_fields:
- scenario_results
golden_cases:
- V89_010_candidate_good_portfolio_bad
activation_threshold:
min_t20_sample: 30
retirement_condition: performance_degradation
WALK_FORWARD_BOOTSTRAP_V1:
purpose: >
FORECAST_SIMULATION_ENGINE_V1이 입력으로 받는 net_profit_distribution_after_tax_fee_slippage를
실제 historical_returns 표본에서 walk-forward(시간순 비복원, in-sample/out-of-sample 분리) 및
regime-matched(현재 레짐과 동일한 구간만 필터) 리샘플링으로 생성한다. 가짜 분포 생성을 금지하며
historical_returns가 없거나 표본이 1건뿐이면 DATA_MISSING.
(governance/todo/v8_9_p3_adoption_plan.yaml P3-B,
source: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:forecast_and_simulation_engine_v8_9.allowed_estimators)
applicable: FORECAST_SIMULATION_ENGINE_V1 직전 — 이 엔진의 출력이 FORECAST_SIMULATION_ENGINE_V1의 입력이 된다.
inputs:
- field: historical_returns
unit: list_of_object
note: 'spec/29_backtest_harness_contract.yaml 연동. [{date, regime_state, net_return_after_cost_pct}]. 현재 t20 n_sample=0.'
- field: current_regime_state
unit: string
- field: bootstrap_method
unit: 'enum: walk_forward | regime_matched'
- field: resample_count
unit: count
default: 1000
note: 리샘플링 반복 횟수. historical_returns 표본이 적으면 resample_count와 무관하게 sample_count_total은 historical_returns 길이로 결정.
estimator_rule:
walk_forward: >
historical_returns를 시간순으로 정렬해 첫 70%를 in-sample, 나머지 30%를 out-of-sample로
고정 분리한다. out-of-sample 구간에서만 비복원 블록 리샘플링(block size=5)으로
net_profit_distribution을 생성한다. in-sample 재사용 금지(leakage 방지).
regime_matched: >
historical_returns 중 regime_state == current_regime_state인 행만 필터링 후
복원추출(bootstrap with replacement)로 net_profit_distribution을 생성한다.
필터 결과가 비어 있으면 DATA_MISSING(다른 레짐으로 대체 금지).
leakage_controls:
- asof_join_required
- future_constituent_exclusion
- calendar_alignment
output:
field: net_profit_distribution_after_tax_fee_slippage
unit: list_of_KRW_or_null
additional_outputs:
- sample_count_total
- sample_count_same_regime
- leakage_check_status
missing_policy: historical_returns 결측 또는 표본 1건 이하면 net_profit_distribution=null + gate=DATA_MISSING. 보간·추정 금지.
canonical_ref: spec/29_backtest_harness_contract.yaml:current_metrics.walk_forward
implementation: tools/build_walk_forward_bootstrap_v1.py
owner: quant_team
lifecycle_state: shadow
input_fields:
- historical_returns
- current_regime_state
- bootstrap_method
- resample_count
output_fields:
- net_profit_distribution_after_tax_fee_slippage
- sample_count_total
- sample_count_same_regime
golden_cases:
- V89_014_same_regime_sample_low
- V89_048_solver_failure
activation_threshold:
min_t20_sample: 30
retirement_condition: performance_degradation