feat: 리밸런싱 엔진 V1 + GAS 버그 수정 (2026-06-13)
주요 변경: - 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>
This commit is contained in:
@@ -0,0 +1,670 @@
|
||||
schema_version: formula_domain.v1
|
||||
source: C:\Temp\data_feed\spec\13_formula_registry.yaml
|
||||
domain: portfolio
|
||||
formulas:
|
||||
TOTAL_HEAT_V1:
|
||||
purpose: 손절 기준 총 위험노출 계산
|
||||
inputs:
|
||||
- field: average_cost
|
||||
source: account_snapshot
|
||||
unit: KRW_per_share
|
||||
- field: stop_price
|
||||
source: account_snapshot
|
||||
unit: KRW_per_share
|
||||
- field: quantity
|
||||
source: account_snapshot.holding_quantity
|
||||
unit: shares
|
||||
- field: total_asset
|
||||
unit: KRW
|
||||
expression: sum((average_cost - stop_price) * quantity for each confirmed account_snapshot
|
||||
holding) / total_asset * 100
|
||||
output:
|
||||
field: total_heat_pct
|
||||
unit: percent
|
||||
missing_policy:
|
||||
stop_price: if atr20 exists use entry_price - atr20*2.0 else assume portfolio
|
||||
heat contribution cap breach
|
||||
quantity: NO_TOTAL_HEAT
|
||||
total_asset: NO_TOTAL_HEAT
|
||||
gates:
|
||||
- if: total_heat_pct >= 10
|
||||
action: BLOCK_NEW_BUY
|
||||
- if: 7 <= total_heat_pct < 10
|
||||
action: HALVE_NEW_BUY_QUANTITY
|
||||
- if: total_heat_pct < 7
|
||||
action: ALLOW_CONTINUE
|
||||
canonical_ref: spec/risk/aggregate_risk.yaml:risk_control.aggregate_risk_cap
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- average_cost
|
||||
- stop_price
|
||||
- quantity
|
||||
- total_asset
|
||||
output_fields:
|
||||
- total_heat_pct
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
RISK_BUDGET_CASCADE_V1:
|
||||
purpose: base risk budget에 Bayesian, 성과, 국면, Kelly 감액을 순서대로 적용
|
||||
inputs:
|
||||
- field: base_risk_budget
|
||||
unit: ratio
|
||||
default: 0.007
|
||||
- field: net_return_feedback_multiplier
|
||||
unit: ratio
|
||||
default: 1.0
|
||||
- field: performance_brake_multiplier
|
||||
unit: ratio
|
||||
default: 1.0
|
||||
- field: regime_reset_multiplier
|
||||
unit: ratio
|
||||
default: 1.0
|
||||
- field: bayesian_confidence_multiplier
|
||||
unit: ratio
|
||||
- field: kelly_brake_multiplier
|
||||
unit: ratio
|
||||
default: 1.0
|
||||
expression: base_risk_budget * net_return_feedback_multiplier * performance_brake_multiplier
|
||||
* regime_reset_multiplier * bayesian_confidence_multiplier * kelly_brake_multiplier
|
||||
output:
|
||||
field: final_risk_budget
|
||||
unit: ratio
|
||||
floor_rule:
|
||||
if: final_risk_budget < 0.001
|
||||
action: NO_BET
|
||||
canonical_ref: spec/05_position_sizing.yaml:position_sizing.cascade_risk_budget_rule
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- base_risk_budget
|
||||
- net_return_feedback_multiplier
|
||||
- performance_brake_multiplier
|
||||
- regime_reset_multiplier
|
||||
- bayesian_confidence_multiplier
|
||||
- kelly_brake_multiplier
|
||||
output_fields:
|
||||
- final_risk_budget
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
POSITION_SIZE_V1:
|
||||
purpose: 최종 정수 매수수량 산출
|
||||
inputs:
|
||||
- field: total_asset
|
||||
unit: KRW
|
||||
- field: final_risk_budget
|
||||
unit: ratio
|
||||
- field: atr20
|
||||
unit: KRW_per_share
|
||||
- field: atr_multiplier
|
||||
unit: ratio
|
||||
default: 1.5
|
||||
- field: available_cash
|
||||
unit: KRW
|
||||
- field: entry_price
|
||||
unit: KRW_per_share
|
||||
- field: target_weight_limit_amount
|
||||
unit: KRW
|
||||
- field: sector_limit_amount
|
||||
unit: KRW
|
||||
- field: liquidity_limit_amount
|
||||
unit: KRW
|
||||
intermediate_outputs:
|
||||
atr_quantity: floor((total_asset * final_risk_budget) / (atr20 * atr_multiplier))
|
||||
cash_limit_quantity: floor(available_cash / entry_price)
|
||||
target_weight_limit_quantity: floor(target_weight_limit_amount / entry_price)
|
||||
sector_limit_quantity: floor(sector_limit_amount / entry_price)
|
||||
liquidity_limit_quantity: floor(liquidity_limit_amount / entry_price)
|
||||
expression: min(atr_quantity, cash_limit_quantity, target_weight_limit_quantity,
|
||||
sector_limit_quantity, liquidity_limit_quantity)
|
||||
output:
|
||||
field: final_quantity
|
||||
unit: shares_integer
|
||||
missing_policy:
|
||||
atr20: NO_BUY_QUANTITY
|
||||
total_asset: NO_BUY_QUANTITY
|
||||
available_cash: NO_BUY_QUANTITY
|
||||
entry_price: NO_BUY_QUANTITY
|
||||
target_weight_limit_amount: use very large number only if portfolio rule says
|
||||
NOT_APPLICABLE
|
||||
sector_limit_amount: use very large number only if sector cap says NOT_APPLICABLE
|
||||
liquidity_limit_amount: allow PARTIAL only for report; BUY validation_status
|
||||
cannot PASS
|
||||
canonical_ref: spec/05_position_sizing.yaml:position_sizing.volatility_targeting
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- total_asset
|
||||
- final_risk_budget
|
||||
- atr20
|
||||
- atr_multiplier
|
||||
- available_cash
|
||||
- entry_price
|
||||
- target_weight_limit_amount
|
||||
- sector_limit_amount
|
||||
- liquidity_limit_amount
|
||||
output_fields:
|
||||
- final_quantity
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
PORTFOLIO_BAND_STATUS_V1:
|
||||
purpose: 현재 비중이 목표 밴드보다 낮은지, 정상인지, 초과인지 판정
|
||||
inputs:
|
||||
- field: current_weight_pct
|
||||
unit: percent
|
||||
- field: target_band_min_pct
|
||||
unit: percent
|
||||
- field: target_band_max_pct
|
||||
unit: percent
|
||||
rules:
|
||||
- if: current_weight_pct < target_band_min_pct
|
||||
status: UNDERWEIGHT
|
||||
action: ADD_ALLOWED_IF_ALL_GATES_PASS
|
||||
- if: target_band_min_pct <= current_weight_pct <= target_band_max_pct
|
||||
status: IN_BAND
|
||||
action: HOLD_OR_SELECTIVE_ADD
|
||||
- if: current_weight_pct > target_band_max_pct
|
||||
status: OVERWEIGHT
|
||||
action: TRIM_REVIEW
|
||||
output:
|
||||
field: portfolio_band_status
|
||||
unit: enum
|
||||
missing_policy: DATA_MISSING. add/trim 결론 보류.
|
||||
canonical_ref: spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.target_allocation_structure
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- current_weight_pct
|
||||
- target_band_min_pct
|
||||
- target_band_max_pct
|
||||
output_fields:
|
||||
- portfolio_band_status
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
PORTFOLIO_BETA_V1:
|
||||
purpose: 보유 포지션의 시가기준 가중평균 베타를 산출하여 팩터 과집중 판단에 사용
|
||||
inputs:
|
||||
- field: beta_i
|
||||
source: data_feed.Beta for each holding i
|
||||
unit: ratio
|
||||
- field: market_value_i
|
||||
source: account_snapshot.holding_quantity × close_price
|
||||
unit: KRW
|
||||
- field: total_equity_value
|
||||
source: sum(market_value_i)
|
||||
unit: KRW
|
||||
expression: sum(beta_i × market_value_i / total_equity_value) for each holding
|
||||
with known beta
|
||||
output:
|
||||
field: portfolio_beta
|
||||
unit: ratio
|
||||
missing_policy:
|
||||
beta_i_missing_single: '해당 종목 제외 후 부분 산출. 제외 종목 시가 비중이 30% 초과 시 결과에 "(PARTIAL
|
||||
— Beta 미확인 {N}개 종목 제외)" 표기.
|
||||
|
||||
'
|
||||
beta_i_missing_all: NO_PORTFOLIO_BETA. 팩터 리스크 점검 PARTIAL 표기.
|
||||
total_equity_value_zero: NO_PORTFOLIO_BETA
|
||||
example:
|
||||
holdings:
|
||||
- name: 삼성전자
|
||||
market_value: 100000000
|
||||
beta: 1.1
|
||||
- name: SK하이닉스
|
||||
market_value: 80000000
|
||||
beta: 1.3
|
||||
- name: 한화에어로스페이스
|
||||
market_value: 40000000
|
||||
beta: 1.6
|
||||
total_equity: 220000000
|
||||
result: (1.1×100 + 1.3×80 + 1.6×40) / 220 = (110 + 104 + 64) / 220 = 278/220
|
||||
≈ 1.26
|
||||
canonical_ref: spec/risk/portfolio_exposure.yaml:portfolio_exposure_framework.factor_risk_limit
|
||||
version: 2026-05-18_ROUTING_OPTIMIZATION_V1
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- beta_i
|
||||
- market_value_i
|
||||
- total_equity_value
|
||||
output_fields:
|
||||
- portfolio_beta
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
PORTFOLIO_CORRELATION_GATE_V1:
|
||||
purpose: '위성 포지션들 간 20D 수익률 Pearson 상관관계를 계산해 동일 방향 클러스터가 포트폴리오 하락 리스크를 증폭시키는지
|
||||
감지한다. 개별 Beta x 상관관계 조정으로 실질 포트폴리오 Beta(satellite_cluster_beta) 산출.
|
||||
|
||||
'
|
||||
applicable: calcApexExecutionHarness_ 포트폴리오 집계 단계. SAPG_V1 이후 실행.
|
||||
inputs:
|
||||
- field: ticker
|
||||
- field: price.ret20D
|
||||
- field: beta_proxy
|
||||
- field: weight_pct
|
||||
computed:
|
||||
correlation_matrix: 각 위성 쌍 (i,j) Pearson 상관계수. 데이터 부족 시 ret20D/globalKospiRet20D_
|
||||
프록시.
|
||||
satellite_cluster_beta: sum(weight_i * weight_j * beta_i * beta_j * corr_ij)
|
||||
for all i,j pairs
|
||||
effective_portfolio_beta: (core_weight * core_beta) + satellite_cluster_beta
|
||||
gate_status:
|
||||
CORRELATION_BLOCK:
|
||||
condition: satellite_cluster_beta > 1.5 AND corr >= 0.70인 위성 쌍이 2쌍 이상
|
||||
action: 고상관 약한 위성 ADD 금지, REVIEW 위성 우선 정리, 실질 beta 보고서 표기 의무
|
||||
CORRELATION_WARN:
|
||||
condition: satellite_cluster_beta > 1.2 OR corr >= 0.70인 위성 쌍이 1쌍
|
||||
action: 신규 위성 편입 시 저상관 후보 우선
|
||||
CORRELATION_PASS:
|
||||
condition: satellite_cluster_beta <= 1.2
|
||||
action: 정상. M2 독립 적용.
|
||||
output_fields:
|
||||
- field: satellite_cluster_beta
|
||||
- field: effective_portfolio_beta
|
||||
- field: high_corr_pairs
|
||||
unit: list [{ticker1,ticker2,corr_coef}]
|
||||
- field: correlation_gate_status
|
||||
unit: enum [CORRELATION_PASS,CORRELATION_WARN,CORRELATION_BLOCK]
|
||||
ground_truth: harness
|
||||
llm_allowed: cite_only
|
||||
prohibition:
|
||||
- LLM이 상관행렬 직접 계산 금지
|
||||
- 개별 beta 낮아도 satellite_cluster_beta 높으면 분산 됐다 서술 금지
|
||||
output:
|
||||
field: satellite_cluster_beta
|
||||
additional_fields:
|
||||
- effective_portfolio_beta
|
||||
- high_corr_pairs
|
||||
- correlation_gate_status
|
||||
version: 2026-05-21_PCG_V1
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- ticker
|
||||
- price.ret20D
|
||||
- beta_proxy
|
||||
- weight_pct
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
DYNAMIC_HEAT_GATE_V1:
|
||||
purpose: '국면별 총 위험노출 임계값을 산출해 신규 매수 차단 여부를 결정한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
- field: total_heat_pct
|
||||
unit: pct
|
||||
output:
|
||||
field: heat_gate_status
|
||||
input_fields:
|
||||
- market_regime
|
||||
- total_heat_pct
|
||||
expected_outputs:
|
||||
- heat_gate_status
|
||||
- heat_gate_threshold_pct
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- heat_gate_status
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
POSITION_SIZE_REGIME_SCALE_V1:
|
||||
purpose: '국면별 포지션 크기 스케일을 결정론적으로 산출한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: regime_size_scale
|
||||
input_fields:
|
||||
- market_regime
|
||||
expected_outputs:
|
||||
- regime_size_scale
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- regime_size_scale
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
DRAWDOWN_GUARD_V1:
|
||||
purpose: '연속 손절/성과 악화 구간에서 신규 매수 수량을 자동 축소하거나 차단한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: win_loss_streak_state
|
||||
unit: enum
|
||||
- field: win_loss_streak_buy_scale
|
||||
unit: multiplier
|
||||
output:
|
||||
field: drawdown_guard_state
|
||||
input_fields:
|
||||
- consecutive_loss_count
|
||||
- recent_win_loss_state
|
||||
expected_outputs:
|
||||
- drawdown_guard_state
|
||||
- drawdown_buy_scale
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- drawdown_guard_state
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
POSITION_COUNT_LIMIT_V1:
|
||||
purpose: '동시 보유 종목 수 상한과 초과 여부를 판단한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: position_count
|
||||
unit: integer
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: position_count_gate
|
||||
input_fields:
|
||||
- position_count
|
||||
- market_regime
|
||||
expected_outputs:
|
||||
- position_count_gate
|
||||
- position_count_max
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- position_count_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
SINGLE_POSITION_WEIGHT_CAP_V1:
|
||||
purpose: '단일 종목 비중 상한과 초과 TRIM 필요 여부를 판단한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: single_position_weight_json
|
||||
unit: json
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: single_position_weight_gate
|
||||
input_fields:
|
||||
- position_weight_pct
|
||||
- market_regime
|
||||
expected_outputs:
|
||||
- single_position_weight_gate
|
||||
- weight_cap_pct
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- single_position_weight_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
REGIME_TRIM_GUIDANCE_V1:
|
||||
purpose: '국면별 현금확보용 TRIM 우선순위를 결정한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: regime_adjusted_sell_priority_json
|
||||
unit: json
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: regime_trim_guidance
|
||||
input_fields:
|
||||
- market_regime
|
||||
- sector_rank
|
||||
expected_outputs:
|
||||
- regime_trim_guidance
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- regime_trim_guidance
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
HEAT_CONCENTRATION_ALERT_V1:
|
||||
purpose: '단일 종목이 총 Heat의 과도한 비중을 차지하는지 경보를 낸다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: heat_share_pct
|
||||
unit: pct
|
||||
output:
|
||||
field: heat_concentration_gate
|
||||
input_fields:
|
||||
- heat_share_pct
|
||||
expected_outputs:
|
||||
- heat_concentration_gate
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- heat_concentration_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
SECTOR_CONCENTRATION_LIMIT_V1:
|
||||
purpose: '섹터 편중 한도와 신규 BUY 차단 여부를 판단한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: sector_concentration_json
|
||||
unit: json
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: sector_concentration_gate
|
||||
input_fields:
|
||||
- sector_concentration_pct
|
||||
- market_regime
|
||||
expected_outputs:
|
||||
- sector_concentration_gate
|
||||
- sector_concentration_limit_pct
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- sector_concentration_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
PORTFOLIO_DRAWDOWN_GATE_V1:
|
||||
purpose: '포트폴리오 고점 대비 낙폭을 산출해 신규 BUY 차단 여부를 판단한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: portfolio_peak_krw
|
||||
unit: KRW
|
||||
- field: total_asset_krw
|
||||
unit: KRW
|
||||
output:
|
||||
field: portfolio_drawdown_gate
|
||||
input_fields:
|
||||
- portfolio_peak_krw
|
||||
- total_asset_krw
|
||||
expected_outputs:
|
||||
- portfolio_drawdown_gate
|
||||
- portfolio_drawdown_pct
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- portfolio_drawdown_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
SECTOR_ROTATION_MOMENTUM_V1:
|
||||
purpose: '섹터 로테이션 모멘텀 상태와 신규 매수 적합성을 판정한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: sector
|
||||
unit: string
|
||||
- field: momentum_state
|
||||
unit: enum
|
||||
output:
|
||||
field: sector_rotation_momentum_json
|
||||
input_fields:
|
||||
- sector
|
||||
- momentum_state
|
||||
expected_outputs:
|
||||
- sector_rotation_momentum_json
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- sector_rotation_momentum_json
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
MARKET_WEIGHT_AWARE_CLUSTER_GATE_V1:
|
||||
purpose: '시장 반도체 비중을 반영한 동적 클러스터 차단/경고 임계값을 산출한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: semiconductor_cluster_json
|
||||
unit: json
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: semiconductor_cluster_gate
|
||||
input_fields:
|
||||
- kospi_semi_weight_pct
|
||||
- combined_pct
|
||||
- market_regime
|
||||
expected_outputs:
|
||||
- cluster_gate
|
||||
- cap_pct
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- semiconductor_cluster_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
LEADER_POSITION_WEIGHT_CAP_V1:
|
||||
purpose: '주도주 종목별 차등 비중 상한과 초과 TRIM 필요 여부를 산출한다.
|
||||
|
||||
'
|
||||
inputs:
|
||||
- field: single_position_weight_json
|
||||
unit: json
|
||||
- field: market_regime
|
||||
unit: enum
|
||||
output:
|
||||
field: single_position_weight_gate
|
||||
input_fields:
|
||||
- ticker
|
||||
- position_weight_pct
|
||||
- market_regime
|
||||
expected_outputs:
|
||||
- leader_position_weight_gate
|
||||
- weight_cap_pct
|
||||
llm_allowed: cite_only
|
||||
version: 2026-05-30_PHASE8
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
output_fields:
|
||||
- single_position_weight_gate
|
||||
missing_policy: DATA_MISSING. 계산 결과를 추정하지 않는다.
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
REGIME_CONDITIONAL_MACRO_FACTOR_V1:
|
||||
purpose: 거시팩터 종목별 FX 민감도 베타 적용 — 단일팩터 전 종목 균일 지배 차단 (Direction SFP1)
|
||||
agents_md_ref: 'Direction SFP1: SINGLE_FACTOR_DOMINANCE_CAP_V1'
|
||||
inputs:
|
||||
- field: base_macro_score
|
||||
unit: ratio_0_1
|
||||
- field: ticker
|
||||
unit: string
|
||||
- field: ticker_type
|
||||
unit: 'enum: export | domestic | neutral'
|
||||
expression: base_macro_score x fx_sensitivity_beta(ticker_type)
|
||||
components:
|
||||
fx_sensitivity_beta:
|
||||
export: 1.2
|
||||
domestic: 0.7
|
||||
neutral: 1.0
|
||||
note: '수출주(삼성전자·SK하이닉스 등): FX 민감도 20% 가중. 내수주: 30% 축소.'
|
||||
output:
|
||||
field: macro_factor_applied
|
||||
unit: ratio_0_1
|
||||
gate:
|
||||
condition: single_factor_max_share_pct > 50
|
||||
result: SINGLE_FACTOR_DEGENERATE
|
||||
action: WARN — synthesis_verdict 다양성 확보 실패, 보고서 첫 줄 경고 의무
|
||||
missing_policy: ticker_type 미확인 시 fx_beta=1.0(neutral) 적용
|
||||
implementation: tools/build_predictive_alpha_dialectic_engine_v2.py:NF1
|
||||
calibration_ref: spec/calibration_registry.yaml:NF1 (EXPERT_PRIOR)
|
||||
version: 2026-06-04_NF1
|
||||
owner: quant_team
|
||||
lifecycle_state: active
|
||||
input_fields:
|
||||
- base_macro_score
|
||||
- ticker
|
||||
- ticker_type
|
||||
output_fields:
|
||||
- macro_factor_applied
|
||||
golden_cases: []
|
||||
activation_threshold:
|
||||
min_t20_sample: 30
|
||||
retirement_condition: performance_degradation
|
||||
Reference in New Issue
Block a user