ee3e799de1
주요 변경: - tools/build_rebalance_engine_v1.py: REBALANCE_ENGINE_V1 신규 * account_snapshot 직접 합산(_build_snap_position_map) → 소수주 분리 행 병합 * 레짐 소스 macro.REGIME_PRELIM 최우선 (GAS 와 동일) - src/gas_adapter_parts/gdf_06_rebalance.gs: runRebalanceSheet_() 신규 * Logger.log / getSpreadsheet_() 로 run_all 연동 수정 - src/gas_adapter_parts/gdc_01_fetch_fundamentals.gs * _mergePositionRecord_(): 소수주 중복 행 합산 신규 * parseInt → parseFloat (qty, availQty) - src/gas_adapter_parts/gdf_01_price_metrics.gs * 미보유 종목 SELL_READY → WATCH_EXIT_SIGNAL - spec/41_release_dag.yaml: build_rebalance_sheet 노드 추가 (step_count 63) - spec/51_formula_lifecycle_registry.yaml: REBALANCE_ENGINE_V1 등록 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
680 lines
23 KiB
YAML
680 lines
23 KiB
YAML
tests:
|
|
- id: T001_NO_SELL_QTY_WITHOUT_HOLDINGS
|
|
name: "보유수량 미확인 상태에서 매도수량 금지"
|
|
input:
|
|
holdings_quantity_status: "DATA_MISSING"
|
|
requested_action: "SELL"
|
|
expected:
|
|
investment_action: "INSUFFICIENT_DATA"
|
|
prohibited_fields: ["sell_quantity_number"]
|
|
triggered_rule: "non_negotiable_principles[0]"
|
|
|
|
- id: T002_NO_BUY_QTY_WITHOUT_ATR20
|
|
name: "ATR20 미확인 상태에서 정수 매수수량 금지"
|
|
input:
|
|
atr20_status: "DATA_MISSING"
|
|
requested_action: "BUY"
|
|
expected:
|
|
investment_action: "WATCH"
|
|
buy_quantity: 0
|
|
triggered_rule: "non_negotiable_principles[1]"
|
|
|
|
- id: T003_TOTAL_HEAT_HARD_BLOCK
|
|
name: "Total_Heat 10% 이상이면 신규매수 전면 차단"
|
|
input:
|
|
total_heat_pct: 10.0
|
|
requested_action: "BUY"
|
|
expected:
|
|
investment_action: "AVOID"
|
|
triggered_rule: "spec/risk/aggregate_risk.yaml:risk_control.aggregate_risk_cap.threshold.hard_block"
|
|
|
|
- id: T004_FLOW_ROWS_LT_20_NO_A_GRADE
|
|
name: "Flow_Rows<20이면 20D 수급 기반 A등급 금지"
|
|
input:
|
|
flow_rows: 19
|
|
flow20d_based_grade: "A"
|
|
expected:
|
|
max_grade: "B"
|
|
triggered_rule: "non_negotiable_principles[3]"
|
|
|
|
- id: T005_BUY_SET_REQUIRED
|
|
name: "매수 제안은 6개 주문 필드 세트 필수"
|
|
input:
|
|
action: "BUY"
|
|
limit_price: 25000
|
|
quantity: 10
|
|
stop_price: null
|
|
stop_quantity: null
|
|
take_profit_price: 30000
|
|
take_profit_quantity: 5
|
|
expected:
|
|
investment_action: "INSUFFICIENT_DATA"
|
|
prohibited_output: "immediate_execution_playbook"
|
|
triggered_rule: "spec/07_output_schema.yaml:output_format.buy_proposal_template.validation"
|
|
|
|
- id: T006_RISK_OVERRIDES_STRATEGY
|
|
name: "전략 점수가 높아도 리스크 차단이 우선"
|
|
input:
|
|
total_score: 92
|
|
hard_stop_triggered: true
|
|
expected:
|
|
investment_action: "AVOID"
|
|
grade_not_allowed: "A"
|
|
triggered_rule: "conflict_resolution.risk_vs_strategy"
|
|
|
|
- id: T007_DATA_STALE_HOLDS_DECISION
|
|
name: "데이터 최신성 미달이면 주문 결론 보류"
|
|
input:
|
|
data_freshness: "DATA_STALE"
|
|
requested_action: "BUY"
|
|
expected:
|
|
investment_action: "WATCH"
|
|
order_quantity: "not_calculated"
|
|
triggered_rule: "conflict_resolution.data_vs_decision"
|
|
|
|
- id: T008_INTEGER_ONLY
|
|
name: "소수점 수량 금지"
|
|
input:
|
|
calculated_quantity: 12.7
|
|
expected:
|
|
final_quantity_rule: "floor_to_integer"
|
|
final_quantity: 12
|
|
triggered_rule: "non_negotiable_principles[5]"
|
|
|
|
- id: T009_DECISION_FLOW_ORDER
|
|
name: "하드필터 전 BUY 결론 금지"
|
|
input:
|
|
current_state: "STRATEGY_SCORING"
|
|
hard_filter_checked: false
|
|
proposed_action: "BUY"
|
|
expected:
|
|
final_action: "BLOCKED"
|
|
triggered_rule: "spec/09_decision_flow.yaml:global_prohibitions[0]"
|
|
|
|
- id: T010_SCORE_CANNOT_OVERRIDE_HARD_FILTER
|
|
name: "점수가 높아도 하드필터 실패 시 BUY 금지"
|
|
input:
|
|
strategy_score: 95
|
|
failed_hard_filter: "HF002_ATR20_REQUIRED_FOR_QUANTITY"
|
|
proposed_action: "BUY"
|
|
expected:
|
|
final_action: "INSUFFICIENT_DATA"
|
|
buy_quantity: "not_calculated"
|
|
triggered_rule: "spec/08_scoring_rules.yaml:scoring_policy.source_priority"
|
|
|
|
- id: T011_PORTFOLIO_RULES_BEFORE_SIZING
|
|
name: "포트폴리오 제약 통과 전 수량 산출 금지"
|
|
input:
|
|
portfolio_constraint_status: "UNKNOWN"
|
|
requested_action: "BUY"
|
|
expected:
|
|
final_action: "INSUFFICIENT_DATA"
|
|
order_quantity: "not_calculated"
|
|
triggered_rule: "spec/10_portfolio_rules.yaml:portfolio_decision_gate.sequence"
|
|
|
|
- id: T012_MARKET_REGIME_UNKNOWN_NO_A
|
|
name: "거시 핵심 입력 2개 이상 누락 시 Risk-On 추정 금지"
|
|
input:
|
|
missing_macro_inputs: ["VIX_Close", "KOSPI_MA20"]
|
|
proposed_market_regime: "RISK_ON"
|
|
proposed_grade: "A"
|
|
expected:
|
|
market_regime_state: "UNKNOWN"
|
|
max_grade: "B"
|
|
triggered_rule: "spec/11_market_regime.yaml:market_regime.missing_policy"
|
|
|
|
- id: T013_PROMPT_ENTRYPOINTS_EXIST
|
|
name: "분석/리뷰 프롬프트 진입점 존재"
|
|
input:
|
|
required_prompt_files:
|
|
- "prompts/analysis_prompt.md"
|
|
- "prompts/review_prompt.md"
|
|
expected:
|
|
validation_status: "PASS"
|
|
|
|
- id: T014_OUTPUT_COMPAT_FIELDS_REQUIRED
|
|
name: "타 도구 호환 최상위 출력 필드 필수"
|
|
input:
|
|
schema_version: "2026-05-15-F6-compat-output"
|
|
omitted_fields: ["analysis_scope", "evidence", "rule_ids_used"]
|
|
expected:
|
|
validation_status: "FAIL"
|
|
triggered_rule: "schemas/output_schema.json:required"
|
|
|
|
- id: T015_DATA_SAMPLE_VALIDATOR_EXISTS
|
|
name: "실제 xlsx 샘플 정합성 검증 도구 존재"
|
|
input:
|
|
required_tool: "tools/validate_data_sample.py"
|
|
required_sheets: ["data_feed", "sector_flow", "macro", "event_risk", "core_satellite"]
|
|
expected:
|
|
validation_status: "PASS"
|
|
|
|
- id: T016_SPLIT_CANONICAL_FILES_EXIST
|
|
name: "risk/strategy 2차 분해 canonical 파일 존재"
|
|
input:
|
|
required_files:
|
|
- "spec/risk/portfolio_exposure.yaml"
|
|
- "spec/risk/aggregate_risk.yaml"
|
|
- "spec/risk/circuit_breakers.yaml"
|
|
- "spec/risk/market_risk_cash.yaml"
|
|
- "spec/risk/quality_control.yaml"
|
|
- "spec/strategy/sector_model.yaml"
|
|
- "spec/strategy/entry_core.yaml"
|
|
- "spec/strategy/leader_scan.yaml"
|
|
- "spec/strategy/staged_entry.yaml"
|
|
- "spec/strategy/discovery.yaml"
|
|
- "spec/strategy/stock_model.yaml"
|
|
- "spec/strategy/rebalancing_trigger.yaml"
|
|
- "spec/exit/stop_loss.yaml"
|
|
- "spec/exit/take_profit.yaml"
|
|
- "spec/exit/event_response.yaml"
|
|
- "spec/exit/position_review.yaml"
|
|
expected:
|
|
validation_status: "PASS"
|
|
|
|
- id: T017_SMART_CASH_RAISE_ROUTE_D_ONLY_ON_BREACH_OR_EMERGENCY
|
|
name: "ROUTE_D는 stop_breach_gate=BREACH 또는 emergency_full_sell=true에서만 허용"
|
|
input:
|
|
smart_cash_raise_route: "ROUTE_D"
|
|
emergency_full_sell: false
|
|
stop_breach_gate: "PASS"
|
|
expected:
|
|
validation_status: "FAIL"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:SMART_CASH_RAISE_V2"
|
|
|
|
- id: T018_ROUTE_C_REQUIRES_PROFIT_LOCK_STAGE_ENUM
|
|
name: "ROUTE_C는 PROFIT_LOCK_STAGE_20/30 enum만 허용"
|
|
input:
|
|
smart_cash_raise_route: "ROUTE_C"
|
|
profit_lock_stage: "PROFIT_LOCK_20"
|
|
position_type: "CORE"
|
|
secular_leader_gate: "PASS"
|
|
expected:
|
|
validation_status: "FAIL"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PROFIT_LOCK_STAGE_CLASSIFIER_V1"
|
|
|
|
- id: T019_FOLLOW_THROUGH_CANONICAL_KEY_REQUIRED
|
|
name: "하네스 canonical follow_through 키는 follow_through_json/follow_through_lock"
|
|
input:
|
|
present_keys: ["follow_through_confirm_json", "follow_through_confirm_lock"]
|
|
missing_keys: ["follow_through_json", "follow_through_lock"]
|
|
expected:
|
|
validation_status: "FAIL"
|
|
triggered_rule: "spec/19_harness_contract.yaml:required_harness_context_keys.apex_upgrade_keys"
|
|
|
|
- id: T020_ROUTE_D_ALLOWED_ON_BREACH
|
|
name: "ROUTE_D는 stop_breach_gate=BREACH 또는 emergency_full_sell=true에서 허용"
|
|
input:
|
|
smart_cash_raise_route: "ROUTE_D"
|
|
emergency_full_sell: true
|
|
stop_breach_gate: "PASS"
|
|
expected:
|
|
validation_status: "PASS"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:SMART_CASH_RAISE_V2"
|
|
|
|
- id: T021_FOLLOW_THROUGH_CANONICAL_KEY_PRESENT
|
|
name: "하네스 canonical follow_through 키가 있으면 PASS"
|
|
input:
|
|
present_keys: ["follow_through_json", "follow_through_lock"]
|
|
expected:
|
|
validation_status: "PASS"
|
|
triggered_rule: "spec/19_harness_contract.yaml:required_harness_context_keys.apex_upgrade_keys"
|
|
|
|
- id: T022_ROUTE_C_ENUM_OK
|
|
name: "ROUTE_C는 PROFIT_LOCK_STAGE_20/30 enum만 허용"
|
|
input:
|
|
smart_cash_raise_route: "ROUTE_C"
|
|
profit_lock_stage: "PROFIT_LOCK_STAGE_20"
|
|
position_type: "CORE"
|
|
secular_leader_gate: "PASS"
|
|
expected:
|
|
validation_status: "PASS"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PROFIT_LOCK_STAGE_CLASSIFIER_V1"
|
|
|
|
- id: T023_OVERSOLD_REBOUND_50_50_SPLIT
|
|
name: "OVERSOLD_REBOUND_SELL은 즉시/대기 50/50 분할"
|
|
input:
|
|
execution_style: "OVERSOLD_REBOUND_SELL"
|
|
base_qty: 100
|
|
holding_qty: 100
|
|
close_price: 100000
|
|
cash_shortfall_min_krw: 0
|
|
expected:
|
|
immediate_sell_qty: 50
|
|
rebound_wait_qty: 50
|
|
k2_emergency: false
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:K2_STAGED_REBOUND_SELL_V1"
|
|
|
|
- id: T024_OVERSOLD_REBOUND_EMERGENCY_FULL_EXIT
|
|
name: "현금 부족 시 OVERSOLD_REBOUND_SELL은 전량 즉시 매도"
|
|
input:
|
|
execution_style: "OVERSOLD_REBOUND_SELL"
|
|
base_qty: 80
|
|
holding_qty: 80
|
|
close_price: 50000
|
|
cash_shortfall_min_krw: 10000000
|
|
expected:
|
|
immediate_sell_qty: 80
|
|
rebound_wait_qty: 0
|
|
k2_emergency: true
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:K2_STAGED_REBOUND_SELL_V1"
|
|
|
|
- id: T025_PROFIT_PROTECT_TRIM_LIMIT_POLICY
|
|
name: "PROFIT_PROTECT_TRIM은 ratchet_stop_price가 지정가 상한"
|
|
input:
|
|
execution_style: "PROFIT_PROTECT_TRIM"
|
|
ratchet_stop_price: 258000
|
|
close_price: 260000
|
|
profit_lock_stage: "PROFIT_LOCK_30"
|
|
expected:
|
|
sell_limit_price: 258000
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:LIMIT_PRICE_POLICY_V1"
|
|
|
|
- id: T026_WAIT_PILOT_SETUP_NO_POSITION
|
|
name: "보유 없음 + PILOT 불가면 WAIT_PILOT_SETUP"
|
|
input:
|
|
has_position: false
|
|
alpha_lead_state: "WATCH"
|
|
follow_through_state: "WATCH_RESET_REQUIRED"
|
|
buy_permission_state: "WATCH"
|
|
expected:
|
|
tranche_phase: "WAIT_PILOT_SETUP"
|
|
current_tranche_allowed_pct: 0
|
|
next_tranche_condition: "ALPHA_LEAD_SCORE_GTE_75_AND_DISTRIBUTION_PASS"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:STAGED_ENTRY_TRANCHE_V1"
|
|
|
|
- id: T027_PA1_EXIT_SIGNAL_BLOCKS_BUY_PERMISSION
|
|
name: "PA1 EXIT_SIGNAL은 buy_permission를 BLOCKED로 전환"
|
|
input:
|
|
synthesis_verdict: "EXIT_SIGNAL"
|
|
buy_permission_state: "ELIGIBLE"
|
|
predictive_alpha_present: true
|
|
expected:
|
|
pa1_synthesis_verdict: "EXIT_SIGNAL"
|
|
buy_permission_state: "BLOCKED"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PREDICTIVE_ALPHA_ENGINE_V1"
|
|
|
|
- id: T028_PA2_BLOCKED_LATE_ENTRY_FORCES_BLOCK
|
|
name: "PA2 BLOCK은 buy_permission를 BLOCKED로 전환"
|
|
input:
|
|
final_gate_status: "BLOCK"
|
|
entry_grade: "D"
|
|
buy_permission_state: "ELIGIBLE"
|
|
expected:
|
|
anti_late_entry_grade: "D"
|
|
buy_permission_state: "BLOCKED"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:ANTI_LATE_ENTRY_GATE_V2"
|
|
|
|
- id: T029_PA3_PORTFOLIO_ALPHA_CONFIDENCE_NEGATIVE_BLOCK
|
|
name: "포트폴리오 알파 신뢰도 음수면 신규 매수 전면 차단"
|
|
input:
|
|
portfolio_alpha_confidence: -12.5
|
|
buy_permission_state: "ELIGIBLE"
|
|
expected:
|
|
buy_permission_state: "BLOCKED"
|
|
portfolio_alpha_confidence: -12.5
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:CASH_PRESERVATION_SELL_ENGINE_V2"
|
|
|
|
- id: T030_PA5_CONSISTENCY_VALIDATOR_PASSES
|
|
name: "PA5 일관성 검증은 score 90 이상이면 PASS"
|
|
input:
|
|
consistency_score: 96
|
|
cv_verdict: "PASS"
|
|
has_required_keys: true
|
|
expected:
|
|
consistency_score_min: 90
|
|
cv_verdict: "PASS"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:CONSISTENCY_VALIDATOR_V2"
|
|
|
|
- id: T031_WATCHLIST_ONLY_DOWNGRADES_PILOT
|
|
name: "WATCHLIST_ONLY는 PILOT 허용을 WATCH로 다운그레이드"
|
|
input:
|
|
saqg_state: "WATCHLIST_ONLY"
|
|
alpha_lead_state: "PILOT_ALLOWED"
|
|
follow_through_state: "WATCH_RESET_REQUIRED"
|
|
buy_permission_state: "ALLOW_PILOT"
|
|
expected:
|
|
buy_permission_state: "WATCH"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:BUY_PERMISSION_MATRIX_V1"
|
|
|
|
- id: T032_DISTRIBUTION_EXIT_STYLE
|
|
name: "분산 매도 차단이면 execution_style는 DISTRIBUTION_EXIT"
|
|
input:
|
|
anti_distribution_state: "BLOCK_BUY"
|
|
profit_preservation_state: "NORMAL"
|
|
rsi14: 55
|
|
expected:
|
|
execution_style: "DISTRIBUTION_EXIT"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:SMART_CASH_RAISE_PLAN_V1"
|
|
|
|
- id: T033_PROFIT_LOCK_20_CAP_35
|
|
name: "PROFIT_LOCK_20은 즉시 매도 상한 35%"
|
|
input:
|
|
execution_style: "PROFIT_PROTECT_TRIM"
|
|
profit_preservation_state: "PROFIT_LOCK_20"
|
|
holding_qty: 100
|
|
base_qty: 100
|
|
expected:
|
|
immediate_sell_qty_max: 35
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:SELL_VALUE_PRESERVATION_GATE_V1"
|
|
|
|
- id: T034_SAQG_EXCLUDED_FORCES_BLOCKED
|
|
name: "SAQG EXCLUDED는 무조건 BLOCKED"
|
|
input:
|
|
saqg_state: "EXCLUDED"
|
|
buy_permission_state: "ALLOW_PILOT"
|
|
expected:
|
|
buy_permission_state: "BLOCKED"
|
|
blocked_reason: "saqg_EXCLUDED"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:SATELLITE_ALPHA_QUALITY_GATE_V1"
|
|
|
|
- id: T035_FOMC_7D_GATE_ACTIVE
|
|
name: "FOMC 7일 이내면 FOMC size gate ACTIVE"
|
|
input:
|
|
fomc_days_remaining: 7
|
|
buy_permission_state: "ALLOW_PILOT"
|
|
expected:
|
|
fomc_position_size_gate: "ACTIVE"
|
|
fomc_size_limit: 0.5
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T036_PA1_ANTITHESIS_BOOST_APPLIES_UNDER_60
|
|
name: "예측 정확도 60 미만이면 PA1 antithesis 보정"
|
|
input:
|
|
prediction_accuracy_rate: 48.4
|
|
antithesis_score: 40
|
|
synthesis_verdict: "HOLD_NEUTRAL"
|
|
expected:
|
|
antithesis_score_original: 40
|
|
antithesis_weight_boost: 10
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PREDICTIVE_ALPHA_ENGINE_V1"
|
|
|
|
- id: T037_WATCH_BREAKOUT_PROMOTE_TO_WATCH
|
|
name: "위험 회피 급등탐지는 watch breakout 승격"
|
|
input:
|
|
lifecycle_stage: "REVIEW"
|
|
promotion_eligible: true
|
|
velocity_1d: 3.2
|
|
expected:
|
|
breakout_promotion_recommendation: "PROMOTE_TO_WATCH"
|
|
breakout_signal: "WATCH_BREAKOUT_REALTIME_GATE_V1"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:WATCH_BREAKOUT_REALTIME_GATE_V1"
|
|
|
|
- id: T038_ANTI_WHIPSAW_REENTRY_MARKS_CANDIDATE
|
|
name: "급반등 종목은 anti-whipsaw reentry 후보 마킹"
|
|
input:
|
|
sell_candidate_tier: 1
|
|
velocity_1d: 3.4
|
|
close_vs_ma20_pct: 1.0
|
|
expected:
|
|
reentry_candidate: true
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:ANTI_WHIPSAW_REENTRY_GATE_V1"
|
|
|
|
- id: T039_FOMC_8D_GATE_INACTIVE
|
|
name: "FOMC 8일이면 FOMC size gate 비활성"
|
|
input:
|
|
fomc_days_remaining: 8
|
|
buy_permission_state: "ALLOW_PILOT"
|
|
expected:
|
|
fomc_position_size_gate: "INACTIVE"
|
|
fomc_size_limit: 1.0
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T040_PA1_ANTITHESIS_NO_BOOST_AT_60
|
|
name: "예측 정확도 60이면 PA1 antithesis 보정 없음"
|
|
input:
|
|
prediction_accuracy_rate: 60
|
|
antithesis_score: 40
|
|
synthesis_verdict: "HOLD_NEUTRAL"
|
|
expected:
|
|
antithesis_weight_boost: 0
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PREDICTIVE_ALPHA_ENGINE_V1"
|
|
|
|
- id: T041_PA1_ANTITHESIS_BOOST_AT_59_9
|
|
name: "예측 정확도 59.9면 PA1 antithesis 보정 10"
|
|
input:
|
|
prediction_accuracy_rate: 59.9
|
|
antithesis_score: 40
|
|
synthesis_verdict: "HOLD_NEUTRAL"
|
|
expected:
|
|
antithesis_weight_boost: 10
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PREDICTIVE_ALPHA_ENGINE_V1"
|
|
|
|
- id: T042_PREDICTION_ACCURACY_ONE_PERCENT_PARSE
|
|
name: "예측 정확도 1.0은 100으로 파싱"
|
|
input:
|
|
prediction_accuracy_rate: 1.0
|
|
antithesis_score: 40
|
|
synthesis_verdict: "HOLD_NEUTRAL"
|
|
expected:
|
|
prediction_accuracy_rate: 100
|
|
antithesis_weight_boost: 0
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PREDICTIVE_ALPHA_ENGINE_V1"
|
|
|
|
- id: T043_PREDICTION_ACCURACY_POINT_NINE_NINE_PARSE
|
|
name: "예측 정확도 0.99는 99.0으로 파싱"
|
|
input:
|
|
prediction_accuracy_rate: 0.99
|
|
antithesis_score: 40
|
|
synthesis_verdict: "HOLD_NEUTRAL"
|
|
expected:
|
|
prediction_accuracy_rate: 99
|
|
antithesis_weight_boost: 10
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:PREDICTIVE_ALPHA_ENGINE_V1"
|
|
|
|
- id: T044_MACRO_ELEVATED_AT_40
|
|
name: "macro risk 40이면 MACRO_ELEVATED"
|
|
input:
|
|
usd_krw: 1481
|
|
foreign_sell_consecutive_days: 5
|
|
domestic_cpi: 2.6
|
|
vix: 19
|
|
sp500_ret5d: -2.0
|
|
fomc_days_remaining: 6
|
|
expected:
|
|
macro_risk_score: 40
|
|
macro_risk_regime: "MACRO_ELEVATED"
|
|
heat_gate_adj: -1
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T045_MACRO_CRITICAL_AT_60
|
|
name: "macro risk 60이면 MACRO_CRITICAL"
|
|
input:
|
|
usd_krw: 1501
|
|
foreign_sell_consecutive_days: 10
|
|
domestic_cpi: 2.6
|
|
vix: 21
|
|
sp500_ret5d: -3.1
|
|
fomc_days_remaining: 5
|
|
expected:
|
|
macro_risk_score: 60
|
|
macro_risk_regime: "MACRO_CRITICAL"
|
|
heat_gate_adj: -3
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T046_MACRO_USD_KRW_WEAK_AT_1481
|
|
name: "usd_krw 1481이면 weak 점수 15"
|
|
input:
|
|
usd_krw: 1481
|
|
foreign_sell_consecutive_days: 0
|
|
domestic_cpi: 2.0
|
|
vix: 10
|
|
sp500_ret5d: 0.0
|
|
fomc_days_remaining: 30
|
|
expected:
|
|
macro_risk_score: 15
|
|
macro_risk_regime: "MACRO_FAVORABLE"
|
|
heat_gate_adj: 1
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T047_MACRO_VIX_ELEVATED_AT_21
|
|
name: "vix 21이면 elevated 점수 10"
|
|
input:
|
|
usd_krw: 1400
|
|
foreign_sell_consecutive_days: 0
|
|
domestic_cpi: 2.0
|
|
vix: 21
|
|
sp500_ret5d: 0.0
|
|
fomc_days_remaining: 30
|
|
expected:
|
|
macro_risk_score: 10
|
|
macro_risk_regime: "MACRO_FAVORABLE"
|
|
heat_gate_adj: 1
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T048_MACRO_FOREIGN_SELL_HIGH_AT_5
|
|
name: "foreign sell 5일이면 high 점수 15"
|
|
input:
|
|
usd_krw: 1400
|
|
foreign_sell_consecutive_days: 5
|
|
domestic_cpi: 2.0
|
|
vix: 10
|
|
sp500_ret5d: 0.0
|
|
fomc_days_remaining: 30
|
|
expected:
|
|
macro_risk_score: 15
|
|
macro_risk_regime: "MACRO_FAVORABLE"
|
|
heat_gate_adj: 1
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T049_MACRO_FOREIGN_SELL_MEGA_AT_10
|
|
name: "foreign sell 10일이면 mega 점수 20"
|
|
input:
|
|
usd_krw: 1400
|
|
foreign_sell_consecutive_days: 10
|
|
domestic_cpi: 2.0
|
|
vix: 10
|
|
sp500_ret5d: 0.0
|
|
fomc_days_remaining: 30
|
|
expected:
|
|
macro_risk_score: 20
|
|
macro_risk_regime: "MACRO_NEUTRAL"
|
|
heat_gate_adj: 0
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T050_WATCH_BREAKOUT_PROMOTION_ELIGIBLE
|
|
name: "watch breakout이면 승격 후보 마킹"
|
|
input:
|
|
lifecycle_stage: "REVIEW"
|
|
promotion_eligible: true
|
|
velocity_1d: 2.5
|
|
expected:
|
|
breakout_signal: "WATCH_BREAKOUT_DETECTED"
|
|
promotion_eligible: true
|
|
promotion_block_reason: null
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:WATCH_BREAKOUT_REALTIME_GATE_V1"
|
|
|
|
- id: T051_ANTI_WHIPSAW_REENTRY_GRADE_A
|
|
name: "급반등 + LEADER + RSI<50이면 reentry grade A"
|
|
input:
|
|
sell_candidate_tier: 1
|
|
velocity_1d: 3.4
|
|
rsi14: 45
|
|
rs_verdict: "LEADER"
|
|
expected:
|
|
reentry_grade: "A"
|
|
reentry_signal: "REENTRY_CANDIDATE"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:ANTI_WHIPSAW_REENTRY_GATE_V1"
|
|
|
|
- id: T052_CONSISTENCY_WARNING_BOUNDARY
|
|
name: "consistency 92면 WARNING"
|
|
input:
|
|
consistency_score: 92
|
|
cv_verdict: "WARNING"
|
|
expected:
|
|
consistency_score: 92
|
|
cv_verdict: "WARNING"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:CONSISTENCY_VALIDATOR_V2"
|
|
|
|
- id: T053_CONSISTENCY_BLOCK_BOUNDARY
|
|
name: "consistency 83이면 BLOCK"
|
|
input:
|
|
consistency_score: 83
|
|
cv_verdict: "BLOCK"
|
|
expected:
|
|
consistency_score: 83
|
|
cv_verdict: "BLOCK"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:CONSISTENCY_VALIDATOR_V2"
|
|
|
|
- id: T054_MACRO_FOMC_NEAR_AT_5
|
|
name: "fomc 5일 이내면 near 점수 15"
|
|
input:
|
|
usd_krw: 1400
|
|
foreign_sell_consecutive_days: 0
|
|
domestic_cpi: 2.0
|
|
vix: 10
|
|
sp500_ret5d: 0.0
|
|
fomc_days_remaining: 5
|
|
expected:
|
|
macro_risk_score: 15
|
|
macro_risk_regime: "MACRO_FAVORABLE"
|
|
heat_gate_adj: 1
|
|
event_matrix:
|
|
- event: "FOMC_WEEK"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T055_MACRO_MEGA_SELL_ALERT_TRIGGER
|
|
name: "외국인 순매도 1조 이상이면 mega sell alert"
|
|
input:
|
|
usd_krw: 1400
|
|
foreign_sell_krw_today: 1000000000000
|
|
foreign_sell_consecutive_days: 0
|
|
domestic_cpi: 2.0
|
|
vix: 10
|
|
sp500_ret5d: 0.0
|
|
fomc_days_remaining: 30
|
|
expected:
|
|
mega_sell_alert: true
|
|
buy_gate_block_until: "NON_EMPTY"
|
|
event_matrix:
|
|
- event: "MEGA_SELL_ALERT"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:MACRO_EVENT_SYNCHRONIZER_V1"
|
|
|
|
- id: T056_WATCH_BREAKOUT_BLOCKED_BY_LATE_ENTRY
|
|
name: "late entry F면 watch breakout 승격 차단"
|
|
input:
|
|
lifecycle_stage: "REVIEW"
|
|
promotion_eligible: false
|
|
velocity_1d: 2.5
|
|
expected:
|
|
breakout_signal: "WATCH_BREAKOUT_DETECTED"
|
|
promotion_eligible: false
|
|
promotion_block_reason: "ANTI_LATE_ENTRY_GRADE_F"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:WATCH_BREAKOUT_REALTIME_GATE_V1"
|
|
|
|
- id: T057_ANTI_WHIPSAW_REENTRY_GRADE_B
|
|
name: "급반등 + RSI<60이면 reentry grade B"
|
|
input:
|
|
sell_candidate_tier: 2
|
|
velocity_1d: 3.4
|
|
rsi14: 55
|
|
rs_verdict: "NEUTRAL"
|
|
expected:
|
|
reentry_grade: "B"
|
|
reentry_signal: "REENTRY_CANDIDATE"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:ANTI_WHIPSAW_REENTRY_GATE_V1"
|
|
|
|
- id: T058_WATCH_BREAKOUT_LOW_VELOCITY_MONITORED
|
|
name: "저속이면 watch breakout은 monitored"
|
|
input:
|
|
lifecycle_stage: "REVIEW"
|
|
promotion_eligible: false
|
|
velocity_1d: 1.2
|
|
expected:
|
|
breakout_signal: "WATCH_BREAKOUT_MONITORED"
|
|
promotion_eligible: false
|
|
promotion_block_reason: "LOW_VELOCITY"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:WATCH_BREAKOUT_REALTIME_GATE_V1"
|
|
|
|
- id: T059_ANTI_WHIPSAW_REENTRY_GRADE_C
|
|
name: "급반등이지만 RSI>=60이면 reentry grade C"
|
|
input:
|
|
sell_candidate_tier: 2
|
|
velocity_1d: 3.4
|
|
rsi14: 60
|
|
rs_verdict: "NEUTRAL"
|
|
expected:
|
|
reentry_grade: "C"
|
|
reentry_signal: "REENTRY_CANDIDATE"
|
|
triggered_rule: "spec/13b_harness_formulas.yaml:ANTI_WHIPSAW_REENTRY_GATE_V1"
|