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>
815 lines
28 KiB
YAML
815 lines
28 KiB
YAML
schema_version: gas_migration_wave2_4.v1
|
|
generated_at: '2026-06-10'
|
|
playbook_ref: suggest/quant_engine_refactor_playbook_v1.yaml#P5-T01
|
|
total_findings: 103
|
|
wave: "2-4"
|
|
wave_size: 78
|
|
wave_items:
|
|
|
|
- idx: 25
|
|
file: gas_data_feed.gs
|
|
line: 656
|
|
text: 'priceBasis = Number.isFinite(tp2Price) ? "TAKE_PROFIT_TIER2_PRICE" : "PRIOR_CLOSE_X_0.998";'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: GAS determines price basis label and fallback in take-profit dispatch logic. Python should select and return priceBasis as part of TAKE_PROFIT_LADDER_V2 output.
|
|
python_path: src/quant_engine/
|
|
formula_id: TAKE_PROFIT_LADDER_V2
|
|
|
|
- idx: 26
|
|
file: gas_data_feed.gs
|
|
line: 665
|
|
text: 'priceBasis = Number.isFinite(tp2Price) ? "TAKE_PROFIT_TIER2_PRICE" : "PRIOR_CLOSE_X_0.998";'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: Duplicate of idx=25 in adjacent branch; same priceBasis fallback decision.
|
|
python_path: src/quant_engine/
|
|
formula_id: TAKE_PROFIT_LADDER_V2
|
|
|
|
- idx: 27
|
|
file: gas_data_feed.gs
|
|
line: 674
|
|
text: 'priceBasis = Number.isFinite(tp1Price) ? "TAKE_PROFIT_TIER1_PRICE" : "PRIOR_CLOSE_X_0.998";'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: Tier1 variant of priceBasis fallback; same migration target as idx=25.
|
|
python_path: src/quant_engine/
|
|
formula_id: TAKE_PROFIT_LADDER_V2
|
|
|
|
- idx: 28
|
|
file: gas_data_feed.gs
|
|
line: 678
|
|
text: 'action = "TAKE_PROFIT_TIER1";'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: GAS directly assigns action string — this is a decision outcome that should come from Python.
|
|
python_path: src/quant_engine/
|
|
formula_id: TAKE_PROFIT_LADDER_V2
|
|
|
|
- idx: 29
|
|
file: gas_data_feed.gs
|
|
line: 683
|
|
text: 'priceBasis = Number.isFinite(tp1Price) ? "TAKE_PROFIT_TIER1_PRICE" : "PRIOR_CLOSE_X_0.998";'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: Another branch of same priceBasis fallback; TAKE_PROFIT_LADDER_V2 migration target.
|
|
python_path: src/quant_engine/
|
|
formula_id: TAKE_PROFIT_LADDER_V2
|
|
|
|
- idx: 30
|
|
file: gas_data_feed.gs
|
|
line: 741
|
|
text: '// SL003_PRIORITY_MATRIX: 복수 손절 조건 동시 발동 시 max(prices) 적용 — spec/exit/stop_loss.yaml'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Comment referencing spec/exit/stop_loss.yaml; no code logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 31
|
|
file: gas_data_feed.gs
|
|
line: 742
|
|
text: '// TP 계열(PROFIT_TRIM_*, TAKE_PROFIT_TIER1)은 별도 프레임워크이므로 이 블록 적용 제외'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Documentation comment only.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 32
|
|
file: gas_data_feed.gs
|
|
line: 1577
|
|
text: 'score += THRESHOLDS["SP_TAKE_PROFIT"];'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: GAS computes a score by adding the SP_TAKE_PROFIT threshold. Score computation must move to Python.
|
|
python_path: src/quant_engine/
|
|
formula_id: SELL_PRIORITY_SCORING_V1
|
|
|
|
- idx: 33
|
|
file: gas_data_feed.gs
|
|
line: 1578
|
|
text: 'breakdown.push(`take_profit:+${THRESHOLDS["SP_TAKE_PROFIT"]}`);'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: "Part of the same score breakdown accumulation as idx=32. Migration target: Python returns the breakdown list."
|
|
python_path: src/quant_engine/
|
|
formula_id: SELL_PRIORITY_SCORING_V1
|
|
|
|
- idx: 34
|
|
file: gas_data_feed.gs
|
|
line: 2164
|
|
text: 'TAKE_PROFIT_BASE: 10,'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: Threshold constant defined inline in GAS constants object. Should be in spec/calibration_registry.yaml (source=SPEC_DERIVED, owner_formula=TAKE_PROFIT_LADDER_V2).
|
|
python_path: spec/calibration_registry.yaml
|
|
formula_id: TAKE_PROFIT_LADDER_V2
|
|
migration_action: Register TAKE_PROFIT_BASE=10 in calibration_registry.yaml.
|
|
|
|
- idx: 35
|
|
file: gas_data_feed.gs
|
|
line: 2259
|
|
text: "+ ' h5.decisions=' + ((h5 && h5[\"decisions\"]) ? h5[\"decisions\"].length : 0)"
|
|
classification: ADAPTER_OK
|
|
rationale: Log line reading length of Python decisions array; no business logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 36
|
|
file: gas_data_feed.gs
|
|
line: 2330
|
|
text: 'var routeCount = ((h5 && h5["decisions"]) ? h5["decisions"].length : 0);'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python decisions count for logging/routing. No decision made.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 37
|
|
file: gas_data_feed.gs
|
|
line: 2339
|
|
text: "+ ' | decisions=' + routeCount"
|
|
classification: ADAPTER_OK
|
|
rationale: Log string interpolation; no business logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 38
|
|
file: gas_data_feed.gs
|
|
line: 2343
|
|
text: "Logger.log('[LOG_METRIC_MISMATCH_WARN] decisions>0 이지만 sellCandidates=0');"
|
|
classification: ADAPTER_OK
|
|
rationale: Warning log only; no score or decision computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 39
|
|
file: gas_data_feed.gs
|
|
line: 3172
|
|
text: "formula_id: 'ROUTING_DECISION_EXPLAIN_LOCK_V1',"
|
|
classification: ADAPTER_OK
|
|
rationale: Setting formula_id field in output packet using a string constant; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 40
|
|
file: gas_data_feed.gs
|
|
line: 3285
|
|
text: "formula_id: 'ROUTING_SERVING_DECISION_TRACE_V2'"
|
|
classification: ADAPTER_OK
|
|
rationale: Formula ID tag in output struct; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 41
|
|
file: gas_data_feed.gs
|
|
line: 3399
|
|
text: "* spec/exit/take_profit.yaml:secular_leader_profit_lock.activation_required_all 완전 구현."
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: JSDoc comment referencing spec; no code logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 42
|
|
file: gas_data_feed.gs
|
|
line: 5246
|
|
text: 'var profitLockBase = SP["TAKE_PROFIT_BASE"];'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading TAKE_PROFIT_BASE from SP constants object to pass downstream. The constant itself (idx=34) is the migration target; this read is adapter use.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 43
|
|
file: gas_data_feed.gs
|
|
line: 5472
|
|
text: '* TAKE_PROFIT_LADDER_V2 (tier1/tier2) → TICK_NORMALIZER_V1'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: JSDoc comment describing data flow; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 44
|
|
file: gas_data_feed.gs
|
|
line: 5551
|
|
text: '// ── TAKE_PROFIT_LADDER_V2 ─────────────────────────────────────────────'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Section header comment only.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 45
|
|
file: gas_data_feed.gs
|
|
line: 5571
|
|
text: '// spec/exit/take_profit.yaml:profit_lock_ratchet.ratchet_table 기준'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Comment citing spec; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 46
|
|
file: gas_data_feed.gs
|
|
line: 5714
|
|
text: '* spec/09_decision_flow.yaml 핵심 경로 GAS 구현'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: JSDoc comment; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 47
|
|
file: gas_data_feed.gs
|
|
line: 5895
|
|
text: 'return { ["decisions"]: routes, traces: traces, lock: true };'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: GAS function returns a decisions array it built (routes). Decision routing belongs in Python; GAS should receive this as input.
|
|
python_path: src/quant_engine/
|
|
formula_id: ROUTING_SERVING_DECISION_TRACE_V2
|
|
|
|
- idx: 48
|
|
file: gas_data_feed.gs
|
|
line: 5920
|
|
text: "if (holding && holding.stopBreach) return 'STOP_LOSS';"
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: GAS evaluates stopBreach condition and returns 'STOP_LOSS' — this is a sell decision in GAS that must live in Python stop_loss logic.
|
|
python_path: src/quant_engine/
|
|
formula_id: STOP_LOSS_TRIGGER_V1
|
|
|
|
- idx: 49
|
|
file: gas_data_feed.gs
|
|
line: 5941
|
|
text: "var h5RouteRows_ = (h5 && h5[\"decisions\"]) ? h5[\"decisions\"] : [];"
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python decisions array with null-guard; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 50
|
|
file: gas_data_feed.gs
|
|
line: 5992
|
|
text: "} else if (orderType === 'STOP_LOSS') {"
|
|
classification: ADAPTER_OK
|
|
rationale: Dispatching on Python-provided orderType string; routing-only, not making the stop_loss decision.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 51
|
|
file: gas_data_feed.gs
|
|
line: 6028
|
|
text: '["take_profit_price_krw"]: validation === "PASS" ? (priceRow.tp1_price || null) : null,'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python-provided tp1_price with validation gate check. No price computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 52
|
|
file: gas_data_feed.gs
|
|
line: 6029
|
|
text: '["take_profit_quantity"]: validation === "PASS" ? (priceRow.tp1_qty || null) : null,'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python-provided tp1_qty; same pattern as idx=51.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 53
|
|
file: gas_data_feed.gs
|
|
line: 6058
|
|
text: "if (ot !== 'SELL' && ot !== 'STOP_LOSS') {"
|
|
classification: ADAPTER_OK
|
|
rationale: Filtering on Python-provided order type string; dispatch logic only.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 54
|
|
file: gas_data_feed.gs
|
|
line: 6206
|
|
text: "|| (row.order_type || '').toString().toUpperCase() === 'STOP_LOSS';"
|
|
classification: ADAPTER_OK
|
|
rationale: Reading order_type from Python-provided row; string comparison for filtering.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 55
|
|
file: gas_data_feed.gs
|
|
line: 6688
|
|
text: '["distribution_risk_score"]: Math.min(100, Math.max(0, score)),'
|
|
classification: DELETE_DUPLICATE
|
|
rationale: GAS computes distribution_risk_score; Python already has DISTRIBUTION_RISK_SCORE_V1. Remove GAS computation, read Python output instead.
|
|
python_path: src/quant_engine/compute_formula_outputs.py
|
|
formula_id: DISTRIBUTION_RISK_SCORE_V1
|
|
migration_action: Delete GAS computation block (L6658-6700 approx), read Python result from sheet row.
|
|
|
|
- idx: 56
|
|
file: gas_data_feed.gs
|
|
line: 6692
|
|
text: "formula_id: 'DISTRIBUTION_RISK_SCORE_V1'"
|
|
classification: DELETE_DUPLICATE
|
|
rationale: Part of same GAS computation block as idx=55; remove with the block.
|
|
python_path: src/quant_engine/compute_formula_outputs.py
|
|
formula_id: DISTRIBUTION_RISK_SCORE_V1
|
|
|
|
- idx: 57
|
|
file: gas_data_feed.gs
|
|
line: 6774
|
|
text: '["late_chase_risk_score"]: Math.min(100, Math.max(0, Math.round(lateChaseRisk))),'
|
|
classification: DELETE_DUPLICATE
|
|
rationale: GAS computes late_chase_risk_score; Python has this via LATE_CHASE_RISK_SCORE_V1. Remove GAS block, read Python output.
|
|
python_path: src/quant_engine/compute_formula_outputs.py
|
|
formula_id: LATE_CHASE_RISK_SCORE_V1
|
|
migration_action: Delete GAS computation block (L6740-6780 approx), read Python result from alpha sheet row.
|
|
|
|
- idx: 58
|
|
file: gas_data_feed.gs
|
|
line: 6902
|
|
text: 'var distributionRiskScore = distRow && typeof distRow["distribution_risk_score"] === "number" ? distRow["distribution_risk_score"]...'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading distribution_risk_score from a sheet row (Python output); null-safe read.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 59
|
|
file: gas_data_feed.gs
|
|
line: 6903
|
|
text: 'var lateChaseRiskScore = alphaRow && typeof alphaRow["late_chase_risk_score"] === "number" ? alphaRow["late_chase_risk_score"]...'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading late_chase_risk_score from alphaRow (Python output); null-safe read.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 60
|
|
file: gas_data_feed.gs
|
|
line: 7285
|
|
text: 'if (bqRow.breakout_quality_gate === "BLOCKED_LATE_CHASE" || alphaRow["late_chase_risk_score"] >= 70)'
|
|
classification: MIGRATE_TO_PYTHON
|
|
rationale: GAS applies a score threshold (>=70) to make a gate decision. This threshold comparison should live in Python as part of the anti-late-entry gate.
|
|
python_path: src/quant_engine/
|
|
formula_id: ANTI_LATE_ENTRY_GATE_V2
|
|
migration_action: Move threshold check to Python; GAS reads gate result string.
|
|
|
|
- idx: 61
|
|
file: gas_data_feed.gs
|
|
line: 7315
|
|
text: '["late_chase_risk_score"]: alphaRow["late_chase_risk_score"] != null ? alphaRow["late_chase_risk_score"]...'
|
|
classification: ADAPTER_OK
|
|
rationale: Null-guarded read from alphaRow; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 62
|
|
file: gas_data_feed.gs
|
|
line: 7995
|
|
text: '* 외국인 순매도 연속일·USD/KRW·FOMC·VIX 등 거시 변수를 macro_risk_score로 환산.'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: JSDoc comment describing inputs; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 63
|
|
file: gas_data_feed.gs
|
|
line: 8877
|
|
text: '// stop_loss: final_stop_price/stop_price(없는 키) → protected_stop_price/auto_trailing_stop.'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Comment describing field mapping; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 64
|
|
file: gas_data_feed.gs
|
|
line: 8891
|
|
text: '["stop_loss"]: [pp0.auto_trailing_stop, pp0.protected_stop_price, pp0.profit_preservation_state]'
|
|
classification: ADAPTER_OK
|
|
rationale: Assembling stop_loss fields from Python-computed pp0 object; no decision logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 65
|
|
file: gas_data_feed.gs
|
|
line: 8968
|
|
text: "{ id: 'Stage_04_macro', key: 'macro_risk_score' },"
|
|
classification: ADAPTER_OK
|
|
rationale: Stage config entry referencing a Python-provided key; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 66
|
|
file: gas_data_feed.gs
|
|
line: 9047
|
|
text: "{ yaml: 'TAKE_PROFIT_LADDER_V1', gs: 'calcTpQuantityLadder_' },"
|
|
classification: ADAPTER_OK
|
|
rationale: GAS/YAML function mapping table entry; registration metadata, not logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 67
|
|
file: gas_data_feed.gs
|
|
line: 9133
|
|
text: "{ yaml: 'ROUTING_SERVING_DECISION_TRACE_V2', gs: 'buildRoutingServingTraceV2_' },"
|
|
classification: ADAPTER_OK
|
|
rationale: Function mapping table entry; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 68
|
|
file: gas_data_feed.gs
|
|
line: 9138
|
|
text: "{ yaml: 'ROUTING_DECISION_EXPLAIN_LOCK_V1', gs: 'calcRoutingExplainLockV1_' },"
|
|
classification: ADAPTER_OK
|
|
rationale: Function mapping table entry; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 69
|
|
file: gas_data_feed.gs
|
|
line: 9508
|
|
text: '["stop_loss_calc"]: bp["stop_loss"] || df["stop_loss_price"] || null,'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python-provided stop_loss with fallback to df field; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 70
|
|
file: gas_data_feed.gs
|
|
line: 9509
|
|
text: '["take_profit_calc"]: bp["take_profit"] || df["tp1_price"] || null,'
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python-provided take_profit/tp1_price with null fallback; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 71
|
|
file: gas_harness_rows.gs
|
|
line: 3
|
|
text: '// Pure output assembly - no decision logic. Rarely changes after V stabilizes.'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: File-level comment; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 72
|
|
file: gas_harness_rows.gs
|
|
line: 60
|
|
text: '* source_manifest_json, decision_trace_json 등에 사용.'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: JSDoc comment; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 73
|
|
file: gas_harness_rows.gs
|
|
line: 166
|
|
text: 'var p6DecisionMap = {};'
|
|
classification: ADAPTER_OK
|
|
rationale: Initializing a lookup map to organize Python decisions for sheet writing; no business logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 74
|
|
file: gas_harness_rows.gs
|
|
line: 167
|
|
text: '(h5.decisions || []).forEach(function(row) { p6DecisionMap[row.ticker] = row; });'
|
|
classification: ADAPTER_OK
|
|
rationale: Building ticker→decision lookup map from Python h5.decisions array; pure organization.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 75
|
|
file: gas_harness_rows.gs
|
|
line: 187
|
|
text: 'Object.keys(p6DecisionMap).forEach(function(t) { p6Tickers[t] = true; });'
|
|
classification: ADAPTER_OK
|
|
rationale: Building ticker set from Python decisions for iteration; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 76
|
|
file: gas_harness_rows.gs
|
|
line: 193
|
|
text: 'var da = p6DecisionMap[a] || {};'
|
|
classification: ADAPTER_OK
|
|
rationale: Null-safe lookup of Python decision by ticker; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 77
|
|
file: gas_harness_rows.gs
|
|
line: 194
|
|
text: 'var db = p6DecisionMap[b] || {};'
|
|
classification: ADAPTER_OK
|
|
rationale: Null-safe lookup of Python decision by ticker; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 78
|
|
file: gas_harness_rows.gs
|
|
line: 200
|
|
text: "if (action.indexOf('SELL') >= 0 || action.indexOf('TRIM') >= 0 || action.indexOf('EXIT') >= 0 || act..."
|
|
classification: ADAPTER_OK
|
|
rationale: Sorting rows by Python-provided action string category for sheet display order; presentation logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 79
|
|
file: gas_harness_rows.gs
|
|
line: 227
|
|
text: 'var d = p6DecisionMap[ticker] || {};'
|
|
classification: ADAPTER_OK
|
|
rationale: Null-safe lookup from Python decisions map.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 80
|
|
file: gas_harness_rows.gs
|
|
line: 235
|
|
text: "if (finalAction.indexOf('SELL') >= 0 || finalAction.indexOf('TRIM') >= 0 || finalAction.indexOf('EXI..."
|
|
classification: ADAPTER_OK
|
|
rationale: Categorizing Python-provided finalAction string for sheet rendering; display logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 81
|
|
file: gas_harness_rows.gs
|
|
line: 265
|
|
text: "} else if (finalAction.indexOf('TAKE_PROFIT') >= 0 || orderType.indexOf('TAKE_PROFIT') >= 0) {"
|
|
classification: ADAPTER_OK
|
|
rationale: Categorizing Python-provided finalAction for display; presentation routing.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 82
|
|
file: gas_harness_rows.gs
|
|
line: 464
|
|
text: "['decisions_json', JSON.stringify(h5.decisions)],"
|
|
classification: ADAPTER_OK
|
|
rationale: Serializing Python h5.decisions to sheet; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 83
|
|
file: gas_harness_rows.gs
|
|
line: 465
|
|
text: "['decision_trace_json', (function() { ..."
|
|
classification: ADAPTER_OK
|
|
rationale: Serializing Python decision_trace to sheet cell; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 84
|
|
file: gas_harness_rows.gs
|
|
line: 475
|
|
text: "['decision_lock', 'true'],"
|
|
classification: ADAPTER_OK
|
|
rationale: Writing static lock flag to sheet; no business logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 85
|
|
file: gas_harness_rows.gs
|
|
line: 489
|
|
text: "['decision_trace_checksum', computeStringChecksum_(JSON.stringify(h5.traces))],"
|
|
classification: ADAPTER_OK
|
|
rationale: Computing integrity checksum of Python trace data for audit; sheet-writing utility, not business logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 86
|
|
file: gas_harness_rows.gs
|
|
line: 699
|
|
text: "'ALPHA_LEAD_SCORE_V1,FOLLOW_THROUGH_CONFIRM_V1,DISTRIBUTION_RISK_SCORE_V1,'"
|
|
classification: ADAPTER_OK
|
|
rationale: String literal listing formula IDs for a manifest field; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 87
|
|
file: gas_harness_rows.gs
|
|
line: 728
|
|
text: "['macro_risk_score', (hApex || {}).macro_risk_score !== undefined ? String(...)..."
|
|
classification: ADAPTER_OK
|
|
rationale: Reading Python macro_risk_score from hApex for sheet writing; null-safe adapter.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 88
|
|
file: gas_harness_rows.gs
|
|
line: 1133
|
|
text: "+ '▶ 재계산 금지: sell_priority_lock·quantities_lock·prices_lock·decision_lock...'"
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: UI warning string constant embedded in a log/display message; not decision logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 89
|
|
file: gas_harness_rows.gs
|
|
line: 1267
|
|
text: "['routing_decision_explain_json', JSON.stringify((hApex || {}).routing_decision_explain_json || {})]"
|
|
classification: ADAPTER_OK
|
|
rationale: Serializing Python routing explanation to sheet; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 90
|
|
file: gas_harness_rows.gs
|
|
line: 1299
|
|
text: "'decision_lock', 'blueprint_row_count', 'blueprint_checksum', 'blueprint_hash_algo',"
|
|
classification: ADAPTER_OK
|
|
rationale: Column name list for sheet schema definition; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 91
|
|
file: gas_harness_rows.gs
|
|
line: 1300
|
|
text: "'source_manifest_checksum', 'decision_trace_checksum', 'checksum_hash_algo',"
|
|
classification: ADAPTER_OK
|
|
rationale: Column name list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 92
|
|
file: gas_harness_rows.gs
|
|
line: 1305
|
|
text: "'prices_json', 'decisions_json', 'decision_trace_json',"
|
|
classification: ADAPTER_OK
|
|
rationale: Column name list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 93
|
|
file: gas_harness_rows.gs
|
|
line: 1419
|
|
text: "'cashflow_stability_json','routing_decision_explain_json'"
|
|
classification: ADAPTER_OK
|
|
rationale: Column name list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 94
|
|
file: gas_lib.gs
|
|
line: 145
|
|
text: '"Setup_Decision","Exit_Reason"'
|
|
classification: ADAPTER_OK
|
|
rationale: Column header list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 95
|
|
file: gas_lib.gs
|
|
line: 158
|
|
text: '"Timing_Score_Entry","Timing_Score_Exit","T1_Forced_Sell_Risk_Score","Sell_Conflict_Score",'
|
|
classification: ADAPTER_OK
|
|
rationale: Column header list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 96
|
|
file: gas_lib.gs
|
|
line: 946
|
|
text: '"Sector_Score","Sector_Rank","Alert_Level","Data_Quality","Decision_Use","Reason","AsOfDate"'
|
|
classification: ADAPTER_OK
|
|
rationale: Column header list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 97
|
|
file: gas_lib.gs
|
|
line: 1091
|
|
text: '"Flow_Breadth_5D","Alert_Level","Data_Quality","Decision_Use","ETF_Liquidity_Status","ETF_Execution_..."'
|
|
classification: ADAPTER_OK
|
|
rationale: Column header list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 98
|
|
file: gas_lib.gs
|
|
line: 1226
|
|
text: '"Alert_Level","Data_Quality","Decision_Use","Reason","RW1","RW3","AsOfDate",'
|
|
classification: ADAPTER_OK
|
|
rationale: Column header list; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 99
|
|
file: gas_lib.gs
|
|
line: 1411
|
|
text: '// MARKET_RISK_SCORE_V1'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Section comment only.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 100
|
|
file: gas_lib.gs
|
|
line: 1517
|
|
text: '// spec/05_position_sizing.yaml:net_return_feedback'
|
|
classification: COMMENT_FALSE_POSITIVE
|
|
rationale: Comment referencing spec; no logic.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 101
|
|
file: gas_lib.gs
|
|
line: 1553
|
|
text: 'rows.push(["MRS_COMPUTED", "Market_Risk_Score", "Computed", mrs, ...]'
|
|
classification: ADAPTER_OK
|
|
rationale: Assembling a display row with Python-computed mrs value; sheet output assembly.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
- idx: 102
|
|
file: gas_lib.gs
|
|
line: 2128
|
|
text: 'const mrsRow = byName["Market_Risk_Score"] ?? {};'
|
|
classification: ADAPTER_OK
|
|
rationale: Null-safe lookup of Market_Risk_Score row from Python-provided data; no computation.
|
|
python_path: null
|
|
formula_id: null
|
|
|
|
wave2_4_summary:
|
|
ADAPTER_OK: 50
|
|
COMMENT_FALSE_POSITIVE: 14
|
|
MIGRATE_TO_PYTHON: 11
|
|
DELETE_DUPLICATE: 3
|
|
total_wave2_4: 78
|
|
|
|
full_migration_summary:
|
|
wave1:
|
|
ADAPTER_OK: 17
|
|
COMMENT_FALSE_POSITIVE: 7
|
|
MIGRATE_TO_PYTHON: 1
|
|
DELETE_DUPLICATE: 0
|
|
total: 25
|
|
wave2_4:
|
|
ADAPTER_OK: 50
|
|
COMMENT_FALSE_POSITIVE: 14
|
|
MIGRATE_TO_PYTHON: 11
|
|
DELETE_DUPLICATE: 3
|
|
total: 78
|
|
all_103:
|
|
ADAPTER_OK: 67
|
|
COMMENT_FALSE_POSITIVE: 21
|
|
MIGRATE_TO_PYTHON: 12
|
|
DELETE_DUPLICATE: 3
|
|
grand_total: 103
|
|
|
|
migration_priority:
|
|
phase1_delete_duplicates:
|
|
- note: "3 DELETE_DUPLICATE items — GAS computations that duplicate Python exactly"
|
|
- gas_data_feed.gs:6688 distribution_risk_score (DISTRIBUTION_RISK_SCORE_V1)
|
|
- gas_data_feed.gs:6692 formula_id reference for above (remove with block)
|
|
- gas_data_feed.gs:6774 late_chase_risk_score (LATE_CHASE_RISK_SCORE_V1)
|
|
|
|
phase2_migrate_to_python:
|
|
- note: "12 MIGRATE_TO_PYTHON items — logic that must move to Python"
|
|
- gas_data_feed.gs:186 SP_TAKE_PROFIT=10 threshold (→ calibration_registry.yaml) [wave1]
|
|
- gas_data_feed.gs:2164 TAKE_PROFIT_BASE=10 constant (→ calibration_registry.yaml)
|
|
- gas_data_feed.gs:656/665/674/678/683 priceBasis + action for TAKE_PROFIT (→ TAKE_PROFIT_LADDER_V2 output)
|
|
- gas_data_feed.gs:1577/1578 score += SP_TAKE_PROFIT (→ SELL_PRIORITY_SCORING_V1)
|
|
- gas_data_feed.gs:5895 return decisions (→ ROUTING_SERVING_DECISION_TRACE_V2)
|
|
- gas_data_feed.gs:5920 stopBreach → STOP_LOSS (→ STOP_LOSS_TRIGGER_V1)
|
|
- gas_data_feed.gs:7285 late_chase_risk_score >= 70 gate (→ ANTI_LATE_ENTRY_GATE_V2)
|
|
|
|
phase3_comment_cleanup:
|
|
- note: "21 COMMENT_FALSE_POSITIVE items — no code changes needed, scanner false positives"
|
|
|
|
phase4_adapter_ok:
|
|
- note: "67 ADAPTER_OK items — compliant thin-adapter reads; no changes needed"
|
|
|
|
action_items:
|
|
- id: REGISTER_SP_TAKE_PROFIT
|
|
status: TODO
|
|
file: spec/calibration_registry.yaml
|
|
action: Add SP_TAKE_PROFIT=10, source=SPEC_DERIVED, owner_formula=TAKE_PROFIT_LADDER_V2
|
|
|
|
- id: REGISTER_TAKE_PROFIT_BASE
|
|
status: TODO
|
|
file: spec/calibration_registry.yaml
|
|
action: Add TAKE_PROFIT_BASE=10, source=SPEC_DERIVED, owner_formula=TAKE_PROFIT_LADDER_V2
|
|
|
|
- id: DELETE_DISTRIBUTION_RISK_GAS
|
|
status: TODO
|
|
file: gas_data_feed.gs
|
|
action: Delete distribution_risk_score computation block (~L6658-6700), replace with read from Python output sheet row
|
|
|
|
- id: DELETE_LATE_CHASE_RISK_GAS
|
|
status: TODO
|
|
file: gas_data_feed.gs
|
|
action: Delete late_chase_risk_score computation block (~L6740-6780), replace with read from Python output alpha row
|
|
|
|
- id: MIGRATE_PRICEBASIS_TO_PYTHON
|
|
status: TODO
|
|
file: gas_data_feed.gs + src/quant_engine/
|
|
action: Move priceBasis/action assignment (L656-683) to TAKE_PROFIT_LADDER_V2 Python output; GAS reads result
|
|
|
|
- id: MIGRATE_SCORE_CALCULATION
|
|
status: TODO
|
|
file: gas_data_feed.gs + src/quant_engine/
|
|
action: Move score += THRESHOLDS["SP_TAKE_PROFIT"] + breakdown.push (L1577-1578) to SELL_PRIORITY_SCORING_V1 Python
|
|
|
|
- id: MIGRATE_STOP_BREACH_DECISION
|
|
status: TODO
|
|
file: gas_data_feed.gs + src/quant_engine/
|
|
action: Move stopBreach → STOP_LOSS decision (L5920) to Python STOP_LOSS_TRIGGER_V1
|
|
|
|
- id: MIGRATE_DECISIONS_ROUTING
|
|
status: TODO
|
|
file: gas_data_feed.gs + src/quant_engine/
|
|
action: Move decisions route-building (L5895 return block) to Python ROUTING_SERVING_DECISION_TRACE_V2
|
|
|
|
- id: MIGRATE_LATE_CHASE_GATE
|
|
status: TODO
|
|
file: gas_data_feed.gs + src/quant_engine/
|
|
action: Move late_chase_risk_score >= 70 threshold gate (L7285) to Python ANTI_LATE_ENTRY_GATE_V2
|
|
|
|
- id: UPDATE_GAS_SCANNER_FALSE_POSITIVES
|
|
status: TODO
|
|
file: tools/validate_gas_thin_adapter_v2.py
|
|
action: Add 21 confirmed false-positive patterns to scanner exclusion list to reduce noise in future runs
|