690 lines
32 KiB
YAML
690 lines
32 KiB
YAML
meta:
|
||
title: "GatherTradingData.json — Raw Data Mapping"
|
||
parent_file: "RetirementAssetPortfolio.yaml"
|
||
version: "2026-05-16-F15_valuation_mapping"
|
||
language: "ko-KR"
|
||
timezone: "Asia/Seoul"
|
||
role: "canonical"
|
||
has_code_implementation: true
|
||
code_path: "src/quant_engine/convert_xlsx_to_json.py"
|
||
purpose: >
|
||
제공 raw JSON의 data.<sheet> 배열과 컬럼을 canonical field로 매핑한다.
|
||
xlsx는 JSON 재생성 소스이며 일반 LLM 분석에서는 직접 파싱하지 않는다.
|
||
Snapshot Admin의 workbook inventory와 migration classification은
|
||
GatherTradingData.xlsx를 직접 읽어서 계산한다.
|
||
이 파일은 시장/종목/섹터/매크로 데이터만 담당하며 계좌·보유·현금 데이터는
|
||
spec/15_account_snapshot_contract.yaml이 담당한다.
|
||
|
||
raw_json:
|
||
file: "GatherTradingData.json"
|
||
source_workbook: "GatherTradingData.xlsx"
|
||
schema_version: "2026-05-18-json-raw-data-v1"
|
||
role: "market_raw_json"
|
||
root_paths:
|
||
metadata: "metadata"
|
||
data: "data"
|
||
required_paths:
|
||
data_feed: "data.data_feed"
|
||
sector_flow: "data.sector_flow"
|
||
macro: "data.macro"
|
||
event_risk: "data.event_risk"
|
||
core_satellite: "data.core_satellite"
|
||
validation_tool: "tools/validate_data_sample_json.py"
|
||
conversion_tool: "tools/convert_xlsx_to_json.py"
|
||
raw_workbook:
|
||
file: "GatherTradingData.xlsx"
|
||
role: "market_raw_workbook_source_for_json"
|
||
header_policy:
|
||
header_search_rows: 8
|
||
meta_row_allowed: true
|
||
required_sheets:
|
||
data_feed:
|
||
role: "보유/관심 핵심 종목 시장 데이터"
|
||
required_columns: ["Ticker", "Name", "Close", "ATR20", "Flow_OK", "Frg_5D", "Inst_5D"]
|
||
recommended_columns:
|
||
- "Open"
|
||
- "PrevClose"
|
||
- "High"
|
||
- "Low"
|
||
- "Volume"
|
||
- "AvgVolume_5D"
|
||
- "MA20"
|
||
- "MA60"
|
||
- "Ret5D"
|
||
- "Ret10D"
|
||
- "Ret20D"
|
||
- "Ret60D"
|
||
- "AvgTradeValue_5D_KRW"
|
||
- "AvgTradeValue_20D_KRW"
|
||
- "TradeValue_Unit"
|
||
- "Timing_Action"
|
||
- "Timing_Score_Entry"
|
||
- "Timing_Score_Exit"
|
||
- "Entry_Mode"
|
||
- "Entry_Mode_Gate"
|
||
- "Entry_Mode_Reason"
|
||
- "Candidate_Quality_Grade"
|
||
- "T1_Forced_Sell_Risk_Score"
|
||
- "T1_Forced_Sell_Risk_State"
|
||
- "Sell_Conflict_Score"
|
||
- "Sell_Conflict_State"
|
||
- "Execution_Recommendation_State"
|
||
- "Forward_PE"
|
||
- "PBR"
|
||
- "EPS_Revision_Status"
|
||
- "EPS_Growth_1Y_Pct" # Yahoo earningsTrend +1y 성장률 → KOSDAQ PEG 계산 (A2)
|
||
- "DividendYield"
|
||
- "DPS" # 주당 배당금 Yahoo lastDividendValue (A4)
|
||
- "ROE_Pct" # 자기자본이익률(%) Yahoo financialData.returnOnEquity×100
|
||
- "Operating_Margin_Pct" # 영업이익률(%) Yahoo financialData.operatingMargins×100
|
||
- "Debt_To_Equity" # 부채비율(D/E) Yahoo defaultKeyStatistics.debtToEquity
|
||
- "Current_Ratio" # 유동비율 Yahoo financialData.currentRatio
|
||
- "FCF_B" # 잉여현금흐름(억원) Yahoo financialData.freeCashflow÷1e8
|
||
- "Revenue_Growth_Pct" # 매출 성장률(%) Yahoo financialData.revenueGrowth×100
|
||
- "Beta"
|
||
- "High52W"
|
||
- "Low52W"
|
||
- "Pct_52W_High"
|
||
- "Pct_From_52W_Low"
|
||
- "Target_Price"
|
||
- "Upside_Pct"
|
||
- "Earnings_Date"
|
||
- "Days_To_Earnings"
|
||
- "Ex_Dividend_Date" # 배당락일 (A4)
|
||
- "Days_To_Ex_Div" # 배당락일 잔여 일수
|
||
- "Timing_Score_Entry" # 진입 타이밍 종합 점수(0~100)
|
||
- "Timing_Score_Exit" # 청산/축소 타이밍 종합 점수(0~100)
|
||
- "Timing_Action" # BUY_STAGE1_READY/NO_BUY_OVERHEATED 등 실행 액션
|
||
- "Timing_Block_Reason" # 타이밍 액션 산출 핵심 사유
|
||
- "Sell_Action" # HOLD/TRIM_50/EXIT_100 등 매도 액션
|
||
- "Sell_Ratio_Pct" # 보유수량 확인 시 적용할 매도 비율
|
||
- "Sell_Qty" # 보유수량 확인 시 정수 매도수량. 미확인 시 blank
|
||
- "Sell_Limit_Price" # HTS 입력용 매도 지정가
|
||
- "Sell_Price_Source" # TP/Trailing/Close 등 가격 출처
|
||
- "Sell_Price_Basis" # PRIOR_CLOSE_X_0.998/TRAILING_STOP_TRIGGER 등 산출 기준
|
||
- "Sell_Execution_Window" # INTRADAY_AFTER_09_30/CLOSE_REVIEW_OR_NEXT_OPEN 등 실행 시간대
|
||
- "Sell_Order_Type" # LIMIT_SELL/PROTECTIVE_LIMIT_SELL
|
||
- "Sell_Reason" # RW_EXIT/TIME_STOP/PROFIT_PROTECT 등 근거
|
||
- "Sell_Validation" # PASS/NO_HOLDING_QTY/NO_SELL_PRICE 등 검산상태
|
||
- "Account_Holding_Qty" # account_snapshot에서 확인한 보유수량
|
||
- "Account_Avg_Cost" # account_snapshot에서 확인한 평단
|
||
- "Account_Market_Value" # account_snapshot에서 확인한 평가금액
|
||
- "Account_Parse_Status" # CAPTURE_READ_OK 등 캡처 판독 상태
|
||
- "Rule_Sell_Qty" # 룰엔진 기본 매도수량
|
||
- "Rebalance_Target_Cash_Pct" # 주간 D+2 현금 목표
|
||
- "Rebalance_Need_KRW" # 목표 D+2 현금까지 부족액
|
||
- "Override_Sell_Qty" # 부족현금만 채우는 최소 조정 매도수량
|
||
- "Override_Reason" # 조정 수량 사유
|
||
- "Override_Validation" # PASS_USER_CASH_TARGET 등
|
||
- "Final_Action" # 룰엔진 최종 액션. LLM 임의 재판단 금지
|
||
- "Action_Priority" # 낮을수록 우선 처리
|
||
- "Priority_Score" # 동일 액션 내 정렬 점수
|
||
- "Final_Rank" # Action_Priority ASC, Priority_Score DESC 기준 순위
|
||
- "Decision_Source" # RULE_ENGINE / RULE_ENGINE_WITH_MISSING_DATA
|
||
- "Limit_Price_Est"
|
||
- "Stop_Price_Est" # account_snapshot 우선, ATR 추정 폴백 (A7)
|
||
- "Stop_Price_Source" # 출처 표시
|
||
- "EE_Est" # Bayesian multiplier 반영 기대우위 (S1)
|
||
- "Pos_Size_Qty" # POSITION_SIZE_V1 간략 추정 수량 (A6)
|
||
- "Breakout_Score"
|
||
- "Breakout_Gate"
|
||
- "AC_S1"
|
||
- "AC_S2"
|
||
- "AC_S3"
|
||
- "AC_S4"
|
||
- "AC_S5"
|
||
- "AC_Total"
|
||
- "AC_Gate"
|
||
- "C1_Price"
|
||
- "C2_RelStr"
|
||
- "C3_VolSurge"
|
||
- "C4_Flow"
|
||
- "C5_Sector"
|
||
- "Leader_Scan_Total"
|
||
- "Leader_Gate"
|
||
- "RW1"
|
||
- "RW2"
|
||
- "RW3"
|
||
- "RW4"
|
||
- "RW5"
|
||
- "RW_Partial"
|
||
core_satellite:
|
||
role: "위성 후보군 시장 데이터"
|
||
required_columns: ["Ticker", "Name", "Sector", "Close", "ATR20", "Flow_OK", "Rotation_Score", "Alert_Level"]
|
||
recommended_columns:
|
||
- "Open"
|
||
- "PrevClose"
|
||
- "High"
|
||
- "Low"
|
||
- "Volume"
|
||
- "AvgVolume_5D"
|
||
- "MA20"
|
||
- "MA60"
|
||
- "Ret10D"
|
||
- "Ret20D"
|
||
- "Ret60D"
|
||
- "AvgTradeValue_5D_KRW"
|
||
- "AvgTradeValue_20D_KRW"
|
||
- "TradeValue_Unit"
|
||
sector_flow:
|
||
role: "섹터 수급·상대강도 canonical 분석 시트"
|
||
required_columns: ["Sector", "Sector_Score", "Sector_Rank", "Alert_Level"]
|
||
status: "canonical"
|
||
usage_limit: >
|
||
옛 sector_flow_v2의 역할을 sector_flow가 대신한다.
|
||
ETF_Code/ETF_Ret* 컬럼명과 Rotation_* 컬럼은 legacy 호환용 별칭이며 실제 의미는 Proxy_Ticker/Proxy_Ret* 및 Sector_Score/Sector_Rank이다.
|
||
Frg_5D_SUM/Inst_5D_SUM은 v2 원화 수급 집계값을 legacy 호환 컬럼에 매핑한 값으로 해석한다.
|
||
added_columns:
|
||
- "Sector_Median_PE"
|
||
- "Sector_Median_PBR"
|
||
- "ETF_Ret10D" # ETF 10일 수익률 → RW2 상대약세 판단 입력
|
||
- "Rotation_Rank" # Sector_Score 내림차순 순위 (1=최고) → C5, RW1 판단
|
||
sector_universe:
|
||
role: "sector_flow canonical 섹터 구성 원장"
|
||
optional_sheet: true
|
||
fallback: "시트가 없으면 gas_data_feed.gs DEFAULT_SECTOR_UNIVERSE_V2 사용 후 sector_universe 기본 템플릿 생성"
|
||
external_seed_policy: "sector_targets.json은 legacy seed/archive이며 실행 입력·LLM 업로드 대상이 아니다."
|
||
canonical_source_note: "sector_flow의 구성종목 universe는 sector_universe 시트 또는 DEFAULT_SECTOR_UNIVERSE_V2만 사용한다."
|
||
required_columns:
|
||
- "Sector"
|
||
- "Proxy_Ticker"
|
||
- "Proxy_Name"
|
||
- "Proxy_Type"
|
||
- "Base_Ticker"
|
||
- "Constituent_Code"
|
||
- "Constituent_Name"
|
||
- "Weight"
|
||
- "Is_ETF"
|
||
- "Enabled"
|
||
- "Effective_Date"
|
||
- "Source"
|
||
aggregation_rule: >
|
||
Is_ETF=Y 행은 proxy/실행상품 식별용으로 보존하되 sector_flow의 구성종목 smart money,
|
||
Flow_Breadth_5D, Coverage_Weight 산출에서는 제외한다. ETF 자체 수급·NAV·괴리율은 후속 etf_raw가 담당한다.
|
||
sector_flow_v2:
|
||
status: "deprecated"
|
||
note: "sector_flow가 sector_flow_v2 canonical 분석 시트를 대체한다."
|
||
quality_gate:
|
||
A: "Coverage_Weight >= 0.80 AND Flow_Rows_Min >= 20 AND Stale_Count=0 AND 원화 수급/거래대금 산출 가능"
|
||
B: "Coverage_Weight >= 0.60 AND 핵심 가격·수급 대부분 정상"
|
||
C: "coverage 부족 또는 proxy/거래대금 일부 누락. Decision_Use=WATCH_ONLY"
|
||
D: "가격·수급 핵심 실패. Decision_Use=INVALID"
|
||
usage_rule: "Data_Quality C/D는 Strong_Buy 또는 섹터 단독 강매도 근거로 사용 금지"
|
||
etf_raw:
|
||
role: "ETF 실행 유동성·자체 수급 원천 시트"
|
||
optional_sheet: true
|
||
required_columns:
|
||
- "Sector"
|
||
- "ETF_Ticker"
|
||
- "ETF_Name"
|
||
- "Close"
|
||
- "NAV"
|
||
- "iNAV"
|
||
- "Premium_Discount_Pct"
|
||
- "Tracking_Error"
|
||
- "AUM"
|
||
- "Bid"
|
||
- "Ask"
|
||
- "Spread_Pct"
|
||
- "AvgTradeValue_5D_KRW"
|
||
- "AvgTradeValue_20D_KRW"
|
||
- "ETF_Frg_5D_KRW"
|
||
- "ETF_Inst_5D_KRW"
|
||
- "LP_Quality_Flag"
|
||
- "ETF_Liquidity_Score"
|
||
- "ETF_NAV_Risk"
|
||
- "ETF_Liquidity_Status"
|
||
- "ETF_Execution_Use"
|
||
- "ETF_Data_Status"
|
||
- "NAV_Source"
|
||
- "NAV_Source_Date"
|
||
limitation: >
|
||
Phase 3 interim은 Yahoo/Naver 기반 가격·스프레드·거래대금·ETF 자체 수급을 자동 산출하고,
|
||
NAV/iNAV/괴리율/추적오차/AUM은 etf_nav_manual 시트 값이 있으면 반영한다.
|
||
수동 NAV 입력이 없으면 blank 및 ETF_NAV_Risk=NAV_DATA_MISSING으로 둔다.
|
||
이 경우 ETF_Execution_Use는 WATCH_ONLY이며 ETF 매매 실행 핵심 근거로 사용하지 않는다.
|
||
etf_nav_manual:
|
||
role: "ETF NAV·괴리율·추적오차 수동 검증 입력 시트"
|
||
optional_sheet: true
|
||
required_columns:
|
||
- "ETF_Ticker"
|
||
- "ETF_Name"
|
||
- "Close"
|
||
- "NAV"
|
||
- "iNAV"
|
||
- "Premium_Discount_Pct"
|
||
- "Tracking_Error"
|
||
- "AUM"
|
||
- "Source_Date"
|
||
- "Source"
|
||
- "Enabled"
|
||
usage_rule: >
|
||
KRX/KIND/운용사 자료를 수동 확인해 입력한다. Enabled=Y 행만 etf_raw에 반영한다.
|
||
Premium_Discount_Pct가 비어 있으면 Close와 NAV 또는 iNAV로 자동 산출한다.
|
||
importer: "tools/import_etf_nav_manual.py — KRX/KIND/운용사 CSV/XLSX export를 etf_nav_manual 시트로 변환. --enable 옵션은 NAV/iNAV와 Source_Date가 있는 etf_raw 매칭 행만 Enabled=Y 처리."
|
||
rebalance:
|
||
role: "리밸런싱 실행 계획 시트 (bucket drift → 레짐 적응 밴드 → 비용효익 게이트 → 3단계 분할 실행)"
|
||
optional_sheet: true
|
||
generator: "tools/build_rebalance_engine_v1.py (Python) + GAS src/gas_adapter_parts/gdf_06_rebalance.gs:runRebalanceSheet_()"
|
||
artifact: "Temp/rebalance_engine_v1.json"
|
||
layout: "multi-section — 4섹션이 단일 시트에 순서대로 배치됨 (구분: === SECTION_NAME === 행)"
|
||
sections:
|
||
SUMMARY:
|
||
description: "포트폴리오 전체 요약 (key-value 2열 형식)"
|
||
fields:
|
||
- "Run_Date" # 실행 시각 (ISO-8601 KST)
|
||
- "Regime" # 시장 레짐 (RISK_ON/NEUTRAL/RISK_OFF 등)
|
||
- "Regime_Band" # 적용된 밴드 레이블 (예: RISK_ON ±15%p)
|
||
- "Total_Portfolio_KRW" # 전체 포트폴리오 평가금액 (원)
|
||
- "Core_Pct" # 현재 코어 비중 (%)
|
||
- "Satellite_Pct" # 현재 위성 비중 (%)
|
||
- "Cash_Pct" # 현재 현금 비중 (%)
|
||
- "Target_Core_Pct" # 목표 코어 비중 (%)
|
||
- "Target_Sat_Pct" # 목표 위성 비중 (%)
|
||
- "Target_Cash_Pct" # 목표 현금 비중 (%)
|
||
- "Rebalance_Needed" # 리밸런싱 필요 여부 (true/false)
|
||
- "Holdings_Count" # 보유 종목 수
|
||
- "Orders_Count" # 생성된 주문 수
|
||
- "Min_Actionable_Drift_Pct" # 최소 실행 기준 드리프트 (%)
|
||
BUCKETS:
|
||
description: "버킷별 드리프트 분석 (행 형식)"
|
||
columns:
|
||
- "Bucket" # Core / Satellite / Cash
|
||
- "Target_Pct" # 목표 비중 (%)
|
||
- "Current_Pct" # 현재 비중 (%)
|
||
- "Drift_Pct" # 드리프트 (현재 − 목표, %)
|
||
- "Band_Min" # 레짐 적응 하단 경계 (%)
|
||
- "Band_Max" # 레짐 적응 상단 경계 (%)
|
||
- "Regime_Band" # 적용 밴드 레이블
|
||
- "Drift_Status" # NORMAL / WARN / BREACH_LOW / BREACH_HIGH
|
||
TICKERS:
|
||
description: "종목별 드리프트 분석 + 강제 신호 + 3단계 분할 수량 (행 형식)"
|
||
columns:
|
||
- "Ticker" # 종목 코드
|
||
- "Name" # 종목명
|
||
- "Bucket" # Core / Satellite
|
||
- "Target_Pct" # 버킷 내 equal-weight 목표 비중 (%)
|
||
- "Current_Pct" # 현재 보유 비중 (%)
|
||
- "Drift_Pct" # 드리프트 (현재 − 목표, %)
|
||
- "Band_Min" # 레짐 적응 하단 경계 (%)
|
||
- "Band_Max" # 레짐 적응 상단 경계 (%)
|
||
- "Regime_Band" # 적용 밴드 레이블
|
||
- "Drift_Status" # NORMAL/WARN/BREACH_LOW/BREACH_HIGH/FORCE_ABS_FLOOR/FORCE_TIME_STOP
|
||
- "Force_Signal" # ABS_FLOOR / TIME_STOP / (empty)
|
||
- "Gate_Status" # PASS / BLOCKED_BY_COST / FORCE_OVERRIDE
|
||
- "Action" # SELL / BUY / WATCH / HOLD
|
||
- "Stage1_Qty" # 1단계 수량 (전체의 30%)
|
||
- "Stage1_Price" # 1단계 지정가 (원)
|
||
- "Stage2_Qty" # 2단계 수량 (전체의 30%)
|
||
- "Stage2_Price" # 2단계 지정가 (원)
|
||
- "Stage3_Qty" # 3단계 수량 (전체의 40%)
|
||
- "Stage3_Price" # 3단계 지정가 (원)
|
||
- "Trade_Value_KRW" # 예상 거래금액 (원)
|
||
- "Cost_Est_KRW" # 예상 비용 (수수료+세금, 원)
|
||
- "Net_Benefit_Pct" # 비용 차감 순 드리프트 개선 효과 (%)
|
||
- "Close" # 직전 종가 (원)
|
||
ORDERS:
|
||
description: "실행 주문 목록 (행 형식) — gate_status=PASS 또는 FORCE_OVERRIDE 종목만 포함"
|
||
columns:
|
||
- "Order_No" # 주문 순번
|
||
- "Ticker" # 종목 코드
|
||
- "Name" # 종목명
|
||
- "Bucket" # Core / Satellite
|
||
- "Action" # SELL / BUY
|
||
- "Stage" # 1 / 2 / 3
|
||
- "Qty" # 수량
|
||
- "Limit_Price_KRW" # 지정가 (원)
|
||
- "Trade_Value_KRW" # 예상 거래금액 (원)
|
||
- "Reason" # 주문 근거 (BREACH_HIGH / ABS_FLOOR / TIME_STOP 등)
|
||
sector_flow_history:
|
||
role: "sector_flow 누적 스냅샷 및 RW1/RW3 이력 근거"
|
||
optional_sheet: true
|
||
required_columns:
|
||
- "Snapshot_Date"
|
||
- "Sector"
|
||
- "Sector_Score"
|
||
- "Sector_Rank"
|
||
- "SmartMoney_5D_KRW"
|
||
- "SmartMoney_20D_KRW"
|
||
- "Flow_Breadth_5D"
|
||
- "Alert_Level"
|
||
- "Data_Quality"
|
||
- "Decision_Use"
|
||
- "ETF_Execution_Use"
|
||
usage_rule: "legacy sector_flow의 RW1/RW3는 sector_flow_history를 우선 사용하고, 이력이 없을 때만 기존 sector_flow/PropertiesService 값을 fallback으로 사용한다."
|
||
backdata_feature_bank:
|
||
role: "GAS 자동 수집 진입-청산 백데이터 원장"
|
||
optional_sheet: true
|
||
required_columns:
|
||
- "Record_Date"
|
||
- "Trade_ID"
|
||
- "Signal_Date"
|
||
- "Ticker"
|
||
- "Name"
|
||
- "Account"
|
||
- "Entry_Stage"
|
||
- "Source_Origin"
|
||
- "Entry_Price"
|
||
- "Close_At_Entry"
|
||
- "MA20_At_Entry"
|
||
- "MA60_At_Entry"
|
||
- "ATR20_At_Entry"
|
||
- "Volume_Ratio_5D"
|
||
- "Flow_Credit"
|
||
- "RSI14_At_Entry"
|
||
- "Late_Chase_Risk_Score"
|
||
- "Follow_Through_Score"
|
||
- "Breakout_Score"
|
||
- "Rebound_Preservation_Score"
|
||
- "Setup_Decision"
|
||
- "Exit_Reason"
|
||
- "PnL_Pct"
|
||
- "Holding_Days"
|
||
- "MAE_Pct"
|
||
- "MFE_Pct"
|
||
usage_rule: >
|
||
GAS가 data_feed / alpha_lead_json / sell_priority / performance를 합쳐 자동 생성한
|
||
1차 원장이다. 사용자가 직접 등록한 기록은 Source_Origin=MANUAL_CORRECTION일 때만
|
||
보정용으로 해석하며, 신규 전략 판단의 primary source로 쓰지 않는다.
|
||
source_priority:
|
||
1: "GAS daily snapshot"
|
||
2: "performance trade journal"
|
||
3: "manual correction"
|
||
macro:
|
||
role: "행 기반 macro indicator table"
|
||
required_columns: ["Symbol", "Name", "Category", "Close", "Status"]
|
||
added_columns:
|
||
- "Ret2D" # USD/JPY 2일 변화율 → MRS usd_jpy_score 입력
|
||
- "Ret10D" # KOSPI/KOSDAQ 10일 수익률 → C2 daily_leader_scan
|
||
- "MA60" # KOSPI MA60 → RISK_ON 판정 조건
|
||
- "HYG_HY_Bond" # 신용위험 proxy (credit_stress_status 산출 기반)
|
||
computed_rows:
|
||
MRS_COMPUTED: "MARKET_RISK_SCORE_V1 자동 계산 결과 (score/10, target_cash_pct)"
|
||
REGIME_PRELIM: "1차 시장국면 판정 (sector_flow 미포함 간이 판정)"
|
||
row_based_mapping:
|
||
vix_close: "row where Symbol or Name contains VIX -> Close"
|
||
kospi_close: "row where Symbol or Name contains KOSPI -> Close"
|
||
usd_krw: "row where Symbol or Name contains USD/KRW or USDKRW -> Close"
|
||
sp500_ret5d: "row where Symbol or Name contains S&P500 -> Ret5D"
|
||
missing_policy:
|
||
kospi_ma20: "JSON 미제공 시 formula_registry.MARKET_RISK_SCORE_V1의 missing_points 적용"
|
||
usd_jpy_2d_change_pct: "JSON 미제공 시 missing_points 적용"
|
||
credit_stress_status: "JSON 미제공 시 caution equivalent missing_points 적용"
|
||
event_calendar:
|
||
role: "이벤트 일정 입력 탭. 운영자가 직접 관리하는 source-of-truth. GAS seedEventCalendar_()가 최초 seed를 제공하며 이후 수동 갱신."
|
||
required_columns: ["Date", "Event", "Type", "Impact", "Alert"]
|
||
update_policy: "수동 갱신 (FOMC 연 8회, CPI 월 1회, IPO/만기 수시). seedEventCalendar_()로 초기화 가능."
|
||
note: "event_risk 탭의 원본 소스. GAS 코드에 날짜를 hardcode하지 않는다."
|
||
event_risk:
|
||
role: "이벤트 리스크 calendar (event_calendar 탭에서 DaysLeft 계산 후 기록된 runtime output)"
|
||
required_columns: ["Date", "Event", "Impact"]
|
||
core_satellite_status:
|
||
role: "core_satellite 청크 실행 완료 상태"
|
||
optional_sheet: true
|
||
required_columns:
|
||
- "Status"
|
||
- "Universe_Count"
|
||
- "Processed_Count"
|
||
- "Coverage_Pct"
|
||
- "Chunk_Size"
|
||
- "Total_Chunks"
|
||
- "Next_Chunk_Idx"
|
||
- "Updated_At"
|
||
usage_rule: "Status=COMPLETE AND Coverage_Pct>=99.9일 때 core_satellite 전체 갱신 완료로 본다."
|
||
transient_sheets:
|
||
cs_chunk_N:
|
||
role: "core_satellite 생성 중 임시 청크"
|
||
lifecycle: "runCoreSatelliteFinalize()가 core_satellite 병합을 완료하면 삭제"
|
||
deletion_allowed_when: "core_satellite_status.Status=COMPLETE AND Coverage_Pct>=99.9"
|
||
prohibition:
|
||
- "FINALIZING 또는 IN_PROGRESS 상태에서 삭제 금지"
|
||
- "core_satellite 병합 실패 상태에서 시트 다이어트 목적으로 삭제 금지"
|
||
sheet_diet_policy:
|
||
keep:
|
||
canonical_required: ["data_feed", "sector_flow", "macro", "event_risk", "core_satellite"]
|
||
support: ["settings", "account_snapshot", "sector_universe", "sector_flow_history", "etf_nav_manual", "universe", "monthly_history", "performance", "backdata_feature_bank", "event_calendar", "daily_history", "pa1_feedback", "alpha_history", "evaluation_dashboard", "trade_quality_history", "rebalance"]
|
||
deprecated: ["positions", "chat_input", "etf_raw", "core_satellite_status", "orbit_gap", "asset_history"]
|
||
delete:
|
||
transient_after_complete: ["cs_chunk_N"]
|
||
notes:
|
||
- "orbit_gap·asset_history → monthly_history 통합 (Month당 1행, 16컬럼)."
|
||
- "etf_raw → GAS in-memory map 전환. 시트 쓰기 제거."
|
||
- "core_satellite_status → ScriptProperties 이전."
|
||
- "sector_flow는 sector_flow_v2 역할을 대체하는 canonical 분석 시트다."
|
||
|
||
canonical_field_mapping:
|
||
ticker: {sheet: ["data_feed", "core_satellite"], column: "Ticker"}
|
||
name: {sheet: ["data_feed", "core_satellite"], column: "Name"}
|
||
close_price: {sheet: ["data_feed", "core_satellite"], column: "Close"}
|
||
open_price: {sheet: ["data_feed", "core_satellite"], column: "Open", fallback: "DATA_MISSING"}
|
||
previous_close_price: {sheet: ["data_feed", "core_satellite"], column: "PrevClose", fallback: "DATA_MISSING"}
|
||
volume: {sheet: ["data_feed", "core_satellite"], column: "Volume", fallback: "DATA_MISSING"}
|
||
avg_volume_5d: {sheet: ["data_feed", "core_satellite"], column: "AvgVolume_5D", fallback: "DATA_MISSING"}
|
||
ma20: {sheet: ["data_feed", "core_satellite"], column: "MA20", fallback: "DATA_MISSING"}
|
||
ma60: {sheet: ["data_feed", "core_satellite"], column: "MA60", fallback: "DATA_MISSING"}
|
||
atr20: {sheet: ["data_feed", "core_satellite"], column: "ATR20"}
|
||
avg_trade_value_5d:
|
||
sheet: ["data_feed", "core_satellite"]
|
||
preferred_column: "AvgTradeValue_5D_KRW"
|
||
legacy_column: "AvgTradeValue_5D_M"
|
||
unit_rule: "preferred_column은 KRW. legacy_column은 million KRW로 해석해 ×1,000,000 적용."
|
||
avg_trade_value_20d:
|
||
sheet: ["data_feed", "core_satellite"]
|
||
preferred_column: "AvgTradeValue_20D_KRW"
|
||
legacy_column: "AvgTradeValue_20D_M"
|
||
unit_rule: "preferred_column은 KRW. legacy_column은 million KRW로 해석해 ×1,000,000 적용."
|
||
frg_5d_sh: {sheet: ["data_feed", "core_satellite"], column: "Frg_5D"}
|
||
inst_5d_sh: {sheet: ["data_feed", "core_satellite"], column: "Inst_5D"}
|
||
flow_ok: {sheet: ["data_feed", "core_satellite"], column: "Flow_OK"}
|
||
flow_rows: {sheet: ["data_feed", "core_satellite"], column: "Flow_Rows"}
|
||
vix_close: {sheet: "macro", row_mapping: "macro.row_based_mapping.vix_close"}
|
||
kospi_close: {sheet: "macro", row_mapping: "macro.row_based_mapping.kospi_close"}
|
||
usd_krw: {sheet: "macro", row_mapping: "macro.row_based_mapping.usd_krw"}
|
||
# ── 밸류에이션 필드 매핑 (proposal_96 1단계 / 2026-05-16) ───────────────────────
|
||
# data_feed 시트 recommended_columns에 이미 존재하나 canonical_field_mapping 누락이었음.
|
||
forward_pe:
|
||
sheet: ["data_feed"]
|
||
column: "Forward_PE"
|
||
fallback: "DATA_MISSING"
|
||
note: "recommended_column — 미입력 시 PEG_SCORE_V1.fallback(sector_median 기준) 발동. 추정 생성 금지."
|
||
pbr:
|
||
sheet: ["data_feed"]
|
||
column: "PBR"
|
||
fallback: "DATA_MISSING"
|
||
note: "recommended_column — 미입력 시 SS001_VAL_VALUATION valuation_score_zero 처리."
|
||
eps_revision_status:
|
||
sheet: ["data_feed"]
|
||
column: "EPS_Revision_Status"
|
||
fallback: "DATA_MISSING"
|
||
allowed_values: ["UP", "FLAT", "DOWN"]
|
||
note: "recommended_column — 미입력 시 SS001_E_EARNINGS_REVISION 0점 처리."
|
||
# ── 신규 추가 필드 (2026-05-17) ──────────────────────────────────────────────
|
||
dividend_yield:
|
||
sheet: ["data_feed"]
|
||
column: "DividendYield"
|
||
unit: "percent"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["Naver main _dvr", "Yahoo v7 trailingAnnualDividendYield"]
|
||
note: "배당수익률(%). 은퇴포트폴리오 현금흐름 평가에 사용."
|
||
beta:
|
||
sheet: ["data_feed"]
|
||
column: "Beta"
|
||
unit: "ratio"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["Yahoo v7 quote beta", "Yahoo quoteSummary defaultKeyStatistics.beta"]
|
||
note: "1년 베타. 포트폴리오 전체 리스크 계산에 사용."
|
||
high_52w:
|
||
sheet: ["data_feed"]
|
||
column: "High52W"
|
||
unit: "KRW_per_share"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["Naver main 52주최고", "Yahoo v7 fiftyTwoWeekHigh"]
|
||
note: "52주 최고가. Pct_52W_High 계산의 기준값."
|
||
low_52w:
|
||
sheet: ["data_feed"]
|
||
column: "Low52W"
|
||
unit: "KRW_per_share"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["Naver main 52주최저", "Yahoo v7 fiftyTwoWeekLow"]
|
||
pct_52w_high:
|
||
sheet: ["data_feed"]
|
||
column: "Pct_52W_High"
|
||
unit: "percent"
|
||
fallback: "DATA_MISSING"
|
||
expression: "(Close / High52W - 1) * 100"
|
||
note: "현재가의 52주 고점 대비 위치(%). 음수=고점 아래. -20 이하 → 눌림 구간."
|
||
target_price:
|
||
sheet: ["data_feed"]
|
||
column: "Target_Price"
|
||
unit: "KRW_per_share"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["Naver coinfo estimate 목표주가", "Yahoo quoteSummary financialData.targetMeanPrice"]
|
||
note: "애널리스트 컨센서스 목표주가. Upside_Pct 계산 기준."
|
||
upside_pct:
|
||
sheet: ["data_feed"]
|
||
column: "Upside_Pct"
|
||
unit: "percent"
|
||
fallback: "DATA_MISSING"
|
||
expression: "(Target_Price / Close - 1) * 100"
|
||
note: "목표주가 대비 상승여력(%). 포지션 진입/청산 판단 보조."
|
||
# ── 2026-05-17 추가 필드 ──────────────────────────────────────────────────────
|
||
sector_median_pe:
|
||
sheet: ["sector_flow"]
|
||
column: "Sector_Median_PE"
|
||
unit: "ratio"
|
||
fallback: "DATA_MISSING"
|
||
note: "섹터 구성 3종목 PER 중앙값. SS001_VAL_VALUATION의 sector_median_forward_pe 대용."
|
||
sector_median_pbr:
|
||
sheet: ["sector_flow"]
|
||
column: "Sector_Median_PBR"
|
||
unit: "ratio"
|
||
fallback: "DATA_MISSING"
|
||
note: "섹터 구성 3종목 PBR 중앙값. SS001_VAL_VALUATION의 sector_median_pbr 대용."
|
||
rs_rank_20d:
|
||
sheet: ["core_satellite"]
|
||
column: "RS_Rank_20D"
|
||
unit: "rank_integer"
|
||
fallback: "DATA_MISSING"
|
||
note: "섹터 내 20D 수익률 기준 순위 (1=최상위). SS001_P price_strength 입력값."
|
||
rs_pct_20d:
|
||
sheet: ["core_satellite"]
|
||
column: "RS_Pct_20D"
|
||
unit: "percent"
|
||
fallback: "DATA_MISSING"
|
||
note: "섹터 내 20D 수익률 백분위 (100=최상위). relative_strength_1m_percentile 대용."
|
||
earnings_date:
|
||
sheet: ["data_feed"]
|
||
column: "Earnings_Date"
|
||
unit: "date_ISO8601"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["Yahoo quoteSummary calendarEvents.earnings.earningsDate"]
|
||
note: "다음 실적 발표 예정일. 발표 3일 이내 신규매수 자제 기준으로 활용."
|
||
days_to_earnings:
|
||
sheet: ["data_feed"]
|
||
column: "Days_To_Earnings"
|
||
unit: "integer_days"
|
||
fallback: "DATA_MISSING"
|
||
expression: "(Earnings_Date - AsOfDate).days"
|
||
note: "실적 발표까지 잔여 영업일. 음수=이미 지남. event_risk 필터 입력값."
|
||
# ── 2026-05-17 추가 필드 (3단계) ────────────────────────────────────────────
|
||
eps_growth_1y_pct:
|
||
sheet: ["data_feed"]
|
||
column: "EPS_Growth_1Y_Pct"
|
||
unit: "percent"
|
||
fallback: "DATA_MISSING → SS001_VAL_KOSDAQ_PEG.fallback_per_only 발동"
|
||
source: "Yahoo earningsTrend +1y earningsEstimate.growth (A2)"
|
||
note: "KOSDAQ PEG = Forward_PE / EPS_Growth_1Y_Pct. 양수 성장률만 유효."
|
||
dps:
|
||
sheet: ["data_feed"]
|
||
column: "DPS"
|
||
unit: "KRW_per_share"
|
||
fallback: "DATA_MISSING"
|
||
source: "Yahoo defaultKeyStatistics.lastDividendValue (A4)"
|
||
note: "주당 배당금. DividendYield와 함께 은퇴 현금흐름 평가."
|
||
ex_dividend_date:
|
||
sheet: ["data_feed"]
|
||
column: "Ex_Dividend_Date"
|
||
unit: "date_ISO8601"
|
||
fallback: "DATA_MISSING"
|
||
source: "Yahoo calendarEvents.exDividendDate (A4)"
|
||
note: "배당락일. Days_To_Ex_Div 계산 기준."
|
||
days_to_ex_div:
|
||
sheet: ["data_feed"]
|
||
column: "Days_To_Ex_Div"
|
||
unit: "integer_days"
|
||
fallback: "DATA_MISSING"
|
||
expression: "(Ex_Dividend_Date - AsOfDate).days"
|
||
note: "배당락일 잔여 일수. 음수=이미 지남."
|
||
stop_price_est:
|
||
sheet: ["data_feed"]
|
||
column: "Stop_Price_Est"
|
||
unit: "KRW_per_share"
|
||
fallback: "DATA_MISSING"
|
||
source_priority: ["account_snapshot stop_price", "average_cost - ATR20 × 1.5 추정"]
|
||
note: "account_snapshot 실제 손절가 우선. ATR 추정은 참고값. Stop_Price_Source로 출처 구분."
|
||
stop_price_source:
|
||
sheet: ["data_feed"]
|
||
column: "Stop_Price_Source"
|
||
unit: "string"
|
||
values: ["account_snapshot", "ATR추정"]
|
||
note: "Stop_Price_Est의 데이터 출처."
|
||
pos_size_qty:
|
||
sheet: ["data_feed"]
|
||
column: "Pos_Size_Qty"
|
||
unit: "integer_shares"
|
||
fallback: "DATA_MISSING (settings total_asset_krw 미입력)"
|
||
expression: "min(floor(total_asset × risk_budget × bayesian / (ATR20 × 1.5)), floor(total_asset × 0.05 / Close))"
|
||
note: "POSITION_SIZE_V1 간략 추정. cash/sector/유동성 한도 미적용 — account_snapshot 제공 시 정밀화 가능."
|
||
|
||
# ── 2단계 보완 예정 필드 (현재 JSON 미포함) ──────────────────────────────────
|
||
# 아래 필드는 spec에 정의되어 있으나 JSON 컬럼이 없어 DATA_MISSING으로만 처리됨.
|
||
# 2단계 워크북 보완 완료 후 이 주석을 제거하고 매핑 활성화.
|
||
# eps_growth_3y_cagr_pct:
|
||
# sheet: ["data_feed"]
|
||
# column: "EPS_Growth_3Y_CAGR_pct" # 추가 예정 컬럼
|
||
# fallback: "DATA_MISSING → PEG_SCORE_V1.fallback"
|
||
# sector_median_forward_pe:
|
||
# sheet: ["sector_flow"]
|
||
# column: "Sector_Median_PE" # 추가 예정 컬럼
|
||
# fallback: "DATA_MISSING"
|
||
# sector_median_pbr:
|
||
# sheet: ["sector_flow"]
|
||
# column: "Sector_Median_PBR" # 추가 예정 컬럼
|
||
# fallback: "DATA_MISSING"
|
||
# ── 재무 건전성 필드 (2026-05-18_FINANCIAL_HEALTH_V1) ──────────────────────
|
||
roe_pct:
|
||
sheet: ["data_feed"]
|
||
column: "ROE_Pct"
|
||
fallback: "DATA_MISSING"
|
||
note: "자기자본이익률(%). FINANCIAL_HEALTH_SCORE_V1 수익성 축 입력."
|
||
operating_margin_pct:
|
||
sheet: ["data_feed"]
|
||
column: "Operating_Margin_Pct"
|
||
fallback: "DATA_MISSING"
|
||
note: "영업이익률(%). 음수=영업적자 → HF007 하드필터."
|
||
debt_to_equity:
|
||
sheet: ["data_feed"]
|
||
column: "Debt_To_Equity"
|
||
fallback: "DATA_MISSING"
|
||
note: "부채비율(D/E). 금융업(은행·보험·증권) 제외 적용. >400% → HF008."
|
||
current_ratio:
|
||
sheet: ["data_feed"]
|
||
column: "Current_Ratio"
|
||
fallback: "DATA_MISSING"
|
||
note: "유동비율. <1.0이면 단기 유동성 위험."
|
||
fcf_b:
|
||
sheet: ["data_feed"]
|
||
column: "FCF_B"
|
||
fallback: "DATA_MISSING"
|
||
note: "잉여현금흐름(억원). 양수=실제 현금 창출. 음수=현금 소각."
|
||
revenue_growth_pct:
|
||
sheet: ["data_feed"]
|
||
column: "Revenue_Growth_Pct"
|
||
fallback: "DATA_MISSING"
|
||
note: "전년 대비 매출 성장률(%). 성장성 판단 보조."
|
||
|
||
prohibited_use:
|
||
- "이 JSON/xlsx에서 보유수량·평단·현금·미체결 주문을 추정하지 않는다."
|
||
- "시장 raw JSON 누락 필드를 LLM이 임의 생성하지 않는다."
|
||
- "legacy AvgTradeValue_5D_M를 억원 단위로 해석하지 않는다. million KRW로 해석한다."
|