schema_version: formula_domain.v1
source: C:\Temp\data_feed\spec\13_formula_registry.yaml
domain: execution
meta:
  note: >
    governance/todo/v8_9_p1_adoption_plan.yaml P1-B.
    source: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:execution_plan_compiler_v8_9
formulas:
  EXECUTION_CAPACITY_LADDER_V1:
    purpose: >
      계획된 주문금액이 종목의 실제 체결 가능 용량(20일 평균거래대금, 당일 거래대금, 호가창 깊이)을
      초과하지 않도록 결정론적으로 캡핑한다. broker_microstructure_packet이 없으면 주문 계획 자체를
      차단한다(v8.9 V89_019).
      (governance/todo/v8_9_p1_adoption_plan.yaml P1-B.1,
      source: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:execution_plan_compiler_v8_9.broker_microstructure_packet_required)
    applicable: PORTFOLIO_TRANSITION_UTILITY_V1에서 selected_transition 확정 후, 주문 분할(split_order_template) 직전.
    inputs:
    - field: planned_order_amount_krw
      unit: KRW
    - field: avg_trade_value_20d_krw
      unit: KRW
      source: 기존 avg_trade_value_5d(spec/12_field_dictionary.yaml)의 20일 윈도우 변형
    - field: intraday_trade_value_krw
      unit: KRW
    - field: orderbook_top3_depth_krw
      unit: KRW
    - field: spread_bps
      unit: basis_points
    - field: tick_size
      unit: KRW_per_share
      source: spec/formulas/domains/cash.yaml:tick_size_table
    - field: daily_price_limit
      unit: percent
    - field: halt_status
      unit: boolean
    expression: >
      order_capacity_krw = min(planned_order_amount_krw, avg_trade_value_20d_krw * 0.003,
      intraday_trade_value_krw * 0.01, orderbook_top3_depth_krw * 0.30)
    output:
      field: order_capacity_krw
      unit: KRW
    gates:
    - if: halt_status == true
      action: EXECUTION_PLAN_BLOCKED
      reason_code: trading_halt
    - if: avg_trade_value_20d_krw is null OR orderbook_top3_depth_krw is null OR spread_bps is null
      action: EXECUTION_PLAN_BLOCKED
      reason_code: broker_packet_missing
    - if: order_capacity_krw < planned_order_amount_krw
      action: ORDER_SIZE_CAPPED
      reason_code: capacity_too_low
    spread_widen_cancel_rule:
      condition: spread_bps > spread_bps_baseline * 1.5 (slice 체결 사이 측정)
      action: CANCEL_REMAINING_SLICES
      canonical_ref: suggest/quant_investment_engine_v8_9...:execution_plan_compiler_v8_9.cancel_remaining_if
    split_order_template:
      slice_1_pct: 30
      slice_2_pct: 30
      slice_3_pct: 40
      requires_revalidation_before_each_slice: true
      revalidation_fields: [cash_floor, deployable_cash, order_capacity_krw, spread_bps]
    missing_policy: broker_microstructure_packet 필드 중 하나라도 null이면 EXECUTION_PLAN_BLOCKED. 추정 금지.
    canonical_ref: spec/05_position_sizing.yaml
    implementation: tools/build_execution_capacity_ladder_v1.py
    owner: quant_team
    lifecycle_state: shadow
    input_fields:
    - planned_order_amount_krw
    - avg_trade_value_20d_krw
    - intraday_trade_value_krw
    - orderbook_top3_depth_krw
    - spread_bps
    - tick_size
    - daily_price_limit
    - halt_status
    output_fields:
    - order_capacity_krw
    golden_cases:
    - V89_019_broker_packet_missing
    - V89_020_capacity_too_low
    - V89_022_spread_widens
    activation_threshold:
      min_t20_sample: 30
    retirement_condition: performance_degradation
  EXECUTION_PLAN_COMPILER_V1:
    purpose: >
      EXECUTION_CAPACITY_LADDER_V1이 산출한 order_capacity_krw를 30/30/40 LIMIT_SPLIT 슬라이스로
      컴파일하고, 각 슬라이스 실행 직전 cash_floor·capacity·spread를 재검증한다.
      재검증 실패 또는 cancel_remaining_if 조건 충족 시 잔여 슬라이스를 취소한다.
      (governance/todo/v8_9_p2_adoption_plan.yaml P2-D,
      source: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:execution_plan_compiler_v8_9.split_order_template,
      execution_plan_compiler_v8_9.cancel_remaining_if)
    applicable: EXECUTION_CAPACITY_LADDER_V1.gate가 PASS 또는 ORDER_SIZE_CAPPED일 때만 호출.
    inputs:
    - field: order_capacity_krw
      unit: KRW
      source: spec/formulas/domains/execution.yaml:EXECUTION_CAPACITY_LADDER_V1
    - field: slice_index
      unit: 'enum: 1 | 2 | 3'
    - field: revalidation_snapshot
      unit: json
      note: 'slice 직전 시점의 {cash_floor_pct, deployable_cash_krw, order_capacity_krw, spread_bps}'
    - field: baseline_snapshot
      unit: json
      note: 컴파일 시점(slice 1 이전)의 동일 필드 스냅샷. spread_widen_cancel_rule 기준값.
    cancel_remaining_if:
    - captain_reverses_intraday
    - index_drop_exceeds_threshold
    - spread_widens_beyond_limit: "revalidation_snapshot.spread_bps > baseline_snapshot.spread_bps * 1.5"
    - cash_floor_after_fill_breached: "revalidation_snapshot.cash_floor_pct < required_cash_pct"
    - data_quarantine_after_slice
    - orderbook_capacity_collapses: "revalidation_snapshot.order_capacity_krw < baseline_snapshot.order_capacity_krw * 0.5"
    expression: >
      slice_amount_krw(1) = order_capacity_krw * 0.30
      slice_amount_krw(2) = order_capacity_krw * 0.30
      slice_amount_krw(3) = order_capacity_krw * 0.40
      각 슬라이스는 직전 슬라이스 체결 후 revalidation_snapshot을 재계산하고 cancel_remaining_if를
      평가한 뒤에만 진행한다. 어느 한 조건이라도 true이면 이후 슬라이스는 컴파일하지 않는다.
    output:
      field: compiled_slices
      unit: 'list_of_{slice_index, slice_amount_krw, status}'
    additional_outputs:
    - cancel_reason_code
    - slices_executed_count
    missing_policy: order_capacity_krw 또는 baseline_snapshot 결측 시 컴파일 자체를 EXECUTION_PLAN_BLOCKED.
    canonical_ref: spec/formulas/domains/execution.yaml:EXECUTION_CAPACITY_LADDER_V1
    implementation: tools/build_execution_plan_compiler_v1.py
    owner: quant_team
    lifecycle_state: shadow
    input_fields:
    - order_capacity_krw
    - slice_index
    - revalidation_snapshot
    - baseline_snapshot
    output_fields:
    - compiled_slices
    - cancel_reason_code
    golden_cases:
    - V89_021_partial_fill
    - V89_022_spread_widens
    - V89_023_gap_up_chase
    activation_threshold:
      min_t20_sample: 30
    retirement_condition: performance_degradation
