Files
QuantEngineByItz/spec/risk/aggregate_risk.yaml
T
kjh2064 ee3e799de1 feat: 리밸런싱 엔진 V1 + GAS 버그 수정 (2026-06-13)
주요 변경:
- 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>
2026-06-13 13:20:14 +09:00

153 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
meta:
title: "은퇴자산포트폴리오 — 총위험·포트폴리오 하드스톱"
parent_file: "spec/risk/risk_control.yaml"
version: "2026-05-15-F12_split"
language: "ko-KR"
timezone: "Asia/Seoul"
role: "canonical"
migration_status: "canonical_split_active"
risk_control:
attention_map:
always_check:
- "unified_engine.trigger_matrix: 3개 트리거 중 발동 여부 확인"
- "weekly_circuit_breaker: 주간 누적 수익률 확인"
check_if_triggered:
monthly_minus_8: "portfolio_hard_stop_procedure"
correlation_shock_conditions: "correlation_shock"
opening_minus_1pct: "opening_volatility_filter"
top3_over_65pct: "concentration_brake"
turnover_cost_high: "turnover_control_gate"
after_drawdown: "drawdown_recovery_speed_gate"
skip_if_not_triggered: "위 조건 미발동 시 해당 섹션 읽기 생략 허용"
aggregate_risk_cap:
formula: "Total_Heat = Σ (entry_price_i - stop_price_i) × quantity_i / 총자산 × 100 [단위: %]"
threshold:
warning: "Total_Heat >= 7% → 신규 매수 시 기존 포지션 손절선 재확인 필수"
hard_block: "Total_Heat >= 10% → 신규 매수 전면 금지. Total_Heat < 7% 회복 전까지 유지."
calculation_rule:
- "stop_price는 확정된 HTS 조건부 주문 가격. 미설정 시 entry_price × (1 - ATR20/entry_price × 2.0) 사용. (ATR×2.0은 Total_Heat 과소측정 방지용 보수적 추정. 실제 HTS 손절가는 stop_loss.core.hts_entry_formula(ATR×1.5) 기준)"
- "신규 매수 산출 전 현재 Total_Heat를 반드시 계산하고 주문표에 표시한다."
output_column: "Total_Heat(%)"
pre_quantity_gate: # [proposal_65 / 2026-05-15] final_quantity_rule 실행 전 선행 차단 게이트
purpose: >
신규 매수 수량 산출(final_quantity_rule) 실행 전 Total_Heat 수준을 먼저 확인.
이 게이트를 통과하지 못하면 final_quantity_rule 실행 자체를 생략한다.
check_sequence:
step_1: "신규 매수 제안 시 Total_Heat 현재값 산출"
step_2: "hard_block(>=10%) 확인 → 발동 시 즉시 매수 스킵. final_quantity_rule 실행 없음"
step_3: "caution(7~9%) 확인 → final_quantity_rule 수량 × 0.5 감액 후 실행"
step_4: "정상(<7%) → final_quantity_rule 정상 실행"
action_by_level:
hard_block:
condition: "Total_Heat >= 10%"
action: "모든 신규 매수(stage_1·stage_2·pyramiding·pullback 포함) 전면 차단"
exception: "pyramiding_rule 2차 증액(기존 보유 증액)은 caution 적용으로 완화. hard_block 예외."
report: "'Total_Heat 한도 초과(현재 값%) — 신규 매수 불가' 보고서에 필수 표기"
caution:
condition: "7% <= Total_Heat < 10%"
action: "final_quantity_rule 산출 수량 × 0.5. 최소 1주. 0주이면 매수 포기."
report: "'Total_Heat caution(현재 값%) — 수량 50% 감액' 보고서에 필수 표기"
normal:
condition: "Total_Heat < 7%"
action: "final_quantity_rule 정상 실행"
prohibition:
- "Total_Heat 미산출 상태에서 신규 매수 수량 산출 금지"
- "pyramiding hard_block 예외를 일반 신규진입에 적용 금지"
prohibition:
- "Total_Heat 미산출 시 A등급 신규 매수 금지"
- "→ master_prohibitions.P3 전역 적용 (hard_block 완화 포함)"
- "개별 종목 stop_loss 없이 Total_Heat 계산에 포함하는 것 금지 → 손절가 미설정 포지션은 Total_Heat 최대값(15%)으로 가정"
portfolio:
monthly_minus_5: "core_satellite 신규매수 중단"
monthly_minus_8: "위험자산 20% 축소. portfolio_hard_stop_procedure 즉시 실행."
drawdown_minus_12: "전략 재검토, 현금 확대"
bankruptcy:
minus_20: "위성 중단, 신규매수 축소, 목표확률 재계산"
minus_30_or_monthly_minus_12: "공격전략 중단, 위험자산 축소"
minus_40_or_margin_risk: "생존모드. 신규 위험자산 중단"
portfolio_hard_stop_procedure:
trigger: "portfolio.monthly_minus_8 발동 시 즉시 순서대로 실행"
step_1: "신규 매수 전면 중단. 당일 예약 주문 취소 확인."
step_2: "위성 포지션 우선 축소: time_stop 초과 전량 청산 → Flow_OK=N 위성 전량 청산 → 5D 동반 순매도 위성 30~50% 축소. 위성 합계 총자산 3% 이하."
step_3: "중복 ETF 초과분 1~2회 분할 지정가 매도."
step_4: "cash_floor 15% 이상 확인. 미달이면 step_3 후 재확인."
step_5: "코어 유지 원칙. 단 20일선 종가 이탈 + 5D 수급 동반 이탈 시 30% 부분 축소 검토."
resume_condition: ["포트폴리오 수익률 monthly_minus_5 수준 회복", "cash_floor 충족", "VIX 안정·수급 개선 중 1개 이상"]
prohibition: ["→ master_prohibitions.P3 전역 적용", "회복 기대로 위성 손절 지연 금지"]
correlation_shock:
trigger:
required_all: ["포트폴리오 평가액 3거래일 연속 하락", "보유 위험자산 70% 이상이 3거래일 누적 하락"]
required_one: ["KOSPI 20일·60일선 모두 하회", "VIX 25 이상", "credit_stress caution 이상", "USD/KRW 급등에도 해외자산 방어 실패", "USD/JPY 3거래일 내 3% 급락 + 글로벌 동반 하락"]
action:
stage_1: "신규 위험자산 매수 중단."
stage_2: "중복 ETF → 20D 수급 이탈 종목 → 20일선 하회 위성 순서로 축소."
stage_3: "cash_floor 25~30% 상향. 시장지배 주도주 직접보유는 마지막 축소대상."
execution: "즉시 전량청산 아님. 1차 30%, 2차 30%, 잔여 40% 단계 집행."
exception_rule:
decoupling_sector_leadership:
activation_required_all:
- "Price_Status=PRICE_OK, Flow_OK=Y"
- "최근 5거래일 내 52주 신고가 또는 ATH, 또는 섹터 1M/3M 상대강도 상위권"
- "외국인+기관 합산 20D 순매수 양수"
- "종가가 20일선 위 또는 신고가 후 눌림 구간"
- "거래대금 최근 5거래일 평균 대비 급감 아님"
permitted_override:
- "stage_2 1차 축소 순서에서 제외. 신규매수는 금지."
- "trailing_stop을 20일 ATR 1.2~1.5배로 타이트하게 재설정."
sunset: "5거래일마다 재검증. 20일선 이탈·5D 외인·기관 동반 순매도·장대음봉+거래대금 폭증 중 2개 이상이면 예외 해제."
prohibition: ["3일 동반하락만으로 현금 30% 강제 인상 금지", "인버스·레버리지 ETF를 기본 헷지로 사용 금지", "현금 확보 위해 삼성전자·SK하이닉스 직접보유를 중복 ETF보다 먼저 줄이지 않는다", "decoupling 예외를 신규 추격매수 근거로 사용 금지"]
unified_engine:
purpose: "산재된 리스크 트리거를 단일 엔진으로 통합. 위기 발생 시 규칙 충돌 없이 즉각 대응."
trigger_matrix:
Systemic:
conditions: ["USD/JPY 3거래일 내 3% 급락(엔화 폭등)", "VIX 30 돌파", "credit_stress 발동"]
Portfolio:
conditions: ["월간 손실 > 8% (monthly_minus_8)", "최대낙폭 > 12% (drawdown_minus_12)"]
Correlation:
conditions: ["보유종목 70% 이상 3거래일 연속 동반 하락", "KOSPI 20일·60일선 동시 하회"]
action_tiers:
Tier_1_Soft:
trigger: "Systemic·Portfolio·Correlation 중 1개 충족"
action: ["신규 매수 전면 중단", "위성 비중 50% 단계 축소 검토"]
Tier_2_Medium:
trigger: "Systemic·Portfolio·Correlation 중 2개 충족"
action: ["중복 ETF 전량 매도", "현금 비중 20% 확보"]
Tier_3_Hard:
trigger: "Tier_2 조치 후에도 회복 실패"
action: ["생존 모드 진입", "코어 직접보유 외 전량 현금화"]
priority_rule: "individual_risk_rule의 예외 조항이 unified_engine Tier 조치보다 우선할 수 없다."
prohibition: ["→ master_prohibitions.P3 전역 적용", "unified_engine 대신 개별 트리거만 선택 적용 금지"]
circuit_interaction_rule: # [proposal_73 / 2026-05-15] 복수 리스크 차단 조치가 동시 발동 시 충돌 해소 우선순위
purpose: >
sector_crash_intraday_protocol, correlation_shock, unified_engine, opening_volatility_filter 등
복수의 리스크 차단 조치가 동시 발동할 경우, 어떤 조치가 우선하는지를 명문화하여 규칙 충돌을 제거한다.
priority_rule:
rule_1: "지속 기간이 더 긴 조치가 우선한다."
rule_2: "지속 기간이 동일하면 적용 범위가 더 넓은 조치가 우선한다."
rule_3: "적용 범위도 같으면 unified_engine 조치가 개별 프로토콜보다 우선한다."
interaction_matrix:
- {circuit_A: "unified_engine.Tier_3_Hard (전체 포트폴리오)", circuit_B: "sector_crash_intraday_protocol.tier_C (섹터 전량 청산)", winner: "unified_engine.Tier_3_Hard", reason: "범위 더 넓음"}
- {circuit_A: "correlation_shock (3거래일+)", circuit_B: "opening_volatility_filter (당일)", winner: "correlation_shock", reason: "지속 기간 더 김"}
- {circuit_A: "sector_crash_intraday_protocol.tier_A (신규 매수 중단)", circuit_B: "opening_volatility_filter.hard_block (신규 매수 중단)", winner: "둘 다 적용 — 더 엄격한 조치 유지", reason: "동급 범위, 동일 효과"}
output_requirement: "복수 조치 발동 시 블록 4(플레이북) 상단에 [CIRCUIT 충돌 해소] 표기 후 우선 조치와 그 근거를 명시."
stop_loss_execution_sequence: # [proposal_79 / 2026-05-15] 동시 발동 시 포지션 청산 실행 순서
purpose: "weekly_circuit_breaker + sector_crash_intraday_protocol tier_C 동시 발동 시 포지션 청산 실행 순서"
trigger_condition: "weekly_circuit_breaker 발동 AND sector_crash_intraday_protocol.tier_C 동시 발동"
execution_order:
step_1: "sector_crash 해당 섹터 위성(satellite) 포지션 중 staged_entry stage_1 물량 우선 손절"
step_2: "relative_weakness_exit RW점수 가장 높은 위성 포지션 부분 청산 (RW=3: 40%, RW>=4: 80%)"
step_3: "코어(core_bucket) 포지션 현상 유지 — 두 조치 해제까지 신규 매수 전면 중단"
new_buy_block: "weekly_circuit_breaker AND tier_C 동시 해제 조건 모두 충족 후에만 신규 매수 재개"
output_requirement: "블록4 플레이북 상단에 [복수 circuit 발동 — 실행 순서 ①→②→③ 진행 중] 표기"
prohibition:
- "step_1 실행 전 step_2·step_3 실행 금지"
- "코어 포지션을 위성보다 먼저 청산 금지"
prohibition:
- "규칙 충돌을 이유로 두 조치 모두 무시 금지"
- "더 완화된 조치를 우선 적용 금지"