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>
206 lines
7.3 KiB
YAML
206 lines
7.3 KiB
YAML
schema_version: gas_logic_migration_ledger.v1
|
|
source: governance/gas_logic_migration_ledger_v1.yaml
|
|
authored: 2026-06-10
|
|
total_findings: 15
|
|
classification_summary:
|
|
decision_logic: 4
|
|
score_logic: 5
|
|
price_qty_logic: 4
|
|
pure_mapping: 1
|
|
display_text: 1
|
|
unclassified_findings: 0
|
|
|
|
# Canonical classification of GAS thin-adapter findings identified by
|
|
# validate_gas_thin_adapter_v1.py. Each finding is classified by what type
|
|
# of logic it contains and paired with a migration_action.
|
|
findings:
|
|
- id: F01
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 186
|
|
text: "SP_TAKE_PROFIT: 10, // Profit_Pct >= 10% (익절 후보)"
|
|
classification: score_logic
|
|
migration_action: REGISTER_SP_TAKE_PROFIT
|
|
target_file: formulas/score_thresholds_v1.py
|
|
status: TODO
|
|
|
|
- id: F02
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 656
|
|
text: "priceBasis = Number.isFinite(tp2Price) ? \"TAKE_PROFIT_TIER2_PRICE\" : \"PRIOR_CLOSE_X_0.998\";"
|
|
classification: price_qty_logic
|
|
migration_action: MIGRATE_PRICEBASIS_TO_PYTHON
|
|
target_file: formulas/price_basis_v1.py
|
|
status: TODO
|
|
blocking_on: F03 F04 (same function, migrate together)
|
|
|
|
- id: F03
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 665
|
|
text: "priceBasis = Number.isFinite(tp2Price) ? \"TAKE_PROFIT_TIER2_PRICE\" : \"PRIOR_CLOSE_X_0.998\";"
|
|
classification: price_qty_logic
|
|
migration_action: MIGRATE_PRICEBASIS_TO_PYTHON
|
|
target_file: formulas/price_basis_v1.py
|
|
status: TODO
|
|
blocking_on: F02 F04
|
|
|
|
- id: F04
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 674
|
|
text: "priceBasis = Number.isFinite(tp1Price) ? \"TAKE_PROFIT_TIER1_PRICE\" : \"PRIOR_CLOSE_X_0.998\";"
|
|
classification: price_qty_logic
|
|
migration_action: MIGRATE_PRICEBASIS_TO_PYTHON
|
|
target_file: formulas/price_basis_v1.py
|
|
status: TODO
|
|
|
|
- id: F05
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 678
|
|
text: "action = \"TAKE_PROFIT_TIER1\";"
|
|
classification: decision_logic
|
|
migration_action: MIGRATE_DECISIONS_ROUTING
|
|
target_file: formulas/execution_decision_v1.py
|
|
status: TODO
|
|
|
|
- id: F06
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 683
|
|
text: "priceBasis = Number.isFinite(tp1Price) ? \"TAKE_PROFIT_TIER1_PRICE\" : \"PRIOR_CLOSE_X_0.998\";"
|
|
classification: price_qty_logic
|
|
migration_action: MIGRATE_PRICEBASIS_TO_PYTHON
|
|
target_file: formulas/price_basis_v1.py
|
|
status: TODO
|
|
|
|
- id: F07
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 1577
|
|
text: "score += THRESHOLDS[\"SP_TAKE_PROFIT\"];"
|
|
classification: score_logic
|
|
migration_action: MIGRATE_SCORE_CALCULATION
|
|
target_file: formulas/score_thresholds_v1.py
|
|
status: TODO
|
|
|
|
- id: F08
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 1578
|
|
text: "breakdown.push(`take_profit:+${THRESHOLDS[\"SP_TAKE_PROFIT\"]}`)"
|
|
classification: display_text
|
|
migration_action: DISPLAY_TEXT_PASSTHROUGH
|
|
notes: display_text stays in GAS adapter as rendering concern
|
|
status: KEEP_IN_GAS
|
|
|
|
- id: F09
|
|
file: src/gas_adapter_parts/gdf_01_price_metrics.gs
|
|
line: 2164
|
|
text: "TAKE_PROFIT_BASE: 10,"
|
|
classification: score_logic
|
|
migration_action: REGISTER_TAKE_PROFIT_BASE
|
|
target_file: formulas/score_thresholds_v1.py
|
|
status: TODO
|
|
|
|
- id: F10
|
|
file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs
|
|
line: 1335
|
|
text: "return { [\"decisions\"]: routes, traces: traces, lock: true };"
|
|
classification: decision_logic
|
|
migration_action: MIGRATE_DECISIONS_ROUTING
|
|
target_file: formulas/routing_decision_v1.py
|
|
status: TODO
|
|
|
|
- id: F11
|
|
file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs
|
|
line: 1360
|
|
text: "if (holding && holding.stopBreach) return 'STOP_LOSS';"
|
|
classification: decision_logic
|
|
migration_action: MIGRATE_STOP_BREACH_DECISION
|
|
target_file: formulas/stop_loss_gate_v1.py
|
|
status: TODO
|
|
|
|
- id: F12
|
|
file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs
|
|
line: 2128
|
|
text: "[\"distribution_risk_score\"]: Math.min(100, Math.max(0, score)),"
|
|
classification: score_logic
|
|
migration_action: DELETE_DISTRIBUTION_RISK_GAS
|
|
target_file: formulas/distribution_risk_v1.py
|
|
status: TODO
|
|
notes: Python canonical (build_distribution_risk_v1.py) already exists; GAS version is duplicate
|
|
|
|
- id: F13
|
|
file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs
|
|
line: 2132
|
|
text: "formula_id: 'DISTRIBUTION_RISK_SCORE_V1'"
|
|
classification: pure_mapping
|
|
migration_action: DELETE_DISTRIBUTION_RISK_GAS
|
|
status: TODO
|
|
notes: formula_id tag stays with Python canonical; remove from GAS
|
|
|
|
- id: F14
|
|
file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs
|
|
line: 2214
|
|
text: "[\"late_chase_risk_score\"]: Math.min(100, Math.max(0, Math.round(lateChaseRisk))),"
|
|
classification: score_logic
|
|
migration_action: DELETE_LATE_CHASE_RISK_GAS
|
|
target_file: formulas/late_chase_risk_v1.py
|
|
status: TODO
|
|
notes: Python canonical (build_alpha_lead_table_v1.py) computes late_chase_risk; GAS version is duplicate
|
|
|
|
- id: F15
|
|
file: src/gas_adapter_parts/gdf_04_execution_quality.gs
|
|
line: 479
|
|
text: "if (bqRow.breakout_quality_gate === 'BLOCKED_LATE_CHASE' || alphaRow[\"late_chase_risk_score\"] >= 70)"
|
|
classification: decision_logic
|
|
migration_action: MIGRATE_LATE_CHASE_GATE
|
|
target_file: formulas/late_chase_gate_v1.py
|
|
status: TODO
|
|
|
|
# Migration action summary (9 actions)
|
|
migration_actions:
|
|
- action_id: REGISTER_SP_TAKE_PROFIT
|
|
findings: [F01]
|
|
description: Register SP_TAKE_PROFIT threshold (value=10) in Python score_thresholds canonical
|
|
priority: LOW
|
|
|
|
- action_id: REGISTER_TAKE_PROFIT_BASE
|
|
findings: [F09]
|
|
description: Register TAKE_PROFIT_BASE threshold (value=10) in Python score_thresholds canonical
|
|
priority: LOW
|
|
|
|
- action_id: DELETE_DISTRIBUTION_RISK_GAS
|
|
findings: [F12, F13]
|
|
description: Remove distribution_risk_score calculation from gdf_03; Python canonical exists
|
|
priority: HIGH
|
|
blocker: verify build_distribution_risk_v1.py output matches GAS output before delete
|
|
|
|
- action_id: DELETE_LATE_CHASE_RISK_GAS
|
|
findings: [F14]
|
|
description: Remove late_chase_risk_score from gdf_03; Python canonical in alpha_lead_table_v1
|
|
priority: HIGH
|
|
blocker: verify parity before delete
|
|
|
|
- action_id: MIGRATE_PRICEBASIS_TO_PYTHON
|
|
findings: [F02, F03, F04, F06]
|
|
description: priceBasis string selection (TIER1/TIER2 or PRIOR_CLOSE_X_0.998) → Python canonical
|
|
priority: MEDIUM
|
|
|
|
- action_id: MIGRATE_SCORE_CALCULATION
|
|
findings: [F07]
|
|
description: score += THRESHOLDS["SP_TAKE_PROFIT"] pattern → Python canonical scorer
|
|
priority: MEDIUM
|
|
|
|
- action_id: MIGRATE_STOP_BREACH_DECISION
|
|
findings: [F11]
|
|
description: holding.stopBreach → STOP_LOSS decision → Python canonical stop_loss_gate
|
|
priority: HIGH
|
|
notes: critical path — must match validate_stop_loss_policy_v1 spec
|
|
|
|
- action_id: MIGRATE_DECISIONS_ROUTING
|
|
findings: [F05, F10]
|
|
description: TAKE_PROFIT_TIER1 action assignment and routing lock decision → Python canonical
|
|
priority: MEDIUM
|
|
|
|
- action_id: MIGRATE_LATE_CHASE_GATE
|
|
findings: [F15]
|
|
description: BLOCKED_LATE_CHASE gate check (threshold 70) → Python canonical gate formula
|
|
priority: HIGH
|
|
blocker: late_chase_risk_score must come from Python before GAS gate can be removed
|