meta: title: "은퇴자산포트폴리오 — 포트폴리오 노출·현금 정책 분할 후보" parent_file: "RetirementAssetPortfolio.yaml" # 2026-06-22 WBS-7.11: spec/03_risk_policy.yaml 삭제로 갱신 version: "2026-05-18-F10_score_clamp_d2_fix" language: "ko-KR" timezone: "Asia/Seoul" role: "canonical" has_code_implementation: true code_path: ["spec/strategy/action_matrix.yaml"] migration_status: "canonical_split_active" authority_rule: "이 split 파일이 해당 섹션의 canonical source다. parent_file은 legacy compatibility index다." portfolio_exposure_framework: principle: "비중 한도는 파산확률 제어 장치. 시장지배 주도주는 벤치마크와 비교해 판단." exposure_layers: direct_core_leaders: ["삼성전자", "SK하이닉스"] duplicate_beta: ["KODEX 반도체", "동일 섹터 ETF"] tactical_satellites: ["방산", "조선", "전력설비", "건설", "플랜트/EPC", "로보틱스", "기타 고베타"] cash: ["현금", "MMF", "RP", "단기채 ETF"] valid_trim_reasons: - "벤치마크 대비 초과비중이 허용밴드를 초과하고 가격 추세가 훼손됨" - "직접보유와 ETF가 같은 팩터를 중복 보유해 실질노출이 상한 초과" - "포트폴리오 현금이 최소 방어현금 이하이고 신규 기회 또는 손실방어 자금이 필요" - "외국인·기관 5D/20D 수급 동반 이탈 + 거래대금 동반 장대음봉" sell_priority_engine: purpose: > 여러 보유 종목·ETF가 동시에 SELL/TRIM/ROTATE 후보가 되었을 때 어떤 주문을 먼저 실행할지 결정하는 포트폴리오 단위 우선순위 규칙. stop_loss.sell_signal_priority는 종목 내부 매도 신호 우선순위이고, 이 엔진은 계좌·현금·중복노출·상대약세를 종합한 후보 간 정렬 기준이다. activation_any: - "cash_floor.trim_required_when 충족" - "duplicate_exposure_rule 발동" - "동일 리포트에서 SELL/TRIM/ROTATE 후보가 2개 이상" - "risk_off 또는 event_week 현금 상향 필요" - "보유주 진단에서 축소/교체 후보가 2개 이상" required_inputs: - "capture_read_ledger.current_holding_quantity" - "average_cost" - "current_price" - "unrealized_return_pct" - "current_weight_pct" - "target_weight_pct 또는 target_band" - "duplicate_exposure_status" - "cash_floor_status" - "rw_partial 또는 relative_weakness_exit 합계" - "liquidity_status 또는 AvgTradeValue_5D_M" - "account_type" - "tax_cost_estimate 또는 세금 미확인 표시" hard_precedence: 1: "법적·거래정지·상장폐지·회계 리스크 또는 stop_loss.emergency — 수량 확인 시 최우선" 2: "hard stop 손절, trailing_stop 이탈, time_stop 만료, RW>=4 — stop_loss.sell_signal_priority 적용" 3: "cash_floor 미달 또는 policy_event_week_escalation 현금 상향 — 현금 확보 목적 매도 우선" 4: "중복노출 상한 초과 — duplicate_exposure_rule.funding_order 적용" 5: "보유주 진단 교체/축소 후보 — current_holdings_score 낮은 순" 6: "익절·리밸런싱 후보 — 세후 비용 대비 이탈폭 큰 순" 7: "단순 수익 실현 — 다른 우선순위가 없을 때만" candidate_scoring: purpose: "동일 hard_precedence 단계 안에서 후보를 정렬하는 보조 점수. 점수가 높을수록 먼저 매도." score_range: "0~100" clamp: "Sell_Priority_Score = min(max(formula_result, 0), 100)" clamp_rationale: > 컴포넌트 합산 시 이론상 최대 122점 초과 가능(예: hard_stop 50 + 중복ETF 20 + 상대약세 20 + ...). 100 초과 점수는 LLM 임의 가중치 개입 증거로 오인되므로 반드시 min(result, 100) clamp 적용. clamp 발동 시 출력에 "[CLAMP 발동: raw={raw_score} → 100]" 표기 필수. formula: > Sell_Priority_Score = min(max( hard_precedence_points + duplicate_exposure_points + cash_relief_points + weakness_points + overweight_points + liquidity_points - tax_penalty_points - core_quality_protection_points , 0), 100) components: hard_precedence_points: emergency_or_hard_stop: 50 cash_floor_trim_required: 40 duplicate_exposure_required: 30 holding_diagnosis_rotate_or_trim: 20 take_profit_rebalance: 10 duplicate_exposure_points: same_sector_etf: 20 lower_quality_duplicate: 15 no_duplicate: 0 cash_relief_points: expected_net_cash_pct_ge_3: 15 expected_net_cash_pct_1_to_3: 10 expected_net_cash_pct_lt_1: 3 weakness_points: rw_ge_4_or_rs_laggard: 35 # RS_RATIO_V1: rs_ratio < 0.80 (시장 대비 20%+ 약세) rw_3_or_momentum_decel: 25 rw_2: 8 flow_5d_20d_negative: 15 price_below_ma20_ma60: 10 weakness_formula_refs: # [2026-05-19_ALPHA_SHIELD_V1] X3 rs_laggard 공식 확정 rs_laggard: formula_id: "RS_RATIO_V1" definition: "rs_ratio = stock_5d_return / kospi_5d_return < 0.80" rs_leader_protection: "rs_ratio >= 1.20 -> sell_priority 후순위 보호" canonical_ref: "spec/13_formula_registry.yaml:formula_registry.formulas.RS_RATIO_V1" overweight_points: above_target_by_5p_or_more: 12 above_target_by_2_to_5p: 6 within_band: 0 liquidity_points: avg_trade_value_sufficient: 5 low_liquidity: -10 tax_penalty_points: high_tax_or_fee_drag: 10 unknown_tax_cost: 3 tax_loss_harvest_available: -5 core_quality_protection_points: direct_core_leader_in_valid_uptrend: 20 A_core_or_CSCs_ge_85: 12 satellite_or_etf: 0 tie_breakers: 1: "더 높은 hard_precedence 단계" 2: "Sell_Priority_Score 높은 후보" 3: "cash_floor 개선 효과가 큰 후보" 4: "중복노출 해소 효과가 큰 후보" 5: "current_holdings_score 낮은 후보" 6: "세후 비용이 낮은 후보" 7: "유동성이 충분해 지정가 체결 가능성이 높은 후보" account_priority: principle: "계좌별 세금·한도·출금 가능성을 고려하되, hard stop 손절을 세금 이유로 지연하지 않는다." taxable_account: "세금비용이 크면 동일 우선순위 내에서 후순위. 단, 손절·hard stop은 예외." isa: "비과세/분리과세 한도와 납입 여력 확인 후 리밸런싱 후보 우선 가능." pension: "장기 코어·해외ETF 성격은 보호. 위성·중복 ETF만 우선 축소." output_required: table: "sell_priority_decision_table" columns: ["우선순위", "계좌", "종목명", "현재보유수량", "매도가능검산", "매도유형", "우선순위단계", "Sell_Priority_Score", "예상순현금", "세금/비용", "execution_style", "immediate_sell_qty", "rebound_wait_qty", "max_daily_qty", "매도사유", "보류사유", "다음확인사항"] smart_cash_raise_execution: # [2026-05-20_APEX_V1] 현금확보 매도 품질 하네스 purpose: > 현금 부족 해소 목적의 매도를 단순 우선순위 정렬에서 끝내지 않고, 과매도 반등 대기·분산 위험 즉시 감축·수익보호 감축·체결 품질 제한까지 연결한다. formula_refs: cash_raise_plan: "spec/13b_harness_formulas.yaml:SMART_CASH_RAISE_PLAN_V1" rebound_trigger: "spec/13b_harness_formulas.yaml:REBOUND_SELL_TRIGGER_V1" sell_quantity_allocator: "spec/13b_harness_formulas.yaml:SELL_QUANTITY_ALLOCATOR_V1" execution_quality: "spec/13b_harness_formulas.yaml:EXECUTION_QUALITY_GUARD_V1" execution_styles: URGENT_LIQUIDITY_TRIM: trigger: "cash_floor_status=HARD_BLOCK AND rsi14>=35 AND bb_position>=20" rule: "sell_priority rank 순서대로 immediate_sell_qty 배정. 단일 종목 일괄 전량 금지." OVERSOLD_REBOUND_SELL: trigger: "rsi14<35 OR bb_position<20 OR close < ma20 - 8%" rule: "즉시 매도는 cap 이하. 잔여는 rebound_wait_qty로 분리하고 REBOUND_SELL_TRIGGER_V1 충족 시 실행." DISTRIBUTION_EXIT: trigger: "distribution_risk_score>=70" rule: "반등 대기보다 감축 우선. 단 시장가 전량 매도와 불리한 추격 정정 금지." PROFIT_PROTECT_TRIM: trigger: "profit_preservation_state IN [PROFIT_LOCK_20, PROFIT_LOCK_30]" rule: "수익 포지션 일부 이익잠금. secular_leader_gate_active=true이면 하네스 defer 상태 우선." quantity_policy: allocator: "SELL_QUANTITY_ALLOCATOR_V1" immediate_qty_cap_default_pct: 25 max_daily_qty_default_pct: 50 rebound_wait_required_when: "execution_style=OVERSOLD_REBOUND_SELL" prohibition: - "현금 부족을 이유로 과매도 후보를 전량 즉시 매도 금지" - "rebound_wait_qty를 LLM이 immediate_sell_qty로 이동 금지" - "execution_quality_status != PASS인 행을 HTS 주문표 PASS로 출력 금지" - "코어 주도주 직접보유는 tier 1~8 후보 소진 전 현금확보 1순위 금지" prohibition: - "보유수량 미확인 상태에서 Sell_Priority_Score가 높아도 매도수량 숫자 출력 금지" - "세금 최적화를 이유로 hard stop·cash_floor hard stop 매도를 지연 금지" - "주도주 직접보유를 중복 ETF보다 먼저 매도하려면 hard stop 또는 명확한 thesis 훼손 근거 필요" - "매도 우선순위를 산문으로만 설명하고 표를 생략 금지" - "sell_priority_decision_table 없이 복수 매도 후보 중 특정 종목 수량을 확정 금지" # ── 현재 시장 국면 주도 섹터 종목 TRIM 방어 규칙 ──────────────────────────── # 배경: REGIME_TRIM_50 등 현금 확보 목적 매도 시 sell_priority_engine을 거치지 않으면 # 시장 주도 섹터 직접보유 종목(SK하이닉스 등)이 잘못 1순위로 선택되는 오류 발생. regime_leading_sector_protection: rule: > 현재 market_regime_state가 LEADER_CONCENTRATION 또는 SECULAR_LEADER_RISK_ON이고 sector_flow Rotation_Rank 1~2위 섹터의 직접보유 종목은 현금 확보 목적 매도(REGIME_TRIM_50·cash_floor_raise)에서 sell_priority tier=9(마지막) 고정. override_conditions_all_required: - "해당 종목에 hard_stop(EXIT_100·TRAILING_STOP_BREACH) 발동" - "OR thesis 훼손 명시: 실적 하향·외국인+기관 20D 동반 순매도·MA20+MA60 동시 이탈" - "OR tier 1~8 후보가 모두 소진되어 남은 선택지가 없음" gas_check: > runSellPriority() 결과에서 해당 종목이 tier=9로 표시되는지 확인. tier=9가 아닌 상위 순위로 나타나면 calcSellPriorityScore_() 입력 데이터 오류. prohibition: - "현재 장 주도 섹터(반도체·AI전력 등) 직접보유를 '수익이 있어서' 이유로 1차 매도 선정 금지" - "ETF 중복노출(KODEX 반도체·TIGER AI전력기기) 미확인 상태에서 코어주도주 TRIM 금지" - "sell_priority_table 출력 전 '주도주를 먼저 팔자'는 판단 표현 금지" duplicate_exposure_rule: calculation: "반도체 실질노출 = 삼성전자 직접비중 + SK하이닉스 직접비중 + 반도체 ETF × ETF 반도체 순도" funding_order: ["①중복 섹터 ETF", "②20D 수급 이탈·20일선 하회 위성", "③동일 섹터 내 후순위", "④시장지배 코어 직접보유 (마지막)"] leader_quality_switch: # [proposal_86 / 2026-05-16] ETF→반도체 주도주 직접 전환 가속 purpose: > SECULAR_LEADER_RISK_ON 국면에서 반도체 ETF 성과가 직접 주도주 대비 열위일 때 ETF 비중을 감축하고 직접 주도주로 노출 품질을 높인다. etf_staged_reduction(proposal_58)과 병행 가능. 이 규칙이 우선 발동 트리거 역할. trigger_required_all: - "market_regime_state == SECULAR_LEADER_RISK_ON" - "same_sector_etf_weight_pct > 0 (반도체 ETF 보유 중)" - "삼성전자 OR SK하이닉스 중 1개 이상이 SECULAR_LEADER_RISK_ON 조건 통과" - "ETF Ret10D <= 직접 주도주(삼성전자 OR SK하이닉스) Ret10D - 3%p" action: step_1: "ETF 30~50% 감축 검토 (etf_staged_reduction.step_1과 동일 규칙 적용)" step_2: "감축 대금은 동일일 즉시 전량 투입 금지. 2거래일 이내 대기." step_3: "2거래일 이내 주도주 staged_entry_v2 stage_1 OR stage_2 조건 충족 시 전환 매수 실행" prohibition: - "ETF 매도대금으로 anti_climax_buy_gate 미통과 주도주 추격매수 금지" - "ETF 감축 후 semiconductor_total_cap 초과 직접매수 금지" - "SECULAR_LEADER_RISK_ON 비활성 시 이 규칙 적용 금지 — etf_staged_reduction만 사용" - "ETF 성과 비교 데이터 미확인 시 트리거 발동 금지" output_table: columns: - "ETF종목명" - "ETF_Ret10D(%)" - "직접주도주_Ret10D(%)" - "차이(%p)" - "감축검토수량" - "전환대상주도주" - "전환실행예정일" etf_staged_reduction: # [proposal_58 / 2026-05-15] ETF-개별주 중복 노출 단계적 감축 purpose: > ETF-개별주 중복 노출 발생 시 즉각 전량 청산이 아닌 단계적 감축으로 추세 지속 기회비용 손실과 중복 리스크를 동시에 관리한다. trigger: > duplicate_exposure_rule 발동 조건 충족: 동일 섹터 ETF + 개별주 동시 보유 비중이 총자산 대비 20%p 이상 step_1_immediate_reduction: action: "ETF 보유수량의 50% 즉시 매도 (지정가, 당일 장중)" rationale: "중복 노출 절반 즉시 해소. 개별주로의 집중 시작." order_type: "지정가 — 전일종가 -0.5% 이하 호가 우선. 시장가 금지." prohibition: - "패닉 시장가 전량 매도 금지" - "ETF를 매도하기 전 개별주 비중이 총자산 15% 미만인 경우 step_1 연기 가능" step_2_sector_trend_check: timing: "step_1 실행 후 2~5거래일 대기" conditions: continue_reduction: description: "잔여 50% 추가 매도 진행 조건" criteria: - "sector_flow.Rotation_Score 해당 섹터 순위가 3위 이하로 하락" - "주도섹터 ETF(대표지수) 대비 해당 ETF Ret10D <= -3%p" - "daily_leader_scan에서 해당 섹터 C5=0 (섹터 주도 상실)" action: "잔여 50% 매도. 섹터 ETF 포지션 완전 청산." hold_remainder: description: "잔여 50% 유지 조건" criteria: - "sector_flow.Rotation_Score 해당 섹터 순위 1~2위 유지" - "Ret10D_ETF >= 주도섹터ETF Ret10D -2%p 이내" - "daily_leader_scan에서 해당 섹터 C5=1 유지" action: > 잔여 50% 30거래일 추가 보유. 30거래일 후 step_2 재점검. 개별주 비중이 총자산 25% 이상 확대된 시점에 자동 매도 전환. step_3_full_exit_trigger: description: "단계 관계없이 즉시 전량 매도하는 비상 조건" conditions: - "해당 ETF ATR20_Status=DATA_MISSING AND 2거래일 이상 지속" - "섹터 crash_intraday_protocol tier_B 이상 발동" - "weekly_circuit_breaker.circuit_break 발동" - "portfolio_hard_stop_procedure 발동" action: "전량 지정가 분할 매도. 1거래일 내 완료." output_table: columns: - "ETF종목명" - "현재보유수량" - "1단계매도수량" - "잔여수량" - "섹터추세판정" - "2단계처리방향" - "완전청산예상일" prohibition: - "step_1 실행 없이 step_2로 바로 진행 금지 — 50% 우선 감축은 필수" - "ETF 매도 후 동일 섹터 다른 ETF 즉시 매수로 대체 금지 (중복 재발)" - "개별주 미확보 상태에서 ETF 전량 청산 금지 — 섹터 노출 완전 소멸 방지" target_allocation_structure: # [proposal_55 / 2026-05-15] 3-버킷 목표 운영 구조 purpose: > 포트폴리오 운영 목표 비중을 3개 버킷으로 명시. 실제 비중이 목표 밴드를 벗어나면 리밸런싱 신호 발생. 각 버킷은 기존 규칙(special_exception·cash_floor·sector_cap)에 우선하지 않는다. 목표 구조는 방향성 지침이며, 기존 risk_block이 항상 우선한다. buckets: core_bucket: label: "코어 (Core)" target_pct: 65 band: "60~72%" definition: > CSCS >= 70 종목 또는 special_exception 대상. 삼성전자·SK하이닉스·방산·조선 대장주·전력기기 주도주. 60거래일 이상 보유 목표. rebalancing_trigger: trim: "코어 합산 비중 > 72% → 초과분 부분 익절 검토 (take_profit.rebalancing_trim 준용)" add: "코어 합산 비중 < 60% AND orbit_state != unrealistic → A등급 코어 추가매수 검토" prohibition: - "코어 버킷 확대를 이유로 위성·현금 버킷 한도 이하로 압박 금지" tactical_satellite_bucket: label: "전술 위성 (Tactical Satellite)" target_pct: 20 band: "10~25%" definition: > CSCS < 70 종목. staged_entry_v2 탐색매수→확인매수→주력편입 대상. 평균 보유 목표 20~60거래일. 이 버킷이 수익률 엔진이다. 목표 구조 내에서 최대 25%까지 허용. rebalancing_trigger: trim: "위성 합산 비중 > 25% → relative_weakness_exit 점수 높은 종목부터 감축" add: "위성 합산 비중 < 10% AND daily_leader_scan 탐색 후보 존재 → 탐색매수 1건 검토" concentration_rule: "단일 위성 종목 최대 7% (stock_model.core_satellite_rule.max_weight 준수)" cash_fc_bucket: label: "현금 + 탐색 실패 허용 예산 (Cash + FC)" target_pct: 15 band: "10~22% (MRS 연동 가변)" definition: > 즉시 인출 가능 현금 + D+2 추정현금성자산. MRS 기반 목표현금(market_risk_score_based_cash) + FC 예산(explore_loss_budget) 합산. 강한 상승장(MRS=0): 하한 10%. 리스크 이벤트(MRS=8~10): 상한 22%. fc_reserve: formula: "FC_reserve = 총자산 × 0.025 (월 탐색 실패 허용 예산)" note: "FC_reserve는 현금 버킷 내 별도 슬롯. 탐색매수 손절 시 FC_reserve에서 차감." rebalancing_trigger: raise: "현금 < 10% OR MRS 기반 목표현금 > 현재 즉시현금 → 위성 부분 매도 또는 코어 익절" deploy: "현금 > 22% AND orbit_state=achievable → 탐색매수·확인매수 적극 집행" orbit_adjustment_rule: # [proposal_72 / 2026-05-15] orbit_monthly_tracker 오프셋 결과 하한 clamp purpose: "orbit_monthly_tracker의 cash_floor 하한 조정 오프셋이 현금 버킷을 10% 미만으로 밀어내는 것을 방지." clamp_rule: "최종 현금 목표 = max(orbit_adjusted_target, dynamic_cash_floor)" dynamic_cash_floor: # [proposal_85 / 2026-05-16] SECULAR_LEADER_RISK_ON 시 clamp 하한 7% secular_leader_risk_on: "7% — SECULAR_LEADER_RISK_ON 조건 전부 충족 시만 적용" normal: "10% — 기본값" event_week_or_overheated: "12~15%" risk_off: "15~25%" secular_leader_risk_on_required_all: - "market_regime_state == SECULAR_LEADER_RISK_ON" - "MRS <= 3" - "Total_Heat < 7%" secular_leader_risk_on_note: > normal.min_cash_ratio = 7%(cash_floor.regime_numbers.normal)와 동일한 수준. 즉 SECULAR_LEADER_RISK_ON에서도 기존 normal 하한(7%)을 벗어나지 않는다. 이 완화는 orbit_clamp 10%와 normal min 7% 사이의 3%p 공간을 해소하는 것. calculation_sequence: step_1: "orbit_monthly_tracker.adjustment_rules에 따라 orbit_offset(±%p) 계산" step_2: "MRS 기반 목표현금(market_risk_score_based_cash) + orbit_offset = orbit_adjusted_target" step_3: "SECULAR_LEADER_RISK_ON 조건 충족 시 dynamic_cash_floor = 7%, 미충족 시 10%" step_4: "orbit_adjusted_target < dynamic_cash_floor → dynamic_cash_floor로 강제 clamp" prohibition: - "D+2 추정현금성자산을 즉시현금 cash_floor 충족으로 간주 금지" - "SECULAR_LEADER_RISK_ON 해제 즉시 clamp 하한 10%로 복귀 (중간값 유지 금지)" note: "clamp 발동 시 블록 5(현금 룰 판정) 출력에 [CLAMP 발동: orbit_offset 일부 무시, floor=X%] 표기 필수." bucket_rebalancing_workflow: step_1: "매주 수요일 정기점검: 3개 버킷 현재 비중 산출" step_2: "MRS 산출 → cash_fc_bucket 목표 조정" step_3: "각 버킷 벗어남 확인 → 리밸런싱 우선순위 결정" step_4: "리밸런싱 방향: trim 우선(위험 낮추기) → add 이후(기회 포착)" priority: 1: "cash_fc_bucket.raise가 최우선 (risk_block 준수)" 2: "tactical_satellite_bucket.trim 두 번째" 3: "core_bucket 조정 마지막" output_table: columns: - "버킷" - "목표비중(%)" - "현재비중(%)" - "목표밴드" - "이탈여부" - "리밸런싱 방향" - "즉시실행 필요" prohibition: - "목표 구조를 이유로 master_prohibitions·cash_floor·risk_block 완화 금지" - "코어 65% 목표를 채우기 위해 위험 코어 종목을 무리하게 매수 금지" - "위성 20% 목표를 채우기 위해 anti_climax_buy_gate·minimalist_buy_gate 통과 없이 진입 금지" orbit_state_override_rule: # [proposal_70 / 2026-05-15] orbit_state가 target_allocation_structure add 트리거보다 항상 우선 purpose: "orbit_state_action_map이 target_allocation_structure의 add 트리거보다 항상 우선함을 명시." override_rule: unrealistic: condition: "orbit_state = unrealistic" action: "target_allocation_structure의 모든 add 트리거 무시. orbit_state_action_map.unrealistic 규칙(A등급 1건/월)이 최종 제한." stretch: condition: "orbit_state = stretch" action: "tactical_satellite_bucket.add 트리거 발동 시에도 orbit_state_action_map.stretch 기준(A등급만, 주 최대 3건) 내에서만 실행." achievable: condition: "orbit_state = achievable" action: "target_allocation_structure 버킷 트리거 정상 발동. override 없음." priority_order: "1": "orbit_state_action_map (최상위)" "2": "target_allocation_structure (하위 지침)" prohibition: - "orbit_state=unrealistic 상태에서 버킷 add 트리거만으로 신규 매수 집행 금지" - "orbit_state 확인 없이 버킷 트리거 실행 금지" # ── [2026-05-21_CLA_HARNESS_V1] 반도체 클러스터 상태 분리 ─────────────────── cluster_states: purpose: > CLA(CONCENTRATED_LEADER_ADVANCE) 레짐 발동 시 반도체 클러스터의 기존보유 유지(HOLD)와 신규추가매수(BUY)를 분리해 엔진의 '리더 팔고 위성 추가매수' 오판을 구조적으로 차단한다. CLUSTER_OPEN: description: "기본 상태 (CLA 레짐 비발동). 반도체 O2 섹터 기본 25% 상한 적용." trigger: "market_regime != CLA" new_buy_allowed: true cap_pct: 25 harness_field: cluster_state harness_value: "CLUSTER_OPEN" CLUSTER_HOLD_ONLY: description: > CLA 레짐 발동 시 클러스터 상태. 기존 보유분 HOLD는 허용. 신규 BUY는 RAG_V1=PASS AND cluster_combined_pct < CLUSTER_CAP_CLA_REGIME_PER 조건 모두 충족 시만 허용. O2 반도체 섹터 상한을 기본 25%에서 60%로 상향하여 유동성 보호. CLA 해제 시 기본 상한 복귀. (spec/calibration_registry.yaml:CLUSTER_CAP_CLA_REGIME_PER 참조) trigger: "market_regime == CLA" hold_allowed: true new_buy_conditions: - rag_v1: PASS - cluster_combined_pct_max: calibration_registry.CLUSTER_CAP_CLA_REGIME_PER new_buy_blocked_action: HOLD cap_pct: 60 harness_field: cluster_state harness_value: "CLUSTER_HOLD_ONLY" regime_based_o2_rule: rule: > O2 반도체 섹터 상한은 cluster_state=CLUSTER_OPEN 에서 기본 25%, SECULAR_LEADER_RISK_ON 에서 35%, cluster_state=CLUSTER_HOLD_ONLY 에서 60%까지 적용한다. cluster_state=CLUSTER_HOLD_ONLY 에서는 기존 보유분이 25% 초과해도 강제매도 없음. 신규 추가매수는 RAG_V1 통과 + 60% 상한 적용. original_o2: "spec/03_risk_policy.yaml:semiconductor_total_cap" cla_override: "CLA 발동 시 O2 적용 범위를 CLUSTER_OPEN 상태로 한정" prohibition: - "CLA 레짐에서 코어 반도체 직접보유를 현금확보 1순위로 선정 금지" - "cluster_state 필드 없이 반도체 종목 SELL 판단 금지" - "CLUSTER_HOLD_ONLY 상태를 LLM이 임의로 CLUSTER_OPEN으로 변경 금지" # ── [P0-1.1 / governance/todo/v8_9_p0_adoption_plan.yaml] v8.9 제안 신규 cap 필드 ── # 배경: v8.9 제안서(suggest/quant_investment_engine_v8_9...)는 단일종목·top3 cap을 제시했으나 # 기존 spec에는 이름 지정 예외(삼성전자/SK하이닉스 spec/05_position_sizing.yaml, # 반도체 클러스터 spec/10_portfolio_rules.yaml)만 있고 "이름 없는 일반 종목"의 # 기본 상한과 top3 합산 상한이 없었다. 기존 이름 지정 예외를 덮어쓰지 않고 # 비어있던 두 칸만 채운다. concentration_caps_v8_9_supplement: note: > 이 항목은 기존 regime/cluster_state 연동 cash_floor·반도체 cap을 대체하지 않는다. spec/05_position_sizing.yaml의 삼성전자(soft 45%/hard 48%)·SK하이닉스(soft 22%/hard 25%) named exception과 spec/risk/portfolio_exposure.yaml:target_allocation_structure. tactical_satellite_bucket.concentration_rule(단일 위성 7%)이 항상 우선한다. default_single_stock_cap_pct: applies_when: "named exception(삼성전자·SK하이닉스 등 spec/05_position_sizing.yaml) 또는 위성 7% 규칙이 없는 종목" soft_cap_pct: 15 hard_cap_pct: 20 over_cap_action: "no_additional_buy; evaluate partial_trim_or_core_ETF_transition_after_tax_cost" top3_combined_cap_pct: definition: "포트폴리오 내 비중 상위 3개 종목(직접보유, named exception 포함)의 합산 비중" soft_cap_pct: 50 hard_cap_pct: 65 over_cap_action: "no_additional_buy_increasing_concentration; transition_optimizer가 신규 매수 후보를 hard_constraint_fail로 거부" source_proposal: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml:portfolio_policy_v8_9.concentration_limits cash_floor: # ── 구조 수정: duplicate_exposure_rule 자식(4칸) → portfolio_exposure_framework 직속(2칸) (2026-05-14) normal: "총자산 7~10%" overheated_or_event_week: "총자산 10~15%" risk_off: "총자산 15~25%" rule: > cash_floor는 immediate_cash + eligible_settlement_cash_d2 (즉시현금 + D+2 정산예정현금)을 현금 방어선으로 준수하되, 계좌 범위와 제한을 엄격히 적용한다. 일반계좌의 D+2 현금은 cash_defense_eligible=true로 인정하며 일반계좌의 immediate_cash와 합산하여 방어선으로 취급한다. ISA/연금저축 계좌의 D+2 및 즉시현금은 일반계좌 신규매수 재원으로 합산하는 것을 금지한다. cash_shortfall 계산 로그에는 immediate_cash, settlement_cash_d2, restricted_cash를 명확히 분리 출력한다. settlement_rule: "일반계좌의 즉시현금 + D+2 정산현금을 유동성 방어선(cash_floor) 및 매수 가능 자금의 원장으로 인정한다." buying_power_rule: "매수가능현금 = (일반계좌 즉시현금 + D+2 정산현금) - 예약된 주문금액." numeric_definitions: settlement_cash_ratio: "D+2 정산현금 / 총자산 × 100" total_cash_ratio: "D+2 정산현금 / 총자산 × 100" buy_power_ratio: "(D+2 정산현금 - 예약된 주문금액) / 총자산 × 100" post_trade_total_cash_ratio: "(D+2 정산현금 - 신규매수예상금액 + 매도대금정산분) / 총자산 × 100" regime_numbers: normal: min_cash_ratio: 7 target_cash_ratio: 10 overheated_or_event_week: min_cash_ratio: 10 target_cash_ratio: 15 risk_off: min_cash_ratio: 15 target_cash_ratio: 25 rebalancing_formula: buy_allowed_when: "buy_power_ratio >= target_cash_ratio + rebalancing_buy_ratio AND post_trade_total_cash_ratio >= min_cash_ratio" trim_required_when: "post_trade_total_cash_ratio < min_cash_ratio OR buy_power_ratio < rebalancing_buy_ratio" policy_event_week_escalation: base_condition: "미중 정상회담·FOMC·CPI/PCE·고용·금통위·지정학 이벤트가 해당 주에 예정됨" raise_to_12pct_if_any: ["USD/KRW 1450원 초과", "VIX 18 초과", "KOSPI/KOSDAQ 장중 고점 대비 -2% 이상", "SOXX -4% 이상 하락", "외국인 KOSPI 일간 순매도 1조원 이상 또는 5D 누적 순매도"] raise_to_15pct_if_any: ["USD/KRW 1500원 돌파", "VIX 25 이상", "정책 이벤트 결과가 관세·희토류·반도체 규제·호르무즈 중 2개 이상 악화", "KOSPI 20일선 종가 이탈"] execution_priority: ["중복 ETF", "손실 중 약한 위성", "유동성 낮은 테마 ETF", "코어 직접보유"] required_output: ["현재 즉시현금비중", "D+2 추정현금성자산", "매수가능현금", "목표 즉시현금비중", "리밸런싱 후 최소 즉시현금비중", "추가 필요 현금", "매도 후보별 예상 순현금", "실행 후 즉시현금비중"] # ── [2026-05-18_ROUTING_OPTIMIZATION_V1] 팩터 과집중 수치 임계치 ───────────── # 배경: 포트폴리오.yaml 원칙에 "고베타·고모멘텀 과집중 차단"이 추가됐으나 # "얼마가 과한 것인가?"에 대한 수치 기준이 없어 AI가 주관적 판단에 의존.