#!/usr/bin/env python3 """vol_breakout 현물 롱 — TRX/NEAR/WLD 멀티 tick (Binance 15m ATR 이식).""" from __future__ import annotations import argparse import logging import sys import time 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 bithumb.config import load_settings from bithumb.operations.vol_breakout_runner import VolBreakoutRunner 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 main() -> int: """CLI.""" parser = argparse.ArgumentParser(description="Bithumb vol_breakout 현물 롱 tick") parser.add_argument("--mode", choices=("paper", "live"), default=None) parser.add_argument("--loop", type=int, default=0, metavar="SEC") parser.add_argument("-v", "--verbose", action="store_true") args = parser.parse_args() _configure_logging(args.verbose) if args.mode: import os os.environ["OPS_MODE"] = args.mode settings = load_settings() if not settings.ops_symbols: print("OPS_SYMBOLS 또는 DOWNLOAD_SYMBOLS(BTC 제외)가 필요합니다.", file=sys.stderr) return 1 if settings.ops_mode == "live": if not settings.bithumb_access_key or not settings.bithumb_secret_key: print("live: BITHUMB_ACCESS_KEY / BITHUMB_SECRET_KEY 필요", file=sys.stderr) return 1 print("경고: live — 실제 주문 가능") print( f"vol_breakout {settings.ops_mode} | symbols={settings.ops_symbols} | " f"lookback={settings.vol_lookback} atr={settings.vol_atr_mult} " f"buy_split={settings.vol_buy_split or settings.vol_wallet_pct} " f"exit={settings.vol_exit_enabled}" ) def _once() -> dict: runner = VolBreakoutRunner(settings) report = runner.tick() for row in report.get("results") or []: print( f" {row.get('symbol')}: fills={row.get('fills')} " f"note={row.get('note')}" ) return report if args.loop <= 0: _once() return 0 while True: try: _once() except KeyboardInterrupt: print("\n종료") return 0 except Exception: logging.exception("vol loop tick failed") time.sleep(args.loop) if __name__ == "__main__": raise SystemExit(main())