Files
QuantEngineByItz/spec/strategy/action_matrix.yaml
kjh2064 416da59607 WBS-8.7: spec-code synchronization expanded to 66.4% (93/140 files)
Coverage improvement: 24.07% (39 files) → 66.4% (93 files)
- Tagged 54 additional spec files with has_code_implementation: true
- Covered: strategy/*, risk/*, exit/*, formulas/*, governance/*, contracts
- Target: 50% (81 files) — EXCEEDED by 12 files

Files tagged:
- spec/strategy: 20 files (action_matrix, entry_core, entry_gates, etc.)
- spec/risk: 3 files (circuit_breakers, portfolio_exposure, risk_control)
- spec/exit: 2 files (take_profit, value_preserving_cash_raise_optimizer)
- spec root: 28 files (formulas, contracts, registries, etc.)
- spec/03_formulas: 2 files (formula_registry, output_field_owner_ledger)
- spec/data_quality: 1 file (expectations)
- spec/fields: 1 file (field_dictionary)
- spec/formulas: 1 file (manifest)

Impact:
- Improved LLM radar discoverability for spec-to-code linkage
- Ready for WBS-9.6 (LLM document optimization phase)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-22 23:51:58 +09:00

176 lines
11 KiB
YAML
Raw Permalink 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: "은퇴자산포트폴리오 — Final_Action 결정 매트릭스"
version: "2026-05-17-action_matrix_v1"
language: "ko-KR"
role: "canonical"
has_code_implementation: true
code_path: ["spec/strategy/action_matrix.yaml"]
purpose: >
gas_data_feed.gs의 Allowed_Action(매수 게이트) + calcSellDecision_(매도) +
calcFinalDecision_(통합)이 어떤 조건에서 어떤 Final_Action을 출력하는지
단일 진실 소스로 문서화한다.
"왜 지금 매수/매도인가"의 패턴을 Action_Reason 컬럼과 함께 읽으면 된다.
# ─────────────────────────────────────────────────────────────────────────────
# canonical_fields
# ─────────────────────────────────────────────────────────────────────────────
canonical_fields:
Final_Action:
role: "외부 소비 canonical field — getDailyBrief, API, ChatGPT 모두 이 값을 참조"
allowed_values:
SELL_READY: "Sell_Validation=PASS — 즉시 HTS 주문 가능"
SELL_CHECK_QTY: "Sell_Action 있으나 보유수량 미확인 — 사용자가 확인 후 주문"
EXIT_SIGNAL: "Allowed_Action=EXIT_SIGNAL (RW>=3 또는 STOP_OR_TIME_EXIT_READY)"
EXIT_REVIEW: "Allowed_Action=REVIEW_EXIT (RW=2 또는 EXIT_REVIEW)"
BUY_STAGE1_READY: "SS001_Grade A + Entry_Mode_Gate=PASS + Timing=BUY_STAGE1_READY"
BUY_BREAKOUT_PILOT_ONLY: "SS001_Grade A + 돌파 파일럿 진입 조건 충족"
BUY_PULLBACK_WAIT: "SS001_Grade A/B + 눌림목 대기 (진입 타이밍 준비)"
WATCH_TIMING_SETUP: "SS001_Grade A/B이지만 타이밍 미충족 — Allowed_Action=WATCH_CANDIDATE"
NO_BUY_OVERHEATED: "과열 지표 발동 (AC_Gate=BLOCK 또는 Val_Surge 과도)"
HOLD: "그 외 전체 — Allowed_Action(NO_ADD/HOLD/HOLD_NO_ADD/OBSERVE_ONLY)으로 세분"
Action_Params:
role: "실행 파라미터 압축 — 외부 소비자(getDailyBrief·API·ChatGPT)가 즉시 사용 가능한 실행 정보"
format:
SELL_READY: "{ratio}% {qty}주 @{price}원 | {executionWindow} | {orderType}"
SELL_CHECK_QTY: "{sellAction} | 보유수량 미확인"
EXIT_SIGNAL/EXIT_REVIEW: "보유수량 미확인 — HTS 확인 필요"
BUY_*: "목표 {posSizeQty}주 | 손절 {stopPriceEst}원 | TP1 {tp1Price}원({tp1Qty}주)"
WATCH_TIMING_SETUP: "대기 — {timingBlockReason}"
HOLD/etc: "" # 빈 문자열
Action_Reason:
role: "왜 이 Final_Action인가를 한 문자열로 요약 — 사람이 읽는 컬럼"
format:
SELL_READY: "{sellDetailLabel} {qty}주 @{limitPrice}원 [{sellReason}]"
EXIT_SIGNAL/EXIT_REVIEW: "RW{n}({RW1+RW2...}) {exitSignalDetail}"
BUY_*: "SS001:{grade}{normScore}점 RSI{rsi} 이격{disp}% FC{fc}"
WATCH_TIMING_SETUP: "SS001:{grade}{normScore}점 타이밍미충족({timingBlockReason})"
HOLD: "HeatBlock({heatPct}%) | {regime} | SS001:{grade}"
NO_ADD: "수급이탈 | 거래대금{억}억 | 스프레드{pct}% | {regime}"
HOLD_NO_ADD: "DART:{risk} | 과열({acGate})"
OBSERVE_ONLY: "PRICE_MISSING({priceStatus})"
Allowed_Action:
role: "내부 계산 중간값 — 매수 게이트 판정. 외부 소비 시 Final_Action 우선."
allowed_values:
OBSERVE_ONLY: "가격 데이터 없음 — 모든 계산 불가"
HOLD: "HF005 BLOCK, 레짐 차단, 또는 SS001_Grade C"
NO_ADD: "수급이탈 / 거래대금 부족 / 스프레드 과도 / 레짐 차단(미보유)"
HOLD_NO_ADD: "DART 리스크 또는 과열 게이트"
EXIT_SIGNAL: "RW_Partial >= 3 또는 Timing_Action=STOP_OR_TIME_EXIT_READY"
REVIEW_EXIT: "RW_Partial >= 2 또는 Timing_Action=EXIT_REVIEW"
WATCH_CANDIDATE: "SS001_Grade A/B이지만 타이밍 미충족"
BUY_STAGE1_READY: "SS001_Grade A + 타이밍 충족"
BUY_BREAKOUT_PILOT_ONLY: "SS001_Grade A + 돌파 파일럿"
BUY_PULLBACK_WAIT: "SS001_Grade A/B + 눌림목 대기"
# ─────────────────────────────────────────────────────────────────────────────
# 매수 패턴 매트릭스
# ─────────────────────────────────────────────────────────────────────────────
buy_action_matrix:
purpose: "SS001_Grade × Timing_Action × 제약 → Final_Action 결정 규칙"
BUY_STAGE1_READY:
required_all:
- SS001_Grade: "A"
- Timing_Action: "BUY_STAGE1_READY"
- Entry_Mode_Gate: "PASS"
blocked_if_any:
- heatBlock: true # globalHeatPct >= 10%
- isRiskOffRegime: true # RISK_OFF or RISK_OFF_CANDIDATE
- dartRisk: true
- liquidityFail: true # flow.ok=F or avgTV5D<50 or spread>0.8%
caution_if:
- heatCaution: true # 7~10% → Pos_Size_Qty × 0.5 & Action_Reason에 표기
action_reason_template: "SS001:A{score}점 RSI{rsi} 이격{disp}% FC{fc}"
BUY_BREAKOUT_PILOT_ONLY:
required_all:
- SS001_Grade: "A"
- Timing_Action: "BUY_BREAKOUT_PILOT_ONLY"
- Entry_Mode_Gate: "PASS"
blocked_if_any: [heatBlock, isRiskOffRegime, dartRisk, liquidityFail]
note: "돌파 파일럿 — 전체 수량의 30~50%만 진입. Entry_Mode=BREAKOUT."
BUY_PULLBACK_WAIT:
required_any:
- {SS001_Grade: "A", Timing_Action: "BUY_PULLBACK_WAIT"}
- {SS001_Grade: "B", Timing_Action: "BUY_PULLBACK_WAIT"}
blocked_if_any: [heatBlock, isRiskOffRegime, dartRisk, liquidityFail]
note: "눌림목 대기 — 진입 타이밍 준비 중. 지정가 주문 미리 설정 권장."
WATCH_TIMING_SETUP:
required_all:
- SS001_Grade: ["A", "B"]
timing_condition: "Timing_Action not in [BUY_STAGE1_READY, BUY_BREAKOUT_PILOT_ONLY, BUY_PULLBACK_WAIT]"
note: "등급은 되지만 타이밍 미충족. Action_Reason에 구체적 미충족 이유 표기."
# ─────────────────────────────────────────────────────────────────────────────
# 매도 패턴 매트릭스
# ─────────────────────────────────────────────────────────────────────────────
sell_action_matrix:
purpose: "매도 신호 발생 시 Final_Action 결정 규칙. spec/exit/stop_loss.yaml sell_signal_priority와 연동."
SELL_READY:
trigger: "calcSellDecision_()의 Sell_Validation = PASS"
substates:
EXIT_100: "손절전량 — STOP_OR_TIME_EXIT_READY 또는 RW_Partial >= 4"
REGIME_TRIM_50: "레짐 50% 축소 — getDailyBrief 포트폴리오 경고로 이동 (방향 A: 개별 종목 신호 아님)"
TRIM_70: "RW청산 70% — RW_Partial >= 3 또는 Timing_Exit_Score >= 75"
TRAILING_STOP_BREACH: "트레일링이탈 70% — close <= trailing_stop_price 직접 체크"
TRIM_50: "RW부분 50% — RW_Partial >= 2 OR (RW_Partial >= 1 AND Timing_Exit_Score >= 50). RW_Partial=0 단독 기술지표로는 TRIM_50 불가."
PROFIT_TRIM_50/35/25: "익절 사다리 — Profit_Pct >= 50/30/20"
TAKE_PROFIT_TIER1: "TP1 익절 25% — Profit_Pct >= 10"
TIME_EXIT_100: "타임스탑 전량 — Days_To_Time_Stop <= 0 (spec priority 6)"
TIME_TRIM_50: "타임스탑 50% — Days_To_Time_Stop <= 7 (spec priority 6)"
canonical_price_field: Sell_Limit_Price
canonical_qty_field: Sell_Qty
action_reason_template: "{label} {qty}주 @{price}원 [{reason}]"
note: >
복수 조건 동시 발동 시 SL003_PRIORITY_MATRIX 적용:
Sell_Limit_Price = max(모든 발동 조건의 후보가격). priceSource=PRIORITY_MATRIX_MAX.
EXIT_SIGNAL:
trigger: "Sell_Validation != PASS AND (RW_Partial >= 3 OR Timing_Action=STOP_OR_TIME_EXIT_READY)"
action_reason_template: "RW{n}({items}) {exitSignalDetail}"
note: "보유수량 미확인 상태. 사용자가 HTS에서 보유수량 확인 후 주문."
EXIT_REVIEW:
trigger: "RW_Partial >= 2 OR Timing_Action=EXIT_REVIEW"
action_reason_template: "RW{n}({items}) 검토"
note: "매도 검토 단계. 다음 영업일 재확인 권장."
# ─────────────────────────────────────────────────────────────────────────────
# Action_Priority 우선순위 숫자 (calcFinalDecision_ 기준)
# ─────────────────────────────────────────────────────────────────────────────
action_priority_table:
10: SELL_READY
20: SELL_CHECK_QTY
28: EXIT_SIGNAL
32: EXIT_REVIEW
50: NO_BUY_OVERHEATED
60: BUY_STAGE1_READY
70: BUY_BREAKOUT_PILOT_ONLY
80: BUY_PULLBACK_WAIT
90: WATCH_TIMING_SETUP
99: HOLD
note: "낮을수록 우선순위 높음. Final_Rank는 Priority_Score 기준 내림차순 정렬 후 부여."
# ─────────────────────────────────────────────────────────────────────────────
# 브리핑 출력 형식 (getDailyBrief — C-1 재구조화)
# ─────────────────────────────────────────────────────────────────────────────
brief_format:
canonical_source: "Final_Action (not Allowed_Action)"
sort_within_group: "Final_Rank 오름차순 (Priority_Score 기반)"
sections_order:
1: "SELL_READY — 즉시 HTS 주문 가능"
2: "EXIT_SIGNAL / EXIT_REVIEW — 보유수량 확인 후 매도"
3: "BUY — 진입 조건 충족 (BUY_STAGE1_READY / BUY_BREAKOUT_PILOT_ONLY / BUY_PULLBACK_WAIT)"
4: "WATCH — 타이밍 대기 (WATCH_TIMING_SETUP)"
5: "HOLD / BLOCK — Allowed_Action으로 세분 표시"
dedup_rule: >
같은 종목이 SELL_READY이면서 EXIT_SIGNAL도 발생할 수 있다.
Final_Action=SELL_READY가 최우선 — SELL_READY 섹션에만 출력.
action_reason_display: "각 종목 한 줄에 Action_Reason 출력 → '왜'를 즉시 파악 가능"