Files
QuantEngineByItz/spec/16_data_gaps_roadmap.yaml
T
kjh2064 b78b9f5dc9 fix: data_gaps_roadmap status update - S3 DONE, S5 DATA_GATED
S3_sector_flow_weekly_history: LEGACY_INTERIM -> DONE
  (Prev_Rotation_Rank W1/W2 legacy interim 구현 완료)
S5_etf_raw_execution_quality: PARTIAL_DONE_WITH_MANUAL_NAV -> DATA_GATED
  (NAV/iNAV/AUM 자동수집은 KRX/KIND API 경로 확정 필요)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 18:27:18 +09:00

496 lines
27 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: "데이터 갭 로드맵 — 단계별 보완 계획"
version: "2026-05-17-initial"
language: "ko-KR"
purpose: >
의사결정 파이프라인(spec/09_decision_flow.yaml)에서 식별된 데이터 공백을
우선순위별로 정리하고, 단계별 구현 계획을 명시한다.
GAS 수집 → spec 공식 → LLM 판단 순서로 각 갭의 의존성을 추적한다.
# ─────────────────────────────────────────────────────────────────────────────
# 1단계 완료 (2026-05-17 구현됨)
# ─────────────────────────────────────────────────────────────────────────────
phase_1_completed:
G1_KOSPI_MA60:
status: DONE
implementation: "fetchYahooOhlcMetrics → macro 탭 MA60 컬럼"
enables: "RISK_ON 판정 조건 KOSPI_MA20 >= KOSPI_MA60"
G2_KOSPI_KOSDAQ_Ret10D:
status: DONE
implementation: "fetchYahooOhlcMetrics → macro 탭 Ret10D"
enables: "daily_leader_scan C2: Ret10D_종목 - Ret10D_KOSPI"
G3_ETF_Ret10D:
status: DONE
implementation: "fetchYahooPrice → sector_flow ETF_Ret10D"
enables: "RW2 상대약세: Ret10D_종목 - Ret10D_주도섹터ETF"
G4_USD_JPY_Ret2D:
status: DONE
implementation: "calcDerivedPriceMetrics.ret2D → macro 탭 Ret2D (USD_JPY행)"
enables: "MRS usd_jpy_score: Ret2D <= -1 → +1점"
G5_credit_stress_proxy:
status: DONE
implementation: "HYG ETF Ret5D → REGIME_PRELIM 행 credit_stress 필드"
enables: "MRS credit_score 자동 계산"
limitation: "HYG는 미국 HY proxy. 한국 신용스프레드 직접 수집은 3단계 과제."
G6_Rotation_Rank:
status: DONE
implementation: "runSectorFlow 정렬 후 Rotation_Rank 컬럼"
enables: "C5 Rotation_Score 순위 <= 3 판단, RW1 섹터 순위 변화 추적"
S4_MRS_auto_compute:
status: DONE
implementation: "runMacro 내 MARKET_RISK_SCORE_V1 계산 → macro 탭 MRS_COMPUTED 행"
enables: "LLM이 macro 탭 한 번 읽어 MRS 즉시 확인 가능"
# ─────────────────────────────────────────────────────────────────────────────
# 2단계 — 구조적 갭 (시트 신설 필요, 중간 우선순위)
# ─────────────────────────────────────────────────────────────────────────────
phase_2_structural:
S1_trades_performance_sheet:
priority: HIGH
status: DONE
purpose: >
Bayesian multiplier (high/medium/low/no_bet) 및 net_expectancy 산출 기반.
미구현 시 bayesian_confidence는 항상 medium_confidence(0.5×) 고정.
required_columns:
- "trade_id"
- "ticker"
- "sector"
- "entry_date"
- "entry_price"
- "entry_stage" # stage_1/2/3
- "quantity"
- "stop_price_at_entry"
- "target_price_at_entry"
- "exit_date"
- "exit_price"
- "exit_reason" # stop_loss/take_profit/time_stop/rw_exit/manual
- "pnl_pct"
- "holding_days"
- "entry_c1_score" # daily_leader_scan 입장 시 C1~C5
- "entry_c2_score"
- "entry_c3_score"
- "entry_c4_score"
- "entry_c5_score"
- "entry_mrs_score"
- "fc_bucket" # Y/N: explore_loss_budget 귀속 여부
derived_outputs:
- "win_rate (최근 30건)"
- "avg_win_pct"
- "avg_loss_pct"
- "net_expectancy = (win_rate × avg_win_pct) - (loss_rate × avg_loss_pct)"
- "bayesian_confidence_multiplier 자동 결정"
implementation_plan:
step_1: "Google Sheets에 'performance' 탭 수동 생성"
step_2: "spec/17_performance_contract.yaml 계약서 작성"
step_3: "GAS에 performance 탭 읽기 함수 추가 → Bayesian multiplier 자동 계산"
step_4: "runDataFeed 내 bayesian_multiplier 필드 → data_feed 탭 추가"
implementation_note: >
2026-05-17 구현 완료. spec/17_performance_contract.yaml 신규 작성.
readPerformanceSheet_() GAS 함수 추가. EE_Est 계산에 Bayesian multiplier 반영.
macro 탭 BAYESIAN_COMPUTED 행으로 상태 출력.
S2_stop_price_tracking:
priority: HIGH
status: DONE
purpose: >
TOTAL_HEAT_V1 계산 필수 입력값. 미구현 시 HF005(Total_Heat 10% 차단) 미작동.
stop_price 없으면 포트폴리오 총 위험노출 계산 불가.
required_fields_per_position:
- "ticker"
- "account"
- "average_cost"
- "stop_price" # ATR 기준 계산값 또는 HTS 실제 설정값
- "holding_quantity"
- "last_updated"
implementation_plan:
step_1: "account_snapshot에 stop_price/highest_price_since_entry/last_updated 선택 컬럼 추가"
step_2: "spec/15_account_snapshot_contract.yaml에 account_snapshot_position_state 추가"
step_3: "GAS: account_snapshot 기반 TOTAL_HEAT 및 trailing stop 갱신"
interim_workaround: >
stop_price 미기록 시 STOP_PRICE_CORE_V1 공식으로 ATR 기준 추정:
stop_price_est = average_cost - ATR20 × 1.5
Total_Heat_est = sum((average_cost - stop_price_est) × holding_quantity) / total_asset × 100
implementation_note: >
2026-05-18 account_snapshot 통합 완료. positions_tab은 deprecated.
readAccountSnapshotHeat_() GAS 함수 추가 (ATR 추정 폴백 포함).
macro 탭 TOTAL_HEAT 행으로 HF005 상태 출력.
S3_sector_flow_weekly_history:
priority: MEDIUM
status: DONE
implementation: >
option_B legacy interim 구현 완료 (2026-05-17).
sector_flow 탭에 Prev_Rotation_Rank(W1), Prev_Rotation_Rank_W2 컬럼 추가.
W1 = sector_flow 시트에서 직전 실행 결과 읽기.
W2 = PropertiesService['sf_w2_ranks_json'] 캐시 (직전 실행 시 저장).
RW1·RW3 컬럼이 sector_flow 탭에 자동 계산됨 → data_feed RW1·RW3 컬럼으로 전파.
enables: >
RW1 '2주 연속 섹터 순위 3순위 이상 하락' 자동 판단.
RW3 '외국인+기관 5D 순매도 2주 연속' 자동 판단.
note: >
2회 이상 실행 후 W1/W2 데이터가 축적되어야 RW1·RW3가 작동한다.
단, 이는 전회 실행 기준 legacy interim이며 주간 스냅샷 기반 sector_flow_history는 후속 Phase 4 과제다.
S4_sector_flow:
priority: HIGH
status: DONE
implementation: >
2026-05-17 Phase 1-2 구현.
sector_universe 원장 또는 DEFAULT_SECTOR_UNIVERSE_V2를 canonical source로 사용하고,
구성종목 수급을 수량 단순합산이 아닌 원화금액×가중치로 sector_flow에 집계한다.
Coverage_Weight, SmartMoney_5D_KRW, SmartMoney_5D_Norm, Flow_Breadth_5D,
Data_Quality, Decision_Use를 추가했다.
sector_universe 시트가 없으면 기본 템플릿을 생성하며, Is_ETF=Y 구성행은
ETF 자체 수급 혼입을 막기 위해 섹터 smart money 집계에서 제외한다.
limitation: >
KRX/KIND 기반 NAV/괴리율/추적오차/AUM 수집은 아직 미구현이며 etf_raw에서
ETF_NAV_Risk=NAV_DATA_MISSING으로 명시한다.
S5_etf_raw_execution_quality:
priority: HIGH
status: DATA_GATED
implementation: >
2026-05-17 Phase 3 interim 구현.
etf_raw 시트를 신설하고 ETF proxy/ETF 구성행에 대해 Close, Bid, Ask, Spread_Pct,
AvgTradeValue_5D_KRW, AvgTradeValue_20D_KRW, ETF_Frg_5D_KRW, ETF_Inst_5D_KRW,
ETF_Liquidity_Score, ETF_Liquidity_Status를 산출한다.
NAV_DATA_MISSING 상태에서는 ETF_Execution_Use=WATCH_ONLY로 표시해 ETF 매매 실행 근거와 섹터 수급 근거를 분리한다.
etf_nav_manual 시트가 있으면 NAV, iNAV, 괴리율, 추적오차, AUM을 etf_raw에 반영한다.
tools/import_etf_nav_manual.py로 KRX/KIND/운용사 CSV/XLSX export를 etf_nav_manual로 변환할 수 있다.
limitation: "NAV, iNAV, 괴리율, 추적오차, AUM 자동 수집은 KRX/KIND 수집 경로 확정 전까지 미구현."
S6_sector_flow_history:
priority: HIGH
status: DONE
implementation: >
2026-05-17 Phase 4 interim 구현.
sector_flow_history 시트에 Snapshot_Date+Sector 기준으로 sector_flow 누적 스냅샷을 upsert한다.
sector_flow의 RW1/RW3 계산은 sector_flow_history를 우선 사용하고,
이력이 부족할 때만 기존 sector_flow/PropertiesService 값을 fallback으로 사용한다.
Snapshot_Date는 Apps Script Date 객체와 문자열 날짜를 모두 yyyy-MM-dd로 정규화한다.
# ─────────────────────────────────────────────────────────────────────────────
# 3단계 — 분석 품질 고도화 (낮은 우선순위)
# ─────────────────────────────────────────────────────────────────────────────
phase_3_enhancement:
A1_daily_leader_scan_auto:
priority: MEDIUM
status: DONE
implementation: >
P1(2026-05-17) 구현 완료. runDataFeed 루프 내 C1~C5 자동 계산.
data_feed 탭: C1_Price, C2_RelStr, C3_VolSurge, C4_Flow, C5_Sector, Leader_Scan_Total, Leader_Gate.
output_columns: ["C1_Price","C2_RelStr","C3_VolSurge","C4_Flow","C5_Sector","Leader_Scan_Total","Leader_Gate"]
A2_eps_growth_3y_cagr:
priority: MEDIUM
status: DONE
implementation: >
2026-05-17 구현 완료. fetchYahooConsensusEps() 확장.
Yahoo earningsTrend +1y의 earningsEstimate.growth.raw 직접 추출.
없으면 (+1y avg - 0y avg) / abs(0y avg) × 100 으로 계산.
data_feed 탭 EPS_Growth_1Y_Pct 컬럼 추가 → LLM이 PEG = Forward_PE / EPS_Growth_1Y_Pct 계산 가능.
accuracy_note: "1년 성장률 추정치 (3Y CAGR 완전 대체 불가). KOSDAQ PEG 게이트에서 fallback보다 정확."
A3_pct_from_52w_low:
priority: LOW
status: DONE
purpose: "Low52W 대비 현재가 반등률 — 저점 대비 위치 파악 (눌림 구간 분석)"
expression: "(Close / Low52W - 1) × 100"
implementation: "data_feed 탭 Pct_From_52W_Low 컬럼 (2026-05-17)"
A4_ex_dividend_date:
priority: LOW
status: DONE
implementation: >
2026-05-17 구현 완료. fetchYahooTargetPrice() 확장 (추가 API 호출 없음).
calendarEvents.exDividendDate → data_feed Ex_Dividend_Date, Days_To_Ex_Div 컬럼.
defaultKeyStatistics.lastDividendValue → data_feed DPS 컬럼.
A6_pos_size_qty:
priority: HIGH
status: DONE
implementation: >
2026-05-17 구현 완료.
data_feed Pos_Size_Qty 컬럼: POSITION_SIZE_V1 간략 버전 자동 계산.
atr_qty = floor(total_asset × 0.007 × bayesian_multiplier / (ATR20 × 1.5))
weight_qty = floor(total_asset × 0.05 / Close)
Pos_Size_Qty = min(atr_qty, weight_qty).
requires: settings 탭 total_asset_krw 입력.
limitation: "cash/sector/liquidity 한도는 account_snapshot 필요. 현재는 ATR+weight 한도만 적용."
A7_stop_price_actual:
priority: HIGH
status: DONE
implementation: >
2026-05-17 구현 완료.
data_feed Stop_Price_Est: account_snapshot 실제 stop_price 우선 → ATR 추정 폴백.
Stop_Price_Source 컬럼: "account_snapshot" / "ATR추정" 표시.
EE_Est가 실제 stop_price 기반으로 계산됨 (포지션 있는 종목).
A8_settings_tab:
priority: HIGH
status: DONE
implementation: >
2026-05-17 구현 완료. readSettingsTab_() GAS 함수 추가.
settings 탭: key-value 구조 (key, value, note 컬럼).
total_asset_krw: Pos_Size_Qty, TOTAL_HEAT_V1, FC_BUDGET 계산에 사용.
spec/18_settings_contract.yaml 계약서 작성.
A9_fc_budget_tracking:
priority: MEDIUM
status: DONE
implementation: >
2026-05-17 구현 완료. calcFcBudget_() GAS 함수 추가.
performance 탭 fc_bucket=Y 거래 중 당월 청산 손실 집계.
macro 탭 FC_BUDGET 행 추가: used_pct / 2.5% 예산 상태 출력.
exhausted 시 LLM이 신규 stage_1 탐색 자동 억제 가능.
A5_kosdaq_vs_ma20:
priority: LOW
status: DONE
purpose: "kosdaq_regime_supplement 규칙: KOSDAQ_Close < KOSDAQ_MA20 → MRS +1"
implementation: "runMacro MRS 계산에 kosdaqSupp 로직 추가. macro 탭 KOSDAQ (^KQ11) 이미 수집 중 (2026-05-17)"
# ─────────────────────────────────────────────────────────────────────────────
# 분석 보완 제안 (GAS 미관여, LLM 분석 품질 향상)
# ─────────────────────────────────────────────────────────────────────────────
analysis_enhancements:
B1_rw_signal_checklist:
purpose: "RW1~RW5 자동 계산 및 출력"
current_status:
RW1: "✅ sector_flow RW1 컬럼 자동 계산 (2026-05-17). Prev_Rotation_Rank(W1)+W2 PropertiesService 캐시 기반. 2회 이상 실행 후 정확."
RW2: "✅ data_feed RW2 컬럼 자동 계산 (2026-05-17). Ret10D - ETF_Ret10D <= -5%p"
RW3: "✅ sector_flow RW3 컬럼 자동 계산 (2026-05-17). 외국인+기관 5D 순매도 2주 연속 (현재+W1 비교)."
RW4: "✅ data_feed RW4 컬럼 자동 계산 (2026-05-17). AvgTradeValue_5D/20D <= 0.60"
RW5: "✅ data_feed RW5 컬럼 자동 계산 (2026-05-17). Close < MA20 AND < MA60"
RW_Partial: "✅ data_feed RW_Partial = RW1+RW2+RW3+RW4+RW5 합계 (0~5)"
fully_automated: ["RW1 (2회 이상 실행 후)", "RW2", "RW3 (현재+W1 기준)", "RW4", "RW5"]
note: "RW1·RW3의 '2주 연속' 조건은 2회 이상 실행 후 W1/W2 데이터 축적 시 완전히 정확해짐."
B2_total_heat_estimation:
purpose: "stop_price 미기록 시 ATR 기준 Total_Heat 추정"
formula: >
For each holding in account_snapshot:
stop_price_est = entry_price - ATR20 × 1.5
heat_contribution = (entry_price - stop_price_est) × quantity / total_asset × 100
Total_Heat_est = sum(heat_contribution)
requirement: "ATR20(data_feed), entry_price(account_snapshot), quantity(account_snapshot), total_asset(account_snapshot) 필요"
note: "actual stop_price가 있으면 실제값 우선. 없으면 이 추정으로 HF005 체크 가능."
B3_expected_edge_checklist:
purpose: "EXPECTED_EDGE_V1 계산 전 필수 입력 확인"
required_fields:
- "target_price: data_feed Target_Price (Naver 또는 Yahoo) ✓"
- "entry_price: limit_price (entry_core.yaml limit_price_formula) ✓"
- "stop_price: stop_price_est (B2 또는 실제값) △"
- "bayesian_confidence_multiplier: performance 시트 기반 (S1) — 미구현 시 0.5× 기본"
- "execution_cost_rate: 0.003 고정 ✓"
B4_c2_now_computable:
purpose: "daily_leader_scan C2 바로 계산 가능"
formula: "Ret10D_종목(data_feed) - Ret10D_KOSPI(macro) >= 3%p"
status: "G2 완료로 계산 가능. LLM이 두 탭 조회 후 즉시 판단."
B5_mrs_now_readable:
purpose: "MRS 자동 계산 결과 macro 탭에서 직접 읽기"
location: "macro 탭 Symbol='MRS_COMPUTED' 행 → Close=점수, Status='score=X/10 cash=Y%'"
usage: "LLM이 macro 탭을 읽으면 MRS 재계산 없이 즉시 확인 가능"
B6_flow_credit_v1_auto:
purpose: "FLOW_CREDIT_V1 자동 계산 — data_feed Flow_Credit 컬럼"
status: DONE
implementation: >
2026-05-17 구현 완료. runDataFeed 루프 내 자동 계산.
fc_c1: close >= open OR close > prevClose → 0.30
fc_c2: volume >= avgVolume5D × 1.20 → 0.30
fc_c3: flow_ok AND (frg5 + inst5) > 0 → 0.40
Hard override: C1=0 AND C2=0 → 0 (C3 단독 충족은 물량받기로 간주)
output_column: "data_feed Flow_Credit (0.00~1.00)"
B7_trailing_stop_price_auto:
purpose: "TRAILING_STOP_PRICE_V1 자동 계산 — account_snapshot 최고가 기반"
status: DONE
implementation: >
2026-05-18 account_snapshot highest_price_since_entry 읽기/쓰기 통합 완료.
trailingStopPrice = highest_price_since_entry - ATR20 × 1.5
account_snapshot에 highest_price_since_entry 미입력 시 공백.
output_column: "data_feed Trailing_Stop_Price (KRW 정수)"
B8_ss001_score_auto:
purpose: "SS001 종목 점수 자동 계산 — 6개 축 + 총점 + 등급"
status: DONE
implementation: >
2026-05-17 구현 완료. runDataFeed 루프 내 자동 계산.
SS001_P: core_satellite RS_Pct_20D → percentile=100-RS_Pct_20D → ≤30=25pt/30~60=15pt/>60=0pt
SS001_V: avgTradingValue5D/20D 비율 → ≥120%=15pt/80~120%=8pt/<80%=0pt
SS001_F: Flow_Credit → ≥0.70=25pt/0.40~0.70=12pt/<0.40=0pt
SS001_E: EPS_Revision_Status → UP=20pt/FLAT=10pt/DOWN=0pt
SS001_M: REGIME_PRELIM(전회 macro 결과) → RISK_ON/LEADER_CONCENTRATION=10pt/NEUTRAL=5pt/기타=0pt
SS001_VAL: KOSPI→PER/PBR vs 섹터중앙값(max 5pt), KOSDAQ→PEG 기반(max 12pt)
SS001_Total: 6개 합산 (KOSPI max 100, KOSDAQ max 107)
SS001_Grade: 100점 환산 ≥80=A / ≥65=B / ≥50=C / <50=D
output_columns: ["SS001_P","SS001_V","SS001_F","SS001_E","SS001_M","SS001_VAL","SS001_Total","SS001_Grade"]
data_dependency:
SS001_P: "core_satellite 탭 RS_Pct_20D 컬럼 (runCoreSatelliteFinalize 필요)"
SS001_M: "전회 runMacro 실행 결과 (초회 실행 시 0점)"
SS001_VAL: "sector_flow Sector_Median_PE/PBR (runSectorFlow 필요)"
limitation: "SS001_P는 core_satellite 탭이 비어있으면 0점 처리. 처음 사용 시 runCoreSatellite 먼저 실행."
B9_peg_gate_auto:
purpose: "PEG 게이트 자동 계산 (KOSDAQ 종목 전용)"
status: DONE
implementation: >
2026-05-17 구현 완료. KOSDAQ_TICKERS Set 상수 추가 (현재 비어있음 — 보유 종목 모두 KOSPI).
KOSDAQ 종목에서 EPS_Growth_1Y_Pct > 0 이면: PEG = Forward_PE / EPS_Growth_1Y_Pct
PEG_Gate: PASS(≤1.5) / CAUTION(1.5~2.5) / REJECT(>2.5)
EPS 성장률 미수집 시: Fallback → sector_median_PE 대비 Forward_PE 배수로 대체
output_columns: ["PEG","PEG_Gate"]
B10_full_market_regime:
purpose: "MARKET_REGIME_V1 완전 판정 — macro+sector_flow 통합"
status: DONE
implementation: >
2026-05-17 구현 완료. runMacro() 내에서 sector_flow 탭 읽기 추가.
(runSectorFlow()가 sector_flow 기록 완료 후 runMacro()가 호출되므로 최신값 읽기 가능)
판정 우선순위: RISK_OFF > SECULAR_LEADER_RISK_ON > LEADER_CONCENTRATION > RISK_ON > NEUTRAL > RISK_OFF_CANDIDATE
RISK_OFF: MRS>=7 OR (VIX>=25 AND KOSPI<MA20)
SECULAR_LEADER_RISK_ON: LEADER_CONCENTRATION + top1=반도체 + VIX<22 + KOSPI>MA20
LEADER_CONCENTRATION: top2_sum>=100 AND top1_score>=55 AND top1_alertScore>=2 AND Tier1섹터 AND Ret20D>0 AND VIX<25
RISK_ON: VIX<18 AND KOSPI>MA20 AND (MA20>=MA60 OR Ret20D>0) AND (sfFrg20>0 OR sfInst20>0 OR top2sum>=100)
NEUTRAL: MRS<=5 그 외
RISK_OFF_CANDIDATE: MRS 5~6
output: "REGIME_PRELIM 행 Close 컬럼 (Symbol=REGIME_PRELIM 유지 — 하위 호환)"
note: >
이전 값이 'RISK_ON_CANDIDATE', 'RISK_OFF_CANDIDATE'이던 것이 'RISK_ON', 'RISK_OFF'로 변경됨.
SS001_M 점수 계산이 이제 정상 작동 (이전엔 항상 0점이었음).
B11_net_return_feedback:
purpose: "net_return_feedback 상태 자동 계산 — RISK_BUDGET_CASCADE_V1 입력"
status: DONE
implementation: >
2026-05-17 구현 완료. runMacro() 내 bayesianInfo(performance 탭) 재사용.
규칙 (spec/05_position_sizing.yaml:net_return_feedback):
trades < 20건: NORMAL (규칙 미적용)
ne <= -2%: REDUCED — base_risk 0.007→0.003 삭감 권고
ne <= 0%: CAUTION — high_confidence 금지, multiplier 0.5× 강제
연속손실 ≥5건 (bayesian no_bet와 별개로): NORMAL→CAUTION 승격
그 외: NORMAL
output: "macro 탭 NET_RETURN_FEEDBACK 행 (Symbol=NET_RETURN_FEEDBACK, Close=상태값)"
C1_orbit_gap_tracking:
purpose: "orbit_gap 자동 계산 — 월별 목표궤도 vs 실제 자산 추이 추적"
status: DONE
implementation: >
2026-05-17 구현 완료. spec/01_objective_profile.yaml:orbit_monthly_tracker 구현.
calcOrbitGap_(settings) 함수: 기하평균 보간으로 목표누적수익률 계산.
orbit_gap(%) = ((target/start)^(elapsed/total) - 1) - (current/start - 1)
orbit_state: significantly_behind(>3%p) / mild_behind(1~3%p) / on_track / ahead_of_target(<-2%p)
offensive_slot_adj: significantly_behind=+2, mild_behind=+1, on_track=0, ahead=0
cash_floor_adj: significantly_behind=-2%p, mild_behind=-1%p, on_track=0, ahead=+1%p
runOrbitGap(): orbit_gap 탭에 현재 월 행 추가/갱신 (월 1회 독립 트리거)
runMacro(): ORBIT_GAP + ORBIT_STATE 2개 행 macro 탭에 자동 기록
required_settings:
- "orbit_start_asset_krw — 시작 자산 (1월 기준)"
- "orbit_target_asset_krw — 목표 자산 (예: 5억)"
- "orbit_start_yyyymm — 추적 시작 연월 (예: 2026-01)"
- "orbit_end_yyyymm — 목표 달성 기한 (예: 2028-12)"
- "total_asset_krw — 현재 자산 (기존 settings 항목 재사용)"
output:
macro_tab: "ORBIT_GAP 행(Close=gap %p), ORBIT_STATE 행(Close=상태, Status=slot/cash 조정값)"
orbit_gap_tab: "Month/Start_Asset/Target_Asset/Actual_Asset/Target_Return_Pct/Actual_Return_Pct/Orbit_Gap_Pct/Orbit_State/Slot_Adj/Cash_Floor_Adj/Updated"
api_exposure:
getMacroJson: "orbit_gap_pct, orbit_state, orbit_slot_adj, orbit_cash_adj"
getSummaryJson: "macro_snapshot.orbit_gap_pct, orbit_state, orbit_slot_adj"
limitation: "settings 탭에 4개 orbit_* 파라미터 미입력 시 ORBIT_GAP=N/A 기록 (runOrbitGap 스킵)"
C2_take_profit_ladder:
purpose: "TAKE_PROFIT_LADDER_V1 자동 계산 — core/satellite 분리 익절 사다리"
status: DONE
implementation: >
2026-05-18 account_snapshot average_cost + holding_quantity + position_type 기반으로 변경.
core: TP1=+15%(25% 물량), TP2=+25%(잔여 40% 물량).
satellite: TP1=+10%(50% 물량), TP2=+20%(잔여 50% 물량).
Time_Stop: stage_1=60일, stage_2=30일 (entry_date 기준 만료일 + 잔여일수).
output_columns:
data_feed: ["TP1_Price","TP1_Qty","TP2_Price","TP2_Qty","Time_Stop_Date","Days_To_Time_Stop"]
required_account_snapshot_fields: ["average_cost","holding_quantity","position_type","entry_date","entry_stage"]
C3_position_monitoring:
purpose: "포지션 모니터링 컬럼 자동 계산 — 비중/수익률/PnL/스테이지/밴드"
status: DONE
implementation: >
2026-05-18 account_snapshot + 당일 종가 기반으로 변경.
Weight_Pct: close × quantity / total_asset_krw × 100.
Profit_Pct: (close - entry_price) / entry_price × 100.
Unrealized_PnL: (close - entry_price) × quantity (KRW 정수).
Stage2_Gate: stage_1 포지션에서 가격 +1.5% 이상 시 PASS, 아니면 PENDING.
Band_Status: satellite 단일종목 7% 상한. OVERWEIGHT/IN_BAND/UNDERWEIGHT.
core는 CORE_HIGH(>10%)/CORE_MID(3~10%)/CORE_LOW(<3%).
output_columns:
data_feed: ["Weight_Pct","Profit_Pct","Unrealized_PnL","Stage2_Gate","Band_Status"]
D1_bucket_allocation_status:
purpose: "포트폴리오 버킷 할당 상태 자동 계산 — core/satellite/cash 합계 vs 목표 범위"
status: DONE
implementation: >
2026-05-17 구현 완료. runDataFeed 루프에서 버킷별 Weight_Pct 누산.
calcBucketStatus_() 함수: _bucketSnapshot_ 기반 bucket-level 집계.
목표 범위 (spec/risk): core 60-72%, satellite 10-25%, cash 10-22%.
cash_pct = max(0, 100 - core_pct - satellite_pct) (추정값 — account_snapshot 미연동).
overall: BALANCED / core_UNDERWEIGHT | sat_OVERWEIGHT 등 파이프 구분.
output:
macro_tab: "BUCKET_STATUS 행(Close=overall, Status=core/sat/cash 상세)"
api_exposure:
getMacroJson: "bucket_status, bucket_detail"
getSummaryJson: "macro_snapshot.bucket_status, bucket_detail"
limitation: >
cash_pct는 account_snapshot 마켓밸류를 total_asset에서 뺀 추정값.
실제 현금은 account_snapshot 없이 확인 불가.
runDataFeed 실행 없이 runMacro만 실행하면 N/A.
phase_4_backdata_collection:
B1_gas_backdata_feature_bank:
priority: HIGH
status: PLANNED
purpose: >
매수/매도 뒷북과 설거지 패턴을 줄이기 위한 진입-청산 백데이터 원장.
사람 입력보다 GAS 자동 수집을 1순위로 두고, 사람이 입력한 performance 기록은
보조 검증용 fallback으로만 사용한다.
collection_priority:
1: "GAS가 생성한 backdata_feature_bank 시트/JSON"
2: "performance 시트의 청산 완료 거래"
3: "수동 보정값"
required_signals:
- "entry_stage"
- "entry_leader_scan_total"
- "entry_c1_score"
- "entry_c2_score"
- "entry_c3_score"
- "entry_c4_score"
- "entry_c5_score"
- "entry_mrs_score"
- "entry_close_vs_ma20_pct"
- "entry_volume_ratio_5d"
- "entry_flow_credit"
- "entry_breakout_score"
- "entry_late_chase_risk_score"
- "entry_follow_through_score"
- "pnl_pct"
- "holding_days"
- "max_adverse_excursion_pct"
- "max_favorable_excursion_pct"
implementation_plan:
step_1: "GAS에서 daily setup snapshot을 backdata_feature_bank 시트로 자동 upsert"
step_2: "performance 시트 청산 결과와 join해 outcome label을 자동 부여"
step_3: "convert_xlsx_to_json.py에서 backdata_feature_bank_json 우선 수집"
step_4: "backdata_feature_bank_table을 report/validation에 반영"
fallback_policy:
manual_input: "performance 시트 또는 수동 보정은 fallback일 뿐 primary source가 아니다."
missing_action: "GAS 생성본이 없으면 fallback 기록과 함께 source_origin=FALLBACK_SYNTH로 남긴다."
# 2026-05-30 구현 현황
# - S5_etf_raw: PARTIAL_DONE 유지 (수동 NAV 병행)
# - Stage2_Gate PENDING: T+20 표본 누적 후 자동 평가
# - 주요 지표: outcome_quality=85.23(PASS) guidance_proof=99.26(PASS)
# - 미수집 펀더멘털(ROE/OPM/FCF/Revenue): CHECK_58/59 해결 시 자동 개선