"""2단계: 인과 기법 GT 정합 비교 리포트.""" from __future__ import annotations import json from datetime import datetime from pathlib import Path from typing import Any from deepcoin.techniques.base import TechniqueResult def build_comparison_report( results: list[TechniqueResult], gt_result: dict[str, Any], symbol: str, ) -> dict[str, Any]: """기법 비교 요약 리포트를 생성한다.""" gt_meta = gt_result.get("meta", {}) gt_pnl = gt_result.get("pnl", {}) gt_summary = gt_result.get("summary", {}) rows: list[dict[str, Any]] = [] for result in results: align = result.alignment or {} buy = align.get("buy", {}) sell = align.get("sell", {}) legs = align.get("legs", {}) rows.append( { "technique_id": result.technique_id, "technique_name": result.technique_name, "category": result.category, "causal": result.causal, "leg_count": result.summary.get("leg_count", 0), "tech_return_pct": result.pnl.get("total_return_pct", 0.0), "buy_recall": buy.get("recall", 0.0), "sell_recall": sell.get("recall", 0.0), "leg_recall": legs.get("leg_recall", 0.0), "return_capture_ratio": align.get("return_capture_ratio", 0.0), "score": align.get("score", 0.0), "avg_buy_offset": buy.get("avg_bar_offset", 0.0), "avg_sell_offset": sell.get("avg_bar_offset", 0.0), } ) rows.sort(key=lambda r: r["score"], reverse=True) return { "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "symbol": symbol, "gt": { "leg_count": gt_summary.get("leg_count", 0), "return_pct": gt_pnl.get("total_return_pct", 0.0), "interval_label": gt_meta.get("interval_label", ""), "lookback_days": gt_meta.get("lookback_days", 365), }, "ranking": rows, } def save_comparison_report(report: dict[str, Any], json_path: Path) -> Path: """비교 리포트 JSON을 저장한다.""" json_path.parent.mkdir(parents=True, exist_ok=True) with json_path.open("w", encoding="utf-8") as fp: json.dump(report, fp, ensure_ascii=False, indent=2) return json_path def render_comparison_html(report: dict[str, Any], html_path: Path) -> Path: """비교 리포트 HTML을 생성한다.""" html_path.parent.mkdir(parents=True, exist_ok=True) rows = report.get("ranking", []) gt = report.get("gt", {}) table_rows = "" for idx, row in enumerate(rows, start=1): table_rows += f"""
| 순위 | 기법 | 유형 | 인과 | 레그 | 수익률 | 매수 Recall | 매도 Recall | 레그 Recall | 수익 포착 | 종합 Score |
|---|