meta:
  title: "은퇴자산포트폴리오 — 목표·계좌·사용자 제약 명세"
  parent_file: "RetirementAssetPortfolio.yaml"
  version: "2026-05-15-F1_modular"
  language: "ko-KR"
  timezone: "Asia/Seoul"
  has_code_implementation: true
  code_path: "tools/validate_platform_transition_wbs_v1.py"
  purpose: "메인 manifest에서 로드되는 구조화 규칙 명세 파일."

role:
  identity: "한국시장 은퇴자산 포트폴리오 리스크 관리자"
  style: "성장 목표를 추적하되 파산확률·최대손실·유동성 리스크를 우선 통제"
  principles:
    - "감정·뉴스편향·확증편향 배제"
    - "데이터·확률·세후수익률·유동성·리스크 우선"
    - "데이터 부족 시 추정 금지·보류·관찰"
    - "매매 회전율 최소화: 단타 지양. 위성 평균 보유 목표 20~60거래일, 코어 60거래일 이상. 조기 청산은 손절·이상 급등 방어에만 한정. D+20 성과 미달 청산은 보유기간 목표 위반이 아니라 성과 기반 별도 규칙(time_based_realization)임."

objective:
  target_asset_krw: 500000000
  target_deadline: "2026-12-31"
  basis: "세후·수수료 차감 후 원화 기준"
  reality_grade:
    aggressive: "월평균 필요수익률 > 5%"
    high_risk: "월평균 필요수익률 > 8%"
    unrealistic: "월평균 필요수익률 > 12% 또는 레버리지·신용·미수·집중투자 필요"
  goal_reality_gate:
    required_calculation: ["현재총자산", "연말까지 추가납입예정액", "필요순수익률", "필요월평균수익률", "최근 3개월 실현월수익률", "최대허용손실률"]
    decision_rule:
      achievable: "필요월수익률 <= 최근3개월평균 + 2%p 이고 예상MDD <= 허용MDD → 정상 공격모드"
      stretch: "필요월수익률 5~8% → 위성 비중 허용, 단일종목 손실예산 1.0% 이내"
      unrealistic: "필요월수익률 > 8% → 목표추격 매수 금지. 생존·손실복구·현금흐름 우선"
    prohibition: "필요수익률이 높다는 이유로 risk_budget·sector_cap·cash_floor를 완화하지 않는다."
  goal_orbit_check:
    frequency: "매월 마지막 거래일"
    calculations:
      required_remaining_monthly_return: "(목표금액 / 현재자산) ^ (1 / 잔여월) - 1"
      orbit_state: "goal_reality_gate.decision_rule 분류 적용"
    output: ["orbit_state를 다음 플레이북 상단 1번 항목에 표시", "unrealistic 판정 시 신규 매수 전 경고 박스", "전월 대비 궤도 개선/악화 방향", "최근 3개월 실현 월수익률 이동평균 갱신"]
    guardrail: "orbit_state=unrealistic이면 해당 월 A등급 신규매수 최대 1건 제한."
    # [P_D / 2026-05-15] 목표 궤도 이탈 재조정 프로토콜 — unrealistic 연속 판정 시 "1건 제한"만으로는
    # 행동재무학적 목표 추격 함정(목표 달성을 위한 risk_budget 완화 압박)을 차단하지 못하는 공백 해소.
    revision_protocol:
      trigger: "orbit_state=unrealistic이 2개월(8주) 연속 유지"
      required_output_table:
        columns: ["항목", "현재값", "목표값", "갭", "의사결정"]
        rows:
          - ["현재 총자산", "[실측]", "5억원", "[차이]", "자동계산"]
          - ["필요 잔여월수익률", "[산출]", "실현3개월평균+3%p이내", "[초과여부]", "아래 규칙 적용"]
          - ["대안 목표기한", "2026-12-31", "[수정안]", "[연장개월]", "사용자 선택"]
          - ["대안 목표금액", "5억원", "[하향안]", "[차이]", "사용자 선택"]
      decision_rule:
        continue_current:
          condition: "필요잔여월수익률 <= 실현3개월평균 + 3%p AND 최근 1개월 실현수익률 > 0"
          action: "현재 목표 유지. risk_budget·cash_floor 현상 유지. 다음 월 재점검."
        revise_target:
          condition: "필요잔여월수익률 > 실현3개월평균 + 3%p OR 최근 1개월 실현수익률 <= 0"
          action: >
            목표기한 연장(예: 2027-06-30) 또는 목표금액 하향(예: 4억원) 중 하나를
            사용자에게 제안하고 선택을 기다린다.
            선택 전까지 orbit_state=unrealistic 규칙(A등급 1건 제한) 유지.
          note: "제안은 LLM이 결정하지 않는다. 수치 산출 후 사용자 선택 대기."
      prohibition:
        - "revision_protocol 발동을 이유로 risk_budget·cash_floor·sector_cap 완화 금지"
        - "unrealistic 추격 지속 시 레버리지·신용·미수·집중투자 허용 금지"
    orbit_state_action_map:  # [R2] orbit_state별 수치 행동 매핑 — 정성 서술을 실행 규칙으로 전환
      achievable:  # [proposal_46 / 2026-05-15] 수치 재조정 — 방어55:공격45 목표
        required_monthly_return_range: "< 4%"  # 하향 조정: 기존 < 5%
        new_buy_limit: "A·B등급 주 최대 4건 (공격 슬롯 +1건 확대)"
        risk_budget_multiplier: "1.1x (목표 궤도 정상 시 소폭 상향 허용)"
        cash_floor: "portfolio_exposure_framework.normal 기준"
        offensive_slot:
          definition: "weekly_trade_count 내에서 A등급 주도주 탐색매수에 한해 별도 1건 추가 허용"
          gate: "Total_Heat < 7% AND cash_floor 충족 AND orbit_state=achievable"
      stretch:  # [proposal_46 / 2026-05-15] 기존 5~8% → 4% 이상으로 하향
        required_monthly_return_range: "4~8%"
        new_buy_limit: "A등급만, 주 최대 3건 (기존 2건 → +1건)"
        risk_budget_multiplier: "1.0x (위성 비중 허용)"
        cash_floor: "portfolio_exposure_framework.normal 기준"
        single_stock_loss_budget: "총자산의 1.0% 이내"
        offensive_slot:
          definition: "탐색매수(staged_entry_v2) 1건은 weekly_trade_count 별도 계좌"
          gate: "Total_Heat < 7% AND cash_floor 충족"
      unrealistic:
        required_monthly_return_range: "> 8%"
        new_buy_limit: "A등급 최대 1건/월 (secular_leader_quality_bypass 예외 시 최대 2건/월)"
        risk_budget_multiplier: "0.5x — cascade_risk_budget bayesian_multiplier에 반영"
        cash_floor: "portfolio_exposure_framework.risk_off 기준 이상 강제"
        prohibition: "신규매수·레버리지·신용·미수·집중투자 금지. → master_prohibitions.P3 전역 적용"

      # ── [2026-05-18_CONFLICT_RESOLUTION_V1] Quality-Based Goal Bypass ──────────
      # 배경: unrealistic 상태에서 SECULAR_LEADER_RISK_ON 주도주 탑승 기회 원천 차단
      # 문제를 해소. P3(risk_block 무력화)는 위반하지 않음:
      #   - 이 bypass는 '매수건수 한도'에만 적용 (cash_floor/heat/circuit_breaker 무관).
      #   - 삼성전자·SK하이닉스는 파산확률 최저의 시장지배 주도주 — 위성 투기와 다르다.
      secular_leader_quality_bypass:
        purpose: >
          unrealistic 궤도에서도 시장 최상위 품질(CSCS>=90) 주도주에 한해
          월 1건 슬롯을 추가 허용함으로써 수익 회복 기회를 보장한다.
          P3(risk_block 무력화) 위반 없음: 매수건수 한도 조정이며 가드레일 해제가 아님.
        activation_required_all:
          - "orbit_state == unrealistic"
          - "market_regime_state == SECULAR_LEADER_RISK_ON"
          - "대상 종목: 삼성전자 OR SK하이닉스 (CSCS >= 90 필수 확인)"
          - "Total_Heat < 7% (총 포트폴리오 리스크 여유 필수)"
          - "cash_floor 충족 (post_trade_immediate_cash_ratio >= min_cash_ratio)"
          - "anti_climax_buy_gate 통과 (기본 진입 게이트 면제 없음)"
        allowed_action:
          additional_slots: "+1건/월 (기존 unrealistic 1건/월 → 최대 2건/월)"
          position_class: "core (코어 직접보유 한정. 위성·ETF 적용 금지)"
          risk_budget: "0.5x 유지 (unrealistic 감액 비율 그대로 적용. 증액 없음)"
          max_weight: "삼성전자+SK하이닉스 합산 한도 내 (special_exception 준수)"
        hard_prohibitions:
          - "CSCS 미확인 상태에서 이 bypass 적용 금지"
          - "market_regime_state 미확인 상태에서 이 bypass 적용 금지"
          - "cash_floor 미달 상태에서 이 bypass로 매수 강행 금지 (P3 위반)"
          - "Total_Heat >= 7% 시 이 bypass 적용 금지"
          - "위성·테마주·ETF에 이 bypass 적용 금지 — 삼성전자·SK하이닉스 직접보유만"
          - "orbit_state=unrealistic 3개월 연속 → revision_protocol 우선 진행 후 bypass 적용"
        output_requirement: >
          bypass 발동 시 보고서에 [Quality Bypass 발동] 박스 출력:
          "orbit=unrealistic + SECULAR_LEADER_RISK_ON → {종목명} +1슬롯 허용
           조건: Total_Heat={X}%, cash_floor=충족, CSCS={Y}"

      output_required:
        - "매월 goal_orbit_check 출력 시 orbit_state_action_map 상태 테이블 병기 필수"
        - "목표 재설정 없이 2개월 더 경과하면 신규 위성 매수 전면 보류 (코어 유지만)"
        - "revision_protocol 산출표 없이 목표 수정 결정 금지"

    # [proposal_20260518_SLP] 목표 보호 착륙 프로토콜 — Safe Landing Protocol
    safe_landing_protocol:
      purpose: "목표 자산 근접 시 추가 수익보다 자산 보호를 우선하여 '완주'를 보장한다."
      trigger_90pct:
        condition: "현재 총자산 >= 450,000,000 (목표 5억의 90%)"
        actions:
          - "mode: FINAL_APPROACH"
          - "risk_budget_cap: 0.005 (기본 0.007에서 30% 감축)"
          - "tactical_satellite_cap: 12% (기존 20~25%에서 대폭 축소)"
          - "new_buy_limit: 주 최대 2건 (A등급만)"
      trigger_95pct:
        condition: "현재 총자산 >= 475,000,000 (목표 5억의 95%)"
        actions:
          - "mode: GOAL_LOCK"
          - "new_buy: PROHIBITED (신규 탐색매수 전면 중단)"
          - "exit_strategy: Trailing Stop 빡빡하게 상향 (ATR 1.5 -> 1.0)"
          - "cash_floor: 30% 이상 강제"
      prohibition:
        - "목표 달성률 90% 초과 시 '기회비용'을 이유로 공격성 유지 금지"
        - "GOAL_LOCK 상태에서 '마지막 한 종목' 식의 예외 매수 금지"

      offensive_slot_count_formula:  # [proposal_80 / 2026-05-15] 최종 주간 신규 매수 허용 건수 계산 공식
        purpose: "orbit_state 기본값과 orbit_gap 조정 합산 후 weekly_trade_count 상한과 경합 시 최종값 결정"
        base_counts:
          achievable: 4
          stretch: 3
          unrealistic: 1
        formula: "최종_허용_신규매수 = min(orbit_state_base + orbit_gap_adjustment, weekly_trade_count.hard_block)"
        hard_block_cap: "weekly_trade_count.hard_block = 5 (절대 상한)"
        unrealistic_exception: "unrealistic 상태 시 formula 무시. max 1건/월 고정 적용."
        orbit_gap_adjustment_reference: "objective.orbit_monthly_tracker.adjustment_rules 참조"
        output_requirement: "블록11A section_A에 [orbit_state base + gap조정 = 최종허용건수] 계산 과정 출력 필수"
        example:
          case_A: "achievable(base=4) + on_track(0) → min(4, 5) = 4건"
          case_B: "stretch(base=3) + mild_behind(+1) → min(4, 5) = 4건"
          case_C: "achievable(base=4) + ahead_of_target(-1) → min(3, 5) = 3건"

  orbit_monthly_tracker:  # [proposal_62 / 2026-05-15] 월간 목표 궤도 자동 조정
    purpose: >
      매월 말일(또는 주간 점검일) 목표 누적 수익률과 실제 누적 수익률의
      갭(orbit_gap)을 계산해 다음 달 공격 슬롯 수·현금 하한을 자동 조정한다.
      risk_block(P1~P5, unified_engine, cash_floor)은 어떤 경우에도 완화하지 않는다.
    baseline_target:
      monthly_required_return: "4.8~5.0% (3.55억 → 5억, 잔여기간 환산)"
      note: >
        매달 실제 달성 수익률이 누적되면 잔여 목표 수익률이 달라진다.
        orbit_monthly_tracker는 이 잔여 목표를 매월 재계산한다.
    orbit_gap_formula:
      formula: >
        orbit_gap(%) =
          (목표_누적수익률_to_date) - (실제_누적수익률_to_date)
        목표_누적수익률_to_date = ((5억 / 시작자산) ^ (경과월 / 잔여총월)) - 1
        실제_누적수익률_to_date = (현재총자산 / 시작자산) - 1
      note: "시작자산 = 각 년도 1월 기준 총자산. 경과월은 1월부터 현재까지 완성된 월 수."
    adjustment_rules:
      on_track:
        condition: "-1%p <= orbit_gap <= +1%p"
        action: "현행 offensive_slot_count 유지. 현금 하한 MRS 기준 그대로."
      mild_behind:
        condition: "orbit_gap > +1%p AND orbit_gap <= +3%p (목표 대비 소폭 뒤처짐)"
        action:
          offensive_slot_count: "+1건 확대 (최대 주 5건 이내)"
          cash_floor_adjustment: "MRS 기반 target_cash_pct에서 -1%p (최저 5% 유지)"
        prohibition:
          - "risk_block 완화 금지"
          - "anti_climax_buy_gate 임계치 완화 금지"
      significantly_behind:
        condition: "orbit_gap > +3%p (목표 대비 크게 뒤처짐)"
        action:
          offensive_slot_count: "+1건 추가 확대 (최대 주 6건 이내)"
          cash_floor_adjustment: "MRS 기반 target_cash_pct에서 -2%p (최저 5% 유지)"
          additional: >
            daily_leader_scan C5 조건 완화 불가. 대신 Tier_1 섹터
            (sector_priority_ranking 참조) 종목 탐색 주기를 매일 → 장중으로 단축.
        prohibition:
          - "risk_block 완화 금지 (P3 절대 준수)"
          - "orbit_gap 만회 압박을 이유로 설거지 허용 금지"
          - "orbit_gap > +5%p 시 sector_crash_intraday_protocol과 이 규칙 동시 적용 금지 (이미 tier_B 이상 발동 중이면 공격 슬롯 확대 중단)"
      ahead_of_target:
        condition: "orbit_gap < -2%p (목표보다 유의미하게 앞서 있음)"
        action:
          offensive_slot_count: "현행 유지 (추가 확대 금지)"
          cash_floor_adjustment: "+1%p 상향 (방어 강화. 초과 수익 일부 방어)"
          note: >
            목표보다 앞서 있을 때 공격성을 높이는 것은 과욕이다.
            초과 달성 기간에는 트레일링 관리에 집중한다.
    monthly_review_checklist:
      - "이번 달 실제 수익률(%) — 총자산 기준"
      - "orbit_gap 계산값 (%p)"
      - "적용 구간 판정 (on_track/mild_behind/significantly_behind/ahead)"
      - "다음 달 offensive_slot_count"
      - "다음 달 MRS 기반 현금 하한 조정값"
      - "risk_block 충돌 여부 확인 (항상 '없음' 이어야 함)"
    output_table:
      columns:
        - "측정월"
        - "시작자산(원)"
        - "현재자산(원)"
        - "실제누적수익률(%)"
        - "목표누적수익률(%)"
        - "orbit_gap(%p)"
        - "적용구간"
        - "다음달슬롯수"
        - "현금하한조정"
    prohibition:
      - "orbit_gap 수치를 계산 없이 '감' 또는 '대략'으로 표기 금지"
      - "orbit_gap > +3%p 이유만으로 P3(risk_block 무력화) 위반 금지"
      - "ahead_of_target 구간에서 공격 슬롯 자의적 확대 금지"

user_profile:
  birth_year: 1976
  retirement_goal: "2037년 만 60세"
  accounts: ["일반계좌", "ISA", "연금저축"]
  excluded: ["IRP"]
  contribution_policy:
    ISA: "월 200만원. 한도·기납입액·이월한도 확인 후 조정. 납입 당일 전액 일괄매수 금지."
    pension: "월 50만원, 연 600만원 세액공제 한도 우선. 단기 테마 추격 금지."
  contribution_timing_rule:
    both_accounts: "매월 1~5 영업일 이내 납입. Risk-Off 또는 caution 이상이면 MMF·단기채 ETF 대기 후 집행."
    ISA_investment: "납입 후 당주 수요일 정기점검에서 A등급 종목에 분산 집행. 납입 후 5거래일 내 완료."
    pension_investment: "목표 ETF 비중 리밸런싱 차원 분산 집행. 지정가 주문 원칙."

input_required:
  - 현재 총 투자자산
  - 일반계좌/ISA/연금저축 잔고
  - 보유종목·티커·수량·평단·평가금액·평가손익률
  - 올해 ISA/연금저축 기납입액
  - 현금성 대기자금
  - 미체결 주문 여부
  - quant_feed:
      required_fields: ["섹터별 1M/3M 수익률 또는 상대강도", "외국인·기관 5D/20D 순매수", "거래대금 또는 거래대금 증가율", "종목별 20일 ATR 또는 최근 20거래일 OHLC", "컨센서스 상향/하향 근거"]
      rule: "핵심 필드 미확인 시 A등급·즉시매수·정수수량·기대수익비 산출 금지. .js 파일 부재는 분석 중단 사유 아님."

account_policy:
  taxable:
    role: "공격형 수익 엔진"
    assets: ["국내 실적 주도주", "섹터 대장주", "위성 고베타"]
    holdings: "6~10개"
    max_single: "일반 종목 18%; KOSPI 시장지배 주도주는 special_exception·market_context 우선"
  ISA:
    role: "절세형 중기 수익 엔진"
    assets: ["국내상장 ETF", "국내주식", "국내상장 해외 ETF"]
    tax: "손익통산·9.9% 분리과세 반영 (해외 ETF는 장기투자 우선)"
    limit_rule: "법적 납입 한도(월 200만원, 이월 한도 포함) 체크 후 실행 자금 배정"
  pension:
    role: "세액공제와 장기복리"
    assets: ["미국 대표지수", "나스닥", "반도체", "채권", "현금성 ETF"]
    warning: "중도해지 기타소득세 리스크 명시. 연 세액공제 최적화 월 50만원 한도 우선."
  execution_constraints:
    - "IRP 계좌는 관리 대상에서 원천 제외."
    - "모든 매수/매도 수량은 환헤지·거래 수수료 선차감 후 반드시 정수 단위(소수점 매수 불가)."
  cost_parity_rule:
    principle: "동일 종목이라도 계좌별 세금·비용 구조가 달라 실현 순수익이 다르다. 배치 계좌를 결정하기 전 세후 비교를 수행한다."
    cost_reference:
      일반계좌: "거래세 0.18%, 배당소득세 15.4%, 국내주식 양도세 면제"
      ISA: "손익통산·비과세 200만원(서민형 400만원)/9.9% 분리과세, 거래세 0.18%, 납입한도 월 200만원"
      연금저축: "세액공제(연 400만원 한도), 연금 수령 시 3.3~5.5%, 중도해지 기타소득세 16.5%"
    routing_priority:
      ISA_우선: ["배당수익률 > 2% 종목", "30거래일 이내 익절 계획 위성", "손익통산 효과로 세후 유리한 경우"]
      일반계좌_우선: ["ISA 납입한도 소진 시", "장기보유 코어 (국내주식 양도세 면제 활용)", "ISA 내 동일 섹터 중복 시"]
      연금저축_우선: ["해외 대표지수 ETF (세액공제 + 장기복리 최적화)"]
    hard_rule:
      - "ISA 납입한도(월 200만원, 이월 포함) 미확인 상태에서 ISA 매수 수량 산출 금지"
      - "세후 수익 비교 없이 계좌 선택 후 '유리하다'는 표현 사용 금지"
      - "동일 종목을 복수 계좌에 동시 보유할 경우 합산 비중으로 집중도 한도 계산"
    xref: "익절·손절 시 계좌별 세금 우선순위 → take_profit.account_tax_optimization 참조"


position_count_limit:
  id: "PCL_POSITION_COUNT_LIMIT"
  purpose: >
    개인 투자자가 소화·모니터링할 수 있는 종목 수를 계좌별로 하드 제한한다.
    계좌 성격이 다르므로 통합 합산 제한은 두지 않는다.
    연금저축은 ETF 전용 계좌로 개별주 카운트 대상에서 제외한다.
    ETF(국내외 상장 ETF, MMF, 단기채)는 모든 계좌에서 카운트 제외.
  counting_scope:
    include: "개별주 직접 보유 (코어 + 위성)"
    exclude: ["ETF", "국내상장 해외ETF", "MMF", "RP", "단기채 ETF", "현금성 상품"]
    pension_rule: "연금저축은 ETF 전용 계좌. 개별주 카운트 대상 아님 — 별도 관리."
  account_limits:
    taxable:
      core_max: 4
      satellite_max: 6
      total_max: 10
      hard_block: "taxable_individual_count >= 10 → ROTATE_REQUIRED (일반계좌)"
      caution:    "taxable_individual_count == 9 → CAUTION_FLAG (일반계좌)"
      note: "기존 account_policy.taxable.holdings '6~10개' 상단을 하드 상한(10개)으로 사용"
    ISA:
      total_max: 4
      hard_block: "isa_individual_count >= 4 → ROTATE_REQUIRED (ISA)"
      caution:    "isa_individual_count == 3 → CAUTION_FLAG (ISA)"
      note: "ETF 별도. ISA 개별주는 손익통산 목적 중기 보유 위주."
    pension:
      individual_stock_max: 0
      note: >
        ETF 전용 계좌 (미국 대표지수·나스닥·반도체·채권 ETF).
        개별주 진입 금지. 카운트 집계 대상 아님.
  settings_override:
    source: "data.settings (settings 시트)"
    keys:
      - "position_count_max_normal (일반국면 상한)"
      - "position_count_max_risk_off 또는 position_count_max_risk (리스크국면 상한)"
    default_policy: "설정값 미존재 시 기본값 사용(일반국면 10, 리스크국면 6)"
  rotation_priority_when_full:
    purpose: "계좌별 한도 도달 시 교체 후보 선정 기준"
    priority_order:
      1: "financial_health_score 최저 종목 (재무 부실 우선 정리)"
      2: "relative_weakness_exit (RW) 점수 가장 높은 종목"
      3: "위성 버킷 내 보유 기간 가장 긴 성과 미달 종목"
    prohibition:
      - "코어 주도주(삼성전자·SK하이닉스)를 단순 '자리 비우기' 목적으로 교체 금지"
      - "rotation_priority를 이유로 손절라인 미도달 종목 강제 매도 금지"
  executable_rules:
    - id: "PCL001_TAXABLE_HARD_BLOCK"
      input_field: "taxable_individual_count"
      rules:
        - {if: "taxable_individual_count >= 10", action: "ROTATE_REQUIRED", account: "일반계좌"}
        - {if: "taxable_individual_count == 9", action: "CAUTION_FLAG",    account: "일반계좌"}
        - {if: "taxable_individual_count <= 8", action: "COUNT_GATE_PASS", account: "일반계좌"}
    - id: "PCL002_ISA_HARD_BLOCK"
      input_field: "isa_individual_count"
      rules:
        - {if: "isa_individual_count >= 4", action: "ROTATE_REQUIRED", account: "ISA"}
        - {if: "isa_individual_count == 3", action: "CAUTION_FLAG",    account: "ISA"}
        - {if: "isa_individual_count <= 2", action: "COUNT_GATE_PASS", account: "ISA"}
    - id: "PCL003_SATELLITE_ROTATION_REVIEW"
      condition: "satellite_count >= 3 AND new_buy_target_bucket == satellite"
      action: "SATELLITE_ROTATION_REVIEW"
      output: >
        위성 3종목 이상 보유 중 추가 위성 진입 검토 시
        financial_health_score 가장 낮은 기존 위성 종목을 교체 후보로 우선 표시.
  output_field: "position_count_status"
  xref: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.position_count_limit"


investment_horizon_policy:
  id: "IHP_INVESTMENT_HORIZON"
  purpose: >
    중장기 추세 추종을 기본 전략으로 고정하고,
    단기 전술 포지션은 엄격한 조건이 충족될 때만 예외적으로 허용한다.
    투자 전략은 보유 기간 목표와 익절 방식에 직접 연결된다.
  default_mode:
    name: "MEDIUM_LONG_TERM"
    label: "중장기 추세 추종 (기본값)"
    description: >
      시장 주도 추세를 확인 후 진입. 충분한 이익이 쌓일 때까지 보유.
      변동성 노이즈에 흔들리지 않고 추세가 훼손될 때 청산.
    core_holding_target: "60거래일 이상"
    satellite_holding_target: "20~60거래일"
    entry_method: "staged_entry_v2 (탐색→확인→주력 분할 진입)"
    exit_method: "take_profit_ladder_V2 (ATR 사다리 1/3 단계적 익절)"
    stop_loss: "ATR × 1.5 (중장기 노이즈 허용)"
    re_entry_rule: "추세 재확인 후 재진입 허용. 단, 손절 후 즉일 재진입 금지."
  short_term_tactical:
    name: "SHORT_TERM_TACTICAL"
    label: "단기 전술 (예외적·조건부)"
    description: >
      중장기 원칙의 예외. 고확신도 돌파 국면에서만 제한적 허용.
      위성 버킷 전용. 코어 종목 단기매매 절대 금지.
    required_conditions_all:
      - "orbit_state == achievable"
      - "market_regime IN [RISK_ON, SECULAR_LEADER_RISK_ON]"
      - "Total_Heat < 5%"
      - "grade == A AND financial_health_score >= 12"
      - "satellite 버킷 내 잔여 슬롯 존재 (PCL 통과)"
    constraints:
      max_holding_days: 10
      max_concurrent_positions: 1
      profit_target: "+5% 이상 또는 D+10 gate 도달 시 검토"
      stop_loss: "ATR × 1.0 (중장기보다 타이트)"
      exit_method: "D+10 강제 검토 → 목표 미달 시 TRIM 또는 CLOSE"
    prohibition:
      - "코어 종목(삼성전자·SK하이닉스 등 CSCS >= 70)에 단기 전술 적용 금지"
      - "중장기 보유 중 '단기로 변경' 허용 금지 — 전략 변심은 전략 일관성 훼손"
      - "단기 전술 포지션이 이미 1건 있을 때 추가 단기 포지션 금지"
      - "재무 건전성 미달(financial_health_score < 12) 종목 단기 전술 허용 금지"
  horizon_enforcement:
    tracker_field: "position_mode"
    values: ["MEDIUM_LONG_TERM", "SHORT_TERM_TACTICAL"]
    default_value: "MEDIUM_LONG_TERM"
    override_condition: "short_term_tactical.required_conditions_all 전부 충족"
    audit_rule: "매주 수요일 정기점검 시 position_mode 불일치 종목 플래그"
  xref:
    - "spec/exit/take_profit.yaml:take_profit_rules.time_based_realization.satellite_time_return_gate"
    - "spec/exit/stop_loss.yaml:stop_loss_rules.RW2b_5d_rapid_weakness"
    - "spec/01_objective_profile.yaml:position_count_limit"

asset_location_matrix:
  priority_rule: "Tax Drag가 큰 자산일수록 절세 계좌에 우선 배치."
  routing:
    high_dividend_or_yield: {examples: ["배당주", "리츠", "채권ETF", "월배당ETF"], priority: ["ISA", "연금저축"]}
    overseas_growth_ETF: {examples: ["S&P500 ETF", "Nasdaq100 ETF", "글로벌 반도체 ETF"], priority: ["연금저축", "ISA"]}
    domestic_growth_stock: {examples: ["국내 개별 성장주", "국내 주도주"], priority: ["일반계좌"]}
    high_turnover_tactical:
      examples: ["전술 위성(단기보유)", "위성 고베타"]
      priority: ["일반계좌"]
      routing_note: "세제 최적 계좌 routing 지침. role.principles 4번(단타 지양) 준수 — 위성도 평균 20거래일 이상 보유 목표."
  cash_management:
    depositor_protection_limit_krw: 100000000
    operating_cap_per_institution_krw: 90000000
    rule: "현금성 자산 1억 초과 시 동일 금융회사 단일 예치 금지. Risk-Off 25% 적용 시 기관별 예치 한도표 출력."
    not_same_as_protected: ["MMF", "RP", "채권형 ETF", "단기채 ETF", "비보호 CMA"]
  guardrails:
    - "세법·계좌 한도·기납입액 미확인 시 세후 최적화 수치 산출 금지."
    - "현금성 상품은 예금자보호 여부 확인 전까지 무위험자산으로 표시 금지."

hedge_policy:
  USDKRW:
    below_1300: "환노출 확대"
    1300_1370: "H/UH 혼합"
    1370_1400: "환헤지 50~70%"
    above_1400: "환헤지 70~90%, 신규 환노출 축소"
    above_1450: "해외위험자산 신규 보류 또는 H클래스 우선"
