ee3e799de1
주요 변경: - tools/build_rebalance_engine_v1.py: REBALANCE_ENGINE_V1 신규 * account_snapshot 직접 합산(_build_snap_position_map) → 소수주 분리 행 병합 * 레짐 소스 macro.REGIME_PRELIM 최우선 (GAS 와 동일) - src/gas_adapter_parts/gdf_06_rebalance.gs: runRebalanceSheet_() 신규 * Logger.log / getSpreadsheet_() 로 run_all 연동 수정 - src/gas_adapter_parts/gdc_01_fetch_fundamentals.gs * _mergePositionRecord_(): 소수주 중복 행 합산 신규 * parseInt → parseFloat (qty, availQty) - src/gas_adapter_parts/gdf_01_price_metrics.gs * 미보유 종목 SELL_READY → WATCH_EXIT_SIGNAL - spec/41_release_dag.yaml: build_rebalance_sheet 노드 추가 (step_count 63) - spec/51_formula_lifecycle_registry.yaml: REBALANCE_ENGINE_V1 등록 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
169 lines
7.7 KiB
YAML
169 lines
7.7 KiB
YAML
meta:
|
|
title: "은퇴자산포트폴리오 — 포트폴리오 제약·계좌 라우팅 명세"
|
|
parent_file: "RetirementAssetPortfolio.yaml"
|
|
version: "2026-05-24-F4_portfolio_rules_proposal50"
|
|
language: "ko-KR"
|
|
timezone: "Asia/Seoul"
|
|
role: "derived_adapter"
|
|
purpose: >
|
|
계좌, 납입한도, 비중, 중복노출, 현금 룰을 별도 포트폴리오 규칙으로 제공한다.
|
|
canonical 계산은 기존 risk/account 섹션을 참조하되, LLM 적용 순서를 고정한다.
|
|
authority_rule: "이 파일은 포트폴리오 제약 적용 순서를 제공하는 adapter다. 수치 임계값 충돌 시 canonical_refs 대상 파일을 우선한다."
|
|
|
|
portfolio_rules:
|
|
priority: "risk_policy 다음, position_sizing 이전에 적용"
|
|
canonical_refs:
|
|
account_policy: "spec/01_objective_profile.yaml:account_policy"
|
|
contribution_policy: "spec/01_objective_profile.yaml:user_profile.contribution_policy"
|
|
exposure_framework: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework"
|
|
cash_floor: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.cash_floor"
|
|
duplicate_exposure: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.duplicate_exposure_rule"
|
|
target_allocation: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.target_allocation_structure"
|
|
|
|
account_constraints:
|
|
accounts_allowed: ["일반계좌", "ISA", "연금저축"]
|
|
accounts_excluded: ["IRP"]
|
|
contribution_limits:
|
|
ISA:
|
|
monthly_limit_krw: 2000000
|
|
rule: "월 납입 가능액과 기납입액 확인 전 추가 납입 가정 금지"
|
|
pension:
|
|
monthly_limit_krw: 500000
|
|
account_name: "연금저축"
|
|
rule: "연금저축 납입 한도 확인 전 초과 납입 전제 금지"
|
|
integer_quantity_only: true
|
|
fractional_share_prohibited: true
|
|
|
|
asset_location_rules:
|
|
domestic_tactical_stock:
|
|
preferred_account: "일반계좌"
|
|
rationale: "전술 위성·단기매매는 세제보다 유동성과 실행 자유도가 우선"
|
|
high_dividend_or_yield:
|
|
preferred_accounts: ["ISA", "연금저축"]
|
|
rationale: "세제 혜택과 과세 이연 우선"
|
|
overseas_long_term_etf:
|
|
preferred_accounts: ["연금저축", "ISA"]
|
|
rationale: "장기투자·세제효율 우선"
|
|
cash_or_short_duration:
|
|
preferred_accounts: ["ISA", "연금저축", "일반계좌"]
|
|
rationale: "cash_floor와 대기자금 성격에 따라 배치"
|
|
|
|
exposure_limits:
|
|
target_buckets:
|
|
core:
|
|
target_pct: 65
|
|
band: "60~72"
|
|
canonical_ref: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.target_allocation_structure.buckets.core_bucket"
|
|
tactical_satellite:
|
|
target_pct: 20
|
|
band: "10~25"
|
|
canonical_ref: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.target_allocation_structure.buckets.tactical_satellite_bucket"
|
|
cash_fc:
|
|
target_pct: 15
|
|
band: "10~22"
|
|
canonical_ref: "spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.target_allocation_structure.buckets.cash_fc_bucket"
|
|
single_satellite_max_pct: 7
|
|
duplicate_exposure_action_order:
|
|
- "중복 섹터 ETF"
|
|
- "20D 수급 이탈·20일선 하회 위성"
|
|
- "동일 섹터 내 후순위"
|
|
- "시장지배 코어 직접보유"
|
|
|
|
# ── M5 V1.1 (proposal_50 2-4): 반도체 클러스터 강제 감축 (2026-05-24) ─────────
|
|
sector_concentration:
|
|
O2_semiconductor_cluster:
|
|
cluster_limit_pct: 25
|
|
single_stock_limit_pct: 30
|
|
regime_limit_pct:
|
|
EVENT_SHOCK: 20
|
|
RISK_OFF: 20
|
|
RISK_ON: 25
|
|
SECULAR_LEADER_RISK_ON: 35
|
|
CONCENTRATED_LEADER_ADVANCE: 60
|
|
mandatory_reduction_trigger: "cluster_pct > cluster_limit * 2.0"
|
|
reduction_plan: "MANDATORY_REDUCTION_PLAN_V1"
|
|
weekly_reduction_target: "ceil((cluster_pct - cluster_limit) / 4)"
|
|
reduction_priority_order:
|
|
1: "rs_verdict=BROKEN 코어 클러스터 종목"
|
|
2: "KODEX반도체 등 ETF (세금·슬리피지 유리)"
|
|
3: "SK하이닉스 APEX_SUPER trailing_stop 발동 분"
|
|
4: "삼성전자 CLA_EXIT_CONFIRMED 이후"
|
|
enforcement:
|
|
- "cluster_limit은 market_regime_state 및 CLA 상태에 따라 20/25/35/60으로 상향 조정 가능"
|
|
- "cluster_pct <= cluster_limit * 2.0이면 MANDATORY_REDUCTION 비활성 (추가 BUY만 금지)"
|
|
- "mandatory_reduction=true이면 weekly_target 미만 매도 시 REDUCTION_BEHIND_SCHEDULE 경고"
|
|
- "is_mandatory=true 상태에서 반도체 종목 신규 BUY/ADD_ON 절대 금지"
|
|
|
|
cash_rules:
|
|
cash_basis: "즉시 인출 가능한 현금성 자산 기준"
|
|
buy_power_formula: "즉시현금 + D+2 추정현금성자산 - 예약된 주문금액"
|
|
post_trade_check_required: true
|
|
prohibition:
|
|
- "D+2 추정현금을 cash_floor 충족 현금으로 오인 금지"
|
|
- "post_trade_immediate_cash_ratio 미확인 상태에서 신규매수 확정 금지"
|
|
|
|
portfolio_decision_gate:
|
|
sequence:
|
|
1: "계좌 허용 여부 확인"
|
|
2: "납입 한도 및 현금 원천 확인"
|
|
3: "현재 보유/목표 비중/중복 노출 확인"
|
|
4: "cash_floor 및 post-trade cash 확인"
|
|
4_5: "[MRG001] 이격도 과열 체크 -- MEAN_REVERSION_GATE_V1: deviation_ratio >= 1.15 -> BUY_HARD_BLOCK" # [2026-05-19_ALPHA_SHIELD_V1]
|
|
5: "position_sizing으로 전달할 계좌별 최대 주문 예산 산출"
|
|
pass_output:
|
|
- "account"
|
|
- "max_order_budget_krw"
|
|
- "target_bucket"
|
|
- "current_weight_pct"
|
|
- "post_trade_cash_ratio"
|
|
- "portfolio_constraint_status"
|
|
fail_action:
|
|
cash_floor_fail: "BUY_BLOCKED"
|
|
duplicate_exposure_fail: "TRIM_OR_WAIT"
|
|
account_limit_fail: "ROUTE_TO_OTHER_ACCOUNT_OR_WAIT"
|
|
holdings_unknown: "NO_SELL_QUANTITY"
|
|
|
|
executable_rules:
|
|
field_dictionary_ref: "spec/12_field_dictionary.yaml:field_dictionary"
|
|
formula_refs:
|
|
cash_ratios: "spec/13_formula_registry.yaml:formula_registry.formulas.CASH_RATIOS_V1"
|
|
portfolio_band_status: "spec/13_formula_registry.yaml:formula_registry.formulas.PORTFOLIO_BAND_STATUS_V1"
|
|
mean_reversion_gate: "spec/13_formula_registry.yaml:formula_registry.formulas.MEAN_REVERSION_GATE_V1" # [2026-05-19_ALPHA_SHIELD_V1]
|
|
rules:
|
|
- id: "PG001_ACCOUNT_ALLOWED"
|
|
input_field: "account_type"
|
|
pass_if: "account_type in ['일반계좌', 'ISA', '연금저축']"
|
|
fail_action: "ACCOUNT_NOT_ALLOWED"
|
|
- id: "PG002_CONTRIBUTION_LIMIT"
|
|
input_fields: ["account_type", "monthly_contribution_planned", "monthly_contribution_used"]
|
|
pass_if: "account_type == '일반계좌' OR monthly_contribution_planned + monthly_contribution_used <= account_monthly_limit"
|
|
fail_action: "ACCOUNT_LIMIT_FAIL"
|
|
- id: "PG003_CASH_GATE"
|
|
formula_ref: "CASH_RATIOS_V1"
|
|
pass_if: "post_trade_immediate_cash_ratio >= min_cash_ratio"
|
|
fail_action: "BUY_BLOCKED"
|
|
- id: "MRG001_MEAN_REVERSION_GATE" # [2026-05-19_ALPHA_SHIELD_V1] X1
|
|
formula_ref: "MEAN_REVERSION_GATE_V1"
|
|
pass_if: "deviation_ratio < 1.10"
|
|
caution_if: "1.10 <= deviation_ratio < 1.15"
|
|
fail_action: "BUY_HARD_BLOCK (deviation_ratio >= 1.15)"
|
|
- id: "PG004_EXPOSURE_BUDGET_OUTPUT"
|
|
formula_ref: "PORTFOLIO_BAND_STATUS_V1"
|
|
output_fields: ["max_order_budget_krw", "target_bucket", "portfolio_constraint_status"]
|
|
fail_action: "NO_POSITION_SIZING_INPUT"
|
|
|
|
reporting_requirement:
|
|
table_columns:
|
|
- "계좌"
|
|
- "목표버킷"
|
|
- "현재비중(%)"
|
|
- "목표밴드"
|
|
- "중복노출상태"
|
|
- "즉시현금비중(%)"
|
|
- "매수가능현금"
|
|
- "계좌한도상태"
|
|
- "허용행동"
|
|
prohibition:
|
|
- "계좌 한도·현금·보유수량 미확인 상태에서 최종 주문수량 출력 금지"
|
|
- "포트폴리오 제약 실패를 종목 점수로 상쇄 금지"
|