#!/usr/bin/env python3 """빗썸 WLD(또는 SYMBOL) 최근 N일 캔들 수집 스크립트.""" 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 dataclasses import replace from deepcoin.config import load_settings from deepcoin.data.candle_store import CandleStore from deepcoin.data.downloader import CandleDownloader from deepcoin.data.intervals import interval_label def _configure_logging(verbose: bool) -> None: """로깅 레벨을 설정한다.""" level = logging.DEBUG if verbose else logging.INFO logging.basicConfig( level=level, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) def main() -> int: """CLI 진입점.""" parser = argparse.ArgumentParser(description="빗썸 캔들 데이터 수집") parser.add_argument( "--days", type=int, default=None, help="수집 일수 (기본: .env DOWNLOAD_DAYS 또는 730)", ) parser.add_argument( "--intervals", type=str, default=None, help="쉼표 구분 인터벌. 분봉=분, 일=1440, 주=10080, 월=43200", ) parser.add_argument("-v", "--verbose", action="store_true", help="디버그 로그") args = parser.parse_args() _configure_logging(args.verbose) settings = load_settings() if args.intervals: settings = replace( settings, download_intervals=[ int(x.strip()) for x in args.intervals.split(",") if x.strip() ], ) days = args.days or settings.download_days logging.getLogger(__name__).info( "대상=%s DB=%s days=%s intervals=%s", settings.market, settings.db_path, days, settings.download_intervals, ) store = CandleStore(settings.db_path) try: downloader = CandleDownloader(settings) results = downloader.download_all(store, days=days) print("\n=== 수집 완료 ===") for result in results: count, min_dt, max_dt = store.get_range(settings.symbol, result.interval_min) min_s = min_dt.strftime("%Y-%m-%d %H:%M:%S") if min_dt else "-" max_s = max_dt.strftime("%Y-%m-%d %H:%M:%S") if max_dt else "-" flag = "OK" if result.reached_target else "PARTIAL" label = interval_label(result.interval_min) print( f"[{flag}] {label} ({result.interval_min}) | " f"requests={result.requests} upsert={result.saved_rows} " f"db_rows={count} range={min_s} ~ {max_s}" ) finally: store.close() return 0 if __name__ == "__main__": raise SystemExit(main())