#!/usr/bin/env python3 """ 청산·보유 종목의 매수~매도(또는 ~now) 구간 1분봉을 키움 REST로 즉시 백필. 예: nohup python3 -u scripts/backfill_trade_candles.py \\ --like '2026-07-16%' > /tmp/backfill_trade_candles_0716.log 2>&1 & tail -f /tmp/backfill_trade_candles_0716.log """ from __future__ import annotations import argparse import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from database import TradeDB from kis_trader.engine.post_sell_candle_backfill import backfill_trades_from_db def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--like", default="2026-07-16%", help="buy_date LIKE (%% 바인딩)") ap.add_argument( "--strategies", default="", help="콤마 구분 strategy (비우면 전체)", ) ap.add_argument("--no-active", action="store_true", help="active_trades 제외") ap.add_argument("--active-days", type=int, default=5) args = ap.parse_args() strategies = [s.strip() for s in str(args.strategies).split(",") if s.strip()] or None db = TradeDB() try: results = backfill_trades_from_db( db, buy_date_like=str(args.like), strategies=strategies, include_active=not args.no_active, active_max_age_days=int(args.active_days), ) finally: try: db.close() except Exception: pass ok = sum(1 for r in results if r.get("ok")) improved = sum(1 for r in results if int(r.get("after") or 0) > int(r.get("before") or 0)) print( f"DONE jobs={len(results)} ok={ok} improved={improved} " f"upsert_sum={sum(int(r.get('upserted') or 0) for r in results)}" ) for r in results: if not r.get("ok") or int(r.get("after") or 0) > int(r.get("before") or 0): print( f" {r.get('strategy')} {r.get('code')} " f"{r.get('start')}~{r.get('end')} " f"{r.get('before')}→{r.get('after')} " f"upsert={r.get('upserted')} err={r.get('error')!r}" ) return 0 if __name__ == "__main__": raise SystemExit(main())