refactor: 프로젝트명 bithumb으로 변경 및 futures 파이프라인 제거

deepcoin 패키지를 bithumb으로 rename하고, 3단계 live 운영·사이징 튜닝·텔레그램 알림을 통합한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dsyoon
2026-06-13 17:47:11 +09:00
parent 4890abd9a6
commit c3334e4f77
129 changed files with 1846 additions and 1642 deletions

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python3
"""1단계: 연속 매수·매도 클러스터별 매수·매도 비율 튜닝 (타점 고정)."""
from __future__ import annotations
import argparse
import json
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 bithumb.config import load_settings
from bithumb.ground_truth.sizing_rules import save_sizing_rules
from bithumb.ground_truth.sizing_tune import tune_sizing_rules
from bithumb.operations.signal_pipeline import run_signal_pipeline
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="연속 매수·매도 클러스터 상태별 사이징 비율 학습",
)
parser.add_argument(
"-o",
"--output",
type=str,
default=None,
help="규칙 JSON 경로 (기본: OPS_SIZING_RULES_JSON)",
)
parser.add_argument(
"--min-bucket-samples",
type=int,
default=5,
help="클러스터 버킷별 최소 샘플 수",
)
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args()
_configure_logging(args.verbose)
settings = load_settings()
output_path = Path(args.output) if args.output else settings.ops_sizing_rules_json
if not output_path.is_absolute():
output_path = ROOT / output_path
print("\n=== 매수·매도 비율 튜닝 (타점 고정) ===", flush=True)
print(
f"기법: {settings.ops_technique_id} · sim {settings.gt_sim_lookback_days}일 · "
f"기본 {settings.ops_buy_cash_pct:.0%}/{settings.ops_sell_coin_pct:.0%}",
flush=True,
)
pipeline = run_signal_pipeline(settings, use_cache=True)
rules, final_sim = tune_sizing_rules(
settings,
pipeline["kept"],
data_end=pipeline["data_end"],
last_mark_price=pipeline["last_price"],
technique_id=pipeline["technique_id"],
min_bucket_samples=args.min_bucket_samples,
)
save_sizing_rules(rules, output_path)
tuning = rules.get("tuning") or {}
print(f"\n기준(고정 10%): {tuning.get('baseline_return_pct'):+.2f}%")
print(
f"학습 후: {final_sim.get('total_return_pct'):+.2f}% · "
f"매수/매도 {final_sim.get('buys_executed')}/{final_sim.get('sells_executed')}"
)
print(
f"전역 비율: 매수 {rules.get('default_buy_cash_pct', 0):.0%} · "
f"매도 {rules.get('default_sell_coin_pct', 0):.0%}"
)
by_cluster = rules.get("by_cluster") or {}
if by_cluster.get("buy") or by_cluster.get("sell"):
print("클러스터별:")
print(json.dumps(by_cluster, ensure_ascii=False, indent=2))
print(f"\n규칙 JSON: {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())