Files
Bithumb/scripts/3_run_operations.py
xavis 58802bdc5f feat(spot): 3단계 운영 파이프라인 — composite_v3 + MTF paper/live
MTF 필터 백테스트, paper/live 체결, 빗썸 Private API 연동 및 운영 스크립트·설계 문서를 추가해 2단계 전략을 실거래 단계에 연결한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:27:34 +09:00

95 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""3단계: paper/live 운영 1회 tick (신호 확인·체결)."""
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 deepcoin.config import load_settings
from deepcoin.operations.runner import OperationsRunner
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="3단계: DeepCoin 운영 tick")
parser.add_argument(
"--mode",
choices=("paper", "live"),
default=None,
help="OPS_MODE 덮어쓰기 (기본 .env)",
)
parser.add_argument(
"--no-sync",
action="store_true",
help="캔들 증분 동기화 생략",
)
parser.add_argument(
"--loop",
type=int,
default=0,
metavar="SEC",
help="N초마다 반복 실행 (0=1회)",
)
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 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 모드 — 실제 주문이 발생할 수 있습니다.")
runner = OperationsRunner(settings)
sync = not args.no_sync
while True:
report = runner.tick(sync_candles=sync)
port = report["portfolio"]
print("\n=== 3단계 운영 tick ===")
print(f"모드: {report['mode']}")
print(
f"최신 봉 후보: {report.get('latest_bar_candidates', 0)} · "
f"필터 통과: {report['filtered_signals']} · "
f"처리 bar: {report.get('pending_bars', [])}"
)
print(f"이번 체결: {len(report['executions'])}")
print(
f"포트폴리오: 현금 {port['cash_krw']:,.0f}원 · "
f"코인 {port['coin_qty']:.8f} {settings.symbol}"
)
print(f"리포트: {settings.ops_report_json}")
if args.loop <= 0:
break
time.sleep(args.loop)
return 0
if __name__ == "__main__":
raise SystemExit(main())