""" 봉 간격 상수·빗썸(Upbit 호환) 캔들 API 경로. 분봉·일봉 외 주봉(10080)·월봉(43200)은 DB 테이블명 `{symbol}_{interval}` 에 그대로 사용합니다. """ from __future__ import annotations from dateutil.relativedelta import relativedelta from config import DAILY_INTERVAL_MIN, MONTH_INTERVAL_MIN, WEEK_INTERVAL_MIN WM_INTERVALS: frozenset[int] = frozenset({WEEK_INTERVAL_MIN, MONTH_INTERVAL_MIN}) # 01_download·ops_sync 대상에서 제외 (DB 적재 안 함) DOWNLOAD_EXCLUDED_INTERVALS: frozenset[int] = frozenset({1}) def is_excluded_from_download(interval: int) -> bool: """01_download·ops_sync에서 건너뛸 간격(1분봉 등).""" return interval in DOWNLOAD_EXCLUDED_INTERVALS def is_week_or_month(interval: int) -> bool: """주봉·월봉 여부.""" return interval in WM_INTERVALS def candle_api_segment(interval: int) -> str: """ REST 경로 세그먼트 (minutes/{n} 제외). Returns: 'weeks' | 'months' | 'days' | minutes/{interval} """ if interval == WEEK_INTERVAL_MIN: return "weeks" if interval == MONTH_INTERVAL_MIN: return "months" if interval >= DAILY_INTERVAL_MIN: return "days" return f"minutes/{interval}" def interval_display_label(interval: int) -> str: """로그·UI용 라벨.""" if interval == WEEK_INTERVAL_MIN: return "주봉" if interval == MONTH_INTERVAL_MIN: return "월봉" if interval >= DAILY_INTERVAL_MIN: return "일봉(1440)" return f"{interval}분봉" def pagination_step(interval: int, chunk_bars: int) -> relativedelta: """ get_coin_more_data 역순 수집 시 `to` 감소 단위. Args: interval: 봉 간격(분 표기). chunk_bars: API 1회 최대 봉 수(겹침 청크). Returns: relativedelta. """ if interval == WEEK_INTERVAL_MIN: return relativedelta(weeks=chunk_bars) if interval == MONTH_INTERVAL_MIN: return relativedelta(months=chunk_bars) return relativedelta(minutes=interval * chunk_bars) def bars_for_months(interval: int, months: int, *, extra_days: int = 0) -> int: """ N개월치 예상 봉 수(여유 포함). Args: interval: 봉 간격. months: 보관·적재 개월 수. extra_days: 일봉 계열 여유 일수. Returns: API 요청 목표 봉 수. """ if interval == WEEK_INTERVAL_MIN: return int(months * 30 / 7) + max(extra_days // 7, 5) if interval == MONTH_INTERVAL_MIN: return months + max(extra_days // 30, 2) if interval >= DAILY_INTERVAL_MIN: return months * 30 + extra_days bars_per_day = (24 * 60) // interval return months * 30 * bars_per_day + 200