Files
QuantEngineByItz/spec/02_data_contract.yaml
T

360 lines
25 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: "RetirementAssetPortfolio.yaml"
version: "2026-05-15-F1_modular"
language: "ko-KR"
timezone: "Asia/Seoul"
has_code_implementation: true
code_path: "tools/validate_specs.py"
purpose: "메인 manifest에서 로드되는 구조화 규칙 명세 파일."
quant_feed_contract:
primary_raw_json:
file: "GatherTradingData.json"
source_workbook: "GatherTradingData.xlsx"
role: "provided_raw_analysis_data_json"
priority: "highest_user_provided_market_data"
schema_version: "2026-05-18-json-raw-data-v1"
required_paths:
- "data.data_feed"
- "data.sector_flow"
- "data.macro"
- "data.event_risk"
- "data.core_satellite"
conversion_tool: "tools/convert_xlsx_to_json.py"
usage_rule:
- "종목 후보, 가격, 수급, 섹터 흐름, 매크로, 이벤트 위험은 이 JSON을 1차 raw 데이터로 사용한다."
- "xlsx는 GAS/Google Sheets 원본·감사·JSON 재생성 소스이며 일반 LLM 분석에서 직접 파싱하지 않는다."
- "공개 웹 조회는 JSON 누락·오래됨·충돌 검산용 보조 소스다."
- "JSON 값과 웹 조회 값이 충돌하면 data_rule.conflict_action을 적용하고 평균값을 사용하지 않는다."
validation_tool: "tools/validate_data_sample_json.py"
mapping_file: "spec/14_raw_workbook_mapping.yaml"
account_snapshot_contract: "spec/15_account_snapshot_contract.yaml"
prohibition:
- "JSON이 제공된 상태에서 웹 데이터만으로 종목 점수·수량을 확정하지 않는다."
- "JSON에 없는 필드를 LLM이 임의 생성하지 않는다."
- "JSON 검증 실패 상태에서 BUY·SELL 수량을 확정하지 않는다."
source_priority:
0: "사용자 제공 raw 데이터: 'GatherTradingData.json'.data[core_satellite,event_risk,macro,sector_flow,data_feed]"
1: "AI 직접 공개 데이터 조회: Naver Finance, Yahoo Finance, KRX, OpenDART"
2: "사용자 제공 원자료: HTS, 증권사, FnGuide, KRX, 네이버금융 화면"
3: "부록 자동화 산출물: 공개 URL·기준시각·필드 의미 검증된 경우에만"
account_holdings_snapshot:
file: "사용자 캡처/원장 자료"
usage: "계좌별 보유수량·평단·평가금액·현금 raw 원장. Quantity·Avg_Cost·Cash_Available 없이 정수 주문수량 산출 금지."
prohibition:
- "공개 데이터로 보유수량·평단·현금을 추정하지 않는다."
- "ticker_master·data_feed.csv에 있다는 이유로 실제 보유 중이라고 단정하지 않는다."
- "자동투자 화면 월 적립금액을 잔고·보유수량으로 환산하지 않는다."
screen_type_separation:
canonical_ref: "spec/00_execution_contract.yaml:capture_read_ledger.screen_type_rule"
note: "[XREF / proposal_120] 이 섹션 대신 capture_read_ledger.screen_type_rule을 읽는다."
image_extraction_rules:
label_first_principle: "화면 내 숫자를 먼저 읽지 않는다. 숫자 왼쪽 또는 위쪽 라벨을 먼저 확인하고 계좌·항목을 특정한 뒤에만 값을 추출한다."
exclude_screens:
if_contains_any: ["투자내역 상세", "회차당 투자금액", "투자 회차", "모으기 신청일", "다음 투자(예정)일", "한도설정금액", "한도사용금액", "납입가능금액", "ISA 가입 정보", "isa 10년투자", "10년 연금저축", "매월 1일 투자"]
action: "CAPTURE_PROVIDED_BUT_NOT_HOLDINGS로 분류하고 예수금 판독 제외"
direct_cash_read:
rule: "총금액 - 평가금액 계산 방식은 사용"
required_confirmation:
- "어떤 계좌(일반계좌/ISA/연금저축)의 예수금인지 라벨로 먼저 확인"
- "'예수금' 또는 '주문가능금액' 라벨 확인 후 값 추출"
- "원화(원) 단위 확인"
validation: "예수금 >= 0 확인. 상식 범위 벗어나면 판독 재확인 요청."
direct_public_lookup:
steps:
- "KRX: 상장상태·시장구분·가격·거래대금·시가총액·투자자별 거래"
- "OpenDART: 공시 원문·실적·계약·증자·CB/BW·지분변동 촉매·리스크"
- "Naver Finance: 가격 보조·거래대금·외국인·기관 5D/20D 순매매"
- "Yahoo Finance: OHLC 보조·ATR20·20/60거래일 수익률"
rule: "모든 숫자에 기준일·기준시각·출처·데이터태그 필수. [웹확인:출처명] 또는 [계산값] 태그."
investor_flow_rules:
source: "'GatherTradingData.json'.data.data_feed, 'GatherTradingData.json'.data.core_satellite, Naver Finance frgn 또는 KRX 투자자별 거래 직접 조회"
accepted_fields: ["Frg_5D(sh)", "Inst_5D(sh)", "Frg_20D(sh)", "Inst_20D(sh)", "Ind_5D(sh)", "Flow_Rows", "Flow_Unit=shares", "Flow_OK"]
individual_flow:
field: "Ind_5D(sh) — 개인 5D 순매수(주식수)"
purpose: "과열 경보 및 수급 우위 확신도 보조 확인. A등급 gating 조건에는 포함하지 않는다."
scoring_rules:
high_conviction: "Frg_5D↑ + Inst_5D↑ + Ind_5D↓ → 스마트머니 집중·개인 이탈. 수급 우위 확신도 상향."
caution_signal: "Frg_5D↓ + Inst_5D↓ + Ind_5D↑ → 개인 쏠림 경계. 신규 진입 시 과열 위험 표시."
late_cycle: "외인·기관·개인 모두 순매수 → 추세 후반부 가능성. 추격매수 주의."
not_required: "Ind_5D(sh)가 DATA_MISSING이어도 Flow_OK 판정에는 영향 없음."
caution:
- "Flow_OK=Y가 아니면 외국인·기관 수급 점수 0점."
- "Flow_Rows<20이면 20D 수급 판단 금지."
- "주식 수 단위 수급을 금액 수급으로 임의 환산 금지."
- "Frg_20D(M), Inst_20D(M)은 legacy 더미 컬럼이므로 사용 금지."
- "Ind_5D(sh)는 보조 경보 필드다. 개인 순매수라는 이유만으로 A등급 하향 또는 매도 결정 금지."
active_quality_gate:
# [Q4 / 2026-05-15] C1/C2/C3 시간 기준 미명시로 LLM이 모두 5D로 오산출하거나
# C3의 5D 합산을 "당일" 수급으로 오독하는 할루시네이션 방지.
formula: "flow_credit = C1 × 0.30 + C2 × 0.30 + C3 × 0.40"
time_scope_summary: "C1·C2는 당일 단일 바 기준, C3는 최근 5거래일 누적 기준. 혼용 금지."
components:
C1_price_action:
time_scope: "당일 단일 바 (종가 vs 시가, 또는 종가 vs 전일 종가)"
definition: "당일 종가가 시가 이상(양봉) 또는 전일 대비 상승 시 1점, 미충족 시 0점"
weight: 0.30
C2_volume_action:
time_scope: "당일 거래량 vs 최근 5거래일 평균거래량 (AvgVolume_5D_shares 단위 — 주식 수. AvgTradeValue_5D_M 억원 단위 혼용 금지)"
definition: "당일 거래량이 최근 5일 평균의 120% 이상 시 1점, 미충족 시 0점"
weight: 0.30
C3_flow_action:
time_scope: "최근 5거래일 누적 순매수 (Frg_5D_sh + Inst_5D_sh 합산. 주식 수 단위)"
definition: "외국인+기관 합산 5D 순매수 양수 시 1점, 미충족 시 0점"
weight: 0.40
tier_threshold:
대형: "5D평균거래대금 >= 1,000억 → 기관 합산 순매수 50K주/일 이상 확인 권고"
중형: "5D평균거래대금 100억~1,000억 → 10K주/일 이상"
소형ETF: "5D평균거래대금 < 100억 → 2K주/일 이상"
pass_condition: # [P130] 예외 조건 구조화 — 문자열 매몰 제거
full_credit:
threshold: "flow_credit >= 0.70"
action: "수급 가점 100% 부여"
partial_credit:
threshold: "0.40 <= flow_credit < 0.70"
action: "수급 가점 30%만 인정"
override_to_reject:
condition: "C1 == 0 AND C2 == 0"
action: "reject 처리 (C3 단독 충족 = 물량 받기로 간주)"
reject:
threshold: "flow_credit < 0.40"
also_reject_if: "C1 == 0 AND C2 == 0 (flow_credit 수치 무관)"
action: "수급 점수 0점. kelly.brake_conditions 발동 검토."
prohibition:
- "주가 하락 중 기계적 순매수만 유입되는 '물량 받기' 종목을 A등급으로 추천 금지"
- "C3만 충족(C1·C2 모두 0점)인 경우 flow_credit 수치에 관계없이 reject 처리"
- "flow_credit 미산출 상태에서 수급 기반 A등급 부여 금지"
data_completeness_gate:
buy_ready: "identity·price_value·investor_flow(20D)·volatility_atr·momentum_value_surge 모두 OK, DATA_CONFLICT 없음 → A등급·즉시매수 검토"
watch_only: "identity·price_value만 OK → C-관찰까지"
field_status:
OK: "원시값·기준일·출처·단위 모두 확인"
PARTIAL: "일부 행·기간만 확인"
DATA_MISSING: "Plan A/B/C까지 모두 실패"
DATA_CONFLICT: "출처 간 수치 불일치"
NOT_APPLICABLE: "ETF·신규상장 등 구조적 미해당"
fallback_ladder:
ATR20: "Naver 일별시세(sise_day.naver) 21거래일 OHLC로 계산. Naver 실패 시 KRX 또는 보조 Yahoo로 전환. ATR20_OK=Y는 21거래일 OHLC 원시행 확인 시에만."
investor_flow: "Naver 실패 → KRX 투자자별 거래"
trading_value: "KRX 거래대금 또는 Close×Volume 계산값"
mandatory_collection_sequence: ["①종목코드·상장상태", "②가격·거래량·거래대금", "③5D 수급", "④20D 수급", "⑤21거래일 OHLC로 ATR20·MA20·Val_Surge 계산", "⑥52주 고저·목표가 참고", "⑦OpenDART 공시 촉매·리스크", "⑧필드 완성도 매트릭스 출력 후 등급·매매 판단"]
prohibition:
- "필드 완성도 매트릭스 없이 종목 등급 또는 매수·매도 결론 먼저 작성 금지."
- "로컬 파일 부재를 분석 중단 사유로 사용 금지."
- "자동화 실패와 공개 직접 조회 실패를 같은 의미로 사용 금지."
data_maturity_truth_gate:
objective: "데이터 형식 완성도와 실전 성숙도를 분리한다."
required_outputs:
- "data_integrity_score"
- "data_maturity_score"
- "pending_critical_category_count"
- "pending_critical_categories"
maturity_penalty_rule: "PENDING 카테고리는 분모 제외가 아니라 maturity penalty로 반영한다."
report_rule:
- "보고서 첫 섹션에 data_integrity_score와 data_maturity_score를 함께 표시한다."
- "data_integrity_score=100이어도 pending_critical_category_count>0이면 PASS_100 문구를 쓰지 않는다."
json_analysis_protocol:
purpose: "GatherTradingData.json에서 시장 raw 분석 데이터를 빠르게 파싱해 data_completeness_matrix와 판단 입력으로 사용."
python_parsing_baseline:
shell_rule: "PowerShell에서는 Bash heredoc 금지. '@ ... @ | python -' 형식으로 실행."
json_load_rule: "json.loads(Path('GatherTradingData.json').read_text(encoding='utf-8'))를 기본값으로 사용."
required_top_level: ["metadata", "data"]
required_schema_version: "2026-05-18-json-raw-data-v1"
required_paths: ["data.data_feed", "data.sector_flow", "data.macro", "data.event_risk", "data.core_satellite"]
code_column_rule:
text_columns: ["Ticker", "ETF_Code", "Proxy_Ticker", "Base_Ticker", "Constituent_Code", "ETF_Ticker", "Symbol", "ticker"]
normalization: "숫자로 읽힌 91160.0, 5930.0 등은 문자열화 후 6자리 zero-pad 적용."
validation_commands: ["npm run validate-data-sample", "npm run validate-specs"]
xlsx_refresh_rule: "xlsx 원본을 갱신했으면 npm run convert-data-json 실행 후 JSON을 다시 검증한다."
xlsx_analysis_protocol:
purpose: "xlsx는 HTS 잔고·거래내역 판독 또는 raw JSON 재생성 감사를 위한 보조 프로토콜이다. 시장 raw 일반 분석은 json_analysis_protocol을 우선한다."
python_parsing_baseline:
shell_rule: "PowerShell에서는 Bash heredoc 금지. '@ ... @ | python -' 형식으로 실행."
openpyxl_read_rule: "값 점검은 openpyxl.load_workbook(path, data_only=True, read_only=True)를 기본값으로 사용."
header_rows:
gas_output_sheets: "대부분 row1=updated 메타, row2=헤더, row3부터 데이터."
universe: "row1=헤더, row2부터 데이터."
settings: "key-value 구조. 일반 row2 헤더 시트로 오인 금지."
row_count_rule: "ws.max_row는 서식 범위 때문에 3000일 수 있으므로 데이터 행 수로 사용 금지. 첫 컬럼 또는 핵심 키 컬럼 non-empty 행만 센다."
code_column_rule:
text_columns: ["Ticker", "ETF_Code", "Proxy_Ticker", "Base_Ticker", "Constituent_Code", "ETF_Ticker", "Symbol"]
normalization: "숫자로 읽힌 91160.0, 5930.0 등은 문자열화 후 6자리 zero-pad 적용."
access_rule: "열 번호 하드코딩 금지. 헤더 행에서 header_map을 만든 뒤 컬럼명으로 접근."
validation_commands: ["npm run validate-xlsx-source", "npm run convert-data-json", "npm run validate-data-sample", "npm run validate-specs"]
temporary_sheet_rule: "cs_chunk_N은 core_satellite_status.Status=COMPLETE AND Coverage_Pct>=99.9일 때만 삭제 가능."
sheet_diet_policy:
canonical_required: ["data_feed", "sector_flow", "macro", "event_risk", "core_satellite"]
retained_support:
- "settings"
- "account_snapshot"
- "sector_universe"
- "sector_flow_history"
- "etf_nav_manual"
- "universe"
- "monthly_history"
- "performance"
deprecated_sheets:
- "positions"
- "chat_input"
- "etf_raw"
- "core_satellite_status"
- "orbit_gap"
- "asset_history"
transient_delete_when_complete: ["cs_chunk_N"]
rules:
- "orbit_gap·asset_history는 monthly_history(16컬럼)로 통합됐다."
- "etf_raw는 GAS in-memory map 전환으로 시트 쓰기 중단."
- "core_satellite_status는 ScriptProperties로 이전."
- "cs_chunk_N은 core_satellite 병합 완료 후 삭제해 workbook 비대화를 방지한다."
step_1_file_classification:
types:
holdings_xlsx: "보유종목·수량·평단·현금 포함 → CAPTURE_READ_OK"
transaction_xlsx: "거래내역·체결가·수수료 포함 → CAPTURE_READ_OK (거래 검증용)"
step_2_column_mapping:
label_first_principle: "셀 값보다 헤더 행(보통 1~3행)을 먼저 읽어 컬럼 의미를 확정."
required_columns_for_holdings: ["계좌명 또는 계좌번호", "종목명 또는 종목코드", "보유수량(주)", "평균단가(원/주)", "현재가(원/주)", "평가금액(원)", "예수금 또는 주문가능금액(원)"]
unit_validation:
quantity: "정수. 소수 발견 시 PARSE_FAILED."
price: "원/주. 단위 확인 불가 시 DATA_CONFLICT."
amount: "원. 총금액과 단가×수량 오차 1% 초과 시 DATA_CONFLICT."
step_3_data_validation:
cross_check:
- "평가금액 = 보유수량 × 현재가. 오차 0.5% 초과 시 DATA_CONFLICT."
- "예수금 = 총평가금액 - 보유종목 합산 평가금액 (단순 검증)."
hard_stop:
- "헤더 행 없거나 빈 파일 → PARSE_FAILED."
- "수량 열 전체 공백 → unknown_xlsx로 강등."
- "통화 단위가 달러($) → 환율 확인 전 금액 산출 금지."
step_4_ledger_integration:
rule: "유효성 검사 통과 후 capture_read_ledger에 기재."
ledger_row_format: "[파일화면, 계좌, 화면종류, 읽은값, 확신도, 주문표반영, 판독상태]"
step_5_prohibited:
- "research_xlsx의 컨센서스·목표가만으로 보유수량·평단 대체 금지."
- "xlsx의 수익률 컬럼을 실현수익률로 단정 금지 (미실현 포함 여부 불명)."
- "여러 xlsx가 동일 종목 다른 수량 제공 시 → DATA_CONFLICT, 최신 파일 우선 후 사용자 확인."
- "거래내역 xlsx를 잔고 xlsx로 오인 금지."
step_6_supplementary_types:
fnguide_consensus_xlsx: "컨센서스 참고용. 보유수량·주문수량 산출 금지."
trading_history_xlsx: "실현손익 검증용. 잔고 보유수량 추정 사용 금지."
ticker_master:
status: "dynamic_reference_from_latest_account_snapshot"
scope: "첨부 잔고·계좌 원장에서 확인된 보유 종목의 코드 매핑. 후보 유니버스나 고정 보유 목록 사용 금지."
refresh_rule: "최신 계좌 자료에 없는 종목은 보유종목으로 출력 금지. 최신 자료에 새 종목은 KRX 코드 확인 후 임시 매핑."
prohibited_use: ["있다는 이유로 보유 중 단정", "없다는 이유로 분석 제외", "위성 후보 추출 유니버스로 사용"]
data_rule:
canonical: true # [proposal_122 / 2026-05-15] 투자 판단 시 이 섹션의 rules가 최우선. data_snapshot_precedence·anti_hallucination보다 우선.
supersedes: ["data_snapshot_precedence.conflict_rule", "anti_hallucination.precedence"]
required_label: "모든 숫자에 기준시각·출처·데이터유형 표시"
data_tags: ["[사용자입력]", "[웹확인:출처명]", "[판독값]", "[계산값]", "[데이터누락]"]
priority: ["공식기관·거래소·중앙은행", "증권사·FnGuide", "네이버금융·포털"]
strict_unit_enforcement:
units: {shares: "주 (정수)", amount: "원 (정수)", ratio: "% (소수 2자리)", price: "원/주"}
allowed_transform:
- "amount = shares × price"
- "ratio = amount / capital × 100"
- "risk_amount = shares × (entry_price - stop_price)"
- "qty = floor(risk_amount_budget / risk_per_share)"
forbidden_transform:
- "shares + amount → 이종단위 합산 금지"
- "ratio + shares → 비율과 수량 혼합 금지"
- "price - ratio → 가격과 비율 뺄셈 금지"
hard_rule:
- "단위 미확인 시 해당 연산 결과는 산출 불가 처리. 주문수량 0주."
- "소수점 주 발생 시 floor() 적용. 반올림 금지."
rule: "모든 연산 시 단위(원, 주, %)를 교차 검증하며, 이종 단위(예: 수량과 금액)의 산술 연산 시도는 즉시 차단하고 산출 불가 처리한다."
raw_json_trade_value_rule:
preferred: "AvgTradeValue_5D_KRW, AvgTradeValue_20D_KRW"
legacy: "AvgTradeValue_5D_M, AvgTradeValue_20D_M"
legacy_unit: "million KRW"
transform: "legacy_value * 1000000"
prohibition: "AvgTradeValue_*_M을 억원 단위로 해석 금지."
rules:
- "첨부 이미지·잔고표·거래내역의 확인값만 사용. 불명확 숫자는 판독불가."
- "필수 입력 누락 시 정확한 수익률·계좌별 금액·매수수량·세후성과 산출 금지."
- "미확인 수치는 핵심 근거 제외, 점수 산정 시 0점."
- "기준시각이 다른 데이터는 직접 비교 금지."
- "사용자가 공개 화면에서 복사한 수치는 종목코드·항목명·단위·기준시각이 함께 있을 때만 [사용자입력]으로 인정."
freshness_gate:
price_max_age_trading_days: 1
flow_max_age_trading_days: 2
consensus_max_age_calendar_days: 14
macro_max_age_calendar_days: 3
stale_action: {price: "정수수량 산출 금지", flow: "수급 점수 0점", consensus: "실적 점수 50%만 인정", macro: "market_context 기반 가중 판단 금지"}
conflict_action: "DATA_CONFLICT 표시. A등급·즉시매수·정수수량 산출 금지."
alignment_gate:
purpose: "가격·수급·공시 기준시각이 혼재된 상태에서 매수 신호 산출을 차단한다."
required_fields: ["as_of_date(price)", "as_of_date(flow)", "as_of_date(disclosure)"]
alignment_rule: "주문 산출 시 price와 flow의 as_of_date 차이가 1거래일 초과이면 DATA_STALE 처리."
DATA_STALE_action:
- "정수 수량·손절가·익절가·기대수익비 산출 금지"
- "관찰가(진입 후보가) 표기만 허용"
- "다음 확인 출처와 갱신 예정 시각을 함께 표기"
exception: "macro 데이터는 시장 국면 판단에만 사용. 개별 종목 주문 산출에는 price/flow alignment 기준만 적용."
prohibition: "DATA_STALE 상태에서 최신 price와 구형 flow를 조합해 A등급 산출 금지."
anti_hallucination:
role: "supplementary" # [proposal_122 / 2026-05-15] 종목 진위 확인·수치 검증 용도로만 사용. 우선순위는 data_rule.
krx_listing_integrity:
required_before_recommendation: ["종목코드 또는 표준코드", "정식 종목명", "시장구분", "상장상태", "기준일", "데이터 출처"]
hard_reject: ["KRX 공식 종목마스터 미확인 상품", "AI 생성 유사 종목명·존재하지 않는 테마형 ETF명", "코드 없는 ETF 추천"]
historical_price_integrity:
required: ["OHLC 원시데이터 또는 차트의 기준일·주기·수정주가 여부", "고가/종가 기준 명시", "액면분할·병합·권리락 확인"]
rule: "두 출처의 고점이 다르면 DATA_CONFLICT 표시 후 수량 산출 보류. 추세 돌파 판단에는 종가 확인 필수."
mathematical_cross_check:
formula: "conflict_rate = abs(Source_A - Source_B) / max(abs(Source_A), abs(Source_B), 1)"
field_thresholds:
price: "0.005 (0.5%) — 호가 정밀도 기준. 초과 시 즉시 DATA_CONFLICT"
volume: "0.10 (10%) — 집계 단위 차이 허용 범위"
flow_5d: "0.15 (15%) — 기관/외국인 순매수 집계 오차 허용"
atr20: "0.10 (10%) — ATR 계산 기준일 차이 허용"
target_price: "0.20 (20%) — 컨센서스 목표가 분산 허용"
action:
pass: "임계치 이내 → source_priority 상위 소스 사용, 하위 소스는 보조 검산값으로 기록"
fail: "임계치 초과 → DATA_CONFLICT, 해당 종목 신규 매수·매도 수량 산출 금지"
fallback_rule:
- "두 소스 충돌 시 평균값 사용 금지. source_priority 상위 소스만 사용."
- "세 소스 이상 충돌 시 중앙값 대신 출처 신뢰도 우선순위 적용."
- "신뢰도 동률이면 DATA_CONFLICT로 보류 후 사용자 재확인 요청."
rule: "두 출처의 수치 오차율이 field_thresholds를 초과할 경우, DATA_CONFLICT 처리 및 수량 산출 보류. 기존 1% 단일 임계치는 field_thresholds로 대체."
precedence: "→ data_rule.priority 참조 (data_rule이 canonical)"
market_context:
required_fields:
macro: ["KOSPI", "KOSDAQ", "USD/KRW", "VIX", "미국 10년물", "미국 HY OAS", "국내 CP/CD 스프레드", "WTI/Brent"]
macro_sheets_source: "macro 탭 → Category=Index(KOSPI·KOSDAQ·S&P500), Category=Risk(VIX), Category=FX(USD/KRW), Category=Bond(미국10년물), Category=Commodity(WTI)"
leadership: ["주도섹터 1M/3M 상대수익률", "외국인·기관 5D/20D 수급", "거래대금", "52주 신고가"]
leadership_sheets_source: "sector_flow 탭 → Sector_Ret5D/Sector_Ret20D(상대수익률), SmartMoney_5D_KRW/SmartMoney_20D_KRW(수급), Alert_Level·Sector_Score(리더십판단)"
benchmark: ["KOSPI 시총 상위 비중", "삼성전자+SK하이닉스 KOSPI 비중", "포트폴리오 반도체 실질노출"]
benchmark_sheets_source: "data_feed 탭 → 삼성전자(005930)·SK하이닉스(000660) Frg_5D/Inst_5D로 수급 확인 후 비중 판단"
regime_response:
Risk-On: "분할 집행 허용, 추격매수 금지"
실적장세: "컨센서스 상향·수급 확인 종목 우선"
Risk-Off: "신규 위험자산 축소, cash_floor 상향"
Credit-Stress: "위성·중복 ETF·수급 이탈 종목부터 축소"
guardrails:
- "벤치마크 비중 없으면 주도주 초과비중 판단은 DATA_MISSING."
- "신용스프레드 데이터 없으면 credit stress 발동 금지."
- "뉴스 단독으로 위성 전량청산 금지. 가격·수급·신용 중 2개 이상 확인 필요."
liquidity_execution_audit:
required_fields: ["최근 5D/20D 평균거래대금", "주문금액", "주문금액/5D평균거래대금(%)", "호가단위·지정가", "예상 세금·수수료", "예상 순현금"]
pass_condition:
normal_stock: "주문금액이 5D 평균거래대금의 0.25% 이하"
etf: "주문금액이 5D 평균거래대금의 0.5% 이하이며 괴리율·스프레드 과도하지 않음"
hard_gate:
spread_unknown: "호가스프레드 미확인 시 신규매수 금지. 매도도 시장가 금지, 분할 지정가만 허용. 코어는 주문금액 50% 감액."
spread_too_wide: "예상 스프레드+슬리피지가 목표 기대수익의 20% 초과 시 A등급 금지."
volume_pressure: "주문수량이 20D 평균거래량의 1% 초과 시 최소 3회 분할 또는 보류."
thin_book: "호가 공백 3틱 이상 또는 장중 거래대금 급감 시 시장가 금지."
missing_policy:
- "평균거래대금 없으면 주문금액 제시 가능하나 체결가능성은 PARTIAL 표기."
- "예상금액은 지정가 하한 × 수량에서 세금·수수료 차감 전/후 분리."