#!/usr/bin/env python3 """3단계: 운영 백테스트(+1,873,140%) 매수·매도 타점 HTML 차트 생성.""" from __future__ import annotations import argparse import logging import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SRC = ROOT / "src" if str(SRC) not in sys.path: sys.path.insert(0, str(SRC)) from deepcoin.config import load_settings from deepcoin.operations.chart import render_ops_live_chart def _configure_logging(verbose: bool) -> None: level = logging.DEBUG if verbose else logging.INFO logging.basicConfig( level=level, format="%(asctime)s [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) def _write_index_html( index_path: Path, chart_name: str, report: dict, ) -> Path: """docs/live 인덱스 HTML을 생성한다.""" sim = report["filtered_sim"] ret = sim.get("total_return_pct", 0) index_path.parent.mkdir(parents=True, exist_ok=True) html = f""" DeepCoin Live — 운영 백테스트 차트

DeepCoin Live — 운영 백테스트

{report.get("symbol", "BTC")} · {report.get("technique_name", "")} ({report.get("technique_id", "")})
sim 기간: 최근 {report.get("sim_lookback_days", 1095)}일 · 슬리피지 {report.get("slippage_rate", 0) * 100:.2f}% · 일 체결 상한 {report.get("daily_max_trades", "-")} · MTF {"on" if report.get("mtf_enabled") else "off"}

3년 수익률 (운영 규칙 sim)
{ret:+.2f}%

매수·매도 타점 차트 열기

""" index_path.write_text(html, encoding="utf-8") return index_path def main() -> int: """CLI 진입점.""" parser = argparse.ArgumentParser( description="운영 백테스트 매수·매도 타점 HTML 차트 (docs/live)", ) parser.add_argument( "-o", "--output", type=str, default=None, help="HTML 출력 경로 (기본: docs/live/{technique}_ops_chart.html)", ) parser.add_argument( "--chart-days", type=int, default=None, help="차트 캔들 표시 일수 (기본: GT_SIM_LOOKBACK_DAYS)", ) parser.add_argument("-v", "--verbose", action="store_true") args = parser.parse_args() _configure_logging(args.verbose) settings = load_settings() live_dir = ROOT / "docs" / "live" default_name = f"{settings.ops_technique_id}_ops_chart.html" output_path = Path(args.output) if args.output else live_dir / default_name if not output_path.is_absolute(): output_path = ROOT / output_path print("\n=== 운영 백테스트 차트 생성 ===", flush=True) print( f"기법: {settings.ops_technique_id} · 슬리피지 {settings.ops_slippage_rate} · " f"일 상한 {settings.ops_daily_max_trades}", flush=True, ) chart_path, report = render_ops_live_chart( settings, output_path, chart_lookback_days=args.chart_days, ) data_js = chart_path.with_name(f"{chart_path.stem}_data.js") index_path = _write_index_html(live_dir / "index.html", chart_path.name, report) sim = report["filtered_sim"] print(f"\n3년 수익률: {sim.get('total_return_pct'):+.2f}%") print(f"매수/매도: {sim.get('buys_executed')}/{sim.get('sells_executed')}") print(f"HTML: {chart_path}") print(f"데이터: {data_js} ({data_js.stat().st_size / 1e6:.1f} MB)") print(f"인덱스: {index_path}") return 0 if __name__ == "__main__": raise SystemExit(main())