refactor: GT·시뮬·운영 3축 정리 및 hybrid 실거래 정합

Phase C/dry-run·미사용 모듈·재생성 HTML을 제거하고, 운영 체결을
sim_causal_hybrid와 동일한 hybrid 로직으로 통합한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
xavis
2026-06-03 23:50:28 +09:00
parent a16c942be4
commit d7848df6f7
85 changed files with 177180 additions and 196131 deletions

View File

@@ -16,24 +16,36 @@ from dateutil.relativedelta import relativedelta
from config import (
BITHUMB_MINUTE_INTERVALS,
COIN_NAME,
DAILY_INTERVAL_MIN,
DB_PATH,
DOWNLOAD_BACKFILL_EXTRA_BARS,
DOWNLOAD_DAILY_EXTRA_DAYS,
DOWNLOAD_INTERVALS,
DOWNLOAD_INTERVALS_WM,
DOWNLOAD_MIN_INCREMENTAL_BARS,
DOWNLOAD_MONTHS,
DOWNLOAD_MONTHS_1M,
DOWNLOAD_MONTHS_WM,
INCREMENTAL_OVERLAP_BARS,
KR_COINS,
SYMBOL,
)
from deepcoin.data.candle_intervals import (
bars_for_months,
interval_display_label,
is_excluded_from_download,
is_week_or_month,
)
from deepcoin.ops.monitor import Monitor
def bong_count_for_months(interval_minutes: int, months: int) -> int:
"""N개월치 봉 개수(여유분 포함)."""
if is_week_or_month(interval_minutes):
return bars_for_months(
interval_minutes, months, extra_days=DOWNLOAD_DAILY_EXTRA_DAYS
)
days = months * 30
from config import DAILY_INTERVAL_MIN
if interval_minutes >= DAILY_INTERVAL_MIN:
return days + DOWNLOAD_DAILY_EXTRA_DAYS
bars_per_day = (24 * 60) // interval_minutes
@@ -69,36 +81,44 @@ def trim_to_recent_months(data: pd.DataFrame, months: int) -> pd.DataFrame:
def interval_label(interval: int) -> str:
if interval >= 1440:
return "일봉(1440)"
return f"{interval}분봉"
"""로그용 간격 라벨."""
return interval_display_label(interval)
def months_for_interval(interval: int, default_months: int) -> int:
"""간격별 DB 보관 개월 수 (1분봉은 별도 상한)."""
if interval == 1:
return DOWNLOAD_MONTHS_1M
"""간격별 DB 보관 개월 수 (주·월봉은 DOWNLOAD_MONTHS_WM)."""
if is_week_or_month(interval):
return DOWNLOAD_MONTHS_WM
return default_months
def all_download_intervals() -> tuple[int, ...]:
"""분봉·일봉 + 주·월봉 간격 목록(1분 제외, 중복 제거, 순서 유지)."""
seen: set[int] = set()
out: list[int] = []
for iv in (*DOWNLOAD_INTERVALS, *DOWNLOAD_INTERVALS_WM):
if is_excluded_from_download(iv) or iv in seen:
continue
seen.add(iv)
out.append(iv)
return tuple(out)
def download_jobs() -> list[tuple[int, str]]:
labels = {
1: "1분",
3: "3분",
5: "5분",
10: "10분",
15: "15분",
30: "30분",
60: "60분(1시간)",
240: "240분(4시간)",
1440: "1440분(1일)",
}
jobs = []
for iv in DOWNLOAD_INTERVALS:
if iv < 1440 and iv not in BITHUMB_MINUTE_INTERVALS:
"""
01_download 대상 간격.
Returns:
(interval_min, 표시명) 리스트.
"""
jobs: list[tuple[int, str]] = []
for iv in all_download_intervals():
if is_excluded_from_download(iv):
continue
if not is_week_or_month(iv) and iv < 1440 and iv not in BITHUMB_MINUTE_INTERVALS:
print(f"경고: {iv}분봉은 빗썸 API 미지원 — 건너뜀")
continue
jobs.append((iv, labels.get(iv, f"{iv}")))
jobs.append((iv, interval_label(iv)))
return jobs
@@ -374,23 +394,27 @@ def download_symbol(
def download(months: int | None = None) -> None:
"""
WLD 다중 분봉·일봉을 coins.db에 증분 적재합니다.
WLD 다중 분봉·일봉·주봉·월봉을 coins.db에 증분 적재합니다.
간격: config.DOWNLOAD_INTERVALS
간격: DOWNLOAD_INTERVALS + DOWNLOAD_INTERVALS_WM (주·월은 DOWNLOAD_MONTHS_WM, 기본 24=2년)
"""
months = months or DOWNLOAD_MONTHS
default_months = months or DOWNLOAD_MONTHS
monitor = Monitor(cooldown_file=None)
jobs = download_jobs()
intervals_str = ", ".join(str(iv) for iv, _ in jobs)
print(f"=== {COIN_NAME} ({SYMBOL}) -> {DB_PATH} (증분 INSERT) ===")
print(f"보관 {months}개월 | 간격(분): {intervals_str}")
print(
f"보관 분봉·일봉 {default_months}개월 | "
f"주·월봉 {DOWNLOAD_MONTHS_WM}개월 | 간격(분): {intervals_str}"
)
started = datetime.now()
for interval, desc in jobs:
print(f"\n--- {desc} ---")
job_months = months_for_interval(interval, default_months)
try:
download_symbol(monitor, SYMBOL, interval, months)
download_symbol(monitor, SYMBOL, interval, job_months)
except Exception as e:
print(f"오류 interval={interval}: {e}")