#!/usr/bin/env python3 """ WBS-9.3: ATR20 자동 충전 절차 조건: atr20 IS NULL AND close_price IS NOT NULL """ def calculate_atr20(closes: list[float], period: int = 20) -> float: """ Calculate ATR (Average True Range) for 20 days. 입력: close 가격 리스트 (최소 20일) 출력: ATR20 (숫자) """ if len(closes) < period: return None # True Range 계산 (간소화 버전: 현재 close 기반) trs = [] for i in range(1, len(closes)): high = closes[i] low = closes[i] prev_close = closes[i - 1] tr = max( high - low, abs(high - prev_close), abs(low - prev_close) ) trs.append(tr) if not trs: return None # ATR = SMA of True Range (20일) atr = sum(trs[-period:]) / min(period, len(trs)) return round(atr, 2) def auto_fill_atr20(row: dict, historical_closes: list[float] = None) -> dict: """ 자동 충전: atr20 필드 입력: row: 현재 행 (atr20 = None) historical_closes: 과거 close 가격 (최소 20일) 출력: row (atr20 채워짐) 또는 원본 (실패시) """ if not historical_closes or row.get("atr20") is not None: return row atr20 = calculate_atr20(historical_closes) if atr20 is not None: row["atr20"] = atr20 row["_fill_source"] = "auto_fill_atr20_v1" return row