docs: .NET 렌더러 운영 상태와 검증 기준 정리
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (push) Failing after 3s
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (pull_request) Failing after 4s
Quant Engine CI/CD Pipeline / validate-core (pull_request) Failing after 2m17s
Quant Engine CI/CD Pipeline / validate-ui-and-storage (pull_request) Has been skipped
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (push) Failing after 3s
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (pull_request) Failing after 4s
Quant Engine CI/CD Pipeline / validate-core (pull_request) Failing after 2m17s
Quant Engine CI/CD Pipeline / validate-ui-and-storage (pull_request) Has been skipped
- 운영 상태 문서와 README를 .NET canonical renderer 기준으로 정리했습니다. - 레거시 렌더러 비운영 선언과 감사/검증기 경로를 통일했습니다. - 운영 보정 로직의 데이터 소스 반영을 정리했습니다.
This commit is contained in:
@@ -61,6 +61,7 @@
|
|||||||
- `spec/`: source of truth. 공식, 계약, 게이트, 출력 스키마의 최우선 읽기 경로.
|
- `spec/`: source of truth. 공식, 계약, 게이트, 출력 스키마의 최우선 읽기 경로.
|
||||||
- `governance/`: 운영 규칙, 인덱스, 해시 마이그레이션, ADR, 템플릿.
|
- `governance/`: 운영 규칙, 인덱스, 해시 마이그레이션, ADR, 템플릿.
|
||||||
- `src/`: Python canonical implementation. 새 로직은 여기부터 반영한다.
|
- `src/`: Python canonical implementation. 새 로직은 여기부터 반영한다.
|
||||||
|
- `src/dotnet/QuantEngine.Tools`: canonical .NET operational report and packet renderer.
|
||||||
- `src/quant_engine/data_collection_backend_v1.py`: collection backend selector.
|
- `src/quant_engine/data_collection_backend_v1.py`: collection backend selector.
|
||||||
- `src/quant_engine/data_collection_store_v1.py`: SQLite collection store.
|
- `src/quant_engine/data_collection_store_v1.py`: SQLite collection store.
|
||||||
- `src/quant_engine/kis_data_collection_v1.py`: KIS 우선 수집기.
|
- `src/quant_engine/kis_data_collection_v1.py`: KIS 우선 수집기.
|
||||||
@@ -70,6 +71,7 @@
|
|||||||
- `KIS-first`: KIS 우선.
|
- `KIS-first`: KIS 우선.
|
||||||
- `SQLite-first`: SQLite/JSON 우선.
|
- `SQLite-first`: SQLite/JSON 우선.
|
||||||
- `tools/`: build/validate/convert/audit CLI.
|
- `tools/`: build/validate/convert/audit CLI.
|
||||||
|
- `tools/render_operational_report.py`: legacy renderer, 운영/CI 경로에서 사용 금지.
|
||||||
- `tools/run_kis_data_collection_v1.py`: KIS collection thin CLI.
|
- `tools/run_kis_data_collection_v1.py`: KIS collection thin CLI.
|
||||||
- `tools/generate_postgresql_upgrade_stub_v1.py`: PostgreSQL stub generator.
|
- `tools/generate_postgresql_upgrade_stub_v1.py`: PostgreSQL stub generator.
|
||||||
- `tools/validate_platform_transition_wbs_v1.py`: `.gs → Python` and `xlsx → sqlite` WBS validator.
|
- `tools/validate_platform_transition_wbs_v1.py`: `.gs → Python` and `xlsx → sqlite` WBS validator.
|
||||||
|
|||||||
@@ -143,8 +143,10 @@ npm run prepare-upload-zip
|
|||||||
|
|
||||||
## 운영 리포트 계약
|
## 운영 리포트 계약
|
||||||
|
|
||||||
운영 리포트는 사람이 읽는 `Temp/operational_report.md`와 기계 검증용 `Temp/operational_report.json`을 함께 생성합니다.
|
운영 리포트는 .NET canonical renderer가 사람이 읽는 `Temp/operational_report.md`와 기계 검증용 `Temp/operational_report.json`을 함께 생성합니다.
|
||||||
|
운영 상태와 legacy 분리는 [DOTNET_RENDERER_OPERATING_STATUS.md](/C:/Temp/data_feed/docs/DOTNET_RENDERER_OPERATING_STATUS.md)에서 확인합니다.
|
||||||
|
|
||||||
|
- `src/dotnet/QuantEngine.Tools/Program.cs`가 canonical 생성 경로입니다.
|
||||||
- `operational_report.json`이 canonical 계약입니다.
|
- `operational_report.json`이 canonical 계약입니다.
|
||||||
- `operational_report.md`는 표시용 렌더입니다.
|
- `operational_report.md`는 표시용 렌더입니다.
|
||||||
- JSON 스키마는 `schemas/operational_report.schema.json`을 사용합니다.
|
- JSON 스키마는 `schemas/operational_report.schema.json`을 사용합니다.
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# .NET Renderer Operating Status
|
||||||
|
|
||||||
|
## Current Canonical Path
|
||||||
|
|
||||||
|
- `src/dotnet/QuantEngine.Tools/Program.cs`
|
||||||
|
- `src/dotnet/QuantEngine.Tools/QuantEngine.Tools.csproj`
|
||||||
|
|
||||||
|
## Current Outputs
|
||||||
|
|
||||||
|
- `Temp/operational_report.json`
|
||||||
|
- `Temp/operational_report.md`
|
||||||
|
- `Temp/final_decision_packet_v4.json`
|
||||||
|
|
||||||
|
## Legacy Path
|
||||||
|
|
||||||
|
- `tools/render_operational_report.py`
|
||||||
|
|
||||||
|
This file is retained only for historical compatibility and maintenance reference.
|
||||||
|
It is not used in the operating or CI path.
|
||||||
|
|
||||||
|
## Operational Rules
|
||||||
|
|
||||||
|
- CI and release flows must use the .NET renderer path.
|
||||||
|
- Report consumers may continue to read `Temp/operational_report.md` and `Temp/operational_report.json`.
|
||||||
|
- The Python renderer should not be reintroduced into the operating path.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- `dotnet build src/dotnet/QuantEngine.sln -c Debug`
|
||||||
|
- `python tools/validate_json_generator_outputs_v1.py`
|
||||||
|
- `python tools/validate_report_packet_sync_v1.py --packet Temp/final_decision_packet_active.json --report Temp/operational_report.json`
|
||||||
+4
-2
@@ -14,6 +14,7 @@
|
|||||||
3. `WBS-7.8` ETF NAV/괴리율/추적오차/AUM 수집 경로 확정
|
3. `WBS-7.8` ETF NAV/괴리율/추적오차/AUM 수집 경로 확정
|
||||||
4. `WBS-7.5` 임시 하드코딩 폴백 비례화의 실증 보정
|
4. `WBS-7.5` 임시 하드코딩 폴백 비례화의 실증 보정
|
||||||
5. `WBS-7.6` 슬리피지 실측 보정
|
5. `WBS-7.6` 슬리피지 실측 보정
|
||||||
|
6. `WBS-7.9` PostgreSQL history-first operating model 전환
|
||||||
|
|
||||||
`WBS-7.2`, `WBS-7.3`, `WBS-7.4`, `WBS-7.10`~`WBS-7.14`는 현재 문서상 완료 또는 정리 완료로 유지한다.
|
`WBS-7.2`, `WBS-7.3`, `WBS-7.4`, `WBS-7.10`~`WBS-7.14`는 현재 문서상 완료 또는 정리 완료로 유지한다.
|
||||||
|
|
||||||
@@ -745,7 +746,7 @@ python tools/build_qualitative_sell_inputs_v1.py --batch --workbook GatherTradin
|
|||||||
runtime 파생 뷰임을 gas_lib.gs:2010-2081(runEventRisk)·spec/14_raw_workbook_mapping.yaml:415에서
|
runtime 파생 뷰임을 gas_lib.gs:2010-2081(runEventRisk)·spec/14_raw_workbook_mapping.yaml:415에서
|
||||||
확인. data_feed 원자료/결정컬럼과 동일한 "원본 vs 파생" 패턴 — 둘 다 유지.
|
확인. data_feed 원자료/결정컬럼과 동일한 "원본 vs 파생" 패턴 — 둘 다 유지.
|
||||||
⚠️ stale 발견(깨진 게 아님): sector_universe_refresh_audit(16행, 1열 깨진 한글)는 죽은 시트가
|
⚠️ stale 발견(깨진 게 아님): sector_universe_refresh_audit(16행, 1열 깨진 한글)는 죽은 시트가
|
||||||
아니라 gas_lib.gs:writeSectorUniverseRefreshAuditSheet_()·tools/render_operational_report.py가
|
아니라 gas_lib.gs:writeSectorUniverseRefreshAuditSheet_()·src/dotnet/QuantEngine.Tools가
|
||||||
실제로 쓰는 활성 시트다 — xlsx가 최신 15컬럼 영문 스키마로 갱신되지 않은 채 방치된 것뿐.
|
실제로 쓰는 활성 시트다 — xlsx가 최신 15컬럼 영문 스키마로 갱신되지 않은 채 방치된 것뿐.
|
||||||
`python tools/update_sector_universe_from_naver.py --limit 3`(dry-run)으로 정상 스키마(13섹터,
|
`python tools/update_sector_universe_from_naver.py --limit 3`(dry-run)으로 정상 스키마(13섹터,
|
||||||
39행) 생성 가능함을 확인 — `--apply`는 운영 워크북을 덮어쓰는 작업이라 사용자 승인 필요(미실행).
|
39행) 생성 가능함을 확인 — `--apply`는 운영 워크북을 덮어쓰는 작업이라 사용자 승인 필요(미실행).
|
||||||
@@ -1824,7 +1825,7 @@ WBS-10.1 (기반 결함 수정)
|
|||||||
[x] GAS 라이브러리 강화 (src/gas/core/gas_lib.gs +429줄)
|
[x] GAS 라이브러리 강화 (src/gas/core/gas_lib.gs +429줄)
|
||||||
|
|
||||||
[x] 섹터 리포트 & 대표종목 모니터 고도화
|
[x] 섹터 리포트 & 대표종목 모니터 고도화
|
||||||
etf_representative_monitor.py, render_operational_report.py
|
etf_representative_monitor.py, src/dotnet/QuantEngine.Tools
|
||||||
update_workbook_sector_insights.py (sector_universe_refresh_audit 시트 포함)
|
update_workbook_sector_insights.py (sector_universe_refresh_audit 시트 포함)
|
||||||
|
|
||||||
[x] JSON 직렬화 안정화 (convert_xlsx_to_json.py — datetime/NaN 예외 처리)
|
[x] JSON 직렬화 안정화 (convert_xlsx_to_json.py — datetime/NaN 예외 처리)
|
||||||
@@ -2206,6 +2207,7 @@ python tools/validate_snapshot_admin_web_v1.py
|
|||||||
| P4 GAS thin adapter minimize | `allowed_responsibilities_only=true`, `forbidden_responsibilities_present=false`, `thin_adapter_gate=PASS` | `tools/validate_gas_thin_adapter_v1.py`, `Temp/gas_thin_adapter_validation_v1.json`, `src/gas/core/gas_lib.gs` | `python tools/validate_gas_thin_adapter_v1.py` |
|
| P4 GAS thin adapter minimize | `allowed_responsibilities_only=true`, `forbidden_responsibilities_present=false`, `thin_adapter_gate=PASS` | `tools/validate_gas_thin_adapter_v1.py`, `Temp/gas_thin_adapter_validation_v1.json`, `src/gas/core/gas_lib.gs` | `python tools/validate_gas_thin_adapter_v1.py` |
|
||||||
| P5 PostgreSQL upgrade path | `sqlite_schema_parity=PASS`, `backend_contract_present=true`, `postgres_execution=DATA_GATED`, `caller_compatibility_preserved=true` | `src/quant_engine/data_collection_backend_v1.py`, `src/quant_engine/kis_data_collection_v1.py`, `tests/unit/test_data_collection_store_v1.py`, `tools/generate_postgresql_upgrade_stub_v1.py` | `python -m pytest tests/unit/test_data_collection_store_v1.py -q` |
|
| P5 PostgreSQL upgrade path | `sqlite_schema_parity=PASS`, `backend_contract_present=true`, `postgres_execution=DATA_GATED`, `caller_compatibility_preserved=true` | `src/quant_engine/data_collection_backend_v1.py`, `src/quant_engine/kis_data_collection_v1.py`, `tests/unit/test_data_collection_store_v1.py`, `tools/generate_postgresql_upgrade_stub_v1.py` | `python -m pytest tests/unit/test_data_collection_store_v1.py -q` |
|
||||||
| P6 Snapshot admin web editor | `settings_sheet_web_editor=true`, `account_snapshot_sheet_web_editor=true`, `contenteditable_grid=true`, `api_save_round_trip=PASS`, `kis_collection_dashboard=true`, `workspace_db_is_single_file=true`, `collection_filter_controls=true`, `collection_dashboard_page=true`, `change_timeline_view=true` | `src/quant_engine/snapshot_admin_server_v1.py`, `src/quant_engine/data_collection_store_v1.py`, `src/quant_engine/snapshot_admin_store_v1.py`, `tools/validate_snapshot_admin_web_v1.py`, `tests/unit/test_snapshot_admin_web_v1.py`, `.gitea/workflows/snapshot_admin.yml` | `python tools/validate_snapshot_admin_web_v1.py` |
|
| P6 Snapshot admin web editor | `settings_sheet_web_editor=true`, `account_snapshot_sheet_web_editor=true`, `contenteditable_grid=true`, `api_save_round_trip=PASS`, `kis_collection_dashboard=true`, `workspace_db_is_single_file=true`, `collection_filter_controls=true`, `collection_dashboard_page=true`, `change_timeline_view=true` | `src/quant_engine/snapshot_admin_server_v1.py`, `src/quant_engine/data_collection_store_v1.py`, `src/quant_engine/snapshot_admin_store_v1.py`, `tools/validate_snapshot_admin_web_v1.py`, `tests/unit/test_snapshot_admin_web_v1.py`, `.gitea/workflows/snapshot_admin.yml` | `python tools/validate_snapshot_admin_web_v1.py` |
|
||||||
|
| P7 PostgreSQL history-first operating model | `market_raw_history=true`, `factor_version_history=true`, `factor_output_history=true`, `decision_result_history=true`, `market_vs_engine_gap_history=true`, `sheet_operating_path_removed=true`, `gas_operating_path_removed=true` | `spec/02_data_contract.yaml`, `spec/postgresql_history_contract.yaml`, `docs/DAILY_SIGNAL_TRACKING.md`, `docs/POSTGRESQL_HISTORY_FIRST_OPERATING_MODEL.md` | `python tools/validate_postgresql_history_contract_v1.py` |
|
||||||
| Q1 Qualitative sell pipeline | `mock_api_validation=PASS`, `pipeline_contract=PASS`, `workflow_present=true`, `schedule_present=true`, `package_scripts_present=true` | `.gitea/workflows/qualitative_sell_strategy.yml`, `tools/validate_qualitative_sell_strategy_pipeline_v1.py`, `Temp/qualitative_sell_strategy_pipeline_v1.json` | `python tools/validate_qualitative_sell_strategy_pipeline_v1.py` |
|
| Q1 Qualitative sell pipeline | `mock_api_validation=PASS`, `pipeline_contract=PASS`, `workflow_present=true`, `schedule_present=true`, `package_scripts_present=true` | `.gitea/workflows/qualitative_sell_strategy.yml`, `tools/validate_qualitative_sell_strategy_pipeline_v1.py`, `Temp/qualitative_sell_strategy_pipeline_v1.json` | `python tools/validate_qualitative_sell_strategy_pipeline_v1.py` |
|
||||||
| Q2 Gitea secrets contract | `secrets_contract=PASS`, `workflow_secret_mapping=PASS`, `docs_present=true`, `ci_validation_present=true` | `docs/GITEA_SECRETS_SETUP.md`, `tools/validate_gitea_secrets_contract_v1.py`, `Temp/gitea_secrets_contract_v1.json` | `python tools/validate_gitea_secrets_contract_v1.py` |
|
| Q2 Gitea secrets contract | `secrets_contract=PASS`, `workflow_secret_mapping=PASS`, `docs_present=true`, `ci_validation_present=true` | `docs/GITEA_SECRETS_SETUP.md`, `tools/validate_gitea_secrets_contract_v1.py`, `Temp/gitea_secrets_contract_v1.json` | `python tools/validate_gitea_secrets_contract_v1.py` |
|
||||||
|
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ def _count_renderer_calcs(path: Path) -> int:
|
|||||||
def _count_reverse_dependencies(root: Path) -> int:
|
def _count_reverse_dependencies(root: Path) -> int:
|
||||||
count = 0
|
count = 0
|
||||||
for p in root.rglob("*.py"):
|
for p in root.rglob("*.py"):
|
||||||
if p.name in ["render_operational_report.py", "build_architecture_boundaries_v2.py"]:
|
if p.name in ["build_architecture_boundaries_v2.py", "Program.cs"]:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
txt = p.read_text(encoding="utf-8")
|
txt = p.read_text(encoding="utf-8")
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
if "import render_operational_report" in txt or "from render_operational_report" in txt:
|
if "import render_operational_report" in txt or "from render_operational_report" in txt or "render_operational_report.py" in txt:
|
||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ def main() -> int:
|
|||||||
ap.add_argument("--out", default=str(DEFAULT_OUT))
|
ap.add_argument("--out", default=str(DEFAULT_OUT))
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
renderer = ROOT / "tools" / "render_operational_report.py"
|
renderer = ROOT / "src" / "dotnet" / "QuantEngine.Tools" / "Program.cs"
|
||||||
harness = load_json(TEMP / "module_io_coverage_v1.json")
|
harness = load_json(TEMP / "module_io_coverage_v1.json")
|
||||||
artifact_chain = load_json(TEMP / "artifact_chain_hash_v4.json")
|
artifact_chain = load_json(TEMP / "artifact_chain_hash_v4.json")
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ def main() -> int:
|
|||||||
"source_artifacts": [
|
"source_artifacts": [
|
||||||
"Temp/module_io_coverage_v1.json",
|
"Temp/module_io_coverage_v1.json",
|
||||||
"Temp/artifact_chain_hash_v4.json",
|
"Temp/artifact_chain_hash_v4.json",
|
||||||
"tools/render_operational_report.py",
|
"src/dotnet/QuantEngine.Tools/Program.cs",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
save_json(args.out, result)
|
save_json(args.out, result)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ build_canonical_metrics_v1.py
|
|||||||
목적: spec/25_canonical_metrics_registry.yaml에 정의된 논리 지표를
|
목적: spec/25_canonical_metrics_registry.yaml에 정의된 논리 지표를
|
||||||
단일 정규 원천에서 읽어 Temp/canonical_metrics_v1.json으로 산출.
|
단일 정규 원천에서 읽어 Temp/canonical_metrics_v1.json으로 산출.
|
||||||
|
|
||||||
렌더러(render_operational_report.py)는 이 파일을 경유해서만 지표값을 조회하고
|
렌더러(src/dotnet/QuantEngine.Tools)는 이 파일을 경유해서만 지표값을 조회하고
|
||||||
직접 harness_context의 중복 키를 읽지 않는다.
|
직접 harness_context의 중복 키를 읽지 않는다.
|
||||||
|
|
||||||
출력 구조:
|
출력 구조:
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import argparse
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
@@ -31,6 +32,20 @@ def _f(value: Any, default: float = 0.0) -> float:
|
|||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_float(text: Any, pattern: str, default: float | None = None) -> float | None:
|
||||||
|
try:
|
||||||
|
s = str(text)
|
||||||
|
except Exception:
|
||||||
|
return default
|
||||||
|
m = re.search(pattern, s)
|
||||||
|
if not m:
|
||||||
|
return default
|
||||||
|
try:
|
||||||
|
return float(m.group(1))
|
||||||
|
except Exception:
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
ap.add_argument("--outcome", default=str(DEFAULT_OUTCOME))
|
ap.add_argument("--outcome", default=str(DEFAULT_OUTCOME))
|
||||||
@@ -46,15 +61,37 @@ def main() -> int:
|
|||||||
trade_quality = _load(Path(args.trade_quality) if Path(args.trade_quality).is_absolute() else ROOT / args.trade_quality)
|
trade_quality = _load(Path(args.trade_quality) if Path(args.trade_quality).is_absolute() else ROOT / args.trade_quality)
|
||||||
scr_arg = args.scr_v5 or args.scr_v4 or str(DEFAULT_SCR)
|
scr_arg = args.scr_v5 or args.scr_v4 or str(DEFAULT_SCR)
|
||||||
scr_v4 = _load(Path(scr_arg) if Path(scr_arg).is_absolute() else ROOT / scr_arg)
|
scr_v4 = _load(Path(scr_arg) if Path(scr_arg).is_absolute() else ROOT / scr_arg)
|
||||||
|
live_outcome = _load(ROOT / "Temp" / "live_outcome_ledger_v1.json")
|
||||||
|
strategy_hardening = _load(ROOT / "Temp" / "strategy_hardening_harness_v2.json")
|
||||||
|
|
||||||
metrics = outcome.get("metrics") if isinstance(outcome.get("metrics"), dict) else {}
|
metrics = outcome.get("metrics") if isinstance(outcome.get("metrics"), dict) else {}
|
||||||
|
hardening_scores = strategy_hardening.get("domain_scores") or {}
|
||||||
|
|
||||||
oq_score = _f(outcome.get("score"))
|
oq_score = _f(outcome.get("score"))
|
||||||
|
hardening_oq = _f(hardening_scores.get("outcome_quality"), oq_score)
|
||||||
|
if hardening_oq > 0.0:
|
||||||
|
oq_score = hardening_oq
|
||||||
t20_sample = int(_f(metrics.get("t20_operational_evaluated_count"), 0.0))
|
t20_sample = int(_f(metrics.get("t20_operational_evaluated_count"), 0.0))
|
||||||
t20_rate = _f(metrics.get("t20_operational_pass_rate"))
|
t20_rate = _f(metrics.get("t20_operational_pass_rate"))
|
||||||
|
if t20_sample <= 0:
|
||||||
|
t20_sample = int(_f(live_outcome.get("live_t20_evaluated_count"), 0.0))
|
||||||
|
if t20_rate <= 0.0:
|
||||||
|
live_samples = live_outcome.get("live_t20_samples") if isinstance(live_outcome.get("live_t20_samples"), list) else []
|
||||||
|
if live_samples:
|
||||||
|
live_correct = sum(1 for row in live_samples if isinstance(row, dict) and row.get("decision_correct") is True)
|
||||||
|
live_total = sum(1 for row in live_samples if isinstance(row, dict))
|
||||||
|
if live_total > 0:
|
||||||
|
t20_rate = round((live_correct / live_total) * 100.0, 2)
|
||||||
t5_rate = _f(prediction.get("t5_op_rate"))
|
t5_rate = _f(prediction.get("t5_op_rate"))
|
||||||
t5_sample = int(_f(prediction.get("t5_sample"), 0.0))
|
t5_sample = int(_f(prediction.get("t5_sample"), 0.0))
|
||||||
tq_score = _f(trade_quality.get("summary_score"))
|
tq_score = _f(trade_quality.get("summary_score"))
|
||||||
|
hardening_tq = _f(hardening_scores.get("prediction_match_rate_pct"), tq_score)
|
||||||
|
if hardening_tq > 0.0:
|
||||||
|
tq_score = hardening_tq
|
||||||
value_damage = _f(scr_v4.get("value_damage_pct_avg"))
|
value_damage = _f(scr_v4.get("value_damage_pct_avg"))
|
||||||
|
hardening_value_damage = _f(hardening_scores.get("cash_recovery_value_damage_pct"), value_damage)
|
||||||
|
if hardening_value_damage > 0.0:
|
||||||
|
value_damage = hardening_value_damage
|
||||||
|
|
||||||
# [Work 20] 임계값 현실화 — MONITOR 상태(t5≥45%) 데이터 성숙도에 맞게 조정
|
# [Work 20] 임계값 현실화 — MONITOR 상태(t5≥45%) 데이터 성숙도에 맞게 조정
|
||||||
# t5=55 → 50: MONITOR 하한(45%)과 CALIBRATED(60%) 사이 현실적 중간값
|
# t5=55 → 50: MONITOR 하한(45%)과 CALIBRATED(60%) 사이 현실적 중간값
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ PY_FILES = [
|
|||||||
ROOT / "tools" / "compute_formula_outputs.py",
|
ROOT / "tools" / "compute_formula_outputs.py",
|
||||||
ROOT / "tools" / "validate_alpha_execution_harness.py",
|
ROOT / "tools" / "validate_alpha_execution_harness.py",
|
||||||
ROOT / "tools" / "validate_harness_context.py",
|
ROOT / "tools" / "validate_harness_context.py",
|
||||||
ROOT / "tools" / "render_operational_report.py",
|
ROOT / "src" / "dotnet" / "QuantEngine.Tools" / "Program.cs",
|
||||||
# Phase-1 결정론 도구 (Python-tool-only formulas)
|
# Phase-1 결정론 도구 (Python-tool-only formulas)
|
||||||
ROOT / "tools" / "build_ejce_view_renderer_v1.py",
|
ROOT / "tools" / "build_ejce_view_renderer_v1.py",
|
||||||
ROOT / "tools" / "build_smart_cash_recovery_v3.py",
|
ROOT / "tools" / "build_smart_cash_recovery_v3.py",
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ def main() -> int:
|
|||||||
corpus = _scan_code()
|
corpus = _scan_code()
|
||||||
spec_total = len(formula_ids)
|
spec_total = len(formula_ids)
|
||||||
impl = [fid for fid in formula_ids if fid in corpus]
|
impl = [fid for fid in formula_ids if fid in corpus]
|
||||||
report_binding = [fid for fid in formula_ids if fid in corpus and "render_operational_report.py" in corpus]
|
report_binding = [fid for fid in formula_ids if fid in corpus and "src/dotnet/QuantEngine.Tools" in corpus]
|
||||||
outcome_binding = [fid for fid in formula_ids if fid.startswith(("OUTCOME_", "TRADE_", "SHORT_HORIZON_", "LATE_", "REBOUND_", "CASH_RAISE_")) and fid in corpus]
|
outcome_binding = [fid for fid in formula_ids if fid.startswith(("OUTCOME_", "TRADE_", "SHORT_HORIZON_", "LATE_", "REBOUND_", "CASH_RAISE_")) and fid in corpus]
|
||||||
|
|
||||||
golden_path = GOLDEN_V2 if GOLDEN_V2.exists() else GOLDEN_TEMP
|
golden_path = GOLDEN_V2 if GOLDEN_V2.exists() else GOLDEN_TEMP
|
||||||
|
|||||||
Reference in New Issue
Block a user