feat(vol_breakout): 15m 현물 롱 라이브·모니터·cron 운영 추가
vol_breakout 멀티종목 tick, vol_live HTML 모니터, 마감 봉만 저장하는 캔들 다운로드, 텔레그램 체결 알림, cron/watch 감시 스크립트 및 테스트를 포함한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
87
scripts/3_run_vol_breakout.py
Normal file
87
scripts/3_run_vol_breakout.py
Normal file
@@ -0,0 +1,87 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user