0a51702a9a
Phase 2 implementation complete: P3 - 손절 체계 재정의 (Stop Loss Taxonomy): - spec/exit/stop_loss.yaml: P3 섹션 추가 - calcAbsoluteRiskStopV1_: 절대 손실 금지선 (entry * 0.92 vs ATR * 1.5) - calcRelativeUnderperfAlertV1_: 상대 성과 추적 (WATCH/TRIM_30/TRIM_50/EXIT_100) - calcStopActionLadderV1_: 사다리식 액션 결정 P4 - 라우팅 단일화 (Unified Routing): - spec/xx_routing_contract.yaml: 4가지 스타일 가중치 정의 - buildRoutePacket_: SCALP/SWING/MOMENTUM/POSITION 점수 + best_style 결정 P5 - 뒷북 차단 (Anti-Late Entry): - spec/exit/pre_distribution_gate.yaml: 배분 위험 조기 감지 - calcAlphaLeadV1_: Alpha Lead Entry Gate (alpha_lead_score >= 75) - calcDistributionRiskV1_: Pre-Distribution Early Warning (risk >= 70) P6 - 현금확보 (Cash Recovery): - spec/exit/cash_recovery.yaml: K2 50/50 분할 + value_damage <= 10% - calcCashRecoveryOptimizerV1_: 현금 최적화 (부족액 4,134만원) UI/UX 개선 (MudBlazor 6.10.0): - Dashboard.razor: 단순 버전 (컴파일 에러 제거) - MainLayout.razor: Typo enum 수정 (H5→h5, H6→h6) - NavMenu.razor: Icons.Material.Filled.Portfolio → Inventory2 릴리스 빌드: - dotnet publish -c Release 성공 - publish 폴더 24MB (배포 준비 완료) 실전 운영 계획: - spec/realtime/live_outcome_ledger_plan.yaml: 30건 신호 샘플링 계획 - honest_proof_score: 56.57 → 95.0 개선 경로 정의 - 예상 기간: 2026-06-25 ~ 2026-08-10 (약 6주) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
429 lines
27 KiB
YAML
429 lines
27 KiB
YAML
meta:
|
||
title: "은퇴자산포트폴리오 — 손절 정책"
|
||
parent_file: "spec/06_exit_policy.yaml"
|
||
version: "2026-05-15-F12_split"
|
||
language: "ko-KR"
|
||
timezone: "Asia/Seoul"
|
||
role: "canonical"
|
||
migration_status: "canonical_split_active"
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# 매도 신호 전체 우선순위 계층 (P1-B / 2026-05-17 추가)
|
||
# calcSellDecision_()이 이 순서로 평가한다. 상위 조건이 성립하면 하위 조건 무시.
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
sell_signal_priority:
|
||
purpose: >
|
||
여러 매도 신호가 동시에 발생할 때 어느 신호를 최우선으로 처리할지 결정한다.
|
||
신호 충돌 시 "undefined behavior" 방지가 목적.
|
||
levels:
|
||
1_hard_stop:
|
||
condition: "timingAction == STOP_OR_TIME_EXIT_READY OR rw_partial >= 4"
|
||
action: "EXIT_100 — 전량 즉시 청산"
|
||
gas_field: "Sell_Action=EXIT_100, Sell_Reason=STOP_OR_TIME_EXIT_READY|RW_EXIT_STRONG"
|
||
2_risk_off_regime:
|
||
condition: "REGIME_PRELIM == RISK_OFF OR RISK_OFF_CANDIDATE (포지션 보유 시)"
|
||
action: "REGIME_TRIM_50 — 50% 단계 축소"
|
||
gas_field: "Sell_Action=REGIME_TRIM_50, Sell_Reason=REGIME_RISK_OFF|REGIME_RISK_OFF_CANDIDATE"
|
||
note: "hard_stop이 없는 경우에만 적용. 전량 청산이 아닌 단계적 축소."
|
||
# ── REGIME_TRIM_50 발동 시 sell_priority_engine 의무 실행 ────────────────
|
||
# spec: spec/risk/portfolio_exposure.yaml:sell_priority_engine
|
||
# REGIME_TRIM_50은 '포트폴리오 레벨' 신호 — 어떤 종목에 적용할지는 sell_priority_engine이 결정한다.
|
||
# 개별 종목 내부 신호(level 3~7)로 대상 종목을 임의 선택하는 것은 이 신호의 용도를 오용하는 것.
|
||
mandatory_next_step:
|
||
rule: >
|
||
REGIME_TRIM_50 발동 즉시 sell_priority_engine을 실행하고
|
||
sell_priority_decision_table을 출력한 후 상위 tier 종목에만 TRIM 적용.
|
||
sell_priority_order: "①하드스탑 → ②매도신호 → ③중복ETF → ④손실위성 → ⑥익절후보 → ⑨코어주도주(마지막)"
|
||
gas_endpoint: "?view=sell_priority (runSellPriority() 함수)"
|
||
prohibition:
|
||
- "sell_priority_decision_table 없이 TRIM 대상 종목을 직접 지정 금지"
|
||
- "상승추세 중인 반도체 주도주(SK하이닉스·삼성전자)를 REGIME_TRIM_50 1차 대상으로 선정 금지"
|
||
- "ETF 중복노출 종목이 있는데 코어주도주를 먼저 TRIM하는 행위 금지"
|
||
2b_rw2b_fast_track: # [2026-05-18_ADVANCED_EXIT_V2] 5D 조기약세 fast track
|
||
condition: "RW2b_5d_rapid_weakness == 1 AND rw_partial_excluding_rw2b >= 1"
|
||
action: "TRIM_50 — 50% 선제 부분 청산 (fast_track)"
|
||
gas_field: "Sell_Action=TRIM_50, Sell_Reason=RW2B_FAST_TRACK"
|
||
priority_note: "2번(RISK_OFF)과 3번(rw_partial>=3) 사이 삽입. RISK_OFF 없을 때만 발동."
|
||
3_rw_signals:
|
||
condition: "rw_partial >= 3 OR timingExitScore >= 75"
|
||
action: "TRIM_70 — 70% 부분 청산"
|
||
gas_field: "Sell_Action=TRIM_70, Sell_Reason=RW_EXIT|TIMING_EXIT_SCORE"
|
||
4_trailing_stop:
|
||
condition: "trailingStopPrice 이탈 OR (rw_partial >= 2) OR (rw_partial >= 1 AND timingExitScore >= 50)"
|
||
action: "TRIM_50 — 50% 부분 청산. rw_partial=0 + 기술지표만으로는 TRIM_50 불가 → EXIT_REVIEW 강등."
|
||
gas_field: "Sell_Action=TRIM_50"
|
||
5_take_profit_ladder:
|
||
condition: "Profit_Pct >= 10 (TP1/TP2 도달)"
|
||
action: "TAKE_PROFIT_TIER1 — 25% 익절"
|
||
gas_field: "Sell_Action=TAKE_PROFIT_TIER1|PROFIT_TRIM_*"
|
||
6_time_stop:
|
||
condition: "Days_To_Time_Stop <= 0"
|
||
action: "TIME_EXIT_100 — time stop 만료 전량 청산"
|
||
gas_field: "Sell_Action=TIME_EXIT_100, Sell_Reason=TIME_STOP_EXPIRED"
|
||
7_scheduled_review:
|
||
condition: "분기 정기점검 (수동 검토)"
|
||
action: "사람이 결정. 자동 신호 없음."
|
||
prohibition:
|
||
- "우선순위 높은 신호 무시하고 낮은 신호로 재해석 금지"
|
||
- "신호 충돌 시 '관망'으로 모호하게 처리 금지 — 항상 최고 우선순위 신호 적용"
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# timingExitScore 산출 공식 (calcTimingDecision_ 내 exitScore) — 2026-05-17 v2
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
timing_exit_score_formula:
|
||
version: "v2-2026-05-17"
|
||
purpose: >
|
||
매도 타이밍 강도 점수. 0~100 범위. thresholds: 50=EXIT_REVIEW, 75=STOP_OR_TIME_EXIT_READY.
|
||
v1 대비 변경: RW 가중치 상향(20→25), 기술지표 가중치 하향(18→10).
|
||
이유: 기술지표(RSI, 이격도, MA20) 단독 신호의 오신호율(30~40%)을 억제하고
|
||
수급 기반 RW(상대약세)의 실증적 신뢰도를 반영.
|
||
components:
|
||
rw_partial:
|
||
weight: 25 # 구: 20. 수급 기반 — 외국인·기관 이탈 확인, 신뢰도 높음
|
||
max: 100 # rwPartial × 25, cap=100
|
||
example: "RW=2 → 50pt (EXIT_REVIEW 단독 도달)"
|
||
exit_signal_tokens:
|
||
weight: 10 # 구: 18. 기술지표(VOL_EXHAUSTION/MA20_BREAK/DISPARITY_TOP/RSI_OVERBOUGHT) — 노이즈 多
|
||
note: "RW=0 + 기술신호 4개 = 40pt → 임계값 미달. RW=1 이상 있어야 TRIM_50 발동."
|
||
time_stop_near:
|
||
condition: "daysToTimeStop >= 0 AND <= 7"
|
||
points: 20 # 구: 25
|
||
profit_protect_zone:
|
||
condition: "profitPct >= 10"
|
||
points: 15 # 구: 10. 실현 이익 보호 중요도 상향.
|
||
thresholds:
|
||
EXIT_REVIEW: 50
|
||
STOP_OR_TIME_EXIT_READY: 75
|
||
sell_price_formula:
|
||
v2: "close - ATR20 × 0.3 (변동성 비례 보호 하한). ATR 없으면 close × 0.995 폴백."
|
||
v1_deprecated: "close × 0.998 (0.2% — 변동성 무시, 사실상 시가 매도)"
|
||
trailing_stop_breach: "trailingStop 가격 직접 사용. min(trailingStop, close×0.998) 적용 금지."
|
||
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# [P3: 손절 체계 재정의] ABSOLUTE_RISK_STOP_V1, RELATIVE_UNDERPERFORMANCE_ALERT_V1
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
p3_absolute_risk_stop_v1:
|
||
name: "절대 손실 금지선 (P3)"
|
||
formula: "max(entry_price * 0.92, entry_price - ATR20 * 1.5)"
|
||
purpose: "진입가 대비 절대 손실 8% 또는 변동성 1.5배 중 높은쪽"
|
||
quantity_strategy:
|
||
immediate: "50% 즉시 매도"
|
||
rebound_wait: "50% 반등 대기"
|
||
rebound_trigger: "prevClose + 0.5 * ATR20"
|
||
order_method: "지정가 주문"
|
||
enforcement: "자동 실행, LLM 자유도 없음"
|
||
gas_function: "calcAbsoluteRiskStopV1_(entry_price, atr20) → stop_price"
|
||
|
||
p3_relative_underperformance_alert_v1:
|
||
name: "상대 성과 추적 (P3)"
|
||
condition: "excess_return_20d <= min(-10%, relative_threshold)"
|
||
action_ladder:
|
||
step_1: "WATCH: 모니터링 시작 (상대 underperformance -10%~-15%)"
|
||
step_2: "TRIM_30: 30% 감소 (상대 underperformance -15%~-20%)"
|
||
step_3: "TRIM_50: 추가 20% 감소 총 50% (상대 underperformance -20%~-25%)"
|
||
step_4: "EXIT_100: 완전 청산 (상대 underperformance < -25% AND 절대손실 >= 8%)"
|
||
forbidden:
|
||
- "상대 성과만으로 EXIT_100 금지 (절대손실 8% 미만)"
|
||
- "기술지표만으로 TRIM_50 금지"
|
||
gas_function: "calcRelativeUnderperfAlertV1_(ret_stock_20d, ret_market_20d) → alert_state"
|
||
action_ladder_function: "calcStopActionLadderV1_(alert_state, underperf_pct) → action"
|
||
|
||
p3_fundamental_thesis_break_v1:
|
||
name: "기본 이론 파괴 감지 (P3)"
|
||
description: "기업 기본가치 붕괴 신호 (절대/상대와 독립 평가)"
|
||
signals:
|
||
- "EPS cut ≥ 10%"
|
||
- "분기별 매출 성장률 역신장"
|
||
- "경쟁사 점유율 급락"
|
||
- "법적/규제 문제 발생"
|
||
action: "검증 후 EXIT_100 (다른 제약 불적용)"
|
||
override_absolute_stop: true
|
||
override_relative_alert: true
|
||
enforcement: "수동 검증 + 자동 실행"
|
||
|
||
p3_formula_registry:
|
||
- name: "calcAbsoluteRiskStopV1"
|
||
inputs: ["entry_price", "atr20"]
|
||
output: "stop_price"
|
||
formula: "max(entry * 0.92, entry - atr20 * 1.5)"
|
||
unit: "KRW"
|
||
|
||
- name: "calcRelativeUnderperfAlertV1"
|
||
inputs: ["return_stock_20d", "return_market_20d"]
|
||
output: "alert_state"
|
||
states: ["WATCH", "TRIM_30", "TRIM_50", "EXIT_100"]
|
||
logic: "ladder transition based on excess_return"
|
||
|
||
- name: "calcStopActionLadderV1"
|
||
inputs: ["alert_state", "underperf_pct", "absolute_loss_pct"]
|
||
output: "action"
|
||
logic: "WATCH → TRIM_30 → TRIM_50 → EXIT_100 with absolute_loss check"
|
||
|
||
p3_validation:
|
||
- "gap_down 프로토콜: 매도불가 상황에서 WAIT_FOR_OPEN"
|
||
- "TICK_NORMALIZER 통과 확인"
|
||
- "포지션 크기 조정 후 재진입 재평가"
|
||
- "지정가 주문이 체결되지 않으면 시장가 전환"
|
||
|
||
stop_loss:
|
||
principle: "손절가·손절수량·잔여수량·재진입 조건을 함께 제시"
|
||
priority_matrix: # [proposal_75 / 2026-05-15] 복수 손절 조건 동시 발동 시 최종 HTS 지정가 결정
|
||
purpose: "동일 종목에 trailing_stop·MA20·relative_weakness_exit·time_stop 4개 조건이 동시 발동 시 최종 손절가 결정 규칙"
|
||
priority_order:
|
||
"1_time_stop": "보유기간 초과 → 매도 시간 강제. 가격보다 시간 우선."
|
||
"2_relative_weakness_exit": "RW >= 4 상대약세 → 70~100% 청산 목표가"
|
||
"3_trailing_stop": "고점 대비 trailing_stop% 하락가"
|
||
"4_MA20_break": "종가 MA20 하향 이탈가"
|
||
final_price_rule: "복수 조건 동시 충족 시 → max(time_stop_price, RW_exit_price, trailing_stop_price, MA20_price) 중 가장 높은(보수적인) 값을 최종 손절가로 설정"
|
||
quantity_rule: "최종 손절가 결정 후, 청산 수량은 상위 우선순위 조건의 청산 비율 적용 (time_stop: 100%, RW>=4: 70~100%, RW=3: 30~50%)"
|
||
output_requirement: "블록4 플레이북에 [손절조건] 열에 발동 조건명과 최종가 계산 근거 명시"
|
||
prohibition:
|
||
- "복수 조건 중 더 완화된(낮은) 손절가 선택 금지"
|
||
- "조건 간 충돌을 이유로 손절 전면 보류 금지"
|
||
core: # [P131] ATR 기준 우선. % 기준은 ATR 미확인 시 fallback
|
||
# [Q2 / 2026-05-15] "1.5~2.0배" 범위 표현이 HTS 입력 시 어느 값인지 모호해
|
||
# LLM이 2.0배 적용 또는 임의 중간값 산출하는 착오 방지. hts_entry_formula를 canonical로 고정.
|
||
primary_rule: "HTS 입력 canonical: max(진입가 × 0.92, 진입가 − ATR20 × 1.5). 1.5배 고정."
|
||
extended_rule: "ATR20_Pct >= 8%(고변동성 종목)인 경우에만 ATR20 × 2.0배 허용. 이 경우 hts_entry_formula에서 1.5 → 2.0으로 교체."
|
||
atr_pct_definition: "ATR20_Pct = ATR20 / 현재가 × 100. 8% 기준은 일별 평균 변동폭이 주가의 8%를 초과함을 의미."
|
||
fallback_rule: "ATR20 미산출 시에만 매수가 -8% 단일 고정값 (DATA_MISSING 표시)"
|
||
hts_entry_formula: "max(진입가 × 0.92, 진입가 − ATR20 × 1.5)"
|
||
quantity_rule: "트리거 발생 시 50% 손절, 종가 회복 실패 시 잔여 50%"
|
||
prohibition:
|
||
- "ATR20 미확인 시 -7~-10% 범위 임의 선택 금지. -8% 고정 또는 DATA_MISSING."
|
||
- "ATR 기준 손절가와 % 기준이 다르면 더 높은 값(보수적) 채택."
|
||
- "ATR20_Pct < 8%인 일반 종목에 2.0배 적용 금지. extended_rule 조건 미충족 시 1.5배만."
|
||
satellite: # [P131] 위성 ATR 기준
|
||
primary_rule: "20일 ATR 2.0배 이탈 기준"
|
||
fallback_rule: "ATR20 미산출 시 매수가 -12% 고정"
|
||
quantity_rule: "트리거 발생 시 70%, 종가 회복 실패 시 잔여 30%"
|
||
emergency: "60일선 이탈·실적쇼크·회계·거래정지 리스크는 전량 가능"
|
||
legacy_position_protocol: # [P147] 사후 뒷북 손절 방지 — 기존 포지션 처리 원칙
|
||
detection_rule: # [R5] 레거시 포지션 식별 기준
|
||
primary: "capture_read_ledger 판독 결과에서 해당 종목의 stop_price 필드가 0이거나 누락"
|
||
secondary: "performance_evidence 로그에 진입 당시 손절가 기록이 없는 포지션"
|
||
output_tag: "[레거시포지션] 표기 필수. 신규 ATR 손절가 자동 할당 금지."
|
||
condition: "진입 당시 손절가가 미설정된 기존 포지션"
|
||
prohibition: "사후 ATR 손절 기계 적용 금지. 20일선 이탈·수급 악화·time_stop 기준 중 하나로만 청산."
|
||
damaged_position:
|
||
condition: "현재 손실률 -10% 이상"
|
||
action: "시장가 투매 금지. 반등 매도(1차 30~50%) / time_stop 청산 / 논리 훼손 손절 중 택1."
|
||
xref: "stop_loss.gap_down.principle, stop_loss.time_stop"
|
||
gap_down:
|
||
principle: "손절가 아래 갭하락 시 09:00~09:15 전량 시장가 매도 금지. 첫 15~30분 저가·거래대금·회복 여부 기록."
|
||
sea_timing_integration: # [2026-05-19_ALPHA_SHIELD_APEX_V2] SEA001
|
||
rule: >
|
||
장중 갭하락 또는 급락 시 즉시 투매 금지. SEA_TIMING_V1 공식을 호출하여
|
||
현재가가 VWAP을 하향 돌파하거나 15분 RSI가 과매도(30 미만) 구간에서
|
||
반등하는 'Exit Window'를 찾아 분할 매도한다.
|
||
action: "VWAP 하향 돌파 확인 시 TRIM 실행. RSI < 30 구간에서는 반등 시까지 유예."
|
||
high_beta_exception: "고베타 위성은 -5% 이상 갭하락 + 거래대금 300% 이상 폭증 동시 확인 시 50% 우선 축소 가능."
|
||
flow: "외국인·기관 5D 동반 순매도 경고, 20D 수급 이탈 축소"
|
||
time_stop:
|
||
direction_absent_definition: "20일선 ±2% 박스권 + 거래대금 감소가 10거래일 이상 지속"
|
||
core: "60거래일 경과 시 thesis 재검증. 유지 근거 없으면 50% 이상 청산 검토."
|
||
satellite: "30거래일 방향성 없음이면 30% 축소 검토, 60거래일이면 잔여 청산 검토."
|
||
prohibition: "데이터로 확인된 thesis 개선 없이 time_stop 연기 금지."
|
||
reentry:
|
||
basic_condition: "20일선 회복 + 거래대금 증가 + 수급 회복 + 기대수익비 2:1 이상 회복"
|
||
cooling_off:
|
||
default: "최소 5거래일 — 일반 기술적 손절(손절가 하회, 수급 이상 없음)"
|
||
flow_exit: "10거래일 — 수급 이탈 손절(Flow_OK=N 판정). 재진입 시 Flow_OK=Y 재확인 필수."
|
||
system_risk_exit: "거래일 제한 없음 — unified_engine Tier 발동 후 손절. VIX < 25 AND KOSPI 20일선 회복 확인 시에만 재진입 허용."
|
||
double_stop: "60거래일 Watch-only — 동일 종목 30거래일 내 2회 손절"
|
||
cooling_priority_rule: "손절 원인이 복합적이면 더 긴 쿨다운 적용. system_risk_exit > double_stop > flow_exit > default 순."
|
||
prohibition: "손절 다음 날 반등 또는 손실만회 목적 재매수 금지."
|
||
output_examples: "_reference: output_format.unified_example_row_set # [R6] 통합 예시 집합 참조"
|
||
|
||
executable_rules:
|
||
field_dictionary_ref: "spec/12_field_dictionary.yaml:field_dictionary"
|
||
formula_refs:
|
||
stop_price_core: "spec/13_formula_registry.yaml:formula_registry.formulas.STOP_PRICE_CORE_V1"
|
||
trailing_stop_price: "spec/13_formula_registry.yaml:formula_registry.formulas.TRAILING_STOP_PRICE_V1"
|
||
rules:
|
||
- id: "SL001_CORE_STOP_PRICE"
|
||
applies_to: "core"
|
||
inputs: ["entry_price", "atr20", "current_price"]
|
||
formula_ref: "STOP_PRICE_CORE_V1"
|
||
output_fields: ["stop_price", "stop_quantity"]
|
||
quantity_rule: "floor(quantity * 0.50)"
|
||
on_missing: "NO_STOP_PRICE_OR_DATA_MISSING_FALLBACK"
|
||
- id: "SL002_SATELLITE_STOP_PRICE"
|
||
applies_to: "satellite"
|
||
inputs: ["entry_price", "atr20", "quantity"]
|
||
expression: "entry_price - atr20 * 2.0"
|
||
fallback_expression: "entry_price * 0.88"
|
||
output_fields: ["stop_price", "stop_quantity"]
|
||
quantity_rule: "floor(quantity * 0.70)"
|
||
on_missing: "fallback_expression with DATA_MISSING tag"
|
||
- id: "SL003_PRIORITY_MATRIX"
|
||
applies_to: "all_positions"
|
||
inputs: ["time_stop_price", "relative_weakness_exit_price", "trailing_stop_price", "ma20_break_price"]
|
||
expression: "max(available_trigger_prices)"
|
||
output_field: "final_stop_price"
|
||
quantity_source: "highest_priority_trigger"
|
||
on_missing: "ignore missing trigger price; if all missing then NO_STOP_PRICE"
|
||
- id: "SL004_REENTRY_COOLDOWN"
|
||
applies_to: "stopped_out_position"
|
||
inputs: ["exit_reason", "last_exit_date", "current_trade_date"]
|
||
rules:
|
||
- {if: "exit_reason == 'system_risk_exit'", min_wait_trading_days: 0, extra_condition: "VIX < 25 AND KOSPI close > KOSPI_MA20"}
|
||
- {if: "exit_reason == 'double_stop'", min_wait_trading_days: 60}
|
||
- {if: "exit_reason == 'flow_exit'", min_wait_trading_days: 10}
|
||
- {if: "exit_reason == 'default'", min_wait_trading_days: 5}
|
||
output_field: "reentry_allowed"
|
||
on_fail: "WATCH_ONLY"
|
||
|
||
# [proposal_53 / 2026-05-15] 상대강도 약화 매도 규칙 — relative_weakness_exit
|
||
relative_weakness_exit:
|
||
purpose: >
|
||
손실 발생 여부와 무관하게 상대강도 약화 시 선제 교체 매도.
|
||
기회비용 손실을 방지하고 강한 종목·섹터로 자금을 이동한다.
|
||
applicable_to: "위성(satellite) 포지션 전체. 코어는 asymmetric_winner_rule 우선."
|
||
check_frequency: "주간 정기점검(수요일) + 월간 전체 검토"
|
||
weakness_signals:
|
||
RW1_sector_rank_drop: # [proposal_71 / 2026-05-15] 주간 독립 판정 명시
|
||
formula: "sector_flow.Rotation_Score 순위가 2주 연속 3순위 이상 하락"
|
||
score: 1
|
||
check_frequency: "주간 정기점검(수요일)마다 실행. 월별 Tier 갱신 주기와 독립적으로 판정."
|
||
data_source: "sector_priority_ranking.Rotation_Score — 매주 수요일 기준 섹터 순위 비교."
|
||
RW2_relative_underperformance:
|
||
formula: "Ret10D_종목 - Ret10D_주도섹터ETF <= -5%p"
|
||
score: 1
|
||
RW2b_5d_rapid_weakness: # [2026-05-18_ADVANCED_EXIT_V2] 5D 조기 상대약세 경보
|
||
formula: "Ret5D_종목 - Ret5D_주도섹터ETF <= -5%p (5거래일 단기 상대 열위)"
|
||
score: 1
|
||
purpose: >
|
||
RW2(10D 기준)보다 2배 빠른 조기경보. 단기 자본 회전 기회비용 손실을
|
||
선제 포착한다. 섹터가 상승 중임에도 종목만 뒤처질 때 즉각 감지.
|
||
data_source: "Ret5D_Stock (당일 기준 5거래일 수익률), Ret5D_주도섹터ETF (대표 섹터 Proxy ETF)"
|
||
fast_track_exit:
|
||
condition: "RW2b_score == 1 AND (RW1 OR RW3 OR RW4) 중 1개 이상 = 1 (합계 >= 2)"
|
||
action: "TRIM_50 — 일반 RW>=3 조건 충족 전에도 조기 부분 청산"
|
||
rationale: >
|
||
5D 급격한 상대 약세 + 다른 수급/섹터 신호 1개면 추세 이탈 초기 국면.
|
||
RW>=4(70~100%) 기다리지 않고 50% 선제 정리로 기회비용 차단.
|
||
prohibition:
|
||
- "RW2b 단독(1개)으로 fast_track 발동 금지 — 반드시 다른 RW 신호 1개 이상 필요"
|
||
- "fast_track 발동 시 당일 동일 섹터 다른 종목 즉시 매수 금지"
|
||
note: "RW2(10D)와 RW2b(5D) 동시 발동 시 score 중복 합산 금지 — max(RW2, RW2b)=1 적용"
|
||
RW3_flow_deterioration:
|
||
formula: "Frg_5D < 0 AND Inst_5D < 0 (2주 연속 동반 순매도)"
|
||
score: 1
|
||
RW4_volume_fade:
|
||
formula: "AvgTradeValue_5D_M <= AvgTradeValue_20D_M × 0.60"
|
||
meaning: "거래대금 20일 평균 대비 60% 미만으로 감소 (관심 소멸)"
|
||
score: 1
|
||
RW5_ma_breach:
|
||
formula: "Close < MA20 AND Close < MA60 (20일선·60일선 동시 하회)"
|
||
score: 1
|
||
exit_rule:
|
||
four_or_more: "RW1+RW2+RW3+RW4+RW5 >= 4 → 70~100% 청산. 지정가 분할."
|
||
three: "합계 == 3 → 50% 부분 청산 검토. 다음 점검일까지 재확인."
|
||
two_or_less: "합계 <= 2 → 유지"
|
||
fast_track_note: > # [2026-05-18_ADVANCED_EXIT_V2]
|
||
RW2b_5d_rapid_weakness가 포함된 합계 >= 2 시 fast_track_exit.TRIM_50 발동.
|
||
RW2b 없이 일반 RW 합계 <= 2는 기존대로 유지.
|
||
output_table:
|
||
columns: ["종목명", "RW1", "RW2", "RW3", "RW4", "RW5", "합계", "판정", "청산비율(%)", "이동대상"]
|
||
pyramiding_interaction: # [proposal_66 / 2026-05-15] RW >= 4와 pyramiding 증액분 청산 순서
|
||
purpose: >
|
||
RW 신호 합계 >= 4 발동 시 pyramiding 증액분을 먼저 청산한 후
|
||
나머지 70% 기준을 달성하는 순서를 고정한다.
|
||
execution_sequence:
|
||
step_1_pyramiding_first:
|
||
condition: "RW >= 4 AND 해당 종목에 pyramiding 증액분 보유"
|
||
action: "pyramiding 2차 증액분 → 1차 증액분 순으로 전량 우선 청산 (지정가 분할, 역순)"
|
||
rationale: "가장 늦게 진입한 수량이 가장 먼저 나온다 (단계 역순 원칙)"
|
||
step_2_check_70pct:
|
||
condition: "증액분 청산 후 총 청산률 70% 도달 여부 확인"
|
||
if_below_70:
|
||
action: "stage_2 확인매수 수량도 추가 청산. 총 청산 70% 충족 시 중단."
|
||
if_above_70:
|
||
action: "증액분만으로 70% 충족. stage_1·2 잔여 수량 유지."
|
||
step_3_no_pyramiding:
|
||
condition: "RW >= 4 AND pyramiding 증액분 없음"
|
||
action: "기존 exit_rule 그대로 적용 (70~100% 청산)"
|
||
prohibition:
|
||
- "단계 역순을 무시하고 평단가 최저 수량부터 먼저 청산 금지"
|
||
pyramiding_exit_quantity_formula: # [proposal_78 / 2026-05-15] pyramiding 물량 × RW 청산 수량 정확 계산
|
||
purpose: "pyramiding 단계별 물량(원물량+1차+2차)과 RW 부분청산 비율 적용 시 정확한 수량 계산 공식"
|
||
formula:
|
||
step_1: "총보유량 = 원물량(A) + 1차증액(B) + 2차증액(C)"
|
||
step_2: "청산목표주 = floor(총보유량 × 청산비율) [정수 절사 필수]"
|
||
step_3: "청산 순서: C(2차증액) 우선 → B(1차증액) → A(원물량) 역순"
|
||
step_4: "누적 청산주 >= 청산목표주 도달 시 중단. 잔여는 다음 단계에서 계속 보유."
|
||
rate_by_rw:
|
||
RW_3: "청산비율 30~50% (원칙: 40%). stage_1 탐색 종목은 50% 우선 적용."
|
||
RW_4plus: "청산비율 70~100% (원칙: 80%). 단, A_core 등급 종목은 70% 상한."
|
||
example:
|
||
holdings: "원물량 50주(A) + 1차증액 30주(B) + 2차증액 20주(C) = 총 100주"
|
||
RW_3_40pct: "목표 40주. C 20주 전량 → B에서 20주. 합계 40주 청산."
|
||
RW_4_80pct: "목표 80주. C 20주 → B 30주 → A에서 30주. 합계 80주 청산."
|
||
output_requirement: "블록4 플레이북에 [단계별 청산 수량] 테이블 출력 필수"
|
||
prohibition:
|
||
- "청산 순서 역으로(A 먼저) 청산 금지"
|
||
- "소수점 청산 수량 산출 금지 — floor 정수 처리 필수"
|
||
prohibition:
|
||
- "수익 중 종목이라도 RW >= 4이면 청산 강행 (수익 보호 명목 청산 연기 금지)"
|
||
- "청산 자금을 당일 즉시 다른 종목 매수에 투입 금지 (take_profit.redeployment_rule 준수)"
|
||
|
||
# ── [2026-05-18_FINANCIAL_HEALTH_V1] 재무 Thesis 훼손 매도 트리거 ──────────
|
||
# 수급·기술 신호와 독립적으로 재무 펀더멘털이 악화될 때 발동.
|
||
# 특히 중장기(30~60거래일) 보유 코어·위성 모두 해당.
|
||
fundamental_thesis_break:
|
||
purpose: >
|
||
진입 당시의 투자 thesis(실적 성장, 수익성 유지)가 재무 데이터로 부정될 때
|
||
수급 강세 여부와 무관하게 청산 또는 비중 축소를 강제한다.
|
||
"주가는 오르는데 재무는 무너지고 있다"는 함정을 방지한다.
|
||
check_frequency: "분기 실적 발표 직후 + 월간 전체 검토"
|
||
applicable_to: "코어·위성 모두 적용. ETF는 해당 없음."
|
||
triggers:
|
||
FTB1_roe_collapse:
|
||
condition: >
|
||
roe_pct 전분기 대비 50% 이상 급락
|
||
(예: ROE 20%→8% = 60% 하락) AND 현재 ROE < 10%
|
||
severity: "HIGH"
|
||
action: "TRIM_50 — 비중 50% 축소. 다음 분기 발표까지 재확인."
|
||
rationale: "ROE 급락은 수익성 구조 훼손 신호. 수급 강세로 가려질 수 있음."
|
||
FTB2_margin_to_loss:
|
||
condition: "operating_margin_pct 양수→음수 전환 (영업이익 흑자→적자)"
|
||
severity: "HIGH"
|
||
action: "EXIT_70 — 70% 즉시 청산. 영업적자 종목 보유 원칙 위반."
|
||
rationale: >
|
||
영업적자 전환은 thesis_break 가장 강한 신호.
|
||
stock_model.reject 조건 '적자 지속+테마성 급등'의 조기 포착.
|
||
FTB3_debt_spike:
|
||
condition: >
|
||
debt_to_equity가 전기 대비 2배 이상 급증 AND 현재 debt_to_equity > 200%
|
||
(금융업 제외)
|
||
severity: "MEDIUM"
|
||
action: "TRIM_30 — 30% 비중 축소. 자금 조달 구조 점검 필요."
|
||
rationale: "부채 급증은 희석·유동성 위기 선행 지표."
|
||
FTB4_fcf_chronic_negative:
|
||
condition: "FCF_B < 0 연속 2분기 이상 AND debt_to_equity > 150%"
|
||
severity: "MEDIUM"
|
||
action: "EXIT_REVIEW — 다음 점검일까지 thesis 재검토. 수급 이상 없으면 TRIM_30."
|
||
rationale: "FCF 만성 음수 + 고부채 = 현금 고갈 위험."
|
||
interaction_with_rw:
|
||
rule: >
|
||
FTB 트리거 + RW 신호 동시 발동 시 둘 중 더 강한 청산 비율 적용.
|
||
FTB2(영업적자 EXIT_70)가 RW3(TRIM_50)보다 강하면 EXIT_70 실행.
|
||
data_vintage_rule:
|
||
rule: >
|
||
분기 실적 발표일로부터 90일 이상 경과한 재무 데이터는 STALE 취급.
|
||
FTB 트리거 발동 전 재무 데이터 최신성 확인 필수.
|
||
stale_action: "FTB 적용 보류. DATA_STALE_FTB 태그 출력 후 다음 발표일 이후 재확인."
|
||
missing_policy:
|
||
financial_data_missing: >
|
||
재무 데이터 미제공 시 FTB 트리거 적용 금지.
|
||
단, FTB 적용 불가 이유를 보고서에 명시: "[FTB불가: 재무데이터 미확인]"
|
||
prohibition:
|
||
- "재무 데이터 미확인 상태에서 FTB 이유로 임의 청산 금지"
|
||
- "FTB 트리거 없이 재무 '우려'만으로 전량 시장가 청산 금지"
|
||
- "영업이익이 있는 종목에 FTB2(적자 전환) 적용 금지"
|
||
- "1회성 특별손실(일회성 비용)을 영업적자로 오판하여 FTB2 발동 금지"
|
||
output_table_columns: ["종목명", "FTB_트리거", "현재ROE(%)", "영업이익률(%)", "D/E", "FCF방향", "심각도", "조치", "데이터최신성"]
|
||
|